bool ChatHandler::HandleUnJailCommand(const char *args) { char *charname = strtok((char*)args, " "); std::string cname; if (charname == NULL) return false; else cname = charname; uint64 GUID = sObjectMgr->GetPlayerGUIDByName(cname.c_str()); Player *chr = sObjectMgr->GetPlayer(GUID); if (chr) { if (chr->GetName() == m_session->GetPlayerName()) { SendSysMessage(LANG_JAIL_NO_UNJAIL); return true; } if (chr->m_jail_isjailed) { chr->m_jail_isjailed = false; chr->m_jail_release = 0; chr->m_jail_times = chr->m_jail_times-1; chr->_SaveJail(); if (chr->m_jail_times == 0) { SQLTransaction trans = CharacterDatabase.BeginTransaction(); CharacterDatabase.PQuery("DELETE FROM `jail` WHERE `guid`='%u' LIMIT 1", chr->GetGUIDLow()); CharacterDatabase.CommitTransaction(trans); } PSendSysMessage(LANG_JAIL_WAS_UNJAILED, cname.c_str()); ChatHandler(chr).PSendSysMessage(LANG_JAIL_YOURE_UNJAILED, m_session->GetPlayerName()); chr->CastSpell(chr,8690,false); //chr->GetSession()->LogoutPlayer(false); } else PSendSysMessage(LANG_JAIL_CHAR_NOTJAILED, cname.c_str()); return true; } else { SQLTransaction trans = CharacterDatabase.BeginTransaction(); QueryResult jresult = CharacterDatabase.PQuery("SELECT * FROM `jail` WHERE `guid`='%u' LIMIT 1", GUID_LOPART(GUID)); CharacterDatabase.CommitTransaction(trans); if (!jresult) { PSendSysMessage(LANG_JAIL_CHAR_NOTJAILED, cname.c_str()); return true; } else { Field *fields = jresult->Fetch(); uint32 jail_times = fields[4].GetUInt32()-1; if (jail_times == 0) { SQLTransaction trans = CharacterDatabase.BeginTransaction(); CharacterDatabase.PQuery("DELETE FROM `jail` WHERE `guid`='%u' LIMIT 1", fields[0].GetUInt32()); CharacterDatabase.CommitTransaction(trans); } else { SQLTransaction trans = CharacterDatabase.BeginTransaction(); CharacterDatabase.PQuery("UPDATE `jail` SET `release`='0',`times`='%u' WHERE `guid`='%u' LIMIT 1", jail_times, fields[0].GetUInt32()); CharacterDatabase.CommitTransaction(trans); } PSendSysMessage(LANG_JAIL_WAS_UNJAILED, cname.c_str()); return true; } } return true; }
void WorldSession::HandlePlayerLogin(LoginQueryHolder *holder) { ObjectGuid playerGuid = holder->GetGuid(); Player *pCurrChar = new Player(this); pCurrChar->GetMotionMaster()->Initialize(); // "GetAccountId()==db stored account id" checked in LoadFromDB (prevent login not own character using cheating tools) if(!pCurrChar->LoadFromDB(playerGuid, holder)) { KickPlayer(); // disconnect client, player no set to session and it will not deleted or saved at kick delete pCurrChar; // delete it manually delete holder; // delete all unprocessed queries m_playerLoading = false; return; } SetPlayer(pCurrChar); WorldPacket data( SMSG_LOGIN_VERIFY_WORLD, 20 ); data << pCurrChar->GetMapId(); data << pCurrChar->GetPositionX(); data << pCurrChar->GetPositionY(); data << pCurrChar->GetPositionZ(); data << pCurrChar->GetOrientation(); SendPacket(&data); data.Initialize( SMSG_ACCOUNT_DATA_TIMES, 128 ); for(int i = 0; i < 32; ++i) data << uint32(0); SendPacket(&data); // Send MOTD (1.12.1 not have SMSG_MOTD, so do it in another way) { uint32 linecount=0; std::string str_motd = sWorld.GetMotd(); std::string::size_type pos, nextpos; std::string motd; pos = 0; while ( (nextpos= str_motd.find('@',pos)) != std::string::npos ) { if (nextpos != pos) { ChatHandler(pCurrChar).PSendSysMessage(str_motd.substr(pos,nextpos-pos).c_str()); ++linecount; } pos = nextpos + 1; } if (pos < str_motd.length()) { ChatHandler(pCurrChar).PSendSysMessage(str_motd.substr(pos).c_str()); ++linecount; } DEBUG_LOG( "WORLD: Sent motd (SMSG_MOTD)" ); } //QueryResult *result = CharacterDatabase.PQuery("SELECT guildid,rank FROM guild_member WHERE guid = '%u'",pCurrChar->GetGUIDLow()); QueryResult *resultGuild = holder->GetResult(PLAYER_LOGIN_QUERY_LOADGUILD); if(resultGuild) { Field *fields = resultGuild->Fetch(); pCurrChar->SetInGuild(fields[0].GetUInt32()); pCurrChar->SetRank(fields[1].GetUInt32()); delete resultGuild; } else if(pCurrChar->GetGuildId()) // clear guild related fields in case wrong data about nonexistent membership { pCurrChar->SetInGuild(0); pCurrChar->SetRank(0); } if(pCurrChar->GetGuildId() != 0) { Guild* guild = sGuildMgr.GetGuildById(pCurrChar->GetGuildId()); if(guild) { data.Initialize(SMSG_GUILD_EVENT, (2+guild->GetMOTD().size()+1)); data << uint8(GE_MOTD); data << uint8(1); data << guild->GetMOTD(); SendPacket(&data); DEBUG_LOG( "WORLD: Sent guild-motd (SMSG_GUILD_EVENT)" ); guild->BroadcastEvent(GE_SIGNED_ON, pCurrChar->GetObjectGuid(), pCurrChar->GetName()); } else { // remove wrong guild data sLog.outError("Player %s (GUID: %u) marked as member of nonexistent guild (id: %u), removing guild membership for player.",pCurrChar->GetName(),pCurrChar->GetGUIDLow(),pCurrChar->GetGuildId()); pCurrChar->SetInGuild(0); } } if(!pCurrChar->isAlive()) pCurrChar->SendCorpseReclaimDelay(true); pCurrChar->SendInitialPacketsBeforeAddToMap(); //Show cinematic at the first time that player login if( !pCurrChar->getCinematic() ) { pCurrChar->setCinematic(1); if(ChrRacesEntry const* rEntry = sChrRacesStore.LookupEntry(pCurrChar->getRace())) pCurrChar->SendCinematicStart(rEntry->CinematicSequence); } if (!pCurrChar->GetMap()->Add(pCurrChar)) { // normal delayed teleport protection not applied (and this correct) for this case (Player object just created) AreaTrigger const* at = sObjectMgr.GetGoBackTrigger(pCurrChar->GetMapId()); if(at) pCurrChar->TeleportTo(at->target_mapId, at->target_X, at->target_Y, at->target_Z, pCurrChar->GetOrientation()); else pCurrChar->TeleportToHomebind(); } sObjectAccessor.AddObject(pCurrChar); //DEBUG_LOG("Player %s added to Map.",pCurrChar->GetName()); pCurrChar->GetSocial()->SendFriendList(); pCurrChar->GetSocial()->SendIgnoreList(); pCurrChar->SendInitialPacketsAfterAddToMap(); static SqlStatementID updChars; static SqlStatementID updAccount; SqlStatement stmt = CharacterDatabase.CreateStatement(updChars, "UPDATE characters SET online = 1 WHERE guid = ?"); stmt.PExecute(pCurrChar->GetGUIDLow()); stmt = LoginDatabase.CreateStatement(updAccount, "UPDATE account SET active_realm_id = ? WHERE id = ?"); stmt.PExecute(realmID, GetAccountId()); pCurrChar->SetInGameTime( WorldTimer::getMSTime() ); // announce group about member online (must be after add to player list to receive announce to self) if (Group *group = pCurrChar->GetGroup()) group->SendUpdate(); // friend status sSocialMgr.SendFriendStatus(pCurrChar, FRIEND_ONLINE, pCurrChar->GetObjectGuid(), true); // Place character in world (and load zone) before some object loading pCurrChar->LoadCorpse(); // setting Ghost+speed if dead if (pCurrChar->m_deathState != ALIVE) { // not blizz like, we must correctly save and load player instead... if(pCurrChar->getRace() == RACE_NIGHTELF) pCurrChar->CastSpell(pCurrChar, 20584, true); // auras SPELL_AURA_INCREASE_SPEED(+speed in wisp form), SPELL_AURA_INCREASE_SWIM_SPEED(+swim speed in wisp form), SPELL_AURA_TRANSFORM (to wisp form) pCurrChar->CastSpell(pCurrChar, 8326, true); // auras SPELL_AURA_GHOST, SPELL_AURA_INCREASE_SPEED(why?), SPELL_AURA_INCREASE_SWIM_SPEED(why?) pCurrChar->SetMovement(MOVE_WATER_WALK); } pCurrChar->ContinueTaxiFlight(); // Load pet if any (if player not alive and in taxi flight or another then pet will remember as temporary unsummoned) pCurrChar->LoadPet(); // Set FFA PvP for non GM in non-rest mode if(sWorld.IsFFAPvPRealm() && !pCurrChar->isGameMaster() && !pCurrChar->HasFlag(PLAYER_FLAGS,PLAYER_FLAGS_RESTING) ) pCurrChar->SetFFAPvP(true); if(pCurrChar->HasFlag(PLAYER_FLAGS, PLAYER_FLAGS_CONTESTED_PVP)) pCurrChar->SetContestedPvP(); // Apply at_login requests if(pCurrChar->HasAtLoginFlag(AT_LOGIN_RESET_SPELLS)) { pCurrChar->resetSpells(); SendNotification(LANG_RESET_SPELLS); } if(pCurrChar->HasAtLoginFlag(AT_LOGIN_RESET_TALENTS)) { pCurrChar->resetTalents(true); SendNotification(LANG_RESET_TALENTS); // we can use SMSG_TALENTS_INVOLUNTARILY_RESET here } if (pCurrChar->HasAtLoginFlag(AT_LOGIN_FIRST)) pCurrChar->RemoveAtLoginFlag(AT_LOGIN_FIRST); // show time before shutdown if shutdown planned. if (sWorld.IsShutdowning()) sWorld.ShutdownMsg(true,pCurrChar); if (sWorld.getConfig(CONFIG_BOOL_ALL_TAXI_PATHS)) pCurrChar->SetTaxiCheater(true); if (pCurrChar->isGameMaster()) SendNotification(LANG_GM_ON); if (!pCurrChar->isGMVisible()) SendNotification(LANG_INVISIBLE_INVISIBLE); std::string IP_str = GetRemoteAddress(); sLog.outChar("Account: %d (IP: %s) Login Character:[%s] (guid: %u)", GetAccountId(), IP_str.c_str(), pCurrChar->GetName(), pCurrChar->GetGUIDLow()); if(!pCurrChar->IsStandState() && !pCurrChar->hasUnitState(UNIT_STAT_STUNNED)) pCurrChar->SetStandState(UNIT_STAND_STATE_STAND); m_playerLoading = false; delete holder; }
void UpdateAI(const uint32 uiDiff) { if (!m_pInstance) return; if (!m_creature->SelectHostileTarget() || !m_creature->getVictim()) { if (m_pInstance->GetData(TYPE_THADDIUS) == SPECIAL) // make thaddius attackable 15 seconds after stalagg&feugen are dead if(m_uiStartTimer < uiDiff) m_creature->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); else m_uiStartTimer -= uiDiff; return; } if(m_uiScreamTimer < uiDiff) { switch(urand(0,3)) { case 0: DoScriptText(SAY_SCREAM1,m_creature); break; case 1: DoScriptText(SAY_SCREAM2,m_creature); break; case 2: DoScriptText(SAY_SCREAM3,m_creature); break; case 3: DoScriptText(SAY_SCREAM4,m_creature); break; } m_uiScreamTimer = urand(15000, 60000); } else m_uiScreamTimer -= uiDiff; if(!m_creature->IsWithinDistInMap(m_creature->getVictim(),5.f)) // this is not correct, spell should be cast when checked if no player is near Thaddius { if(m_uiBallLightningTimer < uiDiff) { m_creature->CastSpell(m_creature->getVictim(),SPELL_BALL_LIGHTNING,true); m_uiBallLightningTimer = urand(5000, 10000); // timers probably not right } else m_uiBallLightningTimer -= uiDiff; } if (m_uiChainLightningTimer < uiDiff) { m_creature->CastSpell(m_creature->SelectAttackingTarget(ATTACKING_TARGET_RANDOM,0),m_bIsRegularMode?SPELL_CHAIN_LIGHTNING:SPELL_CHAIN_LIGHTNING_H,true); m_uiChainLightningTimer = urand(14000,16000); } else m_uiChainLightningTimer -= uiDiff; if (m_uiPolarityShiftTimer < uiDiff) { // get count of positive and negative charges uint32 m_uiNegativeCharge = m_creature->GetMap()->GetPlayersCountExceptGMs() / 2; uint32 m_uiPositiveCharge = m_creature->GetMap()->GetPlayersCountExceptGMs() - m_uiNegativeCharge; // split players into positive and negative charged Map* pMap = m_creature->GetMap(); Map::PlayerList const& pPlayers = pMap->GetPlayers(); if (!pPlayers.isEmpty()) { for (Map::PlayerList::const_iterator itr = pPlayers.begin(); itr != pPlayers.end(); ++itr) { if (itr->getSource()->isGameMaster()) continue; Player *pTarget = itr->getSource(); pTarget->RemoveAurasDueToSpell(SPELL_CHARGE_POSITIVE_DMGBUFF); pTarget->RemoveAurasDueToSpell(SPELL_CHARGE_NEGATIVE_DMGBUFF); pTarget->RemoveAurasDueToSpell(SPELL_CHARGE_POSITIVE_NEARDMG); pTarget->RemoveAurasDueToSpell(SPELL_CHARGE_NEGATIVE_NEARDMG); if(((rand()%2) && m_uiNegativeCharge) || (!m_uiPositiveCharge)) { pTarget->CastSpell(pTarget,SPELL_CHARGE_NEGATIVE_NEARDMG,true); m_uiNegativeCharge--; } else { pTarget->CastSpell(pTarget,SPELL_CHARGE_POSITIVE_NEARDMG,true); m_uiPositiveCharge--; } } } m_uiPolarityShiftTimer = 30000; } else m_uiPolarityShiftTimer -= uiDiff; if (m_uiEnrageTimer < uiDiff) { m_creature->CastSpell(m_creature,SPELL_BERSERK,true); m_uiEnrageTimer = 10*MINUTE*IN_MILLISECONDS; } else m_uiEnrageTimer -= uiDiff; DoMeleeAttackIfReady(); }
void BattleGroundWS::Update(uint32 diff) { BattleGround::Update(diff); if (GetStatus() == STATUS_IN_PROGRESS) { if (m_FlagState[BG_TEAM_ALLIANCE] == BG_WS_FLAG_STATE_WAIT_RESPAWN) { m_FlagsTimer[BG_TEAM_ALLIANCE] -= diff; if (m_FlagsTimer[BG_TEAM_ALLIANCE] < 0) { m_FlagsTimer[BG_TEAM_ALLIANCE] = 0; RespawnFlag(ALLIANCE, true); } } if (m_FlagState[BG_TEAM_ALLIANCE] == BG_WS_FLAG_STATE_ON_GROUND) { m_FlagsDropTimer[BG_TEAM_ALLIANCE] -= diff; if (m_FlagsDropTimer[BG_TEAM_ALLIANCE] < 0) { m_FlagsDropTimer[BG_TEAM_ALLIANCE] = 0; RespawnFlagAfterDrop(ALLIANCE); } } if (m_FlagState[BG_TEAM_HORDE] == BG_WS_FLAG_STATE_WAIT_RESPAWN) { m_FlagsTimer[BG_TEAM_HORDE] -= diff; if (m_FlagsTimer[BG_TEAM_HORDE] < 0) { m_FlagsTimer[BG_TEAM_HORDE] = 0; RespawnFlag(HORDE, true); } } if (m_FlagState[BG_TEAM_HORDE] == BG_WS_FLAG_STATE_ON_GROUND) { m_FlagsDropTimer[BG_TEAM_HORDE] -= diff; if (m_FlagsDropTimer[BG_TEAM_HORDE] < 0) { m_FlagsDropTimer[BG_TEAM_HORDE] = 0; RespawnFlagAfterDrop(HORDE); } } if (m_FlagState[BG_TEAM_ALLIANCE] >= BG_WS_FLAG_STATE_ON_PLAYER && m_FlagState[BG_TEAM_HORDE] >= BG_WS_FLAG_STATE_ON_PLAYER) { if (m_FocusedAssault < BG_WS_FIVE_MINUTES) { for(uint8 i = 0; i < BG_TEAMS_COUNT; i++) { Player* carrier = sObjectMgr.GetPlayer(m_FlagKeepers[i]); if(!carrier) continue; if((!carrier->HasAura(BG_WS_SPELL_FOCUSED_ASSAULT) && !carrier->HasAura(BG_WS_SPELL_BRUTAL_ASSAULT)) || (m_FocusedAssaultExtra && m_FocusedAssault < diff)) carrier->CastSpell(carrier, (m_FocusedAssault < diff) ? BG_WS_SPELL_BRUTAL_ASSAULT : BG_WS_SPELL_FOCUSED_ASSAULT, true); } if(m_FocusedAssault < BG_WS_FIVE_MINUTES && m_FocusedAssaultExtra) m_FocusedAssaultExtra = false; }else m_FocusedAssault -= diff; }else { m_FocusedAssault = BG_WS_CARRIER_DEBUFF; m_FocusedAssaultExtra = true; } if (m_EndTimer > 0) if (m_EndTimer <= diff) { uint32 allianceScore = GetTeamScore(ALLIANCE); uint32 hordeScore = GetTeamScore(HORDE); if (allianceScore > hordeScore) EndBattleGround(ALLIANCE); else if (allianceScore < hordeScore) EndBattleGround(HORDE); else { // if 0 => tie EndBattleGround(m_LastCapturedFlagTeam); } } else { uint32 minutesLeftPrev = GetRemainingTimeInMinutes(); m_EndTimer -= diff; uint32 minutesLeft = GetRemainingTimeInMinutes(); if (minutesLeft != minutesLeftPrev) UpdateWorldState(BG_WS_TIME_REMAINING, minutesLeft); } } }
void ArathiBasin::EventUpdateResources(uint32 Team) { uint32 resource_fields[2] = { AB_ALLIANCE_RESOURCES, AB_HORDE_RESOURCES }; uint32 current_resources = m_resources[Team]; uint32 current_bases = m_capturedBases[Team]; if(current_bases>5) current_bases=5; // figure out how much resources we have to add to that team based on the number of captured bases. current_resources += (PointBonusPerUpdate[current_bases]); // did it change? if(current_resources == m_resources[Team]) return; // check for overflow if(current_resources > RESOURCES_WINVAL) current_resources = RESOURCES_WINVAL; m_resources[Team] = current_resources; if((current_resources - m_lastHonorGainResources[Team]) >= RESOURCES_TO_GAIN_BH) { m_mainLock.Acquire(); for(set<uint32>::iterator itr = m_players[Team].begin(); itr != m_players[Team].end(); ++itr) { Player *plr = objmgr.GetPlayer(*itr); if ( plr != NULL ) plr->m_bgScore.BonusHonor += BASE_BH_GAIN; } UpdatePvPData(); m_mainLock.Release(); } // update the world states SetWorldState(resource_fields[Team], current_resources); if(current_resources >= RESOURCES_WARNING_THRESHOLD && !m_nearingVictory[Team]) { m_nearingVictory[Team] = true; SendChatMessage(Team ? CHAT_MSG_BG_EVENT_HORDE : CHAT_MSG_BG_EVENT_ALLIANCE, (uint64)0, "The %s has gathered %u resources and is nearing victory!", Team ? "Horde" : "Alliance", current_resources); uint32 sound = SOUND_ALLIANCE_BGALMOSTEND - Team; PlaySoundToAll(sound); } // check for winning condition if(current_resources == RESOURCES_WINVAL) { m_ended = true; m_winningteam = Team; m_nextPvPUpdateTime = 0; sEventMgr.RemoveEvents(this); sEventMgr.AddEvent(((CBattleground*)this), &CBattleground::Close, EVENT_BATTLEGROUND_CLOSE, 120000, 1,0); /* add the marks of honor to all players */ m_mainLock.Acquire(); SpellEntry * winner_spell = dbcSpell.LookupEntry(24953); SpellEntry * loser_spell = dbcSpell.LookupEntry(24952); for(uint32 i = 0; i < 2; ++i) { for(set<uint32>::iterator itr = m_players[i].begin(); itr != m_players[i].end(); ++itr) { Player *plr = objmgr.GetPlayer(*itr); if ( plr != NULL ) { plr->Root(); if(i == m_winningteam) plr->CastSpell(plr, winner_spell, true); else plr->CastSpell(plr, loser_spell, true); } } } m_mainLock.Release(); } }
void HandleEnergize(SpellEffIndex effIndex) { Player* caster = GetCaster()->ToPlayer(); // No boomy, no deal. if (caster->GetPrimaryTalentTree(caster->GetActiveSpec()) != TALENT_TREE_DRUID_BALANCE) return; switch (GetSpellInfo()->Id) { case SPELL_DRUID_WRATH: { energizeAmount = -GetSpellInfo()->Effects[effIndex].BasePoints; // -13 // If we are set to fill the lunar side or we've just logged in with 0 power.. if ((!caster->HasAura(SPELL_DRUID_SOLAR_ECLIPSE_MARKER) && caster->HasAura(SPELL_DRUID_LUNAR_ECLIPSE_MARKER)) || caster->GetPower(POWER_ECLIPSE) == 0) { caster->CastCustomSpell(caster, SPELL_DRUID_ECLIPSE_GENERAL_ENERGIZE, &energizeAmount, 0, 0, true); // If the energize was due to 0 power, cast the eclipse marker aura if (!caster->HasAura(SPELL_DRUID_LUNAR_ECLIPSE_MARKER)) caster->CastSpell(caster, SPELL_DRUID_LUNAR_ECLIPSE_MARKER, true); } // The energizing effect brought us out of the solar eclipse, remove the aura if (caster->HasAura(SPELL_DRUID_SOLAR_ECLIPSE) && caster->GetPower(POWER_ECLIPSE) <= 0) caster->RemoveAurasDueToSpell(SPELL_DRUID_SOLAR_ECLIPSE); break; } case SPELL_DRUID_STARFIRE: { energizeAmount = GetSpellInfo()->Effects[effIndex].BasePoints; // 20 // If we are set to fill the solar side or we've just logged in with 0 power.. if ((!caster->HasAura(SPELL_DRUID_LUNAR_ECLIPSE_MARKER) && caster->HasAura(SPELL_DRUID_SOLAR_ECLIPSE_MARKER)) || caster->GetPower(POWER_ECLIPSE) == 0) { caster->CastCustomSpell(caster, SPELL_DRUID_ECLIPSE_GENERAL_ENERGIZE, &energizeAmount, 0, 0, true); // If the energize was due to 0 power, cast the eclipse marker aura if (!caster->HasAura(SPELL_DRUID_SOLAR_ECLIPSE_MARKER)) caster->CastSpell(caster, SPELL_DRUID_SOLAR_ECLIPSE_MARKER, true); } // The energizing effect brought us out of the lunar eclipse, remove the aura if (caster->HasAura(SPELL_DRUID_LUNAR_ECLIPSE) && caster->GetPower(POWER_ECLIPSE) >= 0) caster->RemoveAura(SPELL_DRUID_LUNAR_ECLIPSE); break; } case SPELL_DRUID_STARSURGE: { // If we are set to fill the solar side or we've just logged in with 0 power (confirmed with sniffs) if ((!caster->HasAura(SPELL_DRUID_LUNAR_ECLIPSE_MARKER) && caster->HasAura(SPELL_DRUID_SOLAR_ECLIPSE_MARKER)) || caster->GetPower(POWER_ECLIPSE) == 0) { energizeAmount = GetSpellInfo()->Effects[effIndex].BasePoints; // 15 caster->CastCustomSpell(caster, SPELL_DRUID_STARSURGE_ENERGIZE, &energizeAmount, 0, 0, true); // If the energize was due to 0 power, cast the eclipse marker aura if (!caster->HasAura(SPELL_DRUID_SOLAR_ECLIPSE_MARKER)) caster->CastSpell(caster, SPELL_DRUID_SOLAR_ECLIPSE_MARKER, true); } else if (!caster->HasAura(SPELL_DRUID_SOLAR_ECLIPSE_MARKER) && caster->HasAura(SPELL_DRUID_LUNAR_ECLIPSE_MARKER)) { energizeAmount = -GetSpellInfo()->Effects[effIndex].BasePoints; // -15 caster->CastCustomSpell(caster, SPELL_DRUID_STARSURGE_ENERGIZE, &energizeAmount, 0, 0, true); } // The energizing effect brought us out of the lunar eclipse, remove the aura if (caster->HasAura(SPELL_DRUID_LUNAR_ECLIPSE) && caster->GetPower(POWER_ECLIPSE) >= 0) caster->RemoveAura(SPELL_DRUID_LUNAR_ECLIPSE); // The energizing effect brought us out of the solar eclipse, remove the aura else if (caster->HasAura(SPELL_DRUID_SOLAR_ECLIPSE) && caster->GetPower(POWER_ECLIPSE) <= 0) caster->RemoveAura(SPELL_DRUID_SOLAR_ECLIPSE); break; } } }
void HonorHandler::OnPlayerKilledUnit( Player *pPlayer, Unit* pVictim ) { if( pVictim == NULL || pPlayer == NULL || !pVictim->IsPlayer() || !pPlayer->IsPlayer() ) return; if( static_cast< Player* >( pVictim )->m_honorless ) return; if( pVictim->IsPlayer() ) { if( pPlayer->m_bg ) { if( static_cast< Player* >( pVictim )->m_bgTeam == pPlayer->m_bgTeam ) return; // patch 2.4, players killed >50 times in battlegrounds won't be worth honor for the rest of that bg if( static_cast<Player*>(pVictim)->m_bgScore.Deaths >= 50 ) return; } else { if( pPlayer->GetTeam() == static_cast< Player* >( pVictim )->GetTeam() ) return; } } // Calculate points int32 Points = CalculateHonorPointsForKill(pPlayer, pVictim); if( Points > 0 ) { if( pPlayer->m_bg ) { // hackfix for battlegrounds (since the gorups there are disabled, we need to do this manually) vector<Player*> toadd; uint32 t = pPlayer->m_bgTeam; toadd.reserve(15); // shouldnt have more than this pPlayer->m_bg->Lock(); set<Player*> * s = &pPlayer->m_bg->m_players[t]; for(set<Player*>::iterator itr = s->begin(); itr != s->end(); ++itr) { if((*itr) == pPlayer || (*itr)->isInRange(pPlayer,40.0f)) toadd.push_back(*itr); } if( toadd.size() > 0 ) { uint32 pts = Points / (uint32)toadd.size(); for(vector<Player*>::iterator vtr = toadd.begin(); vtr != toadd.end(); ++vtr) { AddHonorPointsToPlayer(*vtr, pts); (*vtr)->m_killsToday++; (*vtr)->m_killsLifetime++; pPlayer->m_bg->HookOnHK(*vtr); if(pVictim) { // Send PVP credit WorldPacket data(SMSG_PVP_CREDIT, 12); uint32 pvppoints = pts * 10; data << pvppoints << pVictim->GetGUID() << uint32(static_cast< Player* >(pVictim)->GetPVPRank()); (*vtr)->GetSession()->SendPacket(&data); } } } pPlayer->m_bg->Unlock(); } else if(pPlayer->GetGroup()) { Group *pGroup = pPlayer->GetGroup(); Player *gPlayer = NULL; int32 GroupPoints; pGroup->Lock(); GroupPoints = (Points / (pGroup->MemberCount() ? pGroup->MemberCount() : 1)); GroupMembersSet::iterator gitr; for(uint32 k = 0; k < pGroup->GetSubGroupCount(); k++) { for(gitr = pGroup->GetSubGroup(k)->GetGroupMembersBegin(); gitr != pGroup->GetSubGroup(k)->GetGroupMembersEnd(); ++gitr) { gPlayer = (*gitr)->m_loggedInPlayer; if(gPlayer && (gPlayer == pPlayer || gPlayer->isInRange(pPlayer,100.0f))) // visible range { gPlayer->m_killsToday++; gPlayer->m_killsLifetime++; if(gPlayer->m_bg) gPlayer->m_bg->HookOnHK(gPlayer); sHookInterface.OnHonorableKill(gPlayer, ((Player*)pVictim)); AddHonorPointsToPlayer(gPlayer, GroupPoints); if(pVictim) { // Send PVP credit WorldPacket data(SMSG_PVP_CREDIT, 12); uint32 pvppoints = GroupPoints * 10; data << pvppoints << pVictim->GetGUID() << uint32(static_cast< Player* >(pVictim)->GetPVPRank()); gPlayer->GetSession()->SendPacket(&data); } //patch by emsy // If we are in Halaa if(pPlayer->GetZoneId() == 3518) { // Add Halaa Battle Token SpellEntry * pvp_token_spell = dbcSpell.LookupEntry(gPlayer->GetTeam()? 33004 : 33005); gPlayer->CastSpell(gPlayer, pvp_token_spell, true); } // If we are in Hellfire Peninsula if(pPlayer->GetZoneId() == 3483) { // Add Mark of Thrallmar/Honor Hold SpellEntry * pvp_token_spell = dbcSpell.LookupEntry(gPlayer->GetTeam()? 32158 : 32155); gPlayer->CastSpell(gPlayer, pvp_token_spell, true); } } } } pGroup->Unlock(); } else { pPlayer->m_killsToday++; pPlayer->m_killsLifetime++; AddHonorPointsToPlayer(pPlayer, Points); if(pPlayer->m_bg) pPlayer->m_bg->HookOnHK(pPlayer); sHookInterface.OnHonorableKill(pPlayer, ((Player*)pVictim)); if(pVictim) { // Send PVP credit WorldPacket data(SMSG_PVP_CREDIT, 12); uint32 pvppoints = Points * 10; data << pvppoints << pVictim->GetGUID() << uint32(static_cast< Player* >(pVictim)->GetPVPRank()); pPlayer->GetSession()->SendPacket(&data); } //patch by emsy // If we are in Halaa if(pPlayer->GetZoneId() == 3518) { // Add Halaa Battle Token SpellEntry * halaa_spell = dbcSpell.LookupEntry(pPlayer->GetTeam()? 33004 : 33005); pPlayer->CastSpell(pPlayer, halaa_spell, true); } } } }
void StrandOfTheAncient::PrepareRound(){ roundprogress = SOTA_ROUND_PREPARATION; if( BattleRound == 1 ){ Attackers = RandomUInt( 1 ); if( Attackers == TEAM_ALLIANCE ) Defenders = TEAM_HORDE; else Defenders = TEAM_ALLIANCE; }else{ std::swap( Attackers, Defenders ); } for( uint32 i = 0; i < GATE_COUNT; i++ ){ m_gates[ i ]->Rebuild(); m_gates[ i ]->SetFaction( TeamFactions[ Defenders ] ); } m_endgate->Rebuild(); m_endgate->SetFaction( TeamFactions[ Defenders ] ); m_relic->SetFaction( TeamFactions[ Attackers ] ); for( uint32 i = 0; i < GATE_COUNT; i++ ) m_gateTransporters[ i ]->SetFaction( TeamFactions[ Defenders ] ); for( uint32 i = 0; i < SOTA_NUM_CANONS; i++ ){ if( canon[ i ] != NULL ) canon[ i ]->Despawn( 0, 0 ); canon[ i ] = SpawnCreature( 27894, CanonLocations[ i ], TeamFactions[ Defenders ] ); } for( uint32 i = 0; i < SOTA_NUM_DOCK_DEMOLISHERS; i++ ){ Creature *c = demolisher[ i ]; demolisher[ i ] = SpawnCreature( 28781, DemolisherLocations[ i ], TeamFactions[ Attackers ] ); if( c != NULL ) c->Despawn( 0, 0 ); } for( uint32 i = SOTA_WEST_WS_DEMOLISHER_INDEX; i < SOTA_NUM_DEMOLISHERS; i++ ){ if( demolisher[ i ] != NULL ){ demolisher[ i ]->Despawn( 0, 0 ); demolisher[ i ] = NULL; } } SOTACPStates state; if( Attackers == TEAM_ALLIANCE ){ state = SOTA_CP_STATE_HORDE_CONTROL; SetWorldState( WORLDSTATE_SOTA_HORDE_ATTACKER, 0 ); SetWorldState( WORLDSTATE_SOTA_ALLIANCE_ATTACKER, 1 ); SetWorldState( WORLDSTATE_SOTA_SHOW_ALLY_ROUND, 1 ); SetWorldState( WORLDSTATE_SOTA_SHOW_HORDE_ROUND, 0 ); SetWorldState( WORLDSTATE_SOTA_SHOW_ALLY_DEFENSE, 0 ); SetWorldState( WORLDSTATE_SOTA_SHOW_HORDE_DEFENSE, 1 ); SetWorldState( WORLDSTATE_SOTA_SHOW_ALLY_BEACHHEAD1, 1 ); SetWorldState( WORLDSTATE_SOTA_SHOW_ALLY_BEACHHEAD2, 1 ); SetWorldState( WORLDSTATE_SOTA_SHOW_HORDE_BEACHHEAD1, 0 ); SetWorldState( WORLDSTATE_SOTA_SHOW_HORDE_BEACHHEAD2, 0 ); }else{ state = SOTA_CP_STATE_ALLY_CONTROL; SetWorldState( WORLDSTATE_SOTA_HORDE_ATTACKER, 1 ); SetWorldState( WORLDSTATE_SOTA_ALLIANCE_ATTACKER, 0 ); SetWorldState( WORLDSTATE_SOTA_SHOW_ALLY_ROUND, 0 ); SetWorldState( WORLDSTATE_SOTA_SHOW_HORDE_ROUND, 1 ); SetWorldState( WORLDSTATE_SOTA_SHOW_ALLY_DEFENSE, 1 ); SetWorldState( WORLDSTATE_SOTA_SHOW_HORDE_DEFENSE, 0 ); SetWorldState( WORLDSTATE_SOTA_SHOW_ALLY_BEACHHEAD1, 0 ); SetWorldState( WORLDSTATE_SOTA_SHOW_ALLY_BEACHHEAD2, 0 ); SetWorldState( WORLDSTATE_SOTA_SHOW_HORDE_BEACHHEAD1, 1 ); SetWorldState( WORLDSTATE_SOTA_SHOW_HORDE_BEACHHEAD2, 1 ); } SpawnControlPoint( SOTA_CONTROL_POINT_EAST_GY, state ); SpawnControlPoint( SOTA_CONTROL_POINT_WEST_GY, state ); SpawnControlPoint( SOTA_CONTROL_POINT_SOUTH_GY, state ); SpawnGraveyard( SOTA_GY_ATTACKER_BEACH, Attackers ); SpawnGraveyard( SOTA_GY_DEFENDER, Defenders ); if( BattleRound == 2 ){ // Teleport players to their place and cast preparation on them m_mainLock.Acquire(); for( std::set< Player* >::iterator itr = m_players[ Attackers ].begin(); itr != m_players[ Attackers ].end(); ++itr ){ Player *p = *itr; p->SafeTeleport( p->GetMapId(), p->GetInstanceID(), sotaAttackerStartingPosition[ 0 ] ); p->CastSpell( p, BG_PREPARATION, true ); } for( std::set< Player* >::iterator itr = m_players[ Defenders ].begin(); itr != m_players[ Defenders ].end(); ++itr ){ Player *p = *itr; p->SafeTeleport( p->GetMapId(), p->GetInstanceID(), sotaDefenderStartingPosition ); p->CastSpell( p, BG_PREPARATION, true ); } m_mainLock.Release(); sEventMgr.AddEvent( this, &StrandOfTheAncient::StartRound, EVENT_SOTA_START_ROUND, 1 * 10 * 1000, 1, 0 ); } };
void WorldSession::HandleMoveTeleportAck(WorldPacket& recv_data) { sLog->outDebug(LOG_FILTER_NETWORKIO, "MSG_MOVE_TELEPORT_ACK"); BitStream mask = recv_data.ReadBitStream(8); uint32 flags, time; recv_data >> flags >> time; ByteBuffer bytes(8, true); recv_data.ReadXorByte(mask[6], bytes[1]); recv_data.ReadXorByte(mask[0], bytes[3]); recv_data.ReadXorByte(mask[1], bytes[2]); recv_data.ReadXorByte(mask[7], bytes[0]); recv_data.ReadXorByte(mask[5], bytes[6]); recv_data.ReadXorByte(mask[3], bytes[4]); recv_data.ReadXorByte(mask[2], bytes[7]); recv_data.ReadXorByte(mask[4], bytes[5]); uint64 guid = BitConverter::ToUInt64(bytes); sLog->outStaticDebug("Guid " UI64FMTD, guid); sLog->outStaticDebug("Flags %u, time %u", flags, time/IN_MILLISECONDS); Unit* mover = _player->_mover; Player* plMover = mover->GetTypeId() == TYPEID_PLAYER ? (Player*)mover : NULL; if (!plMover || !plMover->IsBeingTeleportedNear()) return; if (guid != plMover->GetGUID()) return; plMover->SetSemaphoreTeleportNear(false); uint32 old_zone = plMover->GetZoneId(); WorldLocation const& dest = plMover->GetTeleportDest(); plMover->UpdatePosition(dest, true); uint32 newzone, newarea; plMover->GetZoneAndAreaId(newzone, newarea); plMover->UpdateZone(newzone, newarea); // new zone if (old_zone != newzone) { // honorless target if (plMover->pvpInfo.inHostileArea) plMover->CastSpell(plMover, 2479, true); // in friendly area else if (plMover->IsPvP() && !plMover->HasFlag(PLAYER_FLAGS, PLAYER_FLAGS_IN_PVP)) plMover->UpdatePvP(false, false); } // resummon pet GetPlayer()->ResummonPetTemporaryUnSummonedIfAny(); //lets process all delayed operations on successful teleport GetPlayer()->ProcessDelayedOperations(); }
void HandleDummy(SpellEffIndex /*effIndex*/) { Player* player = GetCaster()->GetCharmerOrOwnerPlayerOrPlayerItself(); if (!player) return; uint32 spellId = 0; switch (GetSpellInfo()->Id) { case SPELL_FEAST_ON_TURKEY: spellId = SPELL_PLAYER_TURKEY; break; case SPELL_FEAST_ON_STUFFING: spellId = SPELL_PLAYER_STUFFING; break; case SPELL_FEAST_ON_PIE: spellId = SPELL_PLAYER_PIE; break; case SPELL_FEAST_ON_CRANBERRY: spellId = SPELL_PLAYER_CRANBERRY; break; case SPELL_FEAST_ON_SWEET_POTATOES: spellId = SPELL_PLAYER_SWEET_POTATOES; break; } if (spellId) { player->CastSpell(player, spellId, true); if (AuraEffect* aur = player->GetAuraEffectDummy(spellId)) { if (aur->GetBase()->GetStackAmount() >= 5) { switch (spellId) { case SPELL_PLAYER_TURKEY: player->CastSpell(player, SPELL_WELL_FED_TURKEY, true); break; case SPELL_PLAYER_STUFFING: player->CastSpell(player, SPELL_WELL_FED_STUFFING, true); break; case SPELL_PLAYER_PIE: player->CastSpell(player, SPELL_WELL_FED_PIE, true); break; case SPELL_PLAYER_CRANBERRY: player->CastSpell(player, SPELL_WELL_FED_CRANBERRY, true); break; case SPELL_PLAYER_SWEET_POTATOES: player->CastSpell(player, SPELL_WELL_FED_SWEET_POTATOES, true); break; } uint8 count = 0; Unit::AuraEffectList const& dummyAuras = player->GetAuraEffectsByType(SPELL_AURA_DUMMY); for (Unit::AuraEffectList::const_iterator i = dummyAuras.begin(); i != dummyAuras.end(); ++i) { if ((*i)->GetId() >= SPELL_PLAYER_CRANBERRY && (*i)->GetId() <= SPELL_PLAYER_PIE) if ((*i)->GetBase()->GetStackAmount() >= 5) ++count; } // Cast spirit of sharing if (count >= 5) player->CastSpell(player, SPELL_SPIRIT_OF_SHARING, true); } } } }
void WorldSession::HandlePlayerLogin(LoginQueryHolder *holder) { uint64 playerGuid = holder->GetGuid(); Player *pCurrChar = new Player(this); pCurrChar->GetMotionMaster()->Initialize(); // "GetAccountId()==db stored account id" checked in LoadFromDB (prevent login not own character using cheating tools) if(!pCurrChar->LoadFromDB(GUID_LOPART(playerGuid), holder)) { KickPlayer(); // disconnect client, player no set to session and it will not deleted or saved at kick delete pCurrChar; // delete it manually delete holder; // delete all unprocessed queries m_playerLoading = false; return; } SetPlayer(pCurrChar); pCurrChar->SendDungeonDifficulty(false); WorldPacket data( SMSG_LOGIN_VERIFY_WORLD, 20 ); data << pCurrChar->GetMapId(); data << pCurrChar->GetPositionX(); data << pCurrChar->GetPositionY(); data << pCurrChar->GetPositionZ(); data << pCurrChar->GetOrientation(); SendPacket(&data); // load player specific part before send times LoadAccountData(holder->GetResult(PLAYER_LOGIN_QUERY_LOADACCOUNTDATA),PER_CHARACTER_CACHE_MASK); SendAccountDataTimes(PER_CHARACTER_CACHE_MASK); data.Initialize(SMSG_FEATURE_SYSTEM_STATUS, 2); // added in 2.2.0 data << uint8(2); // unknown value data << uint8(0); // enable(1)/disable(0) voice chat interface in client SendPacket(&data); // Send MOTD { data.Initialize(SMSG_MOTD, 50); // new in 2.0.1 data << (uint32)0; uint32 linecount=0; std::string str_motd = sWorld.GetMotd(); std::string::size_type pos, nextpos; pos = 0; while ( (nextpos= str_motd.find('@',pos)) != std::string::npos ) { if (nextpos != pos) { data << str_motd.substr(pos, nextpos-pos); ++linecount; } pos = nextpos + 1; } if (pos < str_motd.length()) { data << str_motd.substr(pos); ++linecount; } data.put(0, linecount); SendPacket( &data ); DEBUG_LOG( "WORLD: Sent motd (SMSG_MOTD)" ); } //QueryResult *result = CharacterDatabase.PQuery("SELECT guildid,rank FROM guild_member WHERE guid = '%u'",pCurrChar->GetGUIDLow()); QueryResult *resultGuild = holder->GetResult(PLAYER_LOGIN_QUERY_LOADGUILD); if(resultGuild) { Field *fields = resultGuild->Fetch(); pCurrChar->SetInGuild(fields[0].GetUInt32()); pCurrChar->SetRank(fields[1].GetUInt32()); delete resultGuild; } else if(pCurrChar->GetGuildId()) // clear guild related fields in case wrong data about non existed membership { pCurrChar->SetInGuild(0); pCurrChar->SetRank(0); } if(pCurrChar->GetGuildId() != 0) { Guild* guild = objmgr.GetGuildById(pCurrChar->GetGuildId()); if(guild) { data.Initialize(SMSG_GUILD_EVENT, (2+guild->GetMOTD().size()+1)); data << (uint8)GE_MOTD; data << (uint8)1; data << guild->GetMOTD(); SendPacket(&data); DEBUG_LOG( "WORLD: Sent guild-motd (SMSG_GUILD_EVENT)" ); data.Initialize(SMSG_GUILD_EVENT, (5+10)); // we guess size data<<(uint8)GE_SIGNED_ON; data<<(uint8)1; data<<pCurrChar->GetName(); data<<pCurrChar->GetGUID(); guild->BroadcastPacket(&data); DEBUG_LOG( "WORLD: Sent guild-signed-on (SMSG_GUILD_EVENT)" ); // Increment online members of the guild guild->IncOnlineMemberCount(); } else { // remove wrong guild data sLog.outError("Player %s (GUID: %u) marked as member not existed guild (id: %u), removing guild membership for player.",pCurrChar->GetName(),pCurrChar->GetGUIDLow(),pCurrChar->GetGuildId()); pCurrChar->SetInGuild(0); } } data.Initialize(SMSG_LEARNED_DANCE_MOVES, 4+4); data << uint32(0); data << uint32(0); SendPacket(&data); if(!pCurrChar->isAlive()) pCurrChar->SendCorpseReclaimDelay(true); pCurrChar->SendInitialPacketsBeforeAddToMap(); //Show cinematic at the first time that player login if( !pCurrChar->getCinematic() ) { pCurrChar->setCinematic(1); if(ChrClassesEntry const* cEntry = sChrClassesStore.LookupEntry(pCurrChar->getClass())) { if (cEntry->CinematicSequence) pCurrChar->SendCinematicStart(cEntry->CinematicSequence); else if (ChrRacesEntry const* rEntry = sChrRacesStore.LookupEntry(pCurrChar->getRace())) pCurrChar->SendCinematicStart(rEntry->CinematicSequence); } } if (!pCurrChar->GetMap()->Add(pCurrChar)) { AreaTrigger const* at = objmgr.GetGoBackTrigger(pCurrChar->GetMapId()); if(at) pCurrChar->TeleportTo(at->target_mapId, at->target_X, at->target_Y, at->target_Z, pCurrChar->GetOrientation()); else pCurrChar->TeleportTo(pCurrChar->m_homebindMapId, pCurrChar->m_homebindX, pCurrChar->m_homebindY, pCurrChar->m_homebindZ, pCurrChar->GetOrientation()); } ObjectAccessor::Instance().AddObject(pCurrChar); //sLog.outDebug("Player %s added to Map.",pCurrChar->GetName()); pCurrChar->SendInitialPacketsAfterAddToMap(); CharacterDatabase.PExecute("UPDATE characters SET online = 1 WHERE guid = '%u'", pCurrChar->GetGUIDLow()); loginDatabase.PExecute("UPDATE account SET active_realm_id = %d WHERE id = '%u'", realmID, GetAccountId()); pCurrChar->SetInGameTime( getMSTime() ); // announce group about member online (must be after add to player list to receive announce to self) if(Group *group = pCurrChar->GetGroup()) { //pCurrChar->groupInfo.group->SendInit(this); // useless group->SendUpdate(); } // friend status sSocialMgr.SendFriendStatus(pCurrChar, FRIEND_ONLINE, pCurrChar->GetGUIDLow(), true); // Place character in world (and load zone) before some object loading pCurrChar->LoadCorpse(); // setting Ghost+speed if dead if (pCurrChar->m_deathState != ALIVE) { // not blizz like, we must correctly save and load player instead... if(pCurrChar->getRace() == RACE_NIGHTELF) pCurrChar->CastSpell(pCurrChar, 20584, true, 0);// auras SPELL_AURA_INCREASE_SPEED(+speed in wisp form), SPELL_AURA_INCREASE_SWIM_SPEED(+swim speed in wisp form), SPELL_AURA_TRANSFORM (to wisp form) pCurrChar->CastSpell(pCurrChar, 8326, true, 0); // auras SPELL_AURA_GHOST, SPELL_AURA_INCREASE_SPEED(why?), SPELL_AURA_INCREASE_SWIM_SPEED(why?) pCurrChar->SetMovement(MOVE_WATER_WALK); } pCurrChar->ContinueTaxiFlight(); // reset for all pets before pet loading if(pCurrChar->HasAtLoginFlag(AT_LOGIN_RESET_PET_TALENTS)) Pet::resetTalentsForAllPetsOf(pCurrChar); // Load pet if any (if player not alive and in taxi flight or another then pet will remember as temporary unsummoned) pCurrChar->LoadPet(); // Set FFA PvP for non GM in non-rest mode if(sWorld.IsFFAPvPRealm() && !pCurrChar->isGameMaster() && !pCurrChar->HasFlag(PLAYER_FLAGS,PLAYER_FLAGS_RESTING) ) pCurrChar->SetByteFlag(UNIT_FIELD_BYTES_2, 1, UNIT_BYTE2_FLAG_FFA_PVP); if(pCurrChar->HasFlag(PLAYER_FLAGS, PLAYER_FLAGS_CONTESTED_PVP)) pCurrChar->SetContestedPvP(); // Apply at_login requests if(pCurrChar->HasAtLoginFlag(AT_LOGIN_RESET_SPELLS)) { pCurrChar->resetSpells(); SendNotification(LANG_RESET_SPELLS); } if(pCurrChar->HasAtLoginFlag(AT_LOGIN_RESET_TALENTS)) { pCurrChar->resetTalents(true); pCurrChar->SendTalentsInfoData(false); // original talents send already in to SendInitialPacketsBeforeAddToMap, resend reset state SendNotification(LANG_RESET_TALENTS); } // show time before shutdown if shutdown planned. if(sWorld.IsShutdowning()) sWorld.ShutdownMsg(true,pCurrChar); if(sWorld.getConfig(CONFIG_ALL_TAXI_PATHS)) pCurrChar->SetTaxiCheater(true); if(pCurrChar->isGameMaster()) SendNotification(LANG_GM_ON); std::string IP_str = GetRemoteAddress(); sLog.outChar("Account: %d (IP: %s) Login Character:[%s] (guid:%u)", GetAccountId(), IP_str.c_str(), pCurrChar->GetName(), pCurrChar->GetGUIDLow()); if(!pCurrChar->IsStandState() && !pCurrChar->hasUnitState(UNIT_STAT_STUNNED)) pCurrChar->SetStandState(UNIT_STAND_STATE_STAND); m_playerLoading = false; delete holder; }
void WorldSession::HandleMoveTeleportAck(WorldPacket& recvPacket) { SF_LOG_DEBUG("network", "CMSG_MOVE_TELEPORT_ACK"); ObjectGuid guid; uint32 flags, time; recvPacket >> time >> flags; guid[0] = recvPacket.ReadBit(); guid[7] = recvPacket.ReadBit(); guid[3] = recvPacket.ReadBit(); guid[5] = recvPacket.ReadBit(); guid[4] = recvPacket.ReadBit(); guid[6] = recvPacket.ReadBit(); guid[1] = recvPacket.ReadBit(); guid[2] = recvPacket.ReadBit(); recvPacket.ReadByteSeq(guid[4]); recvPacket.ReadByteSeq(guid[1]); recvPacket.ReadByteSeq(guid[6]); recvPacket.ReadByteSeq(guid[7]); recvPacket.ReadByteSeq(guid[0]); recvPacket.ReadByteSeq(guid[2]); recvPacket.ReadByteSeq(guid[5]); recvPacket.ReadByteSeq(guid[3]); SF_LOG_DEBUG("network", "Guid " UI64FMTD, uint64(guid)); SF_LOG_DEBUG("network", "Flags %u, time %u", flags, time/IN_MILLISECONDS); Player* plMover = _player->m_mover->ToPlayer(); if (!plMover || !plMover->IsBeingTeleportedNear()) return; if (guid != plMover->GetGUID()) return; plMover->SetSemaphoreTeleportNear(false); uint32 old_zone = plMover->GetZoneId(); WorldLocation const& dest = plMover->GetTeleportDest(); plMover->UpdatePosition(dest, true); uint32 newzone, newarea; plMover->GetZoneAndAreaId(newzone, newarea); plMover->UpdateZone(newzone, newarea); // new zone if (old_zone != newzone) { // honorless target if (plMover->pvpInfo.IsHostile) plMover->CastSpell(plMover, 2479, true); // in friendly area else if (plMover->IsPvP() && !plMover->HasFlag(PLAYER_FIELD_PLAYER_FLAGS, PLAYER_FLAGS_IN_PVP)) plMover->UpdatePvP(false, false); } // resummon pet GetPlayer()->ResummonPetTemporaryUnSummonedIfAny(); // resummon battle pet GetPlayer()->GetBattlePetMgr()->ResummonLastBattlePet(); //lets process all delayed operations on successful teleport GetPlayer()->ProcessDelayedOperations(); }
void WorldSession::HandleMoveTeleportAck(WorldPacket& recvData) { #if defined(ENABLE_EXTRAS) && defined(ENABLE_EXTRA_LOGS) sLog->outDebug(LOG_FILTER_NETWORKIO, "MSG_MOVE_TELEPORT_ACK"); #endif uint64 guid; recvData.readPackGUID(guid); uint32 flags, time; recvData >> flags >> time; // unused #if defined(ENABLE_EXTRAS) && defined(ENABLE_EXTRA_LOGS) sLog->outStaticDebug("Guid " UI64FMTD, guid); #endif #if defined(ENABLE_EXTRAS) && defined(ENABLE_EXTRA_LOGS) sLog->outStaticDebug("Flags %u, time %u", flags, time/IN_MILLISECONDS); #endif Player* plMover = _player->m_mover->ToPlayer(); if (!plMover || !plMover->IsBeingTeleportedNear()) return; if (guid != plMover->GetGUID()) return; plMover->SetSemaphoreTeleportNear(0); uint32 old_zone = plMover->GetZoneId(); WorldLocation const& dest = plMover->GetTeleportDest(); Position oldPos(*plMover); plMover->UpdatePosition(dest, true); // xinef: teleport pets if they are not unsummoned if (Pet* pet = plMover->GetPet()) { if (!pet->IsWithinDist3d(plMover, plMover->GetMap()->GetVisibilityRange()-5.0f)) pet->NearTeleportTo(plMover->GetPositionX(), plMover->GetPositionY(), plMover->GetPositionZ(), pet->GetOrientation()); } if (oldPos.GetExactDist2d(plMover) > 100.0f) { uint32 newzone, newarea; plMover->GetZoneAndAreaId(newzone, newarea, true); plMover->UpdateZone(newzone, newarea); // new zone if (old_zone != newzone) { // honorless target if (plMover->pvpInfo.IsHostile) plMover->CastSpell(plMover, 2479, true); // in friendly area else if (plMover->IsPvP() && !plMover->HasFlag(PLAYER_FLAGS, PLAYER_FLAGS_IN_PVP)) plMover->UpdatePvP(false, false); } } // resummon pet GetPlayer()->ResummonPetTemporaryUnSummonedIfAny(); //lets process all delayed operations on successful teleport GetPlayer()->ProcessDelayedOperations(); plMover->GetMotionMaster()->ReinitializeMovement(); // pussywizard: client forgets about losing control, resend it if (plMover->HasUnitState(UNIT_STATE_FLEEING|UNIT_STATE_CONFUSED) || plMover->IsCharmed()) // only in such cases SetClientControl(self, false) is sent plMover->SetClientControl(plMover, false, true); }
bool ChatHandler::HandleFlyMountCommand(char* /*args*/) { Player *chr = m_session->GetPlayer(); // Zakaz: if( chr->isInCombat() // - Pocas combatu || chr->GetMap()->Instanceable() // - V instancii || !chr->CanFreeMove() ) // - Ak sa nemoze volne pohybovat (sap, taxi ...) { SendSysMessage(LANG_YOU_IN_COMBAT); SetSentErrorMessage(true); return false; } // smrt if(chr->isDead()) { SendSysMessage("You are dead!"); SetSentErrorMessage(true); return false; } // zakaz pre low lvl if(chr->getLevel() != 70) { SendSysMessage("Required 70 level!"); SetSentErrorMessage(true); return false; } switch(chr->GetAreaId()) { //case 1637: // orgrimmar //case 1519: // stormwind //case 3487: // silvermoon case 168: // Tirisfal glades sea case 1256: // Azshara sea case 4080: // ioqd SendSysMessage("Not allowed here!"); SetSentErrorMessage(true); return false; } // cely ioqd a Diremaul if(chr->GetZoneId() == 4080 || chr->GetZoneId() == 2557) { SendSysMessage("Not allowed here!"); SetSentErrorMessage(true); return false; } // ine mapy ako azeroth if(chr->GetMapId() != 0 && chr->GetMapId() != 1 && chr->GetMapId() != 530) { SendSysMessage("Not allowed here!"); SetSentErrorMessage(true); return false; } // dismount chr->RemoveSpellsCausingAura(SPELL_AURA_MOUNTED); Item * firstpositem = chr->GetItemByPos(INVENTORY_SLOT_BAG_0, 23); if(firstpositem && ( firstpositem->GetProto()->RequiredSkill == 762 && firstpositem->GetProto()->RequiredSkillRank > 150 || // 762 = riding skill firstpositem->GetProto()->ItemId == 34060 || // Flying Machine Control firstpositem->GetProto()->ItemId == 34061 )) // Turbo-Charged Flying Machine Control chr->CastSpell(chr, firstpositem->GetProto()->Spells[0].SpellId, false); else if(chr->getClass() == CLASS_DRUID) { // odstranenie formy chr->RemoveSpellsCausingAura(SPELL_AURA_MOD_SHAPESHIFT); // swift flight form chr->CastSpell(chr, 40120, false); } // alici grifina else if (chr->GetTeam() == ALLIANCE) chr->CastSpell(chr, 32290, false); // horda netopiera else chr->CastSpell(chr, 32295, false); return true; }
void Arena::EndBattleground(uint32 winner) { // arena rating calculation if (isRated()) { uint32 loserTeamRating = 0; uint32 loserMatchmakerRating = 0; int32 loserChange = 0; int32 loserMatchmakerChange = 0; uint32 winnerTeamRating = 0; uint32 winnerMatchmakerRating = 0; int32 winnerChange = 0; int32 winnerMatchmakerChange = 0; ArenaTeam* winnerArenaTeam = sArenaTeamMgr->GetArenaTeamById(GetArenaTeamIdForTeam(winner)); ArenaTeam* loserArenaTeam = sArenaTeamMgr->GetArenaTeamById(GetArenaTeamIdForTeam(GetOtherTeam(winner))); if (winnerArenaTeam && loserArenaTeam && winnerArenaTeam != loserArenaTeam) { loserTeamRating = loserArenaTeam->GetRating(); loserMatchmakerRating = GetArenaMatchmakerRating(GetOtherTeam(winner)); winnerTeamRating = winnerArenaTeam->GetRating(); winnerMatchmakerRating = GetArenaMatchmakerRating(winner); if (winner != 0) { winnerMatchmakerChange = winnerArenaTeam->WonAgainst(winnerMatchmakerRating, loserMatchmakerRating, winnerChange); loserMatchmakerChange = loserArenaTeam->LostAgainst(loserMatchmakerRating, winnerMatchmakerRating, loserChange); TC_LOG_DEBUG("bg.arena", "match Type: %u --- Winner: old rating: %u, rating gain: %d, old MMR: %u, MMR gain: %d --- Loser: old rating: %u, rating loss: %d, old MMR: %u, MMR loss: %d ---", GetArenaType(), winnerTeamRating, winnerChange, winnerMatchmakerRating, winnerMatchmakerChange, loserTeamRating, loserChange, loserMatchmakerRating, loserMatchmakerChange); SetArenaMatchmakerRating(winner, winnerMatchmakerRating + winnerMatchmakerChange); SetArenaMatchmakerRating(GetOtherTeam(winner), loserMatchmakerRating + loserMatchmakerChange); // bg team that the client expects is different to TeamId // alliance 1, horde 0 uint8 winnerTeam = winner == ALLIANCE ? BG_TEAM_ALLIANCE : BG_TEAM_HORDE; uint8 loserTeam = winner == ALLIANCE ? BG_TEAM_HORDE : BG_TEAM_ALLIANCE; _arenaTeamScores[winnerTeam].Assign(winnerChange, winnerMatchmakerRating, winnerArenaTeam->GetName()); _arenaTeamScores[loserTeam].Assign(loserChange, loserMatchmakerRating, loserArenaTeam->GetName()); TC_LOG_DEBUG("bg.arena", "Arena match Type: %u for Team1Id: %u - Team2Id: %u ended. WinnerTeamId: %u. Winner rating: +%d, Loser rating: %d", GetArenaType(), GetArenaTeamIdByIndex(TEAM_ALLIANCE), GetArenaTeamIdByIndex(TEAM_HORDE), winnerArenaTeam->GetId(), winnerChange, loserChange); if (sWorld->getBoolConfig(CONFIG_ARENA_LOG_EXTENDED_INFO)) for (auto const& score : PlayerScores) if (Player* player = ObjectAccessor::FindConnectedPlayer(ObjectGuid(HighGuid::Player, score.first))) { TC_LOG_DEBUG("bg.arena", "Statistics match Type: %u for %s (GUID: %u, Team: %d, IP: %s): %s", GetArenaType(), player->GetName().c_str(), score.first, player->GetArenaTeamId(GetArenaType() == 5 ? 2 : GetArenaType() == 3), player->GetSession()->GetRemoteAddress().c_str(), score.second->ToString().c_str()); } } // Deduct 16 points from each teams arena-rating if there are no winners after 45+2 minutes else { _arenaTeamScores[BG_TEAM_ALLIANCE].Assign(ARENA_TIMELIMIT_POINTS_LOSS, winnerMatchmakerRating, winnerArenaTeam->GetName()); _arenaTeamScores[BG_TEAM_HORDE].Assign(ARENA_TIMELIMIT_POINTS_LOSS, loserMatchmakerRating, loserArenaTeam->GetName()); winnerArenaTeam->FinishGame(ARENA_TIMELIMIT_POINTS_LOSS); loserArenaTeam->FinishGame(ARENA_TIMELIMIT_POINTS_LOSS); } uint8 aliveWinners = GetAlivePlayersCountByTeam(winner); for (auto const& i : GetPlayers()) { uint32 team = i.second.Team; if (i.second.OfflineRemoveTime) { // if rated arena match - make member lost! if (team == winner) winnerArenaTeam->OfflineMemberLost(i.first, loserMatchmakerRating, winnerMatchmakerChange); else loserArenaTeam->OfflineMemberLost(i.first, winnerMatchmakerRating, loserMatchmakerChange); continue; } Player* player = _GetPlayer(i.first, i.second.OfflineRemoveTime != 0, "Arena::EndBattleground"); if (!player) continue; // per player calculation if (team == winner) { // update achievement BEFORE personal rating update uint32 rating = player->GetArenaPersonalRating(winnerArenaTeam->GetSlot()); player->UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_WIN_RATED_ARENA, rating ? rating : 1); player->UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_WIN_ARENA, GetMapId()); // Last standing - Rated 5v5 arena & be solely alive player if (GetArenaType() == ARENA_TYPE_5v5 && aliveWinners == 1 && player->IsAlive()) player->CastSpell(player, SPELL_LAST_MAN_STANDING, true); winnerArenaTeam->MemberWon(player, loserMatchmakerRating, winnerMatchmakerChange); } else { loserArenaTeam->MemberLost(player, winnerMatchmakerRating, loserMatchmakerChange); // Arena lost => reset the win_rated_arena having the "no_lose" condition player->ResetAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_WIN_RATED_ARENA, ACHIEVEMENT_CRITERIA_CONDITION_NO_LOSE); } } // save the stat changes winnerArenaTeam->SaveToDB(); loserArenaTeam->SaveToDB(); // send updated arena team stats to players // this way all arena team members will get notified, not only the ones who participated in this match winnerArenaTeam->NotifyStatsChanged(); loserArenaTeam->NotifyStatsChanged(); } } // end battleground Battleground::EndBattleground(winner); }
void HandleForceCast(SpellEffIndex effIndex) { PreventHitDefaultEffect(effIndex); Player* target = ObjectAccessor::GetPlayer(*GetCaster(), GetCaster()->GetAI()->GetGUID(DATA_EYEBEAM_TARGET)); target->CastSpell(target, GetSpellInfo()->Effects[effIndex].TriggerSpell, true); }
void HonorHandler::OnPlayerKilled(Player* pPlayer, Player* pVictim) { if(pVictim->m_honorless) return; if(pPlayer->m_bg) { if(pVictim->m_bgTeam == pPlayer->m_bgTeam) return; // patch 2.4, players killed >50 times in battlegrounds won't be worth honor for the rest of that bg if(pVictim->m_bgScore.Deaths >= 50) return; } else { if(pPlayer->GetTeam() == pVictim->GetTeam()) return; } // Calculate points int32 Points = 0; if(pPlayer != pVictim) Points = CalculateHonorPointsForKill(pPlayer->getLevel(), pVictim->getLevel()); if(Points > 0) { if(pPlayer->m_bg) { // hackfix for battlegrounds (since the groups there are disabled, we need to do this manually) vector<Player*> toadd; uint32 t = pPlayer->m_bgTeam; toadd.reserve(15); // shouldn't have more than this pPlayer->m_bg->Lock(); set<Player*> * s = &pPlayer->m_bg->m_players[t]; for(set<Player*>::iterator itr = s->begin(); itr != s->end(); ++itr) { // Also check that the player is in range, and the player is alive. if((*itr) == pPlayer || ((*itr)->isAlive() && (*itr)->isInRange(pPlayer, 100.0f))) toadd.push_back(*itr); } if(toadd.size() > 0) { uint32 pts = Points / (uint32)toadd.size(); for(vector<Player*>::iterator vtr = toadd.begin(); vtr != toadd.end(); ++vtr) { AddHonorPointsToPlayer(*vtr, pts); (*vtr)->m_killsToday++; (*vtr)->m_killsLifetime++; pPlayer->m_bg->HookOnHK(*vtr); if(pVictim) { // Send PVP credit WorldPacket data(SMSG_PVP_CREDIT, 12); uint32 pvppoints = pts * 10; data << pvppoints << pVictim->GetGUID() << uint32(pVictim->GetPVPRank()); (*vtr)->GetSession()->SendPacket(&data); } } } pPlayer->m_bg->Unlock(); } else { set<Player*> contributors; // First loop: Get all the people in the attackermap. pVictim->UpdateOppFactionSet(); for(std::set<Object*>::iterator itr = pVictim->GetInRangeOppFactsSetBegin(); itr != pVictim->GetInRangeOppFactsSetEnd(); itr++) { if(!(*itr)->IsPlayer()) continue; bool added = false; Player* plr = TO_PLAYER(*itr); if(pVictim->CombatStatus.m_attackers.find(plr->GetGUID()) != pVictim->CombatStatus.m_attackers.end()) { added = true; contributors.insert(plr); } if(added && plr->GetGroup()) { Group* pGroup = plr->GetGroup(); uint32 groups = pGroup->GetSubGroupCount(); for(uint32 i = 0; i < groups; i++) { SubGroup* sg = pGroup->GetSubGroup(i); if(!sg) continue; for(GroupMembersSet::iterator itr2 = sg->GetGroupMembersBegin(); itr2 != sg->GetGroupMembersEnd(); itr2++) { PlayerInfo* pi = (*itr2); Player* gm = objmgr.GetPlayer(pi->guid); if(!gm) continue; if(gm->isInRange(pVictim, 100.0f)) contributors.insert(gm); } } } } for(set<Player*>::iterator itr = contributors.begin(); itr != contributors.end(); itr++) { Player* pAffectedPlayer = (*itr); if(!pAffectedPlayer) continue; pAffectedPlayer->m_killsToday++; pAffectedPlayer->m_killsLifetime++; if(pAffectedPlayer->m_bg) pAffectedPlayer->m_bg->HookOnHK(pAffectedPlayer); int32 contributorpts = Points / (int32)contributors.size(); AddHonorPointsToPlayer(pAffectedPlayer, contributorpts); sHookInterface.OnHonorableKill(pAffectedPlayer, pVictim); WorldPacket data(SMSG_PVP_CREDIT, 12); uint32 pvppoints = contributorpts * 10; // Why *10? data << pvppoints << pVictim->GetGUID() << uint32(pVictim->GetPVPRank()); pAffectedPlayer->GetSession()->SendPacket(&data); int PvPToken = 0; Config.OptionalConfig.GetInt("Extra", "PvPToken", &PvPToken); if(PvPToken > 0) { int PvPTokenID = 0; Config.OptionalConfig.GetInt("Extra", "PvPTokenID", &PvPTokenID); if(PvPTokenID > 0) { Item* PvPTokenItem = objmgr.CreateItem(PvPTokenID, pAffectedPlayer); if(PvPTokenItem) { PvPTokenItem->SoulBind(); pAffectedPlayer->GetItemInterface()->AddItemToFreeSlot(PvPTokenItem); } } } if(pAffectedPlayer->GetZoneId() == 3518) { // Add Halaa Battle Token SpellEntry* pvp_token_spell = dbcSpellEntry.LookupEntry(pAffectedPlayer->IsTeamHorde() ? 33004 : 33005); pAffectedPlayer->CastSpell(pAffectedPlayer, pvp_token_spell, true); } // If we are in Hellfire Peninsula <http://www.wowwiki.com/Hellfire_Peninsula#World_PvP_-_Hellfire_Fortifications> if(pAffectedPlayer->GetZoneId() == 3483) { // Hellfire Horde Controlled Towers /*if(pAffectedPlayer->GetMapMgr()->GetWorldState(2478) != 3 && pAffectedPlayer->GetTeam() == 1) return; // Hellfire Alliance Controlled Towers if(pAffectedPlayer->GetMapMgr()->GetWorldState(2476) != 3 && pAffectedPlayer->GetTeam() == 0) return; */ // Add Mark of Thrallmar/Honor Hold SpellEntry* pvp_token_spell = dbcSpellEntry.LookupEntry(pAffectedPlayer->IsTeamHorde() ? 32158 : 32155); pAffectedPlayer->CastSpell(pAffectedPlayer, pvp_token_spell, true); } } } } }
void UpdateAI(const uint32 diff) { if (!UpdateVictim()) return; events.Update(diff); while (uint32 eventId = events.ExecuteEvent()) { switch (eventId) { case EVENT_WITHER_WILL: if (!me->HasAura(SPELL_BOUNDS_OF_REALITY_2)) { if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM)) { me->CastSpell(target, SPELL_WITHER_WILL, false); me->CastSpell(target, SPELL_WITHER_WILL, false); } } events.ScheduleEvent(EVENT_WITHER_WILL, 5000); break; case EVENT_TOUCH_OF_NOTHINGNESS: if (!me->HasAura(SPELL_BOUNDS_OF_REALITY_2)) if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM)) me->CastSpell(target, SPELL_TOUCH_OF_NOTHINGNESS, false); events.ScheduleEvent(EVENT_TOUCH_OF_NOTHINGNESS, 30000); break; case EVENT_BOUNDS_OF_REALITY: { Talk(TALK_FIGMENT_01 + urand(0, 1)); if (me->GetInstanceScript()) me->GetInstanceScript()->SetData(TYPE_CLASS_FIGMENT, 0); me->CastSpell(me, SPELL_BOUNDS_OF_REALITY_2, false); //Spawns the figment of doubt Map::PlayerList const& PlayerList = me->GetMap()->GetPlayers(); if (!PlayerList.isEmpty()) { for (Map::PlayerList::const_iterator i = PlayerList.begin(); i != PlayerList.end(); ++i) { Player* plr = i->getSource(); if (!plr) continue; plr->CastSpell(plr, SPELL_FIGMENT_OF_DOUBT_3, false); plr->CastSpell(plr, SPELL_DRAW_DOUBT, false); } } events.ScheduleEvent(EVENT_BOUNDS_OF_REALITY, 60000); break; } default: break; } } if (!me->HasAura(SPELL_BOUNDS_OF_REALITY_2)) DoMeleeAttackIfReady(); }
void WorldSession::HandleMoveTeleportAck(WorldPacket& recvPacket) { sLog->outDebug(LOG_FILTER_NETWORKIO, "MSG_MOVE_TELEPORT_ACK"); ObjectGuid guid; uint32 ackCount = recvPacket.read<uint32>(); recvPacket.read_skip<uint32>(); // should be new position in kind of struction guid[5] = recvPacket.ReadBit(); guid[0] = recvPacket.ReadBit(); guid[1] = recvPacket.ReadBit(); guid[6] = recvPacket.ReadBit(); guid[3] = recvPacket.ReadBit(); guid[7] = recvPacket.ReadBit(); guid[2] = recvPacket.ReadBit(); guid[4] = recvPacket.ReadBit(); recvPacket.ReadByteSeq(guid[4]); recvPacket.ReadByteSeq(guid[2]); recvPacket.ReadByteSeq(guid[7]); recvPacket.ReadByteSeq(guid[6]); recvPacket.ReadByteSeq(guid[5]); recvPacket.ReadByteSeq(guid[1]); recvPacket.ReadByteSeq(guid[3]); recvPacket.ReadByteSeq(guid[0]); // Skip old result if (_player->m_movement_ack[ACK_TELEPORT] != ackCount) return; Player* plMover = _player->m_mover->ToPlayer(); if (!plMover || !plMover->IsBeingTeleportedNear() || guid != plMover->GetGUID()) return; plMover->SetSemaphoreTeleportNear(false); uint32 old_zone = plMover->GetZoneId(); WorldLocation const& dest = plMover->GetTeleportDest(); plMover->UpdatePosition(dest, true); WorldPacket data(SMSG_MOVE_UPDATE_TELEPORT); MovementInfo info = MovementInfo(plMover->m_movementInfo); info.pos.Relocate(dest.m_positionX, dest.m_positionY, dest.m_positionZ, dest.m_orientation); info.guid = plMover->GetGUID(); info.time = getMSTime(); info.WriteToPacket(data); _player->SendMessageToSet(&data, _player); uint32 newzone, newarea; plMover->GetZoneAndAreaId(newzone, newarea); plMover->UpdateZone(newzone, newarea); if (old_zone != newzone) { if (plMover->pvpInfo.inHostileArea) plMover->CastSpell(plMover, 2479, true); // honorless target else if (plMover->IsPvP() && !plMover->HasFlag(PLAYER_FLAGS, PLAYER_FLAGS_IN_PVP)) plMover->UpdatePvP(false, false); } GetPlayer()->ResummonPetTemporaryUnSummonedIfAny(); GetPlayer()->ProcessDelayedOperations(); }
void WorldSession::HandleMoveTeleportAck(WorldPacket& recvPacket) { sLog->outDebug(LOG_FILTER_NETWORKIO, "MSG_MOVE_TELEPORT_ACK"); ObjectGuid guid; uint32 flags, time; recvPacket >> flags >> time; // didn't tested ; in worst case should switch those but i think isn't needed guid[1] = recvPacket.ReadBit(); guid[7] = recvPacket.ReadBit(); guid[0] = recvPacket.ReadBit(); guid[5] = recvPacket.ReadBit(); guid[4] = recvPacket.ReadBit(); guid[2] = recvPacket.ReadBit(); guid[6] = recvPacket.ReadBit(); guid[3] = recvPacket.ReadBit(); recvPacket.ReadByteSeq(guid[1]); recvPacket.ReadByteSeq(guid[5]); recvPacket.ReadByteSeq(guid[4]); recvPacket.ReadByteSeq(guid[2]); recvPacket.ReadByteSeq(guid[7]); recvPacket.ReadByteSeq(guid[6]); recvPacket.ReadByteSeq(guid[0]); recvPacket.ReadByteSeq(guid[3]); sLog->outDebug(LOG_FILTER_NETWORKIO, "Guid " UI64FMTD, uint64(guid)); sLog->outDebug(LOG_FILTER_NETWORKIO, "Flags %u, time %u", flags, time/IN_MILLISECONDS); Player* plMover = _player->m_mover->ToPlayer(); if (!plMover || !plMover->IsBeingTeleportedNear()) return; if (guid != plMover->GetGUID()) return; plMover->SetSemaphoreTeleportNear(false); uint32 old_zone = plMover->GetZoneId(); WorldLocation const& dest = plMover->GetTeleportDest(); plMover->UpdatePosition(dest, true); uint32 newzone, newarea; plMover->GetZoneAndAreaId(newzone, newarea); plMover->UpdateZone(newzone, newarea); // new zone if (old_zone != newzone) { // honorless target if (plMover->pvpInfo.inHostileArea) plMover->CastSpell(plMover, 2479, true); // in friendly area else if (plMover->IsPvP() && !plMover->HasFlag(PLAYER_FLAGS, PLAYER_FLAGS_IN_PVP)) plMover->UpdatePvP(false, false); } // resummon pet GetPlayer()->ResummonPetTemporaryUnSummonedIfAny(); //lets process all delayed operations on successful teleport GetPlayer()->ProcessDelayedOperations(); }
void UpdateAI(uint32 diff) override { if (!UpdateVictim() || !CheckInRoom()) return; events.Update(diff); if (me->HasUnitState(UNIT_STATE_CASTING)) return; while (uint32 eventId = events.ExecuteEvent()) { switch (eventId) { case EVENT_BERSERK: Talk(EMOTE_BERSERK_RAID); Talk(SAY_BERSERK); DoCast(me, SPELL_BERSERK); break; case EVENT_VAMPIRIC_BITE: { std::list<Player*> targets; SelectRandomTarget(false, &targets); if (!targets.empty()) { Unit* target = targets.front(); DoCast(target, SPELL_VAMPIRIC_BITE); DoCastAOE(SPELL_VAMPIRIC_BITE_DUMMY, true); Talk(SAY_VAMPIRIC_BITE); _vampires.insert(target->GetGUID()); target->CastSpell(target, SPELL_PRESENCE_OF_THE_DARKFALLEN, TRIGGERED_FULL_MASK); target->CastSpell(target, SPELL_PRESENCE_OF_THE_DARKFALLEN_2, TRIGGERED_FULL_MASK); } break; } case EVENT_BLOOD_MIRROR: { // victim can be NULL when this is processed in the same update tick as EVENT_AIR_PHASE if (me->GetVictim()) { Player* newOfftank = SelectRandomTarget(true); if (newOfftank) { if (_offtankGUID != newOfftank->GetGUID()) { _offtankGUID = newOfftank->GetGUID(); // both spells have SPELL_ATTR5_SINGLE_TARGET_SPELL, no manual removal needed newOfftank->CastSpell(me->GetVictim(), SPELL_BLOOD_MIRROR_DAMAGE, true); me->EnsureVictim()->CastSpell(newOfftank, SPELL_BLOOD_MIRROR_DUMMY, true); DoCastVictim(SPELL_BLOOD_MIRROR_VISUAL); if (Is25ManRaid() && newOfftank->GetQuestStatus(QUEST_BLOOD_INFUSION) == QUEST_STATUS_INCOMPLETE && newOfftank->HasAura(SPELL_UNSATED_CRAVING) && !newOfftank->HasAura(SPELL_THIRST_QUENCHED) && !newOfftank->HasAura(SPELL_GUSHING_WOUND)) newOfftank->CastSpell(newOfftank, SPELL_GUSHING_WOUND, TRIGGERED_FULL_MASK); } } else _offtankGUID.Clear(); } events.ScheduleEvent(EVENT_BLOOD_MIRROR, 2500, EVENT_GROUP_CANCELLABLE); break; } case EVENT_DELIRIOUS_SLASH: if (_offtankGUID && !me->HasByteFlag(UNIT_FIELD_BYTES_1, 3, UNIT_BYTE1_FLAG_ALWAYS_STAND | UNIT_BYTE1_FLAG_HOVER)) if (Player* _offtank = ObjectAccessor::GetPlayer(*me, _offtankGUID)) DoCast(_offtank, SPELL_DELIRIOUS_SLASH); events.ScheduleEvent(EVENT_DELIRIOUS_SLASH, urand(20000, 24000), EVENT_GROUP_NORMAL); break; case EVENT_PACT_OF_THE_DARKFALLEN: { std::list<Player*> targets; SelectRandomTarget(false, &targets); Trinity::Containers::RandomResizeList(targets, Is25ManRaid() ? 3 : 2); if (targets.size() > 1) { Talk(SAY_PACT_OF_THE_DARKFALLEN); for (std::list<Player*>::iterator itr = targets.begin(); itr != targets.end(); ++itr) DoCast(*itr, SPELL_PACT_OF_THE_DARKFALLEN); } events.ScheduleEvent(EVENT_PACT_OF_THE_DARKFALLEN, 30500, EVENT_GROUP_NORMAL); break; } case EVENT_SWARMING_SHADOWS: if (Player* target = SelectRandomTarget(false)) { Talk(EMOTE_SWARMING_SHADOWS, target); Talk(SAY_SWARMING_SHADOWS); DoCast(target, SPELL_SWARMING_SHADOWS); } events.ScheduleEvent(EVENT_SWARMING_SHADOWS, 30500, EVENT_GROUP_NORMAL); break; case EVENT_TWILIGHT_BLOODBOLT: { std::list<Player*> targets; SelectRandomTarget(false, &targets); Trinity::Containers::RandomResizeList<Player*>(targets, uint32(Is25ManRaid() ? 4 : 2)); for (std::list<Player*>::iterator itr = targets.begin(); itr != targets.end(); ++itr) DoCast(*itr, SPELL_TWILIGHT_BLOODBOLT); DoCast(me, SPELL_TWILIGHT_BLOODBOLT_TARGET); events.ScheduleEvent(EVENT_TWILIGHT_BLOODBOLT, urand(10000, 15000), EVENT_GROUP_NORMAL); break; } case EVENT_AIR_PHASE: DoStopAttack(); me->SetReactState(REACT_PASSIVE); events.DelayEvents(10000, EVENT_GROUP_NORMAL); events.CancelEventGroup(EVENT_GROUP_CANCELLABLE); me->GetMotionMaster()->MovePoint(POINT_CENTER, centerPos); break; case EVENT_AIR_START_FLYING: me->SetDisableGravity(true); me->SetByteFlag(UNIT_FIELD_BYTES_1, 3, UNIT_BYTE1_FLAG_ALWAYS_STAND); me->GetMotionMaster()->MovePoint(POINT_AIR, airPos); break; case EVENT_AIR_FLY_DOWN: me->GetMotionMaster()->MovePoint(POINT_GROUND, centerPos); break; default: break; } } DoMeleeAttackIfReady(); }
void BattleGround::Update(time_t diff) { if(!GetPlayersSize() && !GetRemovedPlayersSize() && !GetReviveQueueSize()) //BG is empty return; WorldPacket data; if(GetRemovedPlayersSize()) { for(std::map<uint64, uint8>::iterator itr = m_RemovedPlayers.begin(); itr != m_RemovedPlayers.end(); ++itr) { Player *plr = objmgr.GetPlayer(itr->first); switch(itr->second) { //following code is handled by event: /*case 0: sBattleGroundMgr.m_BattleGroundQueues[GetTypeID()].RemovePlayer(itr->first); //RemovePlayerFromQueue(itr->first); if(plr) { sBattleGroundMgr.BuildBattleGroundStatusPacket(&data, this, plr->GetTeam(), plr->GetBattleGroundQueueIndex(m_TypeID), STATUS_NONE, 0, 0); plr->GetSession()->SendPacket(&data); } break;*/ case 1: // currently in bg and was removed from bg if(plr) RemovePlayerAtLeave(itr->first, true, true); else RemovePlayerAtLeave(itr->first, false, false); break; case 2: // revive queue RemovePlayerFromResurrectQueue(itr->first); break; default: sLog.outError("BattleGround: Unknown remove player case!"); } } m_RemovedPlayers.clear(); } // this code isn't efficient and its idea isn't implemented yet /* offline players are removed from battleground in worldsession::LogoutPlayer() // remove offline players from bg after ~5 minutes if(GetPlayersSize()) { for(std::map<uint64, BattleGroundPlayer>::iterator itr = m_Players.begin(); itr != m_Players.end(); ++itr) { Player *plr = objmgr.GetPlayer(itr->first); itr->second.LastOnlineTime += diff; if(plr) itr->second.LastOnlineTime = 0; // update last online time else if(itr->second.LastOnlineTime >= MAX_OFFLINE_TIME) // 5 minutes m_RemovedPlayers[itr->first] = 1; // add to remove list (BG) } }*/ m_LastResurrectTime += diff; if (m_LastResurrectTime >= RESURRECTION_INTERVAL) { if(GetReviveQueueSize()) { for(std::map<uint64, std::vector<uint64> >::iterator itr = m_ReviveQueue.begin(); itr != m_ReviveQueue.end(); ++itr) { Creature *sh = NULL; for(std::vector<uint64>::iterator itr2 = (itr->second).begin(); itr2 != (itr->second).end(); ++itr2) { Player *plr = objmgr.GetPlayer(*itr2); if(!plr) continue; if (!sh) { sh = ObjectAccessor::GetCreature(*plr, itr->first); // only for visual effect if (sh) sh->CastSpell(sh, SPELL_SPIRIT_HEAL, true); // Spirit Heal, effect 117 } plr->CastSpell(plr, SPELL_RESURRECTION_VISUAL, true); // Resurrection visual m_ResurrectQueue.push_back(*itr2); } (itr->second).clear(); } m_ReviveQueue.clear(); m_LastResurrectTime = 0; } else // queue is clear and time passed, just update last resurrection time m_LastResurrectTime = 0; } else if (m_LastResurrectTime > 500) // Resurrect players only half a second later, to see spirit heal effect on NPC { for(std::vector<uint64>::iterator itr = m_ResurrectQueue.begin(); itr != m_ResurrectQueue.end(); ++itr) { Player *plr = objmgr.GetPlayer(*itr); if(!plr) continue; plr->ResurrectPlayer(1.0f); plr->CastSpell(plr, SPELL_SPIRIT_HEAL_MANA, true); ObjectAccessor::Instance().ConvertCorpseForPlayer(*itr); } m_ResurrectQueue.clear(); } if(GetStatus() == STATUS_WAIT_LEAVE) { // remove all players from battleground after 2 minutes m_EndTime += diff; if(m_EndTime >= TIME_TO_AUTOREMOVE) // 2 minutes { for(std::map<uint64, BattleGroundPlayer>::iterator itr = m_Players.begin(); itr != m_Players.end(); ++itr) { m_RemovedPlayers[itr->first] = 1; // add to remove list (BG) } // do not change any battleground's private variables } } }
void UpdateAI(const uint32 diff) { npc_escortAI::UpdateAI(diff); if (PlayerGUID) { Player* AuraPlayer = Unit::GetPlayer(*me,PlayerGUID); if (!AuraPlayer) { me->DisappearAndDie(); return; } else { if (AuraPlayer->isDead()) { AuraPlayer->FailQuest(QUEST_A_FALL_FROM_GRACE); me->DisappearAndDie(); return; } if (EndSequence) { if (EndSequenceTimer <= diff) { EndSequenceTimer = 12000; if (EndSayCount == 6) { me->GetMotionMaster()->MoveJump(HighAbbotLandgrenJumpPos[0][0][0], HighAbbotLandgrenJumpPos[0][0][1], HighAbbotLandgrenJumpPos[0][0][2], 0.5f, 8.0f); EndSequenceTimer = 2000; } if (EndSayCount == 7) { me->MonsterSay(HighAbbotText[6], LANG_UNIVERSAL, 0); EndSequenceTimer = 2000; } if (EndSayCount == 8) { AuraPlayer->KilledMonsterCredit(27444, 0); if (AuraPlayer->HasAura(SPELL_SCARLET_RAVEN_PRIEST_IMAGE_FEMALE)) AuraPlayer->RemoveAura(SPELL_SCARLET_RAVEN_PRIEST_IMAGE_FEMALE); if (AuraPlayer->HasAura(SPELL_SCARLET_RAVEN_PRIEST_IMAGE_MALE)) AuraPlayer->RemoveAura(SPELL_SCARLET_RAVEN_PRIEST_IMAGE_MALE); EndSequence = false; } if (EndSayCount < 6) me->MonsterSay(HighAbbotText[EndSayCount], LANG_UNIVERSAL, PlayerGUID); EndSayCount++; } else EndSequenceTimer -= diff; } if (!EventStarted && me->GetEntry() == NPC_HIGH_ABBOT_LANDGREN_ESCORTEE_ENTRY) { Start(false, false, PlayerGUID, 0, false); EventStarted = true; } if (CheckPlayerDist) if (AuraPlayer->GetDistance(2827.796f, -420.191f, 118.196f) < 4) StartMove(); if (AuraCheckTimer <= diff) { if (AuraPlayer && AuraPlayer->GetQuestStatus(QUEST_A_FALL_FROM_GRACE) == QUEST_STATUS_INCOMPLETE && AuraPlayer->getQuestStatusMap()[QUEST_A_FALL_FROM_GRACE].m_creatureOrGOcount[0] == 1 && !AuraPlayer->HasAura(SPELL_SCARLET_RAVEN_PRIEST_IMAGE_MALE) && !AuraPlayer->HasAura(SPELL_SCARLET_RAVEN_PRIEST_IMAGE_FEMALE)) { switch(AuraPlayer->getGender()) { case GENDER_FEMALE: AuraPlayer->CastSpell(AuraPlayer, SPELL_SCARLET_RAVEN_PRIEST_IMAGE_FEMALE, false); break; case GENDER_MALE: AuraPlayer->CastSpell(AuraPlayer, SPELL_SCARLET_RAVEN_PRIEST_IMAGE_MALE, false); break; } } AuraCheckTimer = 300; } else AuraCheckTimer -= diff; if (me->GetEntry() != NPC_HIGH_ABBOT_LANDGREN_ESCORTEE_ENTRY) { if (BodyGuardStart && AuraPlayer->GetQuestStatus(QUEST_A_FALL_FROM_GRACE) == QUEST_STATUS_INCOMPLETE && AuraPlayer->getQuestStatusMap()[QUEST_A_FALL_FROM_GRACE].m_creatureOrGOcount[0] == 1) { if (Creature* tmp = me->FindNearestCreature(NPC_DEVOUT_BODYGUARD, Range, true)) { if (BodyGuardMoveTimer <= diff) { CAST_AI(npc_devout_bodyguard::npc_devout_bodyguardAI, tmp->AI())->StartMove(); BodyGuardMoveTimer = 6000; Range = 4.0f; if (GuardCount == 1) BodyGuardStart = false; GuardCount++; } else BodyGuardMoveTimer -= diff; } } } } } }
void UpdateAI(const uint32 uiDiff) { if (!m_creature->SelectHostileTarget() || !m_creature->getVictim()) return; if (m_uiCloseDoor_Timer) { if (m_uiCloseDoor_Timer <= uiDiff) { if (m_pInstance) { if (GameObject* pDoor = m_pInstance->instance->GetGameObject(m_pInstance->GetData64(DATA_GO_LIBRARY_DOOR))) pDoor->SetGoState(GO_STATE_READY); m_uiCloseDoor_Timer = 0; } } else m_uiCloseDoor_Timer -= uiDiff; } //Cooldowns for casts if (m_uiArcaneCooldown) { if (m_uiArcaneCooldown >= uiDiff) m_uiArcaneCooldown -= uiDiff; else m_uiArcaneCooldown = 0; } if (m_uiFireCooldown) { if (m_uiFireCooldown >= uiDiff) m_uiFireCooldown -= uiDiff; else m_uiFireCooldown = 0; } if (m_uiFrostCooldown) { if (m_uiFrostCooldown >= uiDiff) m_uiFrostCooldown -= uiDiff; else m_uiFrostCooldown = 0; } if (!m_bDrinking && m_creature->GetMaxPower(POWER_MANA) && (m_creature->GetPower(POWER_MANA)*100 / m_creature->GetMaxPower(POWER_MANA)) < 20) { m_bDrinking = true; m_creature->InterruptNonMeleeSpells(false); DoScriptText(SAY_DRINK, m_creature); if (!m_bDrinkInturrupted) { m_creature->CastSpell(m_creature, SPELL_MASS_POLY, true); m_creature->CastSpell(m_creature, SPELL_CONJURE, false); m_creature->CastSpell(m_creature, SPELL_DRINK, false); m_creature->SetStandState(UNIT_STAND_STATE_SIT); m_uiDrinkInturrupt_Timer = 10000; } } //Drink Inturrupt if (m_bDrinking && m_bDrinkInturrupted) { m_bDrinking = false; m_creature->RemoveAurasDueToSpell(SPELL_DRINK); m_creature->SetStandState(UNIT_STAND_STATE_STAND); m_creature->SetPower(POWER_MANA, m_creature->GetMaxPower(POWER_MANA)-32000); m_creature->CastSpell(m_creature, SPELL_POTION, false); } //Drink Inturrupt Timer if (m_bDrinking && !m_bDrinkInturrupted) { if (m_uiDrinkInturrupt_Timer >= uiDiff) m_uiDrinkInturrupt_Timer -= uiDiff; else { m_creature->SetStandState(UNIT_STAND_STATE_STAND); m_creature->CastSpell(m_creature, SPELL_POTION, true); m_creature->CastSpell(m_creature, SPELL_AOE_PYROBLAST, false); m_bDrinkInturrupted = true; m_bDrinking = false; } } //Don't execute any more code if we are drinking if (m_bDrinking) return; //Normal casts if (m_uiNormalCast_Timer < uiDiff) { if (!m_creature->IsNonMeleeSpellCasted(false)) { Unit* pTarget = m_creature->SelectAttackingTarget(ATTACKING_TARGET_RANDOM, 0); if (!pTarget) return; uint32 auiSpells[3]; uint8 uiAvailableSpells = 0; //Check for what spells are not on cooldown if (!m_uiArcaneCooldown) auiSpells[uiAvailableSpells++] = SPELL_ARCMISSLE; if (!m_uiFireCooldown) auiSpells[uiAvailableSpells++] = SPELL_FIREBALL; if (!m_uiFrostCooldown) auiSpells[uiAvailableSpells++] = SPELL_FROSTBOLT; //If no available spells wait 1 second and try again if (uiAvailableSpells) { m_uiCurrentNormalSpell = auiSpells[rand() % uiAvailableSpells]; DoCastSpellIfCan(pTarget, m_uiCurrentNormalSpell); } } m_uiNormalCast_Timer = 1000; } else m_uiNormalCast_Timer -= uiDiff; if (m_uiSecondarySpell_Timer < uiDiff) { switch(urand(0, 1)) { case 0: DoCastSpellIfCan(m_creature, SPELL_AOE_CS); break; case 1: if (Unit* pUnit = m_creature->SelectAttackingTarget(ATTACKING_TARGET_RANDOM, 0)) DoCastSpellIfCan(pUnit, SPELL_CHAINSOFICE); break; } m_uiSecondarySpell_Timer = urand(5000, 20000); } else m_uiSecondarySpell_Timer -= uiDiff; if (m_uiSuperCast_Timer < uiDiff) { uint8 auiAvailable[2]; switch (m_uiLastSuperSpell) { case SUPER_AE: auiAvailable[0] = SUPER_FLAME; auiAvailable[1] = SUPER_BLIZZARD; break; case SUPER_FLAME: auiAvailable[0] = SUPER_AE; auiAvailable[1] = SUPER_BLIZZARD; break; case SUPER_BLIZZARD: auiAvailable[0] = SUPER_FLAME; auiAvailable[1] = SUPER_AE; break; } m_uiLastSuperSpell = auiAvailable[urand(0, 2)]; switch (m_uiLastSuperSpell) { case SUPER_AE: DoScriptText(urand(0, 1) ? SAY_EXPLOSION1 : SAY_EXPLOSION2, m_creature); m_creature->CastSpell(m_creature, SPELL_BLINK_CENTER, true); m_creature->CastSpell(m_creature, SPELL_PLAYERPULL, true); m_creature->CastSpell(m_creature, SPELL_MASSSLOW, true); m_creature->CastSpell(m_creature, SPELL_AEXPLOSION, false); break; case SUPER_FLAME: DoScriptText(urand(0, 1) ? SAY_FLAMEWREATH1 : SAY_FLAMEWREATH2, m_creature); m_uiFlameWreath_Timer = 20000; m_uiFlameWreathCheck_Timer = 500; memset(&m_uiFlameWreathTarget, 0, sizeof(m_uiFlameWreathTarget)); FlameWreathEffect(); break; case SUPER_BLIZZARD: DoScriptText(urand(0, 1) ? SAY_BLIZZARD1 : SAY_BLIZZARD2, m_creature); if (Creature* pSpawn = m_creature->SummonCreature(NPC_ARAN_BLIZZARD, 0.0f, 0.0f, 0.0f, 0.0f, TEMPSUMMON_TIMED_DESPAWN, 25000)) { pSpawn->setFaction(m_creature->getFaction()); pSpawn->CastSpell(pSpawn, SPELL_CIRCULAR_BLIZZARD, false); } break; } m_uiSuperCast_Timer = urand(35000, 40000); } else m_uiSuperCast_Timer -= uiDiff; if (!m_bElementalsSpawned && m_creature->GetHealthPercent() < 40.0f) { m_bElementalsSpawned = true; for (uint32 i = 0; i < 4; ++i) { if (Creature* pElemental = m_creature->SummonCreature(NPC_WATER_ELEMENTAL, 0.0f, 0.0f, 0.0f, 0.0f, TEMPSUMMON_TIMED_DESPAWN, 90000)) { pElemental->Attack(m_creature->getVictim(), true); pElemental->setFaction(m_creature->getFaction()); } } DoScriptText(SAY_ELEMENTALS, m_creature); } if (m_uiBerserk_Timer < uiDiff) { for (uint32 i = 0; i < 5; ++i) { if (Creature* pShadow = m_creature->SummonCreature(NPC_SHADOW_OF_ARAN, 0.0f, 0.0f, 0.0f, 0.0f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 5000)) { pShadow->Attack(m_creature->getVictim(), true); pShadow->setFaction(m_creature->getFaction()); } } DoScriptText(SAY_TIMEOVER, m_creature); m_uiBerserk_Timer = 60000; } else m_uiBerserk_Timer -= uiDiff; //Flame Wreath check if (m_uiFlameWreath_Timer) { if (m_uiFlameWreath_Timer >= uiDiff) m_uiFlameWreath_Timer -= uiDiff; else m_uiFlameWreath_Timer = 0; if (m_uiFlameWreathCheck_Timer < uiDiff) { for (uint32 i = 0; i < 3; ++i) { if (!m_uiFlameWreathTarget[i]) continue; Player* pPlayer = m_creature->GetMap()->GetPlayer(m_uiFlameWreathTarget[i]); if (pPlayer && !pPlayer->IsWithinDist2d(m_fFWTargPosX[i], m_fFWTargPosY[i], 3.0f)) { pPlayer->CastSpell(pPlayer, SPELL_EXPLOSION, true, 0, 0, m_creature->GetGUID()); pPlayer->CastSpell(pPlayer, SPELL_KNOCKBACK_500, true); m_uiFlameWreathTarget[i] = 0; } } m_uiFlameWreathCheck_Timer = 500; } else m_uiFlameWreathCheck_Timer -= uiDiff; } if (m_uiArcaneCooldown && m_uiFireCooldown && m_uiFrostCooldown) DoMeleeAttackIfReady(); }
void WorldSession::HandlePlayerLogin(LoginQueryHolder * holder) { uint64 playerGuid = holder->GetGuid(); Player* pCurrChar = new Player(this); pCurrChar->GetMotionMaster()->Initialize(); // "GetAccountId()==db stored account id" checked in LoadFromDB (prevent login not own character using cheating tools) if(!pCurrChar->LoadFromDB(GUID_LOPART(playerGuid), holder)) { KickPlayer(); // disconnect client, player no set to session and it will not deleted or saved at kick delete pCurrChar; // delete it manually delete holder; // delete all unprocessed queries m_playerLoading = false; return; } SetPlayer(pCurrChar); pCurrChar->SendDungeonDifficulty(false); WorldPacket data( SMSG_LOGIN_VERIFY_WORLD, 20 ); data << pCurrChar->GetMapId(); data << pCurrChar->GetPositionX(); data << pCurrChar->GetPositionY(); data << pCurrChar->GetPositionZ(); data << pCurrChar->GetOrientation(); SendPacket(&data); data.Initialize( SMSG_ACCOUNT_DATA_TIMES, 128 ); for(int i = 0; i < 32; i++) data << uint32(0); SendPacket(&data); data.Initialize(SMSG_FEATURE_SYSTEM_STATUS, 2); // added in 2.2.0 data << uint8(2); // unknown value data << uint8(0); // enable(1)/disable(0) voice chat interface in client SendPacket(&data); // Send MOTD { data.Initialize(SMSG_MOTD, 50); // new in 2.0.1 data << (uint32)0; uint32 linecount=0; std::string str_motd = sWorld.GetMotd(); std::string::size_type pos, nextpos; pos = 0; while ( (nextpos= str_motd.find('@',pos)) != std::string::npos ) { if (nextpos != pos) { data << str_motd.substr(pos,nextpos-pos); ++linecount; } pos = nextpos+1; } if (pos<str_motd.length()) { data << str_motd.substr(pos); ++linecount; } data.put(0, linecount); SendPacket( &data ); DEBUG_LOG( "WORLD: Sent motd (SMSG_MOTD)" ); } if(pCurrChar->GetGuildId() != 0) { Guild* guild = objmgr.GetGuildById(pCurrChar->GetGuildId()); if(guild) { data.Initialize(SMSG_GUILD_EVENT, (2+guild->GetMOTD().size()+1)); data << (uint8)GE_MOTD; data << (uint8)1; data << guild->GetMOTD(); SendPacket(&data); DEBUG_LOG( "WORLD: Sent guild-motd (SMSG_GUILD_EVENT)" ); data.Initialize(SMSG_GUILD_EVENT, (5+10)); // we guess size data<<(uint8)GE_SIGNED_ON; data<<(uint8)1; data<<pCurrChar->GetName(); data<<pCurrChar->GetGUID(); guild->BroadcastPacket(&data); DEBUG_LOG( "WORLD: Sent guild-signed-on (SMSG_GUILD_EVENT)" ); // Increment online members of the guild guild->IncOnlineMemberCount(); } else { // remove wrong guild data sLog.outError("Player %s (GUID: %u) marked as member not existed guild (id: %u), removing guild membership for player.",pCurrChar->GetName(),pCurrChar->GetGUIDLow(),pCurrChar->GetGuildId()); pCurrChar->SetUInt32Value(PLAYER_GUILDID,0); pCurrChar->SetUInt32ValueInDB(PLAYER_GUILDID,0,pCurrChar->GetGUID()); } } if(!pCurrChar->isAlive()) pCurrChar->SendCorpseReclaimDelay(true); pCurrChar->SendInitialPacketsBeforeAddToMap(); //Show cinematic at the first time that player login if( !pCurrChar->getCinematic() ) { pCurrChar->setCinematic(1); ChrRacesEntry const* rEntry = sChrRacesStore.LookupEntry(pCurrChar->getRace()); if(rEntry) { data.Initialize( SMSG_TRIGGER_CINEMATIC,4 ); data << uint32(rEntry->startmovie); SendPacket( &data ); } } //QueryResult *result = CharacterDatabase.PQuery("SELECT guildid,rank FROM guild_member WHERE guid = '%u'",pCurrChar->GetGUIDLow()); QueryResult *resultGuild = holder->GetResult(PLAYER_LOGIN_QUERY_LOADGUILD); if(resultGuild) { Field *fields = resultGuild->Fetch(); pCurrChar->SetInGuild(fields[0].GetUInt32()); pCurrChar->SetRank(fields[1].GetUInt32()); delete resultGuild; } else if(pCurrChar->GetGuildId()) // clear guild related fields in case wrong data about non existed membership { pCurrChar->SetInGuild(0); pCurrChar->SetRank(0); } if (!MapManager::Instance().GetMap(pCurrChar->GetMapId(), pCurrChar)->Add(pCurrChar)) { AreaTrigger const* at = objmgr.GetGoBackTrigger(pCurrChar->GetMapId()); if(at) pCurrChar->TeleportTo(at->target_mapId, at->target_X, at->target_Y, at->target_Z, pCurrChar->GetOrientation()); else pCurrChar->TeleportTo(pCurrChar->m_homebindMapId, pCurrChar->m_homebindX, pCurrChar->m_homebindY, pCurrChar->m_homebindZ, pCurrChar->GetOrientation()); } ObjectAccessor::Instance().AddObject(pCurrChar); //sLog.outDebug("Player %s added to Map.",pCurrChar->GetName()); pCurrChar->GetSocial()->SendSocialList(); pCurrChar->SendInitialPacketsAfterAddToMap(); CharacterDatabase.PExecute("UPDATE characters SET online = 1 WHERE guid = '%u'", pCurrChar->GetGUIDLow()); loginDatabase.PExecute("UPDATE account SET online = 1 WHERE id = '%u'", GetAccountId()); pCurrChar->SetInGameTime( getMSTime() ); // announce group about member online (must be after add to player list to receive announce to self) if(Group *group = pCurrChar->GetGroup()) { //pCurrChar->groupInfo.group->SendInit(this); // useless group->SendUpdate(); } // friend status sSocialMgr.SendFriendStatus(pCurrChar, FRIEND_ONLINE, pCurrChar->GetGUIDLow(), "", true); // Place character in world (and load zone) before some object loading pCurrChar->LoadCorpse(); // setting Ghost+speed if dead //if ( pCurrChar->m_deathState == DEAD ) if (pCurrChar->m_deathState != ALIVE) { // not blizz like, we must correctly save and load player instead... if(pCurrChar->getRace() == RACE_NIGHTELF) pCurrChar->CastSpell(pCurrChar, 20584, true, 0);// auras SPELL_AURA_INCREASE_SPEED(+speed in wisp form), SPELL_AURA_INCREASE_SWIM_SPEED(+swim speed in wisp form), SPELL_AURA_TRANSFORM (to wisp form) pCurrChar->CastSpell(pCurrChar, 8326, true, 0); // auras SPELL_AURA_GHOST, SPELL_AURA_INCREASE_SPEED(why?), SPELL_AURA_INCREASE_SWIM_SPEED(why?) //pCurrChar->SetUInt32Value(UNIT_FIELD_AURA+41, 8326); //pCurrChar->SetUInt32Value(UNIT_FIELD_AURA+42, 20584); //pCurrChar->SetUInt32Value(UNIT_FIELD_AURAFLAGS+6, 238); //pCurrChar->SetUInt32Value(UNIT_FIELD_AURALEVELS+11, 514); //pCurrChar->SetUInt32Value(UNIT_FIELD_AURAAPPLICATIONS+11, 65535); //pCurrChar->SetUInt32Value(UNIT_FIELD_DISPLAYID, 1825); //if (pCurrChar->getRace() == RACE_NIGHTELF) //{ // pCurrChar->SetSpeed(MOVE_RUN, 1.5f*1.2f, true); // pCurrChar->SetSpeed(MOVE_SWIM, 1.5f*1.2f, true); //} //else //{ // pCurrChar->SetSpeed(MOVE_RUN, 1.5f, true); // pCurrChar->SetSpeed(MOVE_SWIM, 1.5f, true); //} pCurrChar->SetMovement(MOVE_WATER_WALK); } if(uint32 sourceNode = pCurrChar->m_taxi.GetTaxiSource()) { sLog.outDebug( "WORLD: Restart character %u taxi flight", pCurrChar->GetGUIDLow() ); uint32 MountId = objmgr.GetTaxiMount(sourceNode, pCurrChar->GetTeam()); uint32 path = pCurrChar->m_taxi.GetCurrentTaxiPath(); // search appropriate start path node uint32 startNode = 0; TaxiPathNodeList const& nodeList = sTaxiPathNodesByPath[path]; float distPrev = MAP_SIZE*MAP_SIZE; float distNext = (nodeList[0].x-pCurrChar->GetPositionX())*(nodeList[0].x-pCurrChar->GetPositionX())+ (nodeList[0].y-pCurrChar->GetPositionY())*(nodeList[0].y-pCurrChar->GetPositionY())+ (nodeList[0].z-pCurrChar->GetPositionZ())*(nodeList[0].z-pCurrChar->GetPositionZ()); for(uint32 i = 1; i < nodeList.size(); ++i) { TaxiPathNode const& node = nodeList[i]; TaxiPathNode const& prevNode = nodeList[i-1]; // skip nodes at another map if(node.mapid != pCurrChar->GetMapId()) continue; distPrev = distNext; distNext = (node.x-pCurrChar->GetPositionX())*(node.x-pCurrChar->GetPositionX())+ (node.y-pCurrChar->GetPositionY())*(node.y-pCurrChar->GetPositionY())+ (node.z-pCurrChar->GetPositionZ())*(node.z-pCurrChar->GetPositionZ()); float distNodes = (node.x-prevNode.x)*(node.x-prevNode.x)+ (node.y-prevNode.y)*(node.y-prevNode.y)+ (node.z-prevNode.z)*(node.z-prevNode.z); if(distNext + distPrev < distNodes) { startNode = i; break; } } SendDoFlight( MountId, path, startNode ); } // Load pet if any and player is alive and not in taxi flight if(pCurrChar->isAlive() && pCurrChar->m_taxi.GetTaxiSource()==0) pCurrChar->LoadPet(); // Set FFA PvP for non GM in non-rest mode if(sWorld.IsFFAPvPRealm() && !pCurrChar->isGameMaster() && !pCurrChar->HasFlag(PLAYER_FLAGS,PLAYER_FLAGS_RESTING) ) pCurrChar->SetFlag(PLAYER_FLAGS,PLAYER_FLAGS_FFA_PVP); if(pCurrChar->HasFlag(PLAYER_FLAGS, PLAYER_FLAGS_CONTESTED_PVP)) pCurrChar->SetContestedPvP(); // Apply at_login requests if(pCurrChar->HasAtLoginFlag(AT_LOGIN_RESET_SPELLS)) { pCurrChar->resetSpells(); SendNotification(LANG_RESET_SPELLS); } if(pCurrChar->HasAtLoginFlag(AT_LOGIN_RESET_TALENTS)) { pCurrChar->resetTalents(true); SendNotification(LANG_RESET_TALENTS); } // show time before shutdown if shutdown planned. if(sWorld.IsShutdowning()) sWorld.ShutdownMsg(true,pCurrChar); if(sWorld.getConfig(CONFIG_START_ALL_TAXI)) pCurrChar->SetTaxiCheater(true); if(pCurrChar->isGameMaster()) SendNotification(LANG_GM_ON); std::string IP_str = GetRemoteAddress(); sLog.outChar("Account: %d (IP: %s) Login Character:[%s] (guid:%u)",GetAccountId(),IP_str.c_str(),pCurrChar->GetName() ,pCurrChar->GetGUID()); m_playerLoading = false; delete holder; }
void WorldSession::HandlePlayerLogin(LoginQueryHolder * holder) { uint64 playerGuid = holder->GetGuid(); Player* pCurrChar = new Player(this); pCurrChar->GetMotionMaster()->Initialize(); // "GetAccountId()==db stored account id" checked in LoadFromDB (prevent login not own character using cheating tools) if(!pCurrChar->LoadFromDB(GUID_LOPART(playerGuid), holder)) { KickPlayer(); // disconnect client, player no set to session and it will not deleted or saved at kick delete pCurrChar; // delete it manually delete holder; // delete all unprocessed queries m_playerLoading = false; return; } else SetPlayer(pCurrChar); pCurrChar->SendDungeonDifficulty(); WorldPacket data( SMSG_LOGIN_VERIFY_WORLD, 20 ); data << pCurrChar->GetMapId(); data << pCurrChar->GetPositionX(); data << pCurrChar->GetPositionY(); data << pCurrChar->GetPositionZ(); data << pCurrChar->GetOrientation(); SendPacket(&data); data.Initialize( SMSG_ACCOUNT_DATA_MD5, 128 ); for(int i = 0; i < 32; i++) data << uint32(0); SendPacket(&data); pCurrChar->SendFriendlist(); pCurrChar->SendIgnorelist(); // added in 2.2.0 data.Initialize(SMSG_VOICE_SYSTEM_STATUS, 2); data << uint8(2); // unknown value data << uint8(0); // enable(1)/disable(0) voice chat interface in client SendPacket(&data); // Send MOTD { data.Initialize(SMSG_MOTD, 50); // new in 2.0.1 data << (uint32)0; uint32 linecount=0; std::string str_motd = sWorld.GetMotd(); std::string::size_type pos, nextpos; pos = 0; while ( (nextpos= str_motd.find('@',pos)) != std::string::npos ) { if (nextpos != pos) { data << str_motd.substr(pos,nextpos-pos); linecount++; } pos = nextpos+1; } if (pos<str_motd.length()) { data << str_motd.substr(pos); linecount++; } data.put(0, linecount); SendPacket( &data ); DEBUG_LOG( "WORLD: Sent motd (SMSG_MOTD)" ); } if(pCurrChar->GetGuildId() != 0) { Guild* guild = objmgr.GetGuildById(pCurrChar->GetGuildId()); if(guild) { data.Initialize(SMSG_GUILD_EVENT, (2+guild->GetMOTD().size()+1)); data << (uint8)GE_MOTD; data << (uint8)1; data << guild->GetMOTD(); SendPacket(&data); DEBUG_LOG( "WORLD: Sent guild-motd (SMSG_GUILD_EVENT)" ); data.Initialize(SMSG_GUILD_EVENT, (5+10)); // we guess size data<<(uint8)GE_SIGNED_ON; data<<(uint8)1; data<<pCurrChar->GetName(); data<<pCurrChar->GetGUID(); guild->BroadcastPacket(&data); DEBUG_LOG( "WORLD: Sent guild-signed-on (SMSG_GUILD_EVENT)" ); } else { // remove wrong guild data sLog.outError("Player %s (GUID: %u) marked as member not existed guild (id: %u), removing guild membership for player.",pCurrChar->GetName(),pCurrChar->GetGUIDLow(),pCurrChar->GetGuildId()); pCurrChar->SetUInt32Value(PLAYER_GUILDID,0); pCurrChar->SetUInt32ValueInDB(PLAYER_GUILDID,0,pCurrChar->GetGUID()); } } pCurrChar->SendInitialPacketsBeforeAddToMap(); //Show cinematic at the first time that player login if( !pCurrChar->getCinematic() ) { pCurrChar->setCinematic(1); ChrRacesEntry const* rEntry = sChrRacesStore.LookupEntry(pCurrChar->getRace()); if(rEntry) { data.Initialize( SMSG_TRIGGER_CINEMATIC,4 ); data << uint32(rEntry->startmovie); SendPacket( &data ); } } //QueryResult *result = CharacterDatabase.PQuery("SELECT `guildid`,`rank` FROM `guild_member` WHERE `guid` = '%u'",pCurrChar->GetGUIDLow()); QueryResult *resultGuild = holder->GetResult(PLAYER_LOGIN_QUERY_LOADGUILD); if(resultGuild) { Field *fields = resultGuild->Fetch(); pCurrChar->SetInGuild(fields[0].GetUInt32()); pCurrChar->SetRank(fields[1].GetUInt32()); delete resultGuild; } else if(pCurrChar->GetGuildId()) // clear guild related fields in case wrong data about non existed membership { pCurrChar->SetInGuild(0); pCurrChar->SetRank(0); } if (!MapManager::Instance().GetMap(pCurrChar->GetMapId(), pCurrChar)->AddInstanced(pCurrChar)) { // TODO : Teleport to zone-in area } MapManager::Instance().GetMap(pCurrChar->GetMapId(), pCurrChar)->Add(pCurrChar); ObjectAccessor::Instance().AddObject(pCurrChar); //sLog.outDebug("Player %s added to Map.",pCurrChar->GetName()); pCurrChar->SendInitialPacketsAfterAddToMap(); CharacterDatabase.PExecute("UPDATE `character` SET `online` = 1 WHERE `guid` = '%u'", pCurrChar->GetGUIDLow()); loginDatabase.PExecute("UPDATE `account` SET `online` = 1 WHERE `id` = '%u'", GetAccountId()); pCurrChar->SetInGameTime( getMSTime() ); // announce group about member online (must be after add to player list to receive announce to self) if(pCurrChar->GetGroup()) { //pCurrChar->groupInfo.group->SendInit(this); // useless pCurrChar->GetGroup()->SendUpdate(); } // friend status data.Initialize(SMSG_FRIEND_STATUS, 19); data<<uint8(FRIEND_ONLINE); data<<pCurrChar->GetGUID(); data<<uint8(1); data<<pCurrChar->GetAreaId(); data<<pCurrChar->getLevel(); data<<pCurrChar->getClass(); pCurrChar->BroadcastPacketToFriendListers(&data, true, holder->GetResult(PLAYER_LOGIN_QUERY_BROADCASTTOFRIENDLISTERS)); // Place character in world (and load zone) before some object loading pCurrChar->LoadCorpse(); // setting Ghost+speed if dead //if ( pCurrChar->m_deathState == DEAD ) if (pCurrChar->m_deathState != ALIVE) { // not blizz like, we must correctly save and load player instead... if(pCurrChar->getRace() == RACE_NIGHTELF) pCurrChar->CastSpell(pCurrChar, 20584, true, 0);// auras SPELL_AURA_INCREASE_SPEED(+speed in wisp form), SPELL_AURA_INCREASE_SWIM_SPEED(+swim speed in wisp form), SPELL_AURA_TRANSFORM (to wisp form) pCurrChar->CastSpell(pCurrChar, 8326, true, 0); // auras SPELL_AURA_GHOST, SPELL_AURA_INCREASE_SPEED(why?), SPELL_AURA_INCREASE_SWIM_SPEED(why?) //pCurrChar->SetUInt32Value(UNIT_FIELD_AURA+41, 8326); //pCurrChar->SetUInt32Value(UNIT_FIELD_AURA+42, 20584); //pCurrChar->SetUInt32Value(UNIT_FIELD_AURAFLAGS+6, 238); //pCurrChar->SetUInt32Value(UNIT_FIELD_AURALEVELS+11, 514); //pCurrChar->SetUInt32Value(UNIT_FIELD_AURAAPPLICATIONS+11, 65535); //pCurrChar->SetUInt32Value(UNIT_FIELD_DISPLAYID, 1825); //if (pCurrChar->getRace() == RACE_NIGHTELF) //{ // pCurrChar->SetSpeed(MOVE_RUN, 1.5f*1.2f, true); // pCurrChar->SetSpeed(MOVE_SWIM, 1.5f*1.2f, true); //} //else //{ // pCurrChar->SetSpeed(MOVE_RUN, 1.5f, true); // pCurrChar->SetSpeed(MOVE_SWIM, 1.5f, true); //} pCurrChar->SetMovement(MOVE_WATER_WALK); } // Load pet if any and player is alive if(pCurrChar->isAlive()) pCurrChar->LoadPet(); // Apply at_login requests if(pCurrChar->HasAtLoginFlag(AT_LOGIN_RESET_SPELLS)) { pCurrChar->resetSpells(); SendNotification("Spells has been reset."); } if(pCurrChar->HasAtLoginFlag(AT_LOGIN_RESET_TALENTS)) { pCurrChar->resetTalents(true); SendNotification("Talents has been reset."); } // show time before shutdown if shutdown planned. if(sWorld.IsShutdowning()) sWorld.ShutdownMsg(true,pCurrChar); if(pCurrChar->isGameMaster()) SendNotification("GM mode is ON"); std::string IP_str = _socket ? _socket->GetRemoteAddress().c_str() : "-"; sLog.outChar("Account: %d (IP: %s) Login Character:[%s] (guid:%u)",GetAccountId(),IP_str.c_str(),pCurrChar->GetName() ,pCurrChar->GetGUID()); m_playerLoading = false; delete holder; }
void WorldSession::HandlePlayerLogin(LoginQueryHolder* holder) { /* Store the player's GUID for later reference */ ObjectGuid playerGuid = holder->GetGuid(); /* Create a new instance of the player object */ Player* pCurrChar = new Player(this); /* Initialize a motion generator */ pCurrChar->GetMotionMaster()->Initialize(); /* Account ID is validated in LoadFromDB (prevents cheaters logging in to characters not on their account) */ if (!pCurrChar->LoadFromDB(playerGuid, holder)) /// Could not load character from database, cancel login { /* Disconnect the game client */ KickPlayer(); /* Remove references to avoid dangling pointers */ delete pCurrChar; delete holder; /* Checked in WorldSession::Update */ m_playerLoading = false; return; } /* Validation check completely, assign player to WorldSession::_player for later use */ SetPlayer(pCurrChar); WorldPacket data(SMSG_LOGIN_VERIFY_WORLD, 20); data << pCurrChar->GetMapId(); data << pCurrChar->GetPositionX(); data << pCurrChar->GetPositionY(); data << pCurrChar->GetPositionZ(); data << pCurrChar->GetOrientation(); SendPacket(&data); data.Initialize(SMSG_ACCOUNT_DATA_TIMES, 128); for (int i = 0; i < 32; ++i) { data << uint32(0); } SendPacket(&data); /* 1.12.1 does not have SMSG_MOTD, so we send a server message */ /* Used for counting number of newlines in MOTD */ uint32 linecount = 0; /* The MOTD itself */ std::string str_motd = sWorld.GetMotd(); /* Used for tracking our position within the MOTD while iterating through it */ std::string::size_type pos = 0, nextpos; /* Find the next occurance of @ in the string * This is how newlines are represented */ while ((nextpos = str_motd.find('@', pos)) != std::string::npos) { /* If these are not equal, it means a '@' was found * These are used to represent newlines in the string * It is set by the code above here */ if (nextpos != pos) { /* Send the player a system message containing the substring from pos to nextpos - pos */ ChatHandler(pCurrChar).PSendSysMessage(str_motd.substr(pos, nextpos - pos).c_str()); ++linecount; } pos = nextpos + 1; } /* There are no more newlines in our MOTD, so we send whatever is left */ if (pos < str_motd.length()) { ChatHandler(pCurrChar).PSendSysMessage(str_motd.substr(pos).c_str()); } DEBUG_LOG("WORLD: Sent motd (SMSG_MOTD)"); /* Attempt to load guild for player */ if (QueryResult *resultGuild = holder->GetResult(PLAYER_LOGIN_QUERY_LOADGUILD)) { /* We're in a guild, so set the player's guild data to represent that */ Field* fields = resultGuild->Fetch(); pCurrChar->SetInGuild(fields[0].GetUInt32()); pCurrChar->SetRank(fields[1].GetUInt32()); /* Avoid dangling pointers */ delete resultGuild; } /* Player thinks they have a guild, but it isn't in the database. Clear that information */ else if (pCurrChar->GetGuildId()) { pCurrChar->SetInGuild(0); pCurrChar->SetRank(0); } /* Player is in a guild * TODO: Can we move this code into the block above? Not sure why it's down here */ if (pCurrChar->GetGuildId() != 0) { /* Get guild based on what we set the player's guild to above */ Guild* guild = sGuildMgr.GetGuildById(pCurrChar->GetGuildId()); /* More checks to see if they're in a guild? I'm sure this is redundant */ if (guild) { /* Build MOTD packet and send it to the player */ data.Initialize(SMSG_GUILD_EVENT, (1 + 1 + guild->GetMOTD().size() + 1)); data << uint8(GE_MOTD); data << uint8(1); data << guild->GetMOTD(); SendPacket(&data); DEBUG_LOG("WORLD: Sent guild-motd (SMSG_GUILD_EVENT)"); /* Let everyone in the guild know you've just signed in */ guild->BroadcastEvent(GE_SIGNED_ON, pCurrChar->GetObjectGuid(), pCurrChar->GetName()); } /* If the player is not in a guild */ else { sLog.outError("Player %s (GUID: %u) marked as member of nonexistent guild (id: %u), removing guild membership for player.", pCurrChar->GetName(), pCurrChar->GetGUIDLow(), pCurrChar->GetGuildId()); /* Set guild to 0 (again) */ pCurrChar->SetInGuild(0); } } /* Don't let the player get stuck logging in with no corpse */ if (!pCurrChar->IsAlive()) { pCurrChar->SendCorpseReclaimDelay(true); } /* Sends information required before the player can be added to the map * TODO: See if we can send information about game objects here (prevent alt+f4 through object) */ pCurrChar->SendInitialPacketsBeforeAddToMap(); /* If it's the player's first login, send a cinematic */ if (!pCurrChar->getCinematic()) { pCurrChar->setCinematic(1); /* Set the start location to the player's racial starting point */ if (ChrRacesEntry const* rEntry = sChrRacesStore.LookupEntry(pCurrChar->getRace())) { pCurrChar->SendCinematicStart(rEntry->CinematicSequence); } } uint32 miscRequirement = 0; AreaLockStatus lockStatus = AREA_LOCKSTATUS_OK; if (AreaTrigger const* at = sObjectMgr.GetMapEntranceTrigger(pCurrChar->GetMapId())) { lockStatus = pCurrChar->GetAreaTriggerLockStatus(at, miscRequirement); } else { // Some basic checks in case of a map without areatrigger MapEntry const* mapEntry = sMapStore.LookupEntry(pCurrChar->GetMapId()); if (!mapEntry) { lockStatus = AREA_LOCKSTATUS_UNKNOWN_ERROR; } } /* This code is run if we can not add the player to the map for some reason */ if (lockStatus != AREA_LOCKSTATUS_OK || !pCurrChar->GetMap()->Add(pCurrChar)) { /* Attempt to find an areatrigger to teleport the player for us */ AreaTrigger const* at = sObjectMgr.GetGoBackTrigger(pCurrChar->GetMapId()); if (at) { lockStatus = pCurrChar->GetAreaTriggerLockStatus(at, miscRequirement); } /* We couldn't find an areatrigger to teleport, so just move the player back to their home bind */ if (!at || lockStatus != AREA_LOCKSTATUS_OK || !pCurrChar->TeleportTo(at->target_mapId, at->target_X, at->target_Y, at->target_Z, pCurrChar->GetOrientation())) { pCurrChar->TeleportToHomebind(); } } sObjectAccessor.AddObject(pCurrChar); DEBUG_LOG("Player %s added to map %i", pCurrChar->GetName(), pCurrChar->GetMapId()); /* send the player's social lists */ pCurrChar->GetSocial()->SendFriendList(); pCurrChar->GetSocial()->SendIgnoreList(); /* Send packets that must be sent only after player is added to the map */ pCurrChar->SendInitialPacketsAfterAddToMap(); /* Mark player as online in the database */ static SqlStatementID updChars; static SqlStatementID updAccount; SqlStatement stmt = CharacterDatabase.CreateStatement(updChars, "UPDATE characters SET online = 1 WHERE guid = ?"); stmt.PExecute(pCurrChar->GetGUIDLow()); stmt = LoginDatabase.CreateStatement(updAccount, "UPDATE account SET active_realm_id = ? WHERE id = ?"); stmt.PExecute(realmID, GetAccountId()); /* Sync player's in-game time with server time */ pCurrChar->SetInGameTime(WorldTimer::getMSTime()); /* Send logon notification to player's group * This is sent after player is added to the world so that player receives it too */ if (Group* group = pCurrChar->GetGroup()) { group->SendUpdate(); } /* Inform player's friends that player has come online */ sSocialMgr.SendFriendStatus(pCurrChar, FRIEND_ONLINE, pCurrChar->GetObjectGuid(), true); /* Load the player's corpse if it exists, or resurrect the player if not */ pCurrChar->LoadCorpse(); /* If the player is dead, we need to set them as a ghost and increase movespeed */ if (pCurrChar->m_deathState != ALIVE) { /* If player is a night elf, wisp racial should be applied */ if (pCurrChar->getRace() == RACE_NIGHTELF) { pCurrChar->CastSpell(pCurrChar, 20584, true); // auras SPELL_AURA_INCREASE_SPEED(+speed in wisp form), SPELL_AURA_INCREASE_SWIM_SPEED(+swim speed in wisp form), SPELL_AURA_TRANSFORM (to wisp form) } /* Apply ghost spell to player */ pCurrChar->CastSpell(pCurrChar, 8326, true); // auras SPELL_AURA_GHOST, SPELL_AURA_INCREASE_SPEED(why?), SPELL_AURA_INCREASE_SWIM_SPEED(why?) /* Allow player to walk on water */ pCurrChar->SetWaterWalk(true); } /* If player is on a taxi, continue their flight */ pCurrChar->ContinueTaxiFlight(); /* Load pet if player has one * If the player is dead or on a taxi, the pet will be remembered as a temporary summon */ pCurrChar->LoadPet(); /* If we're running an FFA PvP realm and the player isn't a GM, mark them as PvP flagged */ if (sWorld.IsFFAPvPRealm() && !pCurrChar->isGameMaster() && !pCurrChar->HasFlag(PLAYER_FLAGS, PLAYER_FLAGS_RESTING)) { pCurrChar->SetFFAPvP(true); } if (pCurrChar->HasFlag(PLAYER_FLAGS, PLAYER_FLAGS_CONTESTED_PVP)) { pCurrChar->SetContestedPvP(); } /* Apply onLogon requests (such as talent resets) */ if (pCurrChar->HasAtLoginFlag(AT_LOGIN_RESET_SPELLS)) { pCurrChar->resetSpells(); SendNotification(LANG_RESET_SPELLS); } if (pCurrChar->HasAtLoginFlag(AT_LOGIN_RESET_TALENTS)) { pCurrChar->resetTalents(true); SendNotification(LANG_RESET_TALENTS); // we can use SMSG_TALENTS_INVOLUNTARILY_RESET here } /* We've done what we need to, remove the flag */ if (pCurrChar->HasAtLoginFlag(AT_LOGIN_FIRST)) { pCurrChar->RemoveAtLoginFlag(AT_LOGIN_FIRST); } /* If the server is shutting down, show shutdown time remaining */ if (sWorld.IsShutdowning()) { sWorld.ShutdownMsg(true, pCurrChar); } /* If player should have all taxi paths, give them to the player */ if (sWorld.getConfig(CONFIG_BOOL_ALL_TAXI_PATHS)) { pCurrChar->SetTaxiCheater(true); } /* Send GM notifications */ if (pCurrChar->isGameMaster()) { SendNotification(LANG_GM_ON); } if (!pCurrChar->isGMVisible()) { SendNotification(LANG_INVISIBLE_INVISIBLE); SpellEntry const* invisibleAuraInfo = sSpellStore.LookupEntry(sWorld.getConfig(CONFIG_UINT32_GM_INVISIBLE_AURA)); if (invisibleAuraInfo && IsSpellAppliesAura(invisibleAuraInfo)) { pCurrChar->CastSpell(pCurrChar, invisibleAuraInfo, true); } } std::string IP_str = GetRemoteAddress(); sLog.outChar("Account: %d (IP: %s) Login Character:[%s] (guid: %u)", GetAccountId(), IP_str.c_str(), pCurrChar->GetName(), pCurrChar->GetGUIDLow()); /* Make player stand up if they're not already stood up and not stunned */ if (!pCurrChar->IsStandState() && !pCurrChar->hasUnitState(UNIT_STAT_STUNNED)) { pCurrChar->SetStandState(UNIT_STAND_STATE_STAND); } m_playerLoading = false; /* Used for movement */ m_clientTimeDelay = 0; /* Used for looting */ pCurrChar->lastTimeLooted = time(NULL); delete holder; }
void WorldSession::HandlePlayerLogin(LoginQueryHolder *holder) { // The following fixes a crash. Use case: // Session1 created, requests login, kicked. // Session2 created, requests login, and receives 2 login callback. if (GetPlayer() || !m_playerLoading) { sLog.outInfo("[CRASH] HandlePlayerLogin on session %u with player %s [loading=%u]", GetAccountId(), GetPlayerName(), m_playerLoading); delete holder; m_playerLoading = false; return; } ObjectGuid playerGuid = holder->GetGuid(); ASSERT(playerGuid.IsPlayer()); // If the character is online (ALT-F4 logout for example) Player *pCurrChar = sObjectAccessor.FindPlayer(playerGuid); MasterPlayer* pCurrMasterPlayer = sObjectAccessor.FindMasterPlayer(playerGuid); bool alreadyOnline = false; if (pCurrChar) { // Hacking attempt if (pCurrChar->GetSession()->GetAccountId() != GetAccountId()) { KickPlayer(); delete holder; m_playerLoading = false; return; } pCurrChar->GetSession()->SetPlayer(NULL); pCurrChar->SetSession(this); // Need to attach packet bcaster to the new socket pCurrChar->m_broadcaster->ChangeSocket(GetSocket()); alreadyOnline = true; // If the character had a logout request, then he is articifially stunned (cf CMSG_LOGOUT_REQUEST handler). Fix it here. if (pCurrChar->CanFreeMove()) { pCurrChar->SetMovement(MOVE_UNROOT); pCurrChar->SetStandState(UNIT_STAND_STATE_STAND); pCurrChar->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_STUNNED); } } else { // Character found online but not in world ? if (HashMapHolder<Player>::Find(playerGuid)) { sLog.outInfo("[CRASH] Trying to login already ingame character guid %u", playerGuid.GetCounter()); KickPlayer(); delete holder; m_playerLoading = false; return; } pCurrChar = new Player(this); pCurrChar->GetMotionMaster()->Initialize(); } // "GetAccountId()==db stored account id" checked in LoadFromDB (prevent login not own character using cheating tools) if (alreadyOnline) pCurrChar->SendPacketsAtRelogin(); else if (!pCurrChar->LoadFromDB(playerGuid, holder)) { KickPlayer(); // disconnect client, player no set to session and it will not deleted or saved at kick delete pCurrChar; // delete it manually delete holder; // delete all unprocessed queries m_playerLoading = false; return; } ASSERT(pCurrChar->GetSession() == this); SetPlayer(pCurrChar); if (pCurrMasterPlayer) { pCurrMasterPlayer->GetSession()->SetMasterPlayer(NULL); pCurrMasterPlayer->SetSession(this); m_masterPlayer = pCurrMasterPlayer; } else { m_masterPlayer = new MasterPlayer(this); m_masterPlayer->LoadPlayer(GetPlayer()); m_masterPlayer->LoadActions(holder->GetResult(PLAYER_LOGIN_QUERY_LOADACTIONS)); m_masterPlayer->LoadSocial(holder->GetResult(PLAYER_LOGIN_QUERY_LOADSOCIALLIST)); m_masterPlayer->LoadMails(holder->GetResult(PLAYER_LOGIN_QUERY_LOADMAILS)); m_masterPlayer->LoadMailedItems(holder->GetResult(PLAYER_LOGIN_QUERY_LOADMAILEDITEMS)); } m_masterPlayer->UpdateNextMailTimeAndUnreads(); sObjectAccessor.AddObject(m_masterPlayer); WorldPacket data(SMSG_LOGIN_VERIFY_WORLD, 20); data << pCurrChar->GetMapId(); data << pCurrChar->GetPositionX(); data << pCurrChar->GetPositionY(); data << pCurrChar->GetPositionZ(); data << pCurrChar->GetOrientation(); SendPacket(&data); data.Initialize(SMSG_ACCOUNT_DATA_TIMES, 128); for (int i = 0; i < 32; ++i) data << uint32(0); SendPacket(&data); // Send MOTD (1.12.1 not have SMSG_MOTD, so do it in another way) { uint32 linecount = 0; std::string str_motd = sWorld.GetMotd(); std::string::size_type pos, nextpos; std::string motd; pos = 0; while ((nextpos = str_motd.find('@', pos)) != std::string::npos) { if (nextpos != pos) { ChatHandler(pCurrChar).PSendSysMessage(str_motd.substr(pos, nextpos - pos).c_str()); ++linecount; } pos = nextpos + 1; } if (pos < str_motd.length()) { ChatHandler(pCurrChar).PSendSysMessage(str_motd.substr(pos).c_str()); ++linecount; } DEBUG_LOG("WORLD: Sent motd (SMSG_MOTD)"); } if (!alreadyOnline) { //QueryResult *result = CharacterDatabase.PQuery("SELECT guildid,rank FROM guild_member WHERE guid = '%u'",pCurrChar->GetGUIDLow()); QueryResult *resultGuild = holder->GetResult(PLAYER_LOGIN_QUERY_LOADGUILD); if (resultGuild) { Field *fields = resultGuild->Fetch(); pCurrChar->SetInGuild(fields[0].GetUInt32()); pCurrChar->SetRank(fields[1].GetUInt32()); } else if (pCurrChar->GetGuildId()) // clear guild related fields in case wrong data about nonexistent membership { pCurrChar->SetInGuild(0); pCurrChar->SetRank(0); } if (pCurrChar->GetGuildId() != 0) { Guild* guild = sGuildMgr.GetGuildById(pCurrChar->GetGuildId()); if (guild) { data.Initialize(SMSG_GUILD_EVENT, (2 + guild->GetMOTD().size() + 1)); data << uint8(GE_MOTD); data << uint8(1); data << guild->GetMOTD(); SendPacket(&data); DEBUG_LOG("WORLD: Sent guild-motd (SMSG_GUILD_EVENT)"); guild->BroadcastEvent(GE_SIGNED_ON, pCurrChar->GetObjectGuid(), pCurrChar->GetName()); } else { // remove wrong guild data sLog.outError("Player %s (GUID: %u) marked as member of nonexistent guild (id: %u), removing guild membership for player.", pCurrChar->GetName(), pCurrChar->GetGUIDLow(), pCurrChar->GetGuildId()); pCurrChar->SetInGuild(0); } } } if (!pCurrChar->isAlive()) pCurrChar->SendCorpseReclaimDelay(true); pCurrChar->SendInitialPacketsBeforeAddToMap(); GetMasterPlayer()->SendInitialActionButtons(); //Show cinematic at the first time that player login if (!pCurrChar->getCinematic()) { pCurrChar->setCinematic(1); if (ChrRacesEntry const* rEntry = sChrRacesStore.LookupEntry(pCurrChar->getRace())) pCurrChar->SendCinematicStart(rEntry->CinematicSequence); } if (!alreadyOnline && !pCurrChar->GetMap()->Add(pCurrChar)) { // normal delayed teleport protection not applied (and this correct) for this case (Player object just created) AreaTrigger const* at = sObjectMgr.GetGoBackTrigger(pCurrChar->GetMapId()); if (at) pCurrChar->TeleportTo(at->target_mapId, at->target_X, at->target_Y, at->target_Z, pCurrChar->GetOrientation()); else pCurrChar->TeleportToHomebind(); } if (alreadyOnline) pCurrChar->GetMap()->ExistingPlayerLogin(pCurrChar); // SendInitSelf ... else sObjectAccessor.AddObject(pCurrChar); //DEBUG_LOG("Player %s added to Map.",pCurrChar->GetName()); pCurrChar->GetSocial()->SendFriendList(); pCurrChar->GetSocial()->SendIgnoreList(); pCurrChar->SendInitialPacketsAfterAddToMap(); if (alreadyOnline) pCurrChar->SendInitWorldStates(pCurrChar->GetCachedZoneId()); static SqlStatementID updChars; static SqlStatementID updAccount; SqlStatement stmt = CharacterDatabase.CreateStatement(updChars, "UPDATE characters SET online = 1 WHERE guid = ?"); stmt.PExecute(pCurrChar->GetGUIDLow()); stmt = LoginDatabase.CreateStatement(updAccount, "UPDATE account SET current_realm = ?, online = 1 WHERE id = ?"); stmt.PExecute(realmID, GetAccountId()); pCurrChar->SetInGameTime(WorldTimer::getMSTime()); // announce group about member online (must be after add to player list to receive announce to self) if (Group *group = pCurrChar->GetGroup()) group->UpdatePlayerOnlineStatus(pCurrChar); // friend status // TODO: Call it when node finished loading also if (GetMasterPlayer()) sSocialMgr.SendFriendStatus(GetMasterPlayer(), FRIEND_ONLINE, GetMasterPlayer()->GetObjectGuid(), true); if (!alreadyOnline) { // Place character in world (and load zone) before some object loading pCurrChar->LoadCorpse(); // setting Ghost+speed if dead if (pCurrChar->m_deathState != ALIVE) { // not blizz like, we must correctly save and load player instead... if (pCurrChar->getRace() == RACE_NIGHTELF) pCurrChar->CastSpell(pCurrChar, 20584, true); // auras SPELL_AURA_INCREASE_SPEED(+speed in wisp form), SPELL_AURA_INCREASE_SWIM_SPEED(+swim speed in wisp form), SPELL_AURA_TRANSFORM (to wisp form) pCurrChar->CastSpell(pCurrChar, 8326, true); // auras SPELL_AURA_GHOST, SPELL_AURA_INCREASE_SPEED(why?), SPELL_AURA_INCREASE_SWIM_SPEED(why?) pCurrChar->SetMovement(MOVE_WATER_WALK); } } // Load pet if any (if player not alive and in taxi flight or another then pet will remember as temporary unsummoned) if (alreadyOnline) pCurrChar->PetSpellInitialize(); else { pCurrChar->ContinueTaxiFlight(); pCurrChar->LoadPet(); } // Set FFA PvP for non GM in non-rest mode if (sWorld.IsFFAPvPRealm() && !pCurrChar->isGameMaster() && !pCurrChar->HasFlag(PLAYER_FLAGS, PLAYER_FLAGS_RESTING)) pCurrChar->SetFFAPvP(true); if (pCurrChar->HasFlag(PLAYER_FLAGS, PLAYER_FLAGS_CONTESTED_PVP)) pCurrChar->SetContestedPvP(); // Apply at_login requests if (pCurrChar->HasAtLoginFlag(AT_LOGIN_RESET_SPELLS)) { pCurrChar->resetSpells(); SendNotification(LANG_RESET_SPELLS); } if (pCurrChar->HasAtLoginFlag(AT_LOGIN_RESET_TALENTS)) { pCurrChar->resetTalents(true); SendNotification(LANG_RESET_TALENTS); // we can use SMSG_TALENTS_INVOLUNTARILY_RESET here } if (pCurrChar->HasAtLoginFlag(AT_LOGIN_FIRST)) pCurrChar->RemoveAtLoginFlag(AT_LOGIN_FIRST); // show time before shutdown if shutdown planned. if (sWorld.IsShutdowning()) sWorld.ShutdownMsg(true, pCurrChar); if (sWorld.getConfig(CONFIG_BOOL_ALL_TAXI_PATHS)) pCurrChar->SetTaxiCheater(true); if (pCurrChar->isGameMaster()) SendNotification(LANG_GM_ON); if (!pCurrChar->isGMVisible()) SendNotification(LANG_INVISIBLE_INVISIBLE, pCurrChar->GetGMInvisibilityLevel()); std::string IP_str = GetRemoteAddress(); sLog.out(LOG_CHAR, "Account: %d (IP: %s) Login Character:[%s] (guid: %u)%s", GetAccountId(), IP_str.c_str(), pCurrChar->GetName(), pCurrChar->GetGUIDLow(), alreadyOnline ? " Player was already online" : ""); sWorld.LogCharacter(pCurrChar, "Login"); if (!alreadyOnline && !pCurrChar->IsStandState() && !pCurrChar->hasUnitState(UNIT_STAT_STUNNED)) pCurrChar->SetStandState(UNIT_STAND_STATE_STAND); m_playerLoading = false; _clientMoverGuid = pCurrChar->GetObjectGuid(); delete holder; if (alreadyOnline) { pCurrChar->UpdateControl(); // Send "Release spirit" timer, etc ... if (pCurrChar->getDeathState() == CORPSE) pCurrChar->KillPlayer(); } // Update warden speeds //if (GetWarden()) //for (int i = 0; i < MAX_MOVE_TYPE; ++i) //GetWarden()->SendSpeedChange(UnitMoveType(i), pCurrChar->GetSpeed(UnitMoveType(i))); ALL_SESSION_SCRIPTS(this, OnLogin(pCurrChar)); }
void OnApply(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/) { Player* player = GetTarget()->ToPlayer(); if (player->GetPet()) player->CastSpell(player, SPELL_HUNTER_ASPECT_OF_THE_BEAST_PET, true); }
void WorldSession::HandlePlayerLogin(LoginQueryHolder * holder) { uint64 playerGuid = holder->GetGuid(); Player* pCurrChar = new Player(this); // for send server info and strings (config) ChatHandler chH = ChatHandler(pCurrChar); // "GetAccountId() == db stored account id" checked in LoadFromDB (prevent login not own character using cheating tools) if (!pCurrChar->LoadFromDB(GUID_LOPART(playerGuid), holder)) { KickPlayer(); // disconnect client, player no set to session and it will not deleted or saved at kick delete pCurrChar; // delete it manually delete holder; // delete all unprocessed queries m_playerLoading = false; return; } pCurrChar->GetMotionMaster()->Initialize(); SetPlayer(pCurrChar); pCurrChar->SendDungeonDifficulty(false); WorldPacket data(SMSG_LOGIN_VERIFY_WORLD, 20); data << pCurrChar->GetMapId(); data << pCurrChar->GetPositionX(); data << pCurrChar->GetPositionY(); data << pCurrChar->GetPositionZ(); data << pCurrChar->GetOrientation(); SendPacket(&data); data.Initialize(SMSG_ACCOUNT_DATA_TIMES, 128); for (int i = 0; i < 32; i++) data << uint32(0); SendPacket(&data); data.Initialize(SMSG_FEATURE_SYSTEM_STATUS, 2); // added in 2.2.0 data << uint8(2); // unknown value data << uint8(0); // enable(1)/disable(0) voice chat interface in client SendPacket(&data); // Send MOTD { data.Initialize(SMSG_MOTD, 50); // new in 2.0.1 data << (uint32)0; uint32 linecount=0; std::string str_motd = sWorld.GetMotd(); std::string::size_type pos, nextpos; pos = 0; while ((nextpos= str_motd.find('@',pos)) != std::string::npos) { if (nextpos != pos) { data << str_motd.substr(pos,nextpos-pos); ++linecount; } pos = nextpos+1; } if (pos<str_motd.length()) { data << str_motd.substr(pos); ++linecount; } data.put(0, linecount); SendPacket(&data); DEBUG_LOG("WORLD: Sent motd (SMSG_MOTD)"); // send server info if (sWorld.getConfig(CONFIG_ENABLE_SINFO_LOGIN) == 1) chH.PSendSysMessage(_FULLVERSION); DEBUG_LOG("WORLD: Sent server info"); } QueryResult_AutoPtr resultGuild = holder->GetResult(PLAYER_LOGIN_QUERY_LOADGUILD); if (resultGuild) { Field *fields = resultGuild->Fetch(); pCurrChar->SetInGuild(fields[0].GetUInt32()); pCurrChar->SetRank(fields[1].GetUInt32()); } else if (pCurrChar->GetGuildId()) // clear guild related fields in case wrong data about non existed membership { pCurrChar->SetInGuild(0); pCurrChar->SetRank(0); } if (pCurrChar->GetGuildId() != 0) { Guild* guild = objmgr.GetGuildById(pCurrChar->GetGuildId()); if (guild) { data.Initialize(SMSG_GUILD_EVENT, (1+1+guild->GetMOTD().size()+1)); data << uint8(GE_MOTD); data << uint8(1); data << guild->GetMOTD(); SendPacket(&data); DEBUG_LOG("WORLD: Sent guild-motd (SMSG_GUILD_EVENT)"); data.Initialize(SMSG_GUILD_EVENT, (5+10)); // we guess size data<<(uint8)GE_SIGNED_ON; data<<(uint8)1; data<<pCurrChar->GetName(); data<<pCurrChar->GetGUID(); guild->BroadcastPacket(&data); DEBUG_LOG("WORLD: Sent guild-signed-on (SMSG_GUILD_EVENT)"); // Increment online members of the guild guild->IncOnlineMemberCount(); } else { // remove wrong guild data sLog.outError("Player %s (GUID: %u) marked as member of invalid guild (id: %u), removing guild membership for player.",pCurrChar->GetName(),pCurrChar->GetGUIDLow(),pCurrChar->GetGuildId()); pCurrChar->SetInGuild(0); } } if (!pCurrChar->isAlive()) pCurrChar->SendCorpseReclaimDelay(true); pCurrChar->SendInitialPacketsBeforeAddToMap(); //Show cinematic at the first time that player login if (!pCurrChar->getCinematic()) { pCurrChar->setCinematic(1); if (ChrRacesEntry const* rEntry = sChrRacesStore.LookupEntry(pCurrChar->getRace())) { pCurrChar->SendCinematicStart(rEntry->CinematicSequence); // send new char string if not empty if (!sWorld.GetNewCharString().empty()) chH.PSendSysMessage("%s", sWorld.GetNewCharString().c_str()); } } if (!pCurrChar->GetMap()->Add(pCurrChar)) { // normal delayed teleport protection not applied (and this correct) for this case (Player object just created) AreaTrigger const* at = objmgr.GetGoBackTrigger(pCurrChar->GetMapId()); if (at) pCurrChar->TeleportTo(at->target_mapId, at->target_X, at->target_Y, at->target_Z, pCurrChar->GetOrientation()); else pCurrChar->TeleportToHomebind(); } ObjectAccessor::Instance().AddObject(pCurrChar); //sLog.outDebug("Player %s added to Map.",pCurrChar->GetName()); pCurrChar->GetSocial()->SendSocialList(); pCurrChar->SendInitialPacketsAfterAddToMap(); CharacterDatabase.PExecute("UPDATE characters SET online = 1 WHERE guid = '%u'", pCurrChar->GetGUIDLow()); //LoginDatabase.PExecute("UPDATE account SET active_realm_id = %d WHERE id = '%u'", realmID, GetAccountId()); pCurrChar->SetInGameTime(getMSTime()); // announce group about member online (must be after add to player list to receive announce to self) if (Group *group = pCurrChar->GetGroup()) group->SendUpdate(); // friend status sSocialMgr.SendFriendStatus(pCurrChar, FRIEND_ONLINE, pCurrChar->GetGUIDLow(), true); // Place character in world (and load zone) before some object loading pCurrChar->LoadCorpse(); // setting Ghost+speed if dead if (pCurrChar->m_deathState != ALIVE) { // not blizz like, we must correctly save and load player instead... if (pCurrChar->getRace() == RACE_NIGHTELF) { pCurrChar->CastSpell(pCurrChar, 20584, true, 0);// auras SPELL_AURA_INCREASE_SPEED(+speed in wisp form), SPELL_AURA_INCREASE_SWIM_SPEED(+swim speed in wisp form), SPELL_AURA_TRANSFORM (to wisp form) } pCurrChar->CastSpell(pCurrChar, 8326, true, 0); // auras SPELL_AURA_GHOST, SPELL_AURA_INCREASE_SPEED(why?), SPELL_AURA_INCREASE_SWIM_SPEED(why?) pCurrChar->SetMovement(MOVE_WATER_WALK); } pCurrChar->ContinueTaxiFlight(); // Load pet if any and player is alive and not in taxi flight if (pCurrChar->isAlive() && pCurrChar->m_taxi.GetTaxiSource() == 0) pCurrChar->LoadPet(); // Set FFA PvP for non GM in non-rest mode if (sWorld.IsFFAPvPRealm() && !pCurrChar->isGameMaster() && !pCurrChar->HasFlag(PLAYER_FLAGS,PLAYER_FLAGS_RESTING)) pCurrChar->SetFFAPvP(true); if (pCurrChar->HasFlag(PLAYER_FLAGS, PLAYER_FLAGS_CONTESTED_PVP)) pCurrChar->SetContestedPvP(); // Apply at_login requests if (pCurrChar->HasAtLoginFlag(AT_LOGIN_RESET_SPELLS)) { pCurrChar->resetSpells(); SendNotification(LANG_RESET_SPELLS); } if (pCurrChar->HasAtLoginFlag(AT_LOGIN_RESET_TALENTS)) { pCurrChar->resetTalents(true); SendNotification(LANG_RESET_TALENTS); } // show time before shutdown if shutdown planned. if (sWorld.IsShutdowning()) sWorld.ShutdownMsg(true,pCurrChar); // ImpConfig - Max weapon skill when logging in if (sWorld.getConfig(CONFIG_ALWAYS_MAXSKILL)) pCurrChar->UpdateSkillsToMaxSkillsForLevel(); if (sWorld.getConfig(CONFIG_ALL_TAXI_PATHS)) pCurrChar->SetTaxiCheater(true); //Reputations if "StartAllReputation" is enabled if (sWorld.getConfig(CONFIG_START_ALL_REP)) { pCurrChar->SetFactionReputation(sFactionStore.LookupEntry(942),42999); pCurrChar->SetFactionReputation(sFactionStore.LookupEntry(935),42999); pCurrChar->SetFactionReputation(sFactionStore.LookupEntry(936),42999); pCurrChar->SetFactionReputation(sFactionStore.LookupEntry(1011),42999); pCurrChar->SetFactionReputation(sFactionStore.LookupEntry(970),42999); pCurrChar->SetFactionReputation(sFactionStore.LookupEntry(967),42999); pCurrChar->SetFactionReputation(sFactionStore.LookupEntry(989),42999); pCurrChar->SetFactionReputation(sFactionStore.LookupEntry(932),42999); pCurrChar->SetFactionReputation(sFactionStore.LookupEntry(934),42999); pCurrChar->SetFactionReputation(sFactionStore.LookupEntry(1038),42999); pCurrChar->SetFactionReputation(sFactionStore.LookupEntry(1077),42999); pCurrChar->SetFactionReputation(sFactionStore.LookupEntry(990),42999); // Factions depending on team, like cities and some more stuff switch(pCurrChar->GetTeam()) { case ALLIANCE: pCurrChar->SetFactionReputation(sFactionStore.LookupEntry(72),42999); pCurrChar->SetFactionReputation(sFactionStore.LookupEntry(47),42999); pCurrChar->SetFactionReputation(sFactionStore.LookupEntry(69),42999); pCurrChar->SetFactionReputation(sFactionStore.LookupEntry(930),42999); pCurrChar->SetFactionReputation(sFactionStore.LookupEntry(730),42999); pCurrChar->SetFactionReputation(sFactionStore.LookupEntry(978),42999); pCurrChar->SetFactionReputation(sFactionStore.LookupEntry(54),42999); pCurrChar->SetFactionReputation(sFactionStore.LookupEntry(946),42999); break; case HORDE: pCurrChar->SetFactionReputation(sFactionStore.LookupEntry(76),42999); pCurrChar->SetFactionReputation(sFactionStore.LookupEntry(68),42999); pCurrChar->SetFactionReputation(sFactionStore.LookupEntry(81),42999); pCurrChar->SetFactionReputation(sFactionStore.LookupEntry(911),42999); pCurrChar->SetFactionReputation(sFactionStore.LookupEntry(729),42999); pCurrChar->SetFactionReputation(sFactionStore.LookupEntry(941),42999); pCurrChar->SetFactionReputation(sFactionStore.LookupEntry(530),42999); pCurrChar->SetFactionReputation(sFactionStore.LookupEntry(947),42999); break; default: break; } } if (pCurrChar->isGameMaster()) SendNotification(LANG_GM_ON); std::string IP_str = GetRemoteAddress(); sLog.outChar("Account: %d (IP: %s) Login Character:[%s] (guid: %u)", GetAccountId(), IP_str.c_str(), pCurrChar->GetName(), pCurrChar->GetGUIDLow()); m_playerLoading = false; //Hook for OnLogin Event sScriptMgr.OnLogin(pCurrChar); delete holder; }