Example #1
0
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;
}
Example #2
0
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;
}
Example #3
0
    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);
        }
    }
}
Example #5
0
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();
	}
}
Example #6
0
            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;
                    }
                }
            }
Example #7
0
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 );
	}
};
Example #9
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);
                    }
                }
            }
        }
Example #11
0
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;
}
Example #12
0
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);
}
Example #14
0
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;
}
Example #15
0
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);
}
Example #16
0
 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);
 }
Example #17
0
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);
				}
			}
		}
	}
}
Example #18
0
            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();
            }
Example #19
0
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();
}
Example #20
0
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();
}
Example #21
0
            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();
            }
Example #22
0
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
        }
    }
}
Example #23
0
        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();
    }
Example #25
0
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;
}
Example #26
0
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;
}
Example #27
0
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;
}
Example #28
0
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));
}
Example #29
0
 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;
}