Player* FollowerAI::GetLeaderForFollower()
{
    if (Player* player = ObjectAccessor::GetPlayer(*me, m_uiLeaderGUID))
    {
        if (player->IsAlive())
            return player;
        else
        {
            if (Group* group = player->GetGroup())
            {
                for (GroupReference* groupRef = group->GetFirstMember(); groupRef != NULL; groupRef = groupRef->next())
                {
                    Player* member = groupRef->GetSource();

                    if (member && member->IsAlive() && me->IsWithinDistInMap(member, MAX_PLAYER_DISTANCE))
                    {
                        TC_LOG_DEBUG("scripts", "FollowerAI GetLeader changed and returned new leader.");
                        m_uiLeaderGUID = member->GetGUID();
                        return member;
                    }
                }
            }
        }
    }

    TC_LOG_DEBUG("scripts", "FollowerAI GetLeader can not find suitable leader.");
    return NULL;
}
Example #2
0
    uint32 NextStep(uint32 uiStep)
    {
        Player* pPlayer = m_creature->GetMap()->GetPlayer(m_playerGuid);

        if (!pPlayer)
        {
            SetRuffies(m_creepjackGuid, false, true);
            SetRuffies(m_maloneGuid, false, true);
            EnterEvadeMode();
            return 0;
        }

        switch (uiStep)
        {
            case 1:
                DoScriptText(SAY_START, m_creature, pPlayer);
                SetRuffies(m_creepjackGuid, false, false);
                SetRuffies(m_maloneGuid, false, false);
                return 3000;
            case 2: DoScriptText(SAY_COUNT, m_creature, pPlayer);   return 5000;
            case 3: DoScriptText(SAY_COUNT_1, m_creature, pPlayer); return 3000;
            case 4: DoScriptText(SAY_COUNT_2, m_creature, pPlayer); return 3000;
            case 5: DoScriptText(SAY_ATTACK, m_creature, pPlayer);  return 3000;
            case 6:
                if (!m_creature->IsInCombat() && pPlayer->IsAlive())
                { AttackStart(pPlayer); }

                SetRuffies(m_creepjackGuid, true, false);
                SetRuffies(m_maloneGuid, true, false);
                bActiveAttack = true;
                return 2000;
            default:
                return 0;
        }
    }
Example #3
0
Player* FollowerAI::GetLeaderForFollower()
{
    if (Player* pLeader = Unit::GetPlayer(*me, m_uiLeaderGUID))
    {
        if (pLeader->IsAlive())
            return pLeader;
        else
        {
            if (Group* pGroup = pLeader->GetGroup())
            {
                for (GroupReference* pRef = pGroup->GetFirstMember(); pRef != NULL; pRef = pRef->next())
                {
                    Player* pMember = pRef->GetSource();

                    if (pMember && pMember->IsAlive() && me->IsWithinDistInMap(pMember, MAX_PLAYER_DISTANCE))
                    {
                        sLog.outDebug("OSCR: FollowerAI GetLeader changed and returned new leader.");
                        m_uiLeaderGUID = pMember->GetGUID();
                        return pMember;
                        break;
                    }
                }
            }
        }
    }

    sLog.outDebug("OSCR: FollowerAI GetLeader can not find suitable leader.");
    return NULL;
}
Example #4
0
uint8 AoeHealValue::Calculate()
{
    Group* group = bot->GetGroup();
    if (!group)
    	return 0;

    float range = 0;
    if (qualifier == "low")
    	range = sPlayerbotAIConfig.lowHealth;
    else if (qualifier == "medium")
    	range = sPlayerbotAIConfig.mediumHealth;
    else if (qualifier == "critical")
    	range = sPlayerbotAIConfig.criticalHealth;

    uint8 count = 0;
	Group::MemberSlotList const& groupSlot = group->GetMemberSlots();
	for (Group::member_citerator itr = groupSlot.begin(); itr != groupSlot.end(); itr++)
	{
		Player *player = sObjectMgr->GetPlayerByLowGUID(itr->guid);
		if( !player || !player->IsAlive())
			continue;

	    float percent = (static_cast<float> (player->GetHealth()) / player->GetMaxHealth()) * 100;
	    if (percent <= range)
	    	count++;
	}

	return count;
}
Example #5
0
Unit* PartyMemberToHeal::Calculate()
{
    
    IsTargetOfHealingSpell predicate;

    Group* group = bot->GetGroup();
    if (!group)
        return NULL;

    bool isRaid = bot->GetGroup()->isRaidGroup();
    MinValueCalculator calc(100);
    for (GroupReference *gref = group->GetFirstMember(); gref; gref = gref->next()) 
    {
        Player* player = gref->getSource();
        if (!Check(player) || !player->IsAlive())
            continue;

        uint8 health = player->GetHealthPercent();
        if (isRaid || health < sPlayerbotAIConfig.mediumHealth || !IsTargetOfSpellCast(player, predicate))
            calc.probe(health, player);

        Pet* pet = player->GetPet();
        if (pet && CanHealPet(pet)) 
        {
            health = pet->GetHealthPercent();
            if (isRaid || health < sPlayerbotAIConfig.mediumHealth || !IsTargetOfSpellCast(player, predicate))
                calc.probe(health, player);
        }
    }
    return (Unit*)calc.param;
}
Example #6
0
    static bool HandleBotHelperCommand(ChatHandler* handler, const char* /*args*/)
    {
        Player* player = handler->GetSession()->GetPlayer();
        handler->SetSentErrorMessage(true);
        if (/*player->IsInCombat() ||*/
            player->isDead() ||
            !player->IsAlive() ||
            player->IsInFlight() ||
            player->IsCharmed() ||
            bot_ai::CCed(player))
        {
            handler->SendSysMessage("You cannot do this right now");
            return false;
        }
        //close current menu
        player->PlayerTalkClass->SendCloseGossip();
        if (player->GetTrader())
            player->GetSession()->SendCancelTrade();

        BotHelper* hlpr = player->GetBotHelper();
        if (!hlpr)
        {
            hlpr = new BotHelper(player);
            player->SetBotHelper(hlpr);
        }
        return hlpr->OnGossipHello(player);
    }
        void UpdateAI(uint32 diff) override
        {
            events.Update(diff);

            while (uint32 eventId = events.ExecuteEvent())
            {
                switch(eventId)
                {
                case EVENT_CHECK_PLAYER:
                {
                    bool checkPassed = true;
                    Player* player = ObjectAccessor::FindPlayer(playerGuid);

                    if (!player)
                    {
                        me->DespawnOrUnsummon(1000);
                        playerGuid = 0;
                        break;
                    }

                    if (!player->IsAlive())
                    {
                        me->DespawnOrUnsummon(1000);
                        playerGuid = 0;
                        break;
                    }

                    if (player->GetQuestStatus(QUEST_PARCHEMIN_VOLANT) != QUEST_STATUS_INCOMPLETE)
                    {
                        me->DespawnOrUnsummon(1000);
                        playerGuid = 0;
                        break;
                    }

                    events.ScheduleEvent(EVENT_CHECK_PLAYER, 2500);
                    break;
                }
                case EVENT_FEET_OF_FURY:
                    if (me->GetVictim())
                        me->CastSpell(me->GetVictim(), 108958);

                    events.ScheduleEvent(EVENT_FEET_OF_FURY, 5000);
                    break;
                case EVENT_SHADOW_KICK:
                    if (me->GetVictim())
                        me->CastSpell(me->GetVictim(), 108936);

                    events.ScheduleEvent(EVENT_SHADOW_KICK_STUN, 2500);
                    events.ScheduleEvent(EVENT_SHADOW_KICK, 30000);
                    break;
                case 4:
                    if (me->GetVictim())
                        me->CastSpell(me->GetVictim(), 108944);
                    break;
                }
            }

            DoMeleeAttackIfReady();
        }
Example #8
0
        void UpdatePortals() // Here we handle the beams' behavior
        {
            for (int j=0; j<3; ++j) // j = color
                if (Creature* portal = Unit::GetCreature(*me, PortalGUID[j]))
                {
                    // the one who's been casted upon before
                    Unit* current = Unit::GetUnit(*portal, BeamTarget[j]);
                    // temporary store for the best suitable beam reciever
                    Unit* target = me;

                    if (Map* map = me->GetMap())
                    {
                        Map::PlayerList const& players = map->GetPlayers();

                        // get the best suitable target
                        for (Map::PlayerList::const_iterator i = players.begin(); i != players.end(); ++i)
                        {
                            Player* p = i->GetSource();
                            if (p && p->IsAlive() // alive
                                && (!target || target->GetDistance2d(portal)>p->GetDistance2d(portal)) // closer than current best
                                && !p->HasAura(PlayerDebuff[j], 0) // not exhausted
                                && !p->HasAura(PlayerBuff[(j+1)%3], 0) // not on another beam
                                && !p->HasAura(PlayerBuff[(j+2)%3], 0)
                                && IsBetween(me, p, portal)) // on the beam
                                target = p;
                        }
                    }
                    // buff the target
                    if (target->GetTypeId() == TYPEID_PLAYER)
                        target->AddAura(PlayerBuff[j], target);
                    else
                        target->AddAura(NetherBuff[j], target);
                    // cast visual beam on the chosen target if switched
                    // simple target switching isn't working -> using BeamerGUID to cast (workaround)
                    if (!current || target != current)
                    {
                        BeamTarget[j] = target->GetGUID();
                        // remove currently beaming portal
                        if (Creature* beamer = Unit::GetCreature(*portal, BeamerGUID[j]))
                        {
                            beamer->CastSpell(target, PortalBeam[j], false);
                            beamer->DisappearAndDie();
                            BeamerGUID[j] = 0;
                        }
                        // create new one and start beaming on the target
                        if (Creature* beamer = portal->SummonCreature(PortalID[j], portal->GetPositionX(), portal->GetPositionY(), portal->GetPositionZ(), portal->GetOrientation(), TEMPSUMMON_TIMED_DESPAWN, 60000))
                        {
                            beamer->CastSpell(target, PortalBeam[j], false);
                            BeamerGUID[j] = beamer->GetGUID();
                        }
                    }
                    // aggro target if Red Beam
                    if (j == RED_PORTAL && me->GetVictim() != target && target->GetTypeId() == TYPEID_PLAYER)
                        me->getThreatManager().addThreat(target, 100000.0f+DoGetThreat(me->GetVictim()));
                }
        }
Example #9
0
		bool Client::IsFollowing() {
			if(!world) return false;
			if(!world->GetLocalPlayer())
				return false;
			Player *p = world->GetLocalPlayer();
			if(p->GetTeamId() >= 2)
				return true;
			if(p->IsAlive())
				return false;
			else return true;
		}
Example #10
0
void AttackersValue::AddAttackersOf(Group* group, set<Unit*>& targets)
{
    Group::MemberSlotList const& groupSlot = group->GetMemberSlots();
    for (Group::member_citerator itr = groupSlot.begin(); itr != groupSlot.end(); itr++)
    {
        Player *member = sObjectMgr.GetPlayer(itr->guid);
        if (!member || !member->IsAlive() || member == bot)
            continue;

        AddAttackersOf(member, targets);
    }
}
    void MovementInform(uint32 uiType, uint32 uiPointId) override
    {
        if (!m_pInstance)
        { return; }

        if (uiType == WAYPOINT_MOTION_TYPE)
        {
            if (m_uiMovementTimer || m_bIsEventInProgress)
            { return; }

            if (m_pInstance->GetData(TYPE_NAZAN) == SPECIAL)
            {
                m_creature->SetCombatStartPosition(m_creature->GetPositionX(), m_creature->GetPositionY(), m_creature->GetPositionZ());
                m_uiMovementTimer = 1000;
                m_bIsEventInProgress = true;
            }
        }

        if (uiType == POINT_MOTION_TYPE)
        {
            switch (uiPointId)
            {
                case POINT_ID_CENTER:
                    DoSplit();
                    break;
                case POINT_ID_COMBAT:
                {
                    m_creature->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
                    m_pInstance->SetData(TYPE_NAZAN, IN_PROGRESS);

                    // Landing
                    // undo flying
                    m_creature->SetByteValue(UNIT_FIELD_BYTES_1, 3, 0);
                    m_creature->SetLevitate(false);

                    Player* pPlayer = m_creature->GetMap()->GetPlayer(m_lastSeenPlayerGuid);
                    if (pPlayer && pPlayer->IsAlive())
                    { AttackStart(pPlayer); }

                    // Initialize for combat
                    m_uiFireballTimer = urand(5200, 16500);

                    break;
                }
                case POINT_ID_FLYING:
                    if (m_bIsEventInProgress)               // Additional check for wipe case, while nazan is flying to this point
                    { m_uiFireballTimer = 1; }
                    break;
            }
        }
    }
Example #12
0
		void HurtRingView::Draw(){
			SPADES_MARK_FUNCTION();
			
			Vector3 playerFront;
			World *w = client->GetWorld();
			if(!w){
				ClearAll();
				return;
			}
			
			Player *p = w->GetLocalPlayer();
			if(p == NULL || !p->IsAlive()){
				ClearAll();
				return;
			}
			
			playerFront = p->GetFront2D();
			
			float hurtRingSize = renderer->ScreenHeight() * .3f;
			float cx = renderer->ScreenWidth() * .5f;
			float cy = renderer->ScreenHeight() * .5f;
			static const float coords[][2]={
				{-1,-1},{1,-1},{-1,1}
			};
			
			std::list<Item>::iterator it;
			for(it = items.begin(); it != items.end(); it++){
				Item& item = *it;
				
				float fade = item.fade * 2.f;
				if(fade > 1.f)fade = 1.f;
				Vector4 color = {1,1,1,fade};
				renderer->SetColor(color);
				
				Vector3 dir = -item.dir;
				float c = dir.x * playerFront.x + dir.y * playerFront.y;
				float s = dir.y * playerFront.x - dir.x * playerFront.y;
				
				Vector2 verts[3];
				for(int i = 0; i < 3; i++){
					verts[i] = MakeVector2(coords[i][0] * c - coords[i][1] * s,
										   coords[i][0] * s + coords[i][1] * c);
					verts[i] = verts[i] * hurtRingSize + MakeVector2(cx, cy);
				}
				
				renderer->DrawImage(image,
									verts[0], verts[1], verts[2],
									AABB2(0, 0, image->GetWidth(), image->GetHeight()));
			}
		}
Example #13
0
            void JustDied(Unit* /*killer*/)
            {
                Player* target = ObjectAccessor::GetPlayer(*me, _revivePlayerGUID);
                if (!target || target->IsAlive())
                    return;

                if (Creature* mandokir = ObjectAccessor::GetCreature(*me, _instance->GetData64(DATA_MANDOKIR)))
                {
                    mandokir->GetAI()->SetGUID(target->GetGUID());
                    mandokir->GetAI()->DoAction(ACTION_START_REVIVE);
                }

                me->DespawnOrUnsummon();
            }
        bool CheckWipe()
        {
            Map::PlayerList const &players = instance->GetPlayers();
            for (Map::PlayerList::const_iterator itr = players.begin(); itr != players.end(); ++itr)
            {
                Player* player = itr->GetSource();
                if (player->IsGameMaster())
                    continue;

                if (player->IsAlive())
                    return false;
            }

            return true;
        }
Example #15
0
        void SpellHitTarget(Unit* pTarget, const SpellInfo *spell)
        {
            if (spell->Id == SPELL_INSANITY)
            {
                // Not good target or too many players
                if (pTarget->GetTypeId() != TYPEID_PLAYER || insanityHandled > 4)
                    return;

                // First target - start channel visual and set self as unnattackable
                if (!insanityHandled)
                {
					me->RemoveAllAuras();
					me->CastSpell(me, INSANITY_VISUAL, true);
                    me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
                    me->SetControlled(true, UNIT_STATE_STUNNED);
                }

                // phase mask
                pTarget->CastSpell(pTarget, SPELL_INSANITY_TARGET+insanityHandled, true);
                
				// summon twisted party members for this target
                Map::PlayerList const &players = me->GetMap()->GetPlayers();
                for (Map::PlayerList::const_iterator i = players.begin(); i != players.end(); ++i)
                {
                    Player *plr = i->GetSource();
                    if (!plr || !plr->IsAlive() || pTarget->GetGUID() == plr->GetGUID())
                        continue;

                    // Summon clone
                    if (Unit* summon = me->SummonCreature(NPC_TWISTED_VISAGE, plr->GetPositionX(), plr->GetPositionY(), plr->GetPositionZ(), plr->GetOrientation(), TEMPSUMMON_CORPSE_DESPAWN, 0))
                    {
						summon->AddThreat(pTarget, 0.0f);
						summon->SetInCombatWith(pTarget);
						pTarget->SetInCombatWith(summon);

                        plr->CastSpell(summon, SPELL_CLONE_PLAYER, true);
                        summon->SetPhaseMask(1|(1<<(4+insanityHandled)), true);
						summon->SetUInt32Value(UNIT_FIELD_MINDAMAGE, plr->GetUInt32Value(UNIT_FIELD_MINDAMAGE));
						summon->SetUInt32Value(UNIT_FIELD_MAXDAMAGE, plr->GetUInt32Value(UNIT_FIELD_MAXDAMAGE));
                    }
                }

                ++insanityHandled;
            }
        }
        void SpellHitTarget(Unit* target, const SpellInfo* spell) override
        {
            if (spell->Id == SPELL_INSANITY)
            {
                // Not good target or too many players
                if (target->GetTypeId() != TYPEID_PLAYER || insanityHandled > 4)
                    return;
                // First target - start channel visual and set self as unnattackable
                if (!insanityHandled)
                {
                    // Channel visual
                    DoCast(me, INSANITY_VISUAL, true);
                    // Unattackable
                    me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
                    me->SetControlled(true, UNIT_STATE_STUNNED);
                }

                // phase the player
                target->CastSpell(target, SPELL_INSANITY_TARGET + insanityHandled, true);

                SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(SPELL_INSANITY_TARGET + insanityHandled);
                if (!spellInfo)
                    return;

                // summon twisted party members for this target
                Map::PlayerList const &players = me->GetMap()->GetPlayers();
                for (Map::PlayerList::const_iterator i = players.begin(); i != players.end(); ++i)
                {
                    Player* player = i->GetSource();
                    if (!player || !player->IsAlive())
                        continue;
                    // Summon clone
                    if (Unit* summon = me->SummonCreature(NPC_TWISTED_VISAGE, me->GetPositionX(), me->GetPositionY(), me->GetPositionZ(), me->GetOrientation(), TEMPSUMMON_CORPSE_DESPAWN, 0))
                    {
                        // clone
                        player->CastSpell(summon, SPELL_CLONE_PLAYER, true);
                        // phase the summon
                        summon->SetInPhase(spellInfo->Effects[EFFECT_0].MiscValueB, true, true);
                    }
                }
                ++insanityHandled;
            }
        }
Example #17
0
void AttackersValue::AddAttackersOf(Group* group, set<Unit*>& targets)
{
    Group::MemberSlotList const& groupSlot = group->GetMemberSlots();
    for (Group::member_citerator itr = groupSlot.begin(); itr != groupSlot.end(); itr++)
    {
        Player *member = sObjectMgr->GetPlayerByLowGUID(itr->guid);
        if (!member || !member->IsAlive() || member == bot)
            continue;

        if (member->IsBeingTeleported())
            return;

        AddAttackersOf(member, targets);

        Pet* pet = member->GetPet();
        if (pet)
            AddAttackersOf(pet, targets);
    }
}
Example #18
0
bool InstanceScript::IsWipe()
{
    Map::PlayerList const& PlayerList = instance->GetPlayers();
    
    if (PlayerList.isEmpty())
        return true;
        
    for (Map::PlayerList::const_iterator Itr = PlayerList.begin(); Itr != PlayerList.end(); ++Itr)
    {
        Player* player = Itr->GetSource();
    
        if (!player)
            continue;
        
        if (player->IsAlive() && !player->IsGameMaster())
            return false;
    }
    
    return true;
}
Example #19
0
void CreatureAI::DoAttackerGroupInCombat(Player* attacker)
 {
     if(attacker)
     {
         if( Group *pGroup = attacker->GetGroup() )
         {
             for(GroupReference *itr = pGroup->GetFirstMember(); itr != NULL; itr = itr->next())
             {
                 Player *pGroupGuy = itr->GetSource();
 
                 if(pGroupGuy && pGroupGuy->IsAlive() && pGroupGuy->GetMapId() == me->GetMapId())
                 {
                     me->SetInCombatWith(pGroupGuy);
                     pGroupGuy->SetInCombatWith(me);
                     me->AddThreat(pGroupGuy, 0.0f);
                 }
             }
         }
     }
 }
Example #20
0
void instance_uldaman::Update(uint32 uiDiff)
{
    if (GetData(TYPE_ALTAR_EVENT) != IN_PROGRESS)
        return;

    if (!m_uiKeeperCooldown)
        return;

    if (m_uiKeeperCooldown <= uiDiff)
    {
        for (GuidList::const_iterator itr = m_lKeepers.begin(); itr != m_lKeepers.end(); ++itr)
        {
            // Get Keeper which is alive and out of combat
            Creature* pKeeper = instance->GetCreature(*itr);
            if (!pKeeper || !pKeeper->IsAlive() || pKeeper->getVictim())
                continue;

            // Get starter player for attack
            Player* pPlayer = pKeeper->GetMap()->GetPlayer(m_playerGuid);
            if (!pPlayer || !pPlayer->IsAlive())
            {
                // If he's not available, then get a random player, within a reasonamble distance in map
                pPlayer = GetPlayerInMap(true, false);
                if (!pPlayer || !pPlayer->IsWithinDistInMap(pKeeper, 50.0f))
                {
                    SetData(TYPE_ALTAR_EVENT, NOT_STARTED);
                    return;
                }
            }

            // Attack the player
            pKeeper->RemoveAurasDueToSpell(SPELL_STONED);
            pKeeper->AI()->AttackStart(pPlayer);
            break;
        }

        m_uiKeeperCooldown = 0;
    }
    else
        m_uiKeeperCooldown -= uiDiff;
}
Example #21
0
void WorldSession::HandleMovementOpcodes(WorldPacket & recvData)
{
    uint16 opcode = recvData.GetOpcode();

    Unit* mover = _player->m_mover;

    ASSERT(mover != NULL);                      // there must always be a mover

    Player* plrMover = mover->ToPlayer();

    // ignore, waiting processing in WorldSession::HandleMoveWorldportAckOpcode and WorldSession::HandleMoveTeleportAck
    if (plrMover && plrMover->IsBeingTeleported())
    {
        recvData.rfinish();                     // prevent warnings spam
        return;
    }

    /* extract packet */
    uint64 guid;

    recvData.readPackGUID(guid);

    MovementInfo movementInfo;
    movementInfo.guid = guid;
    ReadMovementInfo(recvData, &movementInfo);

    recvData.rfinish();                         // prevent warnings spam

    // pussywizard: typical check for incomming movement packets
    if (!mover || !mover->IsInWorld() || mover->IsDuringRemoveFromWorld() || guid != mover->GetGUID())
        return;

    if (!movementInfo.pos.IsPositionValid())
    {
        recvData.rfinish();                     // prevent warnings spam
        return;
    }

    if (movementInfo.flags & MOVEMENTFLAG_ONTRANSPORT)
    {
        // T_POS ON VEHICLES!
        if (mover->GetVehicle())
            movementInfo.transport.pos = mover->m_movementInfo.transport.pos;

        // transports size limited
        // (also received at zeppelin leave by some reason with t_* as absolute in continent coordinates, can be safely skipped)
        if (movementInfo.transport.pos.GetPositionX() > 75.0f || movementInfo.transport.pos.GetPositionY() > 75.0f || movementInfo.transport.pos.GetPositionZ() > 75.0f ||
            movementInfo.transport.pos.GetPositionX() < -75.0f || movementInfo.transport.pos.GetPositionY() < -75.0f || movementInfo.transport.pos.GetPositionZ() < -75.0f)
        {
            recvData.rfinish();                   // prevent warnings spam
            return;
        }

        if (!Trinity::IsValidMapCoord(movementInfo.pos.GetPositionX() + movementInfo.transport.pos.GetPositionX(), movementInfo.pos.GetPositionY() + movementInfo.transport.pos.GetPositionY(),
            movementInfo.pos.GetPositionZ() + movementInfo.transport.pos.GetPositionZ(), movementInfo.pos.GetOrientation() + movementInfo.transport.pos.GetOrientation()))
        {
            recvData.rfinish();                   // prevent warnings spam
            return;
        }

        // if we boarded a transport, add us to it
        if (plrMover)
        {
            if (!plrMover->GetTransport())
            {
                if (Transport* transport = plrMover->GetMap()->GetTransport(movementInfo.transport.guid))
                {
                    plrMover->m_transport = transport;
                    transport->AddPassenger(plrMover);
                }
            }
            else if (plrMover->GetTransport()->GetGUID() != movementInfo.transport.guid)
            {
                bool foundNewTransport = false;
                plrMover->m_transport->RemovePassenger(plrMover);
                if (Transport* transport = plrMover->GetMap()->GetTransport(movementInfo.transport.guid))
                {
                    foundNewTransport = true;
                    plrMover->m_transport = transport;
                    transport->AddPassenger(plrMover);
                }

                if (!foundNewTransport)
                {
                    plrMover->m_transport = NULL;
                    movementInfo.transport.Reset();
                }
            }
        }

        if (!mover->GetTransport() && !mover->GetVehicle())
            movementInfo.flags &= ~MOVEMENTFLAG_ONTRANSPORT;
    }
    else if (plrMover && plrMover->GetTransport()) // if we were on a transport, leave
    {
        plrMover->m_transport->RemovePassenger(plrMover);
        plrMover->m_transport = NULL;
        movementInfo.transport.Reset();
    }

    if (plrMover && ((movementInfo.flags & MOVEMENTFLAG_SWIMMING) != 0) != plrMover->IsInWater())
    {
        // now client not include swimming flag in case jumping under water
        plrMover->SetInWater(!plrMover->IsInWater() || plrMover->GetBaseMap()->IsUnderWater(movementInfo.pos.GetPositionX(), movementInfo.pos.GetPositionY(), movementInfo.pos.GetPositionZ()));
    }
    // Dont allow to turn on walking if charming other player
    if (mover->GetGUID() != _player->GetGUID())
        movementInfo.flags &= ~MOVEMENTFLAG_WALKING;

    uint32 mstime = World::GetGameTimeMS();
    /*----------------------*/
    if(m_clientTimeDelay == 0)
        m_clientTimeDelay = mstime > movementInfo.time ? std::min(mstime - movementInfo.time, (uint32)100) : 0;

    // Xinef: do not allow to move with UNIT_FLAG_DISABLE_MOVE
    if (mover->HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_DISABLE_MOVE))
    {
        // Xinef: skip moving packets
        if (movementInfo.HasMovementFlag(MOVEMENTFLAG_MASK_MOVING))
            return;
        movementInfo.pos.Relocate(mover->GetPositionX(), mover->GetPositionY(), mover->GetPositionZ());

        if (mover->GetTypeId() == TYPEID_UNIT)
        {
            movementInfo.transport.guid = mover->m_movementInfo.transport.guid;
            movementInfo.transport.pos.Relocate(mover->m_movementInfo.transport.pos.GetPositionX(), mover->m_movementInfo.transport.pos.GetPositionY(), mover->m_movementInfo.transport.pos.GetPositionZ());
            movementInfo.transport.seat = mover->m_movementInfo.transport.seat;
        }
    }

    /* process position-change */
    WorldPacket data(opcode, recvData.size());
    //movementInfo.time = movementInfo.time + m_clientTimeDelay + MOVEMENT_PACKET_TIME_DELAY;
    movementInfo.time = mstime; // pussywizard: set to time of relocation (server time), constant addition may smoothen movement clientside, but client sees target on different position than the real serverside position

    movementInfo.guid = mover->GetGUID();
    WriteMovementInfo(&data, &movementInfo);
    mover->SendMessageToSet(&data, _player);

    mover->m_movementInfo = movementInfo;

    // this is almost never true (pussywizard: only one packet when entering vehicle), normally use mover->IsVehicle()
    if (mover->GetVehicle())
    {
        mover->SetOrientation(movementInfo.pos.GetOrientation());
        mover->UpdatePosition(movementInfo.pos);
        return;
    }

    // pussywizard: previously always mover->UpdatePosition(movementInfo.pos);
    if (movementInfo.flags & MOVEMENTFLAG_ONTRANSPORT && mover->GetTransport())
    {
        float x, y, z, o;
        movementInfo.transport.pos.GetPosition(x, y, z, o);
        mover->GetTransport()->CalculatePassengerPosition(x, y, z, &o);
        mover->UpdatePosition(x, y, z, o);
    }
    else
        mover->UpdatePosition(movementInfo.pos);

    // fall damage generation (ignore in flight case that can be triggered also at lags in moment teleportation to another map).
    // Xinef: moved it here, previously StopMoving function called when player died relocated him to last saved coordinates (which were in air)
    if (opcode == MSG_MOVE_FALL_LAND && plrMover && !plrMover->IsInFlight() && (!plrMover->GetTransport() || plrMover->GetTransport()->IsStaticTransport()))
        plrMover->HandleFall(movementInfo);
    // Xinef: interrupt parachutes upon falling or landing in water
    if (opcode == MSG_MOVE_FALL_LAND || opcode == MSG_MOVE_START_SWIM)
        mover->RemoveAurasWithInterruptFlags(AURA_INTERRUPT_FLAG_LANDING); // Parachutes


    if (plrMover)                                            // nothing is charmed, or player charmed
    {
        if (plrMover->IsSitState() && (movementInfo.flags & (MOVEMENTFLAG_MASK_MOVING | MOVEMENTFLAG_MASK_TURNING)))
            plrMover->SetStandState(UNIT_STAND_STATE_STAND);

        plrMover->UpdateFallInformationIfNeed(movementInfo, opcode);

        if (movementInfo.pos.GetPositionZ() < -500.0f)
            if (!plrMover->GetBattleground() || !plrMover->GetBattleground()->HandlePlayerUnderMap(_player))
            {
                if (plrMover->IsAlive())
                {
                    plrMover->EnvironmentalDamage(DAMAGE_FALL_TO_VOID, GetPlayer()->GetMaxHealth());
                    // player can be alive if GM
                    if (plrMover->IsAlive())
                        plrMover->KillPlayer();
                }
                plrMover->StopMovingOnCurrentPos(); // pussywizard: moving corpse can't release spirit
            }
    }
}
Example #22
0
void WorldSession::HandleMovementOpcodes(WorldPacket& recvData)
{
    uint16 opcode = recvData.GetOpcode();

    Unit* mover = _player->m_mover;

    ASSERT(mover != NULL);                      // there must always be a mover

    Player* plrMover = mover->ToPlayer();

    // ignore, waiting processing in WorldSession::HandleMoveWorldportAckOpcode and WorldSession::HandleMoveTeleportAck
    if (plrMover && plrMover->IsBeingTeleported())
    {
        recvData.rfinish();                     // prevent warnings spam
        return;
    }

    /* extract packet */
    uint64 guid;

    recvData.readPackGUID(guid);

    MovementInfo movementInfo;
    movementInfo.guid = guid;
    ReadMovementInfo(recvData, &movementInfo);

    recvData.rfinish();                         // prevent warnings spam

    // prevent tampered movement data
    if (guid != mover->GetGUID())
        return;

    if (!movementInfo.pos.IsPositionValid())
    {
        recvData.rfinish();                     // prevent warnings spam
        return;
    }

    /* handle special cases */
    if (movementInfo.flags & MOVEMENTFLAG_ONTRANSPORT)
    {
        // transports size limited
        // (also received at zeppelin leave by some reason with t_* as absolute in continent coordinates, can be safely skipped)
        if (movementInfo.transport.pos.GetPositionX() > 50 || movementInfo.transport.pos.GetPositionY() > 50 || movementInfo.transport.pos.GetPositionZ() > 50)
        {
            recvData.rfinish();                 // prevent warnings spam
            return;
        }

        if (!Trinity::IsValidMapCoord(movementInfo.pos.GetPositionX() + movementInfo.transport.pos.GetPositionX(), movementInfo.pos.GetPositionY() + movementInfo.transport.pos.GetPositionY(),
            movementInfo.pos.GetPositionZ() + movementInfo.transport.pos.GetPositionZ(), movementInfo.pos.GetOrientation() + movementInfo.transport.pos.GetOrientation()))
        {
            recvData.rfinish();                 // prevent warnings spam
            return;
        }

        // if we boarded a transport, add us to it
        if (plrMover)
        {
            if (!plrMover->GetTransport())
            {
                // elevators also cause the client to send MOVEMENTFLAG_ONTRANSPORT - just dismount if the guid can be found in the transport list
                for (MapManager::TransportSet::const_iterator iter = sMapMgr->m_Transports.begin(); iter != sMapMgr->m_Transports.end(); ++iter)
                {
                    if ((*iter)->GetGUID() == movementInfo.transport.guid)
                    {
                        plrMover->m_transport = *iter;
                        (*iter)->AddPassenger(plrMover);
                        break;
                    }
                }
            }
            else if (plrMover->GetTransport()->GetGUID() != movementInfo.transport.guid)
            {
                bool foundNewTransport = false;
                plrMover->m_transport->RemovePassenger(plrMover);
                for (MapManager::TransportSet::const_iterator iter = sMapMgr->m_Transports.begin(); iter != sMapMgr->m_Transports.end(); ++iter)
                {
                    if ((*iter)->GetGUID() == movementInfo.transport.guid)
                    {
                        foundNewTransport = true;
                        plrMover->m_transport = *iter;
                        (*iter)->AddPassenger(plrMover);
                        break;
                    }
                }

                if (!foundNewTransport)
                {
                    plrMover->m_transport = NULL;
                    movementInfo.transport.Reset();
                }
            }
        }

        if (!mover->GetTransport() && !mover->GetVehicle())
        {
            GameObject* go = mover->GetMap()->GetGameObject(movementInfo.transport.guid);
            if (!go || go->GetGoType() != GAMEOBJECT_TYPE_TRANSPORT)
                movementInfo.flags &= ~MOVEMENTFLAG_ONTRANSPORT;
        }
    }
    else if (plrMover && plrMover->GetTransport())                // if we were on a transport, leave
    {
        plrMover->m_transport->RemovePassenger(plrMover);
        plrMover->m_transport = NULL;
        movementInfo.transport.Reset();
    }

    // fall damage generation (ignore in flight case that can be triggered also at lags in moment teleportation to another map).
    if (opcode == MSG_MOVE_FALL_LAND && plrMover && !plrMover->IsInFlight())
        plrMover->HandleFall(movementInfo);

    if (plrMover && ((movementInfo.flags & MOVEMENTFLAG_SWIMMING) != 0) != plrMover->IsInWater())
    {
        // now client not include swimming flag in case jumping under water
        plrMover->SetInWater(!plrMover->IsInWater() || plrMover->GetBaseMap()->IsUnderWater(movementInfo.pos.GetPositionX(), movementInfo.pos.GetPositionY(), movementInfo.pos.GetPositionZ()));
    }

    if (plrMover)
    sAnticheatMgr->StartHackDetection(plrMover, movementInfo, opcode);

    /*----------------------*/

    /* process position-change */
    WorldPacket data(opcode, recvData.size());
    movementInfo.time = getMSTime();
    movementInfo.guid = mover->GetGUID();
    WriteMovementInfo(&data, &movementInfo);
    mover->SendMessageToSet(&data, _player);

    mover->m_movementInfo = movementInfo;

    // this is almost never true (not sure why it is sometimes, but it is), normally use mover->IsVehicle()
    if (mover->GetVehicle())
    {
        mover->SetOrientation(movementInfo.pos.GetOrientation());
        return;
    }

    mover->UpdatePosition(movementInfo.pos);

    if (plrMover)                                            // nothing is charmed, or player charmed
    {
        plrMover->UpdateFallInformationIfNeed(movementInfo, opcode);

        if (movementInfo.pos.GetPositionZ() < -500.0f)
        {
            if (!(plrMover->GetBattleground() && plrMover->GetBattleground()->HandlePlayerUnderMap(_player)))
            {
                // NOTE: this is actually called many times while falling
                // even after the player has been teleported away
                /// @todo discard movement packets after the player is rooted
                if (plrMover->IsAlive())
                {
                    plrMover->EnvironmentalDamage(DAMAGE_FALL_TO_VOID, GetPlayer()->GetMaxHealth());
                    // player can be alive if GM/etc
                    // change the death state to CORPSE to prevent the death timer from
                    // starting in the next player update
                    if (!plrMover->IsAlive())
                        plrMover->KillPlayer();
                }
            }
        }
    }
}
Example #23
0
		void UpdateAI(uint32 diff)
		{
			if (!UpdateVictim())
				return;

			if( me->GetPositionX() < 490.0f || me->GetPositionX() > 690.0f || me->GetPositionY() < 130.0f || me->GetPositionY() > 410.0f )
			{
				EnterEvadeMode();
				return;
			}

			events.Update(diff);

			if (me->HasUnitState(UNIT_STATE_CASTING))
				return;

			switch (events.GetEvent())
			{
				case 0:
					break;
				case EVENT_ACTIVATE_CONSTRUCT:
					me->CastCustomSpell(SPELL_ACTIVATE_CONSTRUCT, SPELLVALUE_MAX_TARGETS, 1, (Unit*)NULL, false);
					if (++counter >= 20)
					{
						me->MonsterYell(TEXT_BERSERK, LANG_UNIVERSAL, 0);
						me->PlayDirectSound(SOUND_BERSERK);
						me->CastSpell(me, SPELL_BERSERK, true);
						events.PopEvent();
						break;
					}
					events.RepeatEvent(RAID_MODE(40000,30000));
					break;
				case EVENT_SPELL_SCORCH:
					if( rand()%2 )
					{
						me->MonsterYell(TEXT_SCORCH_1, LANG_UNIVERSAL, 0);
						me->PlayDirectSound(SOUND_SCORCH_1);
					}
					else
					{
						me->MonsterYell(TEXT_SCORCH_2, LANG_UNIVERSAL, 0);
						me->PlayDirectSound(SOUND_SCORCH_2);
					}
					me->SetControlled(true, UNIT_STATE_ROOT);
					me->DisableRotate(true);
					me->SendMovementFlagUpdate();
					me->CastSpell(me->GetVictim(), S_SCORCH, false);
					events.RepeatEvent(20000);
					events.RescheduleEvent(EVENT_ENABLE_ROTATE, 3001);
					break;
				case EVENT_ENABLE_ROTATE:
					me->SetControlled(false, UNIT_STATE_ROOT);
					me->DisableRotate(false);
					events.PopEvent();
					break;
				case EVENT_SPELL_FLAME_JETS:
					me->MonsterTextEmote(TEXT_FLAME_JETS, 0, true);
					me->CastSpell(me->GetVictim(), S_FLAME_JETS, false);
					events.RepeatEvent(25000);
					break;
				case EVENT_GRAB:
					{
						std::list<Creature*> icl;
						me->GetCreaturesWithEntryInRange(icl, 300.0f, NPC_IRON_CONSTRUCT);

						std::vector<uint64> playerGUIDs;
						Map::PlayerList const& pl = me->GetMap()->GetPlayers();
						Player* temp = NULL;

						for( Map::PlayerList::const_iterator itr = pl.begin(); itr != pl.end(); ++itr )
						{
							temp = itr->GetSource();
							if( !temp->IsAlive() || temp->GetExactDist2d(me) > 90.0f )
								continue;
							if( me->GetVictim() && temp->GetGUID() == me->GetVictim()->GetGUID() )
								continue;
							bool found = false;
							for( std::list<Creature*>::iterator itr = icl.begin(); itr != icl.end(); ++itr )
								if( (*itr)->GetVictim() && (*itr)->GetVictim()->GetGUID() == temp->GetGUID() )
								{
									found = true;
									break;
								}

							if( !found )
								playerGUIDs.push_back(temp->GetGUID());
						}

						if( !playerGUIDs.empty() )
						{
							int8 pos = urand(0, playerGUIDs.size()-1);
							if( Player* pTarget = ObjectAccessor::GetPlayer(*me,playerGUIDs.at(pos)) )
							{
								me->MonsterYell(TEXT_SLAG_POT, LANG_UNIVERSAL, 0);
								me->PlayDirectSound(SOUND_SLAG_POT);
								me->CastSpell(pTarget, SPELL_GRAB, false);
							}
						}

						events.RepeatEvent(24000); // +6000 below
						events.DelayEvents(6000);
					}
					break;
			}

			DoMeleeAttackIfReady();
		}
Example #24
0
		void MapView::Draw(){
			World *world = client->GetWorld();
			if(!world)
				return;
			
			Player *player = world->GetLocalPlayer();
			if(client->IsFollowing()){
				player = world->GetPlayer(client->followingPlayerId);
			}
			if(!player)
				return;
			
			if(largeMap)
				if(zoomState < .0001f)
					return;
			
			GameMap *map = world->GetMap();
			Vector2 mapSize = MakeVector2(map->Width(), map->Height());
			
			Vector3 pos = player->GetPosition();;
			if(player->GetTeamId() >= 2){
				pos = client->followPos;
			}
			Vector2 center = {pos.x, pos.y};
			float cfgMapSize = cg_minimapSize;
			if(cfgMapSize < 32) cfgMapSize = 32;
			if(cfgMapSize > 256) cfgMapSize = 256;
			Vector2 mapWndSize = {cfgMapSize, cfgMapSize};
			float scale = actualScale;
			
			center = Mix(center,
						 mapSize * .5f,
						 zoomState);
			
			Vector2 zoomedSize = {512, 512};
			if(renderer->ScreenWidth() < 512.f ||
			   renderer->ScreenHeight() < 512.f)
				zoomedSize = MakeVector2(256, 256);
			if(largeMap){
				float per = zoomState;
				per = 1.f - per;
				per *= per;
				per = 1.f - per;
				per = Mix(.7f, 1.f, per);
				zoomedSize = Mix(MakeVector2(0, 0),
								 zoomedSize,
								 per);
				mapWndSize = zoomedSize;
			}
			
			Vector2 inRange = mapWndSize * .5f * scale;
			AABB2 inRect(center - inRange, center + inRange);
			if(largeMap){
				inRect.min = MakeVector2(0, 0);
				inRect.max = mapSize;
			}else{
				if(inRect.GetMinX() < 0.f)
					inRect = inRect.Translated(-inRect.GetMinX(), 0.f);
				if(inRect.GetMinY() < 0.f)
					inRect = inRect.Translated(0, -inRect.GetMinY());
				if(inRect.GetMaxX() > mapSize.x)
					inRect = inRect.Translated(mapSize.x - inRect.GetMaxX(), 0.f);
				if(inRect.GetMaxY() > mapSize.y)
					inRect = inRect.Translated(0, mapSize.y - inRect.GetMaxY());
			}
			
			
			AABB2 outRect(renderer->ScreenWidth() - mapWndSize.x - 16.f, 16.f,
						  mapWndSize.x,
						  mapWndSize.y);
			if(largeMap){
				outRect.min = MakeVector2((renderer->ScreenWidth() - zoomedSize.x) * .5f,
										  (renderer->ScreenHeight() - zoomedSize.y) * .5f);
				outRect.max =MakeVector2((renderer->ScreenWidth() + zoomedSize.x) * .5f,
										 (renderer->ScreenHeight() + zoomedSize.y) * .5f);
			}
			
			float alpha = 1.f;
			if(largeMap){
				alpha = zoomState;
			}
			
			// fades bg
			if(largeMap) {
				Handle<IImage> bg = renderer->RegisterImage("Gfx/MapBg.png");
				Vector2 scrSize = {renderer->ScreenWidth(),
				renderer->ScreenHeight()};
				float size = std::max(scrSize.x, scrSize.y);
				renderer->SetColorAlphaPremultiplied(MakeVector4(0, 0, 0,alpha * .5f));
				renderer->DrawImage(bg,
									AABB2((scrSize.x - size) * .5f,
										  (scrSize.y - size) * .5f,
										  size, size));
			}
			
			// draw border
			Handle<IImage> border;
			float borderWidth;
			AABB2 borderRect = outRect;
			if(largeMap) {
				border = renderer->RegisterImage("Gfx/MapBorder.png");
				borderWidth = 3.f * outRect.GetHeight() / zoomedSize.y;
			}else{
				border = renderer->RegisterImage("Gfx/MinimapBorder.png");
				borderWidth = 2.f;
			}
			borderRect = borderRect.Inflate(borderWidth - 8.f);
			
			renderer->SetColorAlphaPremultiplied(MakeVector4(alpha,alpha,alpha,alpha));
			renderer->DrawImage(border,
								AABB2(borderRect.GetMinX()-16,
									  borderRect.GetMinY()-16,
									  16, 16),
								AABB2(0, 0, 16, 16));
			renderer->DrawImage(border,
								AABB2(borderRect.GetMaxX(),
									  borderRect.GetMinY()-16,
									  16, 16),
								AABB2(16, 0, 16, 16));
			renderer->DrawImage(border,
								AABB2(borderRect.GetMinX()-16,
									  borderRect.GetMaxY(),
									  16, 16),
								AABB2(0, 16, 16, 16));
			renderer->DrawImage(border,
								AABB2(borderRect.GetMaxX(),
									  borderRect.GetMaxY(),
									  16, 16),
								AABB2(16, 16, 16, 16));
			renderer->DrawImage(border,
								AABB2(borderRect.GetMinX(),
									  borderRect.GetMinY()-16,
									  borderRect.GetWidth(), 16),
								AABB2(16, 0, 0, 16));
			renderer->DrawImage(border,
								AABB2(borderRect.GetMinX(),
									  borderRect.GetMaxY(),
									  borderRect.GetWidth(), 16),
								AABB2(16, 16, 0, 16));
			renderer->DrawImage(border,
								AABB2(borderRect.GetMinX()-16,
									  borderRect.GetMinY(),
									  16, borderRect.GetHeight()),
								AABB2(0, 16, 16, 0));
			renderer->DrawImage(border,
								AABB2(borderRect.GetMaxX(),
									  borderRect.GetMinY(),
									  16, borderRect.GetHeight()),
								AABB2(16, 16, 16, 0));
			
			// draw map
			renderer->SetColorAlphaPremultiplied(MakeVector4(alpha,alpha,alpha,alpha));
			renderer->DrawFlatGameMap(outRect, inRect);
			
			this->inRect = inRect;
			this->outRect = outRect;
			
			// draw grid
			
			renderer->SetColorAlphaPremultiplied(MakeVector4(0,0,0,0.8f*alpha));
			Handle<IImage> dashLine = renderer->RegisterImage("Gfx/DashLine.tga");
			for(float x = 64.f; x < map->Width(); x += 64.f){
				float wx = (x - inRect.GetMinX()) / inRect.GetWidth();
				if(wx < 0.f || wx >= 1.f)
					continue;
				wx = (wx * outRect.GetWidth()) + outRect.GetMinX();
				wx = roundf(wx);
				renderer->DrawImage(dashLine,
									MakeVector2(wx, outRect.GetMinY()),
									AABB2(0, 0, 1.f, outRect.GetHeight()));
			}
			for(float y = 64.f; y < map->Height(); y += 64.f){
				float wy = (y - inRect.GetMinY()) / inRect.GetHeight();
				if(wy < 0.f || wy >= 1.f)
					continue;
				wy = (wy * outRect.GetHeight()) + outRect.GetMinY();
				wy = roundf(wy);
				renderer->DrawImage(dashLine,
									MakeVector2(outRect.GetMinX(), wy),
									AABB2(0, 0, outRect.GetWidth(), 1.f));
			}
			
			// draw grid label
			renderer->SetColorAlphaPremultiplied(MakeVector4(1,1,1,1)*(0.8f*alpha));
			Handle<IImage> mapFont = renderer->RegisterImage("Gfx/Fonts/MapFont.tga");
			for(int i = 0; i < 8; i++){
				float startX = (float)i * 64.f;
				float endX = startX + 64.f;
				if(startX > inRect.GetMaxX() ||
				   endX < inRect.GetMinX())
					continue;
				float fade = std::min((std::min(endX, inRect.GetMaxX()) -
									   std::max(startX, inRect.GetMinX())) /
									  (endX - startX) * 2.f, 1.f);
				renderer->SetColorAlphaPremultiplied(MakeVector4(1,1,1,1)*(fade * .8f * alpha));
				
				float center = std::max(startX, inRect.GetMinX());
				center = .5f * (center + std::min(endX, inRect.GetMaxX()));
				
				float wx = (center - inRect.GetMinX()) / inRect.GetWidth();
				wx = (wx * outRect.GetWidth()) + outRect.GetMinX();
				wx = roundf(wx);
				
				float fntX = static_cast<float>((i & 3) * 8);
				float fntY = static_cast<float>((i >> 2) * 8);
				renderer->DrawImage(mapFont,
									MakeVector2(wx - 4.f, outRect.GetMinY() + 4),
									AABB2(fntX, fntY, 8, 8));
			}
			for(int i = 0; i < 8; i++){
				float startY = (float)i * 64.f;
				float endY = startY + 64.f;
				if(startY > inRect.GetMaxY() ||
				   endY < inRect.GetMinY())
					continue;
				float fade = std::min((std::min(endY, inRect.GetMaxY()) -
									   std::max(startY, inRect.GetMinY())) /
									  (endY - startY) * 2.f, 1.f);
				renderer->SetColorAlphaPremultiplied(MakeVector4(1,1,1,1)*(fade * .8f * alpha));
				
				float center = std::max(startY, inRect.GetMinY());
				center = .5f * (center + std::min(endY, inRect.GetMaxY()));
				
				float wy = (center - inRect.GetMinY()) / inRect.GetHeight();
				wy = (wy * outRect.GetHeight()) + outRect.GetMinY();
				wy = roundf(wy);
				
				int fntX = (i & 3) * 8;
				int fntY = (i >> 2) * 8 + 16;
				renderer->DrawImage(mapFont,
									MakeVector2(outRect.GetMinX() + 4, wy - 4.f),
									AABB2(fntX, fntY, 8, 8));
			}			
			//draw objects
			
			std::string iconmode = cg_Minimap_Player_Icon;//import variable from configuration file
			std::string colormode = cg_Minimap_Player_Color;//import variable from configuration file
			
			Handle<IImage> playerSMG = renderer->RegisterImage("Gfx/Map/SMG.png");
			Handle<IImage> playerRifle = renderer->RegisterImage("Gfx/Map/Rifle.png");
			Handle<IImage> playerShotgun = renderer->RegisterImage("Gfx/Map/Shotgun.png");
			Handle<IImage> playerIcon = renderer->RegisterImage("Gfx/Map/Player.png");
			
			{
				
				IntVector3 teamColor =
				world->GetLocalPlayer()->GetTeamId() >= 2 ?
				IntVector3::Make(200, 200, 200) :
				world->GetTeam(world->GetLocalPlayer()->GetTeamId()).color;
				Vector4 teamColorF = ModifyColor(teamColor);
				teamColorF *= alpha;
				
				// draw local player's view
				{
					Player *p = player;
					Handle<IImage> viewIcon = renderer->RegisterImage("Gfx/Map/View.png");
					if(p->IsAlive()) {
						Vector3 front = p->GetFront2D();
						float ang = atan2(front.x, -front.y);
						if(player->GetTeamId() >= 2){
							ang = client->followYaw - static_cast<float>(M_PI) * .5f;
						}
						
						renderer->SetColorAlphaPremultiplied(teamColorF * 0.9f);
						
						DrawIcon(player->GetTeamId() >= 2 ?
								 client->followPos :
								 p->GetPosition(), viewIcon, ang);
					}
				}
				
				// draw player's icon
				for(int i = 0; i < world->GetNumPlayerSlots(); i++){
					Player * p = world->GetPlayer(i);
					if(p == nullptr ||
					   p->GetTeamId() != world->GetLocalPlayer()->GetTeamId() ||
					   !p->IsAlive())
						continue;
					
					Vector3 front = p->GetFront2D();
					float ang = atan2(front.x, -front.y);
					if(player->GetTeamId() >= 2){
						ang = client->followYaw - static_cast<float>(M_PI) * .5f;
					}
					
					//use a spec color for each player
					if ( colormode=="1"){
						IntVector3 Colorplayer=IntVector3::Make(palette[i][0],palette[i][1],palette[i][2]);
						Vector4 ColorplayerF = ModifyColor(Colorplayer);
						ColorplayerF *=1.0f;
						renderer->SetColorAlphaPremultiplied(ColorplayerF);
					}	
					else {
						renderer->SetColorAlphaPremultiplied(teamColorF);
					}
					
					//use a different icon in minimap according to weapon of player
					if( iconmode=="1"){
						WeaponType weapon=world->GetPlayer(i)->GetWeaponType();
						if (weapon == WeaponType::SMG_WEAPON){
							DrawIcon(player->GetTeamId() >= 2 ?
									client->followPos :
									p->GetPosition(),playerSMG , ang);
						}
						
						else if (weapon == WeaponType::RIFLE_WEAPON){
							DrawIcon(player->GetTeamId() >= 2 ?
									client->followPos :
									p->GetPosition(), playerRifle, ang);
						}
						
						else if (weapon == WeaponType::SHOTGUN_WEAPON){
							DrawIcon(player->GetTeamId() >= 2 ?
									client->followPos :
									p->GetPosition(), playerShotgun, ang);
						}
					}
					else{//draw normal color	
						DrawIcon(player->GetTeamId() >= 2 ?
								client->followPos :
								p->GetPosition(), playerIcon, ang);
					}
				}
			}
			
			IGameMode* mode = world->GetMode();
			if( mode && IGameMode::m_CTF == mode->ModeType() ) {
				CTFGameMode *ctf = static_cast<CTFGameMode *>(mode);
				Handle<IImage> intelIcon = renderer->RegisterImage("Gfx/Map/Intel.png");
				Handle<IImage> baseIcon = renderer->RegisterImage("Gfx/Map/CommandPost.png");
				for(int tId = 0; tId < 2; tId++){
					CTFGameMode::Team& team = ctf->GetTeam(tId);
					IntVector3 teamColor = world->GetTeam(tId).color;
					Vector4 teamColorF = ModifyColor(teamColor);
					teamColorF *= alpha;
					
					// draw base
					renderer->SetColorAlphaPremultiplied(teamColorF);
					DrawIcon(team.basePos, baseIcon, 0.f);
					
					
					// draw flag
					if(!ctf->GetTeam(1-tId).hasIntel){
						renderer->SetColorAlphaPremultiplied(teamColorF);
						DrawIcon(team.flagPos, intelIcon, 0.f);
					}else if(world->GetLocalPlayer()->GetTeamId() == 1-tId){
						// local player's team is carrying
						int cId = ctf->GetTeam(1-tId).carrier;
						
						// in some game modes, carrier becomes invalid
						if(cId < world->GetNumPlayerSlots()){
							Player * carrier= world->GetPlayer(cId);
							if(carrier && carrier->GetTeamId() ==
							   world->GetLocalPlayer()->GetTeamId()){
								
								Vector4 col = teamColorF;
								col *= fabsf(sinf(world->GetTime() * 4.f));
								renderer->SetColorAlphaPremultiplied(col);
								DrawIcon(carrier->GetPosition(), intelIcon, 0.f);
							}
						}
					}
				}
			} else if( mode && IGameMode::m_TC == mode->ModeType() ) {
				TCGameMode *tc = static_cast<TCGameMode *>(mode);
				Handle<IImage> icon = renderer->RegisterImage("Gfx/Map/CommandPost.png");
				int cnt = tc->GetNumTerritories();
				for(int i = 0; i < cnt; i++){
					TCGameMode::Territory *t = tc->GetTerritory(i);
					IntVector3 teamColor = {128,128,128};
					if(t->ownerTeamId < 2){
						teamColor = world->GetTeam(t->ownerTeamId).color;
					}
					Vector4 teamColorF = ModifyColor(teamColor);
					teamColorF *= alpha;
					
					// draw base
					renderer->SetColorAlphaPremultiplied(teamColorF);
					DrawIcon(t->pos, icon, 0.f);
					
				}
			}
		}
Example #25
0
/*this procedure handles clients CMSG_REQUEST_PARTY_MEMBER_STATS request*/
void WorldSession::HandleRequestPartyMemberStatsOpcode(WorldPacket& recvData)
{
    TC_LOG_DEBUG("network", "WORLD: Received CMSG_REQUEST_PARTY_MEMBER_STATS");
    ObjectGuid Guid;
    recvData >> Guid;

    Player* player = ObjectAccessor::FindConnectedPlayer(Guid);
    if (!player)
    {
        WorldPacket data(SMSG_PARTY_MEMBER_STATS_FULL, 3+4+2);
        data << uint8(0);                                   // only for SMSG_PARTY_MEMBER_STATS_FULL, probably arena/bg related
        data << Guid.WriteAsPacked();
        data << uint32(GROUP_UPDATE_FLAG_STATUS);
        data << uint16(MEMBER_STATUS_OFFLINE);
        SendPacket(&data);
        return;
    }

    Pet* pet = player->GetPet();
    Powers powerType = player->getPowerType();
    std::set<uint32> const& phases = player->GetPhases();

    WorldPacket data(SMSG_PARTY_MEMBER_STATS_FULL, 4+2+2+2+1+2*6+8+1+8);
    data << uint8(0);                                       // only for SMSG_PARTY_MEMBER_STATS_FULL, probably arena/bg related
    data << player->GetPackGUID();

    uint32 updateFlags = GROUP_UPDATE_FLAG_STATUS | GROUP_UPDATE_FLAG_CUR_HP | GROUP_UPDATE_FLAG_MAX_HP
                      | GROUP_UPDATE_FLAG_CUR_POWER | GROUP_UPDATE_FLAG_MAX_POWER | GROUP_UPDATE_FLAG_LEVEL
                      | GROUP_UPDATE_FLAG_ZONE | GROUP_UPDATE_FLAG_POSITION | GROUP_UPDATE_FLAG_AURAS
                      | GROUP_UPDATE_FLAG_PET_NAME | GROUP_UPDATE_FLAG_PET_MODEL_ID | GROUP_UPDATE_FLAG_PET_AURAS;

    if (powerType != POWER_MANA)
        updateFlags |= GROUP_UPDATE_FLAG_POWER_TYPE;

    if (pet)
        updateFlags |= GROUP_UPDATE_FLAG_PET_GUID | GROUP_UPDATE_FLAG_PET_CUR_HP | GROUP_UPDATE_FLAG_PET_MAX_HP
                    | GROUP_UPDATE_FLAG_PET_POWER_TYPE | GROUP_UPDATE_FLAG_PET_CUR_POWER | GROUP_UPDATE_FLAG_PET_MAX_POWER;

    if (player->GetVehicle())
        updateFlags |= GROUP_UPDATE_FLAG_VEHICLE_SEAT;

    if (!phases.empty())
        updateFlags |= GROUP_UPDATE_FLAG_PHASE;

    uint16 playerStatus = MEMBER_STATUS_ONLINE;
    if (player->IsPvP())
        playerStatus |= MEMBER_STATUS_PVP;

    if (!player->IsAlive())
    {
        if (player->HasFlag(PLAYER_FLAGS, PLAYER_FLAGS_GHOST))
            playerStatus |= MEMBER_STATUS_GHOST;
        else
            playerStatus |= MEMBER_STATUS_DEAD;
    }

    if (player->IsFFAPvP())
        playerStatus |= MEMBER_STATUS_PVP_FFA;

    if (player->isAFK())
        playerStatus |= MEMBER_STATUS_AFK;

    if (player->isDND())
        playerStatus |= MEMBER_STATUS_DND;

    data << uint32(updateFlags);
    data << uint16(playerStatus);                           // GROUP_UPDATE_FLAG_STATUS
    data << uint32(player->GetHealth());                    // GROUP_UPDATE_FLAG_CUR_HP
    data << uint32(player->GetMaxHealth());                 // GROUP_UPDATE_FLAG_MAX_HP
    if (updateFlags & GROUP_UPDATE_FLAG_POWER_TYPE)
        data << uint8(powerType);

    data << uint16(player->GetPower(powerType));            // GROUP_UPDATE_FLAG_CUR_POWER
    data << uint16(player->GetMaxPower(powerType));         // GROUP_UPDATE_FLAG_MAX_POWER
    data << uint16(player->getLevel());                     // GROUP_UPDATE_FLAG_LEVEL
    data << uint16(player->GetZoneId());                    // GROUP_UPDATE_FLAG_ZONE
    data << uint16(player->GetPositionX());                 // GROUP_UPDATE_FLAG_POSITION
    data << uint16(player->GetPositionY());                 // GROUP_UPDATE_FLAG_POSITION
    data << uint16(player->GetPositionZ());               // GROUP_UPDATE_FLAG_POSITION

    // GROUP_UPDATE_FLAG_AURAS
    data << uint8(1);
    uint64 auramask = 0;
    size_t maskPos = data.wpos();
    data << uint64(auramask);                          // placeholder
    data << uint32(MAX_AURAS);                         // count

    for (uint8 i = 0; i < MAX_AURAS; ++i)
    {
        if (AuraApplication const* aurApp = player->GetVisibleAura(i))
        {
            auramask |= (uint64(1) << i);

            data << uint32(aurApp->GetBase()->GetId());
            data << uint16(aurApp->GetFlags());

            if (aurApp->GetFlags() & AFLAG_ANY_EFFECT_AMOUNT_SENT)
            {
                for (uint32 i = 0; i < MAX_SPELL_EFFECTS; ++i)
                {
                    if (AuraEffect const* eff = aurApp->GetBase()->GetEffect(i))
                        data << int32(eff->GetAmount());
                    else
                        data << int32(0);
                }
            }
        }
    }

    data.put<uint64>(maskPos, auramask);                    // GROUP_UPDATE_FLAG_AURAS

    if (updateFlags & GROUP_UPDATE_FLAG_PET_GUID)
        data << uint64(pet->GetGUID());

    data << std::string(pet ? pet->GetName() : "");         // GROUP_UPDATE_FLAG_PET_NAME
    data << uint16(pet ? pet->GetDisplayId() : 0);          // GROUP_UPDATE_FLAG_PET_MODEL_ID

    if (updateFlags & GROUP_UPDATE_FLAG_PET_CUR_HP)
        data << uint32(pet->GetHealth());

    if (updateFlags & GROUP_UPDATE_FLAG_PET_MAX_HP)
        data << uint32(pet->GetMaxHealth());

    if (updateFlags & GROUP_UPDATE_FLAG_PET_POWER_TYPE)
        data << (uint8)pet->getPowerType();

    if (updateFlags & GROUP_UPDATE_FLAG_PET_CUR_POWER)
        data << uint16(pet->GetPower(pet->getPowerType()));

    if (updateFlags & GROUP_UPDATE_FLAG_PET_MAX_POWER)
        data << uint16(pet->GetMaxPower(pet->getPowerType()));

    // GROUP_UPDATE_FLAG_PET_AURAS
    uint64 petAuraMask = 0;
    data << uint8(1);
    maskPos = data.wpos();
    data << uint64(petAuraMask);                            // placeholder
    data << uint32(MAX_AURAS);                              // count
    if (pet)
    {
        for (uint8 i = 0; i < MAX_AURAS; ++i)
        {
            if (AuraApplication const* aurApp = pet->GetVisibleAura(i))
            {
                petAuraMask |= (uint64(1) << i);

                data << uint32(aurApp->GetBase()->GetId());
                data << uint16(aurApp->GetFlags());

                if (aurApp->GetFlags() & AFLAG_ANY_EFFECT_AMOUNT_SENT)
                {
                    for (uint32 i = 0; i < MAX_SPELL_EFFECTS; ++i)
                    {
                        if (AuraEffect const* eff = aurApp->GetBase()->GetEffect(i))
                            data << int32(eff->GetAmount());
                        else
                            data << int32(0);
                    }
                }
            }
        }
    }

    data.put<uint64>(maskPos, petAuraMask);                 // GROUP_UPDATE_FLAG_PET_AURAS

    if (updateFlags & GROUP_UPDATE_FLAG_VEHICLE_SEAT)
        data << uint32(player->GetVehicle()->GetVehicleInfo()->m_seatID[player->m_movementInfo.transport.seat]);

    if (updateFlags & GROUP_UPDATE_FLAG_PHASE)
    {
        data << uint32(phases.empty() ? 8 : 0);
        data << uint32(phases.size());
        for (std::set<uint32>::const_iterator itr = phases.begin(); itr != phases.end(); ++itr)
            data << uint16(*itr);
    }

    SendPacket(&data);
}
            void UpdateAI(uint32 diff) override
            {
                if (!UpdateVictim())
                    return;

                events.Update(diff);

                if (me->HasUnitState(UNIT_STATE_CASTING))
                    return;

                while (uint32 eventId = events.ExecuteEvent())
                {
                    switch (eventId)
                    {
                        if (events.IsInPhase(PHASE_NORMAL))
                        {
                            case EVENT_BLOODTHIRST:
                                DoCast(me, SPELL_BLOODTHIRST);
                                events.ScheduleEvent(EVENT_BLOODTHIRST, 10000);
                                break;
                            case EVENT_FLAME_SPHERE:
                                DoCastVictim(SPELL_CONJURE_FLAME_SPHERE);
                                events.SetPhase(PHASE_SPECIAL);
                                events.ScheduleEvent(EVENT_CASTING_FLAME_SPHERES, 3000);
                                events.ScheduleEvent(EVENT_FLAME_SPHERE, 15000);
                                break;
                            case EVENT_VANISH:
                            {
                                Map::PlayerList const& players = me->GetMap()->GetPlayers();
                                uint32 targets = 0;
                                for (Map::PlayerList::const_iterator i = players.begin(); i != players.end(); ++i)
                                {
                                    Player* player = i->GetSource();
                                    if (player && player->IsAlive())
                                        ++targets;
                                }

                                if (targets > 2)
                                {
                                    Talk(SAY_VANISH);
                                    DoCast(me, SPELL_VANISH);
                                    events.SetPhase(PHASE_SPECIAL);
                                    events.ScheduleEvent(EVENT_JUST_VANISHED, 500);
                                    if (Unit* embraceTarget = SelectTarget(SELECT_TARGET_RANDOM, 0, 100, true))
                                        _embraceTargetGUID = embraceTarget->GetGUID();
                                }
                                events.ScheduleEvent(EVENT_VANISH, urand(25000, 35000));
                                break;
                            }
                        }
                        case EVENT_CASTING_FLAME_SPHERES:
                        {
                            events.SetPhase(PHASE_NORMAL);
                            Unit* sphereTarget = SelectTarget(SELECT_TARGET_RANDOM, 0, 100, true);
                            if (!sphereTarget)
                                break;

                            float angle, x, y;

                            //DoCast(me, SPELL_FLAME_SPHERE_SUMMON_1);
                            if (Creature* sphere = DoSpawnCreature(CREATURE_FLAME_SPHERE, 0, 0, 5, 0, TEMPSUMMON_TIMED_OR_CORPSE_DESPAWN, 10 * IN_MILLISECONDS))
                            {
                                angle = sphere->GetAngle(sphereTarget);
                                x = sphere->GetPositionX() + DATA_SPHERE_DISTANCE * std::cos(angle);
                                y = sphere->GetPositionY() + DATA_SPHERE_DISTANCE * std::sin(angle);
                                sphere->GetMotionMaster()->MovePoint(0, x, y, sphere->GetPositionZ());
                            }

                            if (IsHeroic())
                            {
                                //DoCast(me, H_SPELL_FLAME_SPHERE_SUMMON_1);
                                if (Creature* sphere = DoSpawnCreature(H_CREATURE_FLAME_SPHERE_1, 0, 0, 5, 0, TEMPSUMMON_TIMED_OR_CORPSE_DESPAWN, 10 * IN_MILLISECONDS))
                                {
                                    angle = sphere->GetAngle(sphereTarget) + DATA_SPHERE_ANGLE_OFFSET;
                                    x = sphere->GetPositionX() + DATA_SPHERE_DISTANCE/2 * std::cos(angle);
                                    y = sphere->GetPositionY() + DATA_SPHERE_DISTANCE/2 * std::sin(angle);
                                    sphere->GetMotionMaster()->MovePoint(0, x, y, sphere->GetPositionZ());
                                }

                                //DoCast(me, H_SPELL_FLAME_SPHERE_SUMMON_2);
                                if (Creature* sphere = DoSpawnCreature(H_CREATURE_FLAME_SPHERE_2, 0, 0, 5, 0, TEMPSUMMON_TIMED_OR_CORPSE_DESPAWN, 10 * IN_MILLISECONDS))
                                {
                                    angle = sphere->GetAngle(sphereTarget) - DATA_SPHERE_ANGLE_OFFSET;
                                    x = sphere->GetPositionX() + DATA_SPHERE_DISTANCE/2 * std::cos(angle);
                                    y = sphere->GetPositionY() + DATA_SPHERE_DISTANCE/2 * std::sin(angle);
                                    sphere->GetMotionMaster()->MovePoint(0, x, y, sphere->GetPositionZ());
                                }
                            }
                            break;
                        }
                        case EVENT_JUST_VANISHED:
                            if (Unit* embraceTarget = GetEmbraceTarget())
                            {
                                me->GetMotionMaster()->Clear();
                                me->SetSpeed(MOVE_WALK, 2.0f, true);
                                me->GetMotionMaster()->MoveChase(embraceTarget);
                            }
                            events.ScheduleEvent(EVENT_VANISHED, 1300);
                            break;
                        case EVENT_VANISHED:
                            if (Unit* embraceTarget = GetEmbraceTarget())
                                DoCast(embraceTarget, SPELL_EMBRACE_OF_THE_VAMPYR);
                            Talk(SAY_FEED);
                            me->GetMotionMaster()->Clear();
                            me->SetSpeed(MOVE_WALK, 1.0f, true);
                            me->GetMotionMaster()->MoveChase(me->GetVictim());
                            events.ScheduleEvent(EVENT_FEEDING, 20000);
                            break;
                        case EVENT_FEEDING:
                            _embraceTargetGUID = 0;
                            events.SetPhase(PHASE_NORMAL);
                            break;
                        default:
                            break;
                    }
                }

                DoMeleeAttackIfReady();
            }
        void UpdateAI(uint32 diff) override
        {
            if (EventInProgress)
            {
                Player* warrior = NULL;

                if (!PlayerGUID.IsEmpty())
                    warrior = ObjectAccessor::GetPlayer(*me, PlayerGUID);

                if (!warrior)
                    return;

                if (!warrior->IsAlive() && warrior->GetQuestStatus(1719) == QUEST_STATUS_INCOMPLETE)
                {
                    Talk(SAY_TWIGGY_FLATHEAD_DOWN);
                    warrior->FailQuest(1719);

                    for (uint8 i = 0; i < 6; ++i) // unsummon challengers
                    {
                        if (!AffrayChallenger[i].IsEmpty())
                        {
                            Creature* creature = ObjectAccessor::GetCreature((*me), AffrayChallenger[i]);
                            if (creature && creature->IsAlive())
                                creature->DisappearAndDie();
                        }
                    }

                    if (!BigWill.IsEmpty()) // unsummon bigWill
                    {
                        Creature* creature = ObjectAccessor::GetCreature((*me), BigWill);
                        if (creature && creature->IsAlive())
                            creature->DisappearAndDie();
                    }
                    Reset();
                }

                if (!EventGrate && EventInProgress)
                {
                    float x, y, z;
                    warrior->GetPosition(x, y, z);

                    if (x >= -1684 && x <= -1674 && y >= -4334 && y <= -4324)
                    {
                        warrior->AreaExploredOrEventHappens(1719);
                        Talk(SAY_TWIGGY_FLATHEAD_BEGIN, warrior);

                        for (uint8 i = 0; i < 6; ++i)
                        {
                            Creature* creature = me->SummonCreature(NPC_AFFRAY_CHALLENGER, AffrayChallengerLoc[i], TEMPSUMMON_TIMED_OR_DEAD_DESPAWN, 600000);
                            if (!creature)
                                continue;
                            creature->setFaction(35);
                            creature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
                            creature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
                            creature->HandleEmoteCommand(EMOTE_ONESHOT_ROAR);
                            AffrayChallenger[i] = creature->GetGUID();
                        }
                        WaveTimer = 5000;
                        ChallengerChecker = 1000;
                        EventGrate = true;
                    }
                }
                else if (EventInProgress)
                {
                    if (ChallengerChecker <= diff)
                    {
                        for (uint8 i = 0; i < 6; ++i)
                        {
                            if (!AffrayChallenger[i].IsEmpty())
                            {
                                Creature* creature = ObjectAccessor::GetCreature((*me), AffrayChallenger[i]);
                                if ((!creature || (!creature->IsAlive())) && !ChallengerDown[i])
                                {
                                    Talk(SAY_TWIGGY_FLATHEAD_DOWN);
                                    ChallengerDown[i] = true;
                                }
                            }
                        }
                        ChallengerChecker = 1000;
                    } else ChallengerChecker -= diff;

                    if (WaveTimer <= diff)
                    {
                        if (Wave < 6 && !AffrayChallenger[Wave].IsEmpty() && !EventBigWill)
                        {
                            Talk(SAY_TWIGGY_FLATHEAD_FRAY);
                            Creature* creature = ObjectAccessor::GetCreature(*me, AffrayChallenger[Wave]);
                            if (creature && (creature->IsAlive()))
                            {
                                creature->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
                                creature->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
                                creature->HandleEmoteCommand(EMOTE_ONESHOT_ROAR);
                                creature->setFaction(14);
                                creature->AI()->AttackStart(warrior);
                                ++Wave;
                                WaveTimer = 20000;
                            }
                        }
                        else if (Wave >= 6 && !EventBigWill)
                        {
                            if (Creature* creature = me->SummonCreature(NPC_BIG_WILL, -1722, -4341, 6.12f, 6.26f, TEMPSUMMON_TIMED_OR_DEAD_DESPAWN, 480000))
                            {
                                BigWill = creature->GetGUID();
                                //creature->GetMotionMaster()->MovePoint(0, -1693, -4343, 4.32f);
                                //creature->GetMotionMaster()->MovePoint(1, -1684, -4333, 2.78f);
                                creature->GetMotionMaster()->MovePoint(2, -1682, -4329, 2.79f);
                                creature->HandleEmoteCommand(EMOTE_STATE_READY_UNARMED);
                                EventBigWill = true;
                                WaveTimer = 1000;
                            }
                        }
                        else if (Wave >= 6 && EventBigWill && !BigWill.IsEmpty())
                        {
                            Creature* creature = ObjectAccessor::GetCreature(*me, BigWill);
                            if (!creature || !creature->IsAlive())
                            {
                                Talk(SAY_TWIGGY_FLATHEAD_OVER);
                                Reset();
                            }
                            else if (creature) // Makes BIG WILL attackable.
                            {
                                creature->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
                                creature->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
                                creature->HandleEmoteCommand(EMOTE_ONESHOT_ROAR);
                                creature->setFaction(14);
                                creature->AI()->AttackStart(warrior);
                            }
                        }
                    } else WaveTimer -= diff;
                }
            }
        }
Example #28
0
void WorldSession::HandleInitiateTradeOpcode(WorldPackets::Trade::InitiateTrade& initiateTrade)
{
    if (GetPlayer()->m_trade)
        return;

    WorldPackets::Trade::TradeStatus info;
    if (!GetPlayer()->IsAlive())
    {
        info.Status = TRADE_STATUS_DEAD;
        SendTradeStatus(info);
        return;
    }

    if (GetPlayer()->HasUnitState(UNIT_STATE_STUNNED))
    {
        info.Status = TRADE_STATUS_STUNNED;
        SendTradeStatus(info);
        return;
    }

    if (isLogingOut())
    {
        info.Status = TRADE_STATUS_LOGGING_OUT;
        SendTradeStatus(info);
        return;
    }

    if (GetPlayer()->IsInFlight())
    {
        info.Status = TRADE_STATUS_TOO_FAR_AWAY;
        SendTradeStatus(info);
        return;
    }

    if (GetPlayer()->getLevel() < sWorld->getIntConfig(CONFIG_TRADE_LEVEL_REQ))
    {
        SendNotification(GetTrinityString(LANG_TRADE_REQ), sWorld->getIntConfig(CONFIG_TRADE_LEVEL_REQ));
        return;
    }

    Player* pOther = ObjectAccessor::FindPlayer(initiateTrade.Guid);
    if (!pOther)
    {
        info.Status = TRADE_STATUS_NO_TARGET;
        SendTradeStatus(info);
        return;
    }

    if (pOther == GetPlayer() || pOther->m_trade)
    {
        info.Status = TRADE_STATUS_PLAYER_BUSY;
        SendTradeStatus(info);
        return;
    }

    if (!pOther->IsAlive())
    {
        info.Status = TRADE_STATUS_TARGET_DEAD;
        SendTradeStatus(info);
        return;
    }

    if (pOther->IsInFlight())
    {
        info.Status = TRADE_STATUS_TOO_FAR_AWAY;
        SendTradeStatus(info);
        return;
    }

    if (pOther->HasUnitState(UNIT_STATE_STUNNED))
    {
        info.Status = TRADE_STATUS_TARGET_STUNNED;
        SendTradeStatus(info);
        return;
    }

    if (pOther->GetSession()->isLogingOut())
    {
        info.Status = TRADE_STATUS_TARGET_LOGGING_OUT;
        SendTradeStatus(info);
        return;
    }

    if (pOther->GetSocial()->HasIgnore(GetPlayer()->GetGUID()))
    {
        info.Status = TRADE_STATUS_PLAYER_IGNORED;
        SendTradeStatus(info);
        return;
    }

    if ((pOther->GetTeam() != _player->GetTeam() ||
        pOther->HasFlag(PLAYER_FLAGS_EX, PLAYER_FLAGS_EX_MERCENARY_MODE) ||
        _player->HasFlag(PLAYER_FLAGS_EX, PLAYER_FLAGS_EX_MERCENARY_MODE)) &&
        (!sWorld->getBoolConfig(CONFIG_ALLOW_TWO_SIDE_TRADE) &&
        !HasPermission(rbac::RBAC_PERM_ALLOW_TWO_SIDE_TRADE)))
    {
        info.Status = TRADE_STATUS_WRONG_FACTION;
        SendTradeStatus(info);
        return;
    }

    if (!pOther->IsWithinDistInMap(_player, TRADE_DISTANCE, false))
    {
        info.Status = TRADE_STATUS_TOO_FAR_AWAY;
        SendTradeStatus(info);
        return;
    }

    if (pOther->getLevel() < sWorld->getIntConfig(CONFIG_TRADE_LEVEL_REQ))
    {
        SendNotification(GetTrinityString(LANG_TRADE_OTHER_REQ), sWorld->getIntConfig(CONFIG_TRADE_LEVEL_REQ));
        return;
    }

    // OK start trade
    _player->m_trade = new TradeData(_player, pOther);
    pOther->m_trade = new TradeData(pOther, _player);

    info.Status = TRADE_STATUS_PROPOSED;
    info.Partner = _player->GetGUID();
    pOther->GetSession()->SendTradeStatus(info);
}
Example #29
0
/*this procedure handles clients CMSG_REQUEST_PARTY_MEMBER_STATS request*/
void WorldSession::HandleRequestPartyMemberStatsOpcode(WorldPacket& recvData)
{
    TC_LOG_DEBUG(LOG_FILTER_NETWORKIO, "WORLD: Received CMSG_REQUEST_PARTY_MEMBER_STATS");
    uint64 guid;
    recvData >> guid;

    Player* player = HashMapHolder<Player>::Find(guid);
    if (!player)
    {
        WorldPacket data(SMSG_PARTY_MEMBER_STATS_FULL, 3+4+2);
        data << uint8(0);                                   // only for SMSG_PARTY_MEMBER_STATS_FULL, probably arena/bg related
        data.appendPackGUID(guid);
        data << uint32(GROUP_UPDATE_FLAG_STATUS);
        data << uint16(MEMBER_STATUS_OFFLINE);
        SendPacket(&data);
        return;
    }

    Pet* pet = player->GetPet();
    Powers powerType = player->getPowerType();

    WorldPacket data(SMSG_PARTY_MEMBER_STATS_FULL, 4+2+2+2+1+2*6+8+1+8);
    data << uint8(0);                                       // only for SMSG_PARTY_MEMBER_STATS_FULL, probably arena/bg related
    data.append(player->GetPackGUID());

    uint32 updateFlags = GROUP_UPDATE_FLAG_STATUS | GROUP_UPDATE_FLAG_CUR_HP | GROUP_UPDATE_FLAG_MAX_HP
                      | GROUP_UPDATE_FLAG_CUR_POWER | GROUP_UPDATE_FLAG_MAX_POWER | GROUP_UPDATE_FLAG_LEVEL
                      | GROUP_UPDATE_FLAG_ZONE | GROUP_UPDATE_FLAG_POSITION | GROUP_UPDATE_FLAG_AURAS
                      | GROUP_UPDATE_FLAG_PET_NAME | GROUP_UPDATE_FLAG_PET_MODEL_ID | GROUP_UPDATE_FLAG_PET_AURAS;

    if (powerType != POWER_MANA)
        updateFlags |= GROUP_UPDATE_FLAG_POWER_TYPE;

    if (pet)
        updateFlags |= GROUP_UPDATE_FLAG_PET_GUID | GROUP_UPDATE_FLAG_PET_CUR_HP | GROUP_UPDATE_FLAG_PET_MAX_HP
                    | GROUP_UPDATE_FLAG_PET_POWER_TYPE | GROUP_UPDATE_FLAG_PET_CUR_POWER | GROUP_UPDATE_FLAG_PET_MAX_POWER;

    if (player->GetVehicle())
        updateFlags |= GROUP_UPDATE_FLAG_VEHICLE_SEAT;

    uint16 playerStatus = MEMBER_STATUS_ONLINE;
    if (player->IsPvP())
        playerStatus |= MEMBER_STATUS_PVP;

    if (!player->IsAlive())
    {
        if (player->HasFlag(PLAYER_FLAGS, PLAYER_FLAGS_GHOST))
            playerStatus |= MEMBER_STATUS_GHOST;
        else
            playerStatus |= MEMBER_STATUS_DEAD;
    }

    if (player->HasByteFlag(UNIT_FIELD_BYTES_2, 1, UNIT_BYTE2_FLAG_FFA_PVP))
        playerStatus |= MEMBER_STATUS_PVP_FFA;

    if (player->isAFK())
        playerStatus |= MEMBER_STATUS_AFK;

    if (player->isDND())
        playerStatus |= MEMBER_STATUS_DND;

    data << uint32(updateFlags);
    data << uint16(playerStatus);                           // GROUP_UPDATE_FLAG_STATUS
    data << uint32(player->GetHealth());                    // GROUP_UPDATE_FLAG_CUR_HP
    data << uint32(player->GetMaxHealth());                 // GROUP_UPDATE_FLAG_MAX_HP
    if (updateFlags & GROUP_UPDATE_FLAG_POWER_TYPE)
        data << uint8(powerType);

    data << uint16(player->GetPower(powerType));            // GROUP_UPDATE_FLAG_CUR_POWER
    data << uint16(player->GetMaxPower(powerType));         // GROUP_UPDATE_FLAG_MAX_POWER
    data << uint16(player->getLevel());                     // GROUP_UPDATE_FLAG_LEVEL
    data << uint16(player->GetZoneId());                    // GROUP_UPDATE_FLAG_ZONE
    data << uint16(player->GetPositionX());                 // GROUP_UPDATE_FLAG_POSITION
    data << uint16(player->GetPositionY());                 // GROUP_UPDATE_FLAG_POSITION
    data << uint16(player->GetPositionZ());               // GROUP_UPDATE_FLAG_POSITION

    // GROUP_UPDATE_FLAG_AURAS
    data << uint8(1);
    uint64 auramask = 0;
    size_t maskPos = data.wpos();
    data << uint64(auramask);                          // placeholder
    data << uint32(MAX_AURAS);                         // count

    for (uint8 i = 0; i < MAX_AURAS; ++i)
    {
        if (AuraApplication const* aurApp = player->GetVisibleAura(i))
        {
            auramask |= (uint64(1) << i);

            data << uint32(aurApp->GetBase()->GetId());
            data << uint16(aurApp->GetFlags());

            if (aurApp->GetFlags() & AFLAG_ANY_EFFECT_AMOUNT_SENT)
            {
                for (uint32 i = 0; i < MAX_SPELL_EFFECTS; ++i)
                {
                    if (AuraEffect const* eff = aurApp->GetBase()->GetEffect(i))
                        data << int32(eff->GetAmount());
                    else
                        data << int32(0);
                }
            }
        }
    }
    data.put<uint64>(maskPos, auramask);                    // GROUP_UPDATE_FLAG_AURAS

    if (updateFlags & GROUP_UPDATE_FLAG_PET_GUID)
        data << uint64(pet->GetGUID());

    data << std::string(pet ? pet->GetName() : "");         // GROUP_UPDATE_FLAG_PET_NAME
    data << uint16(pet ? pet->GetDisplayId() : 0);          // GROUP_UPDATE_FLAG_PET_MODEL_ID

    if (updateFlags & GROUP_UPDATE_FLAG_PET_CUR_HP)
        data << uint32(pet->GetHealth());

    if (updateFlags & GROUP_UPDATE_FLAG_PET_MAX_HP)
        data << uint32(pet->GetMaxHealth());

    if (updateFlags & GROUP_UPDATE_FLAG_PET_POWER_TYPE)
        data << (uint8)pet->getPowerType();

    if (updateFlags & GROUP_UPDATE_FLAG_PET_CUR_POWER)
        data << uint16(pet->GetPower(pet->getPowerType()));

    if (updateFlags & GROUP_UPDATE_FLAG_PET_MAX_POWER)
        data << uint16(pet->GetMaxPower(pet->getPowerType()));

    uint64 petAuraMask = 0;
    maskPos = data.wpos();
    data << uint64(petAuraMask);                            // placeholder
    if (pet)
    {
        // GROUP_UPDATE_FLAG_PET_AURAS
        data << uint8(1);
        uint64 petauramask = 0;
        size_t petMaskPos = data.wpos();
        data << uint64(petauramask);                       // placeholder
        data << uint32(MAX_AURAS);                         // count

        for (uint8 i = 0; i < MAX_AURAS; ++i)
        {
            if (AuraApplication const* aurApp = pet->GetVisibleAura(i))
            {
                petauramask |= (uint64(1) << i);

                data << uint32(aurApp->GetBase()->GetId());
                data << uint16(aurApp->GetFlags());

                if (aurApp->GetFlags() & AFLAG_ANY_EFFECT_AMOUNT_SENT)
                {
                    for (uint32 i = 0; i < MAX_SPELL_EFFECTS; ++i)
                    {
                        if (AuraEffect const* eff = aurApp->GetBase()->GetEffect(i))
                            data << int32(eff->GetAmount());
                        else
                            data << int32(0);
                    }
                }
            }
        }

        data.put<uint64>(petMaskPos, petauramask);           // GROUP_UPDATE_FLAG_PET_AURAS
    }
    // else not needed, flags do not include any PET_ update

    // GROUP_UPDATE_FLAG_PHASE
    data << uint32(8); // either 0 or 8, same unk found in SMSG_PHASESHIFT
    data << uint32(0); // count
    // for (count) *data << uint16(phaseId)

    data.put<uint64>(maskPos, petAuraMask);                 // GROUP_UPDATE_FLAG_PET_AURAS

    if (updateFlags & GROUP_UPDATE_FLAG_VEHICLE_SEAT)
        data << uint32(player->GetVehicle()->GetVehicleInfo()->m_seatID[player->m_movementInfo.transport.seat]);

    SendPacket(&data);
}
Example #30
0
		void Player::FireWeapon() {
			SPADES_MARK_FUNCTION();
			
			Vector3 muzzle = GetEye();
			muzzle += GetFront() * 0.01f;
			
			// for hit-test debugging
			std::map<int, HitTestDebugger::PlayerHit> playerHits;
			std::vector<Vector3> bulletVectors;
			
			//Vector3 right = GetRight();
			//Vector3 up = GetUp();
			
			int pellets = weapon->GetPelletSize();
			float spread = weapon->GetSpread();
			GameMap *map = world->GetMap();
			
			// pyspades takes destroying more than one block as a
			// speed hack (shotgun does this)
			bool blockDestroyed = false;
			
			Vector3 dir2 = GetFront();
			for(int i =0 ; i < pellets; i++){
				
				// AoS 0.75's way (dir2 shouldn't be normalized!)
				dir2.x += (GetRandom() - GetRandom()) * spread;
				dir2.y += (GetRandom() - GetRandom()) * spread;
				dir2.z += (GetRandom() - GetRandom()) * spread;
				Vector3 dir = dir2.Normalize();
				
				bulletVectors.push_back(dir);
				
				// first do map raycast
				GameMap::RayCastResult mapResult;
				mapResult = map->CastRay2(muzzle,
										  dir,
										  500);
				
				Player *hitPlayer = NULL;
				float hitPlayerDistance = 0.f;
				HitBodyPart hitPart = HitBodyPart::None;
				
				for(int i = 0; i < world->GetNumPlayerSlots(); i++){
					Player *other = world->GetPlayer(i);
					if(other == this || other == NULL)
						continue;
					if(other == this || !other->IsAlive() ||
					   other->GetTeamId() >= 2)
						continue;
					// quickly reject players unlikely to be hit
					if(!other->RayCastApprox(muzzle, dir))
						continue;
					
					HitBoxes hb = other->GetHitBoxes();
					Vector3 hitPos;
					
					if(hb.head.RayCast(muzzle, dir, &hitPos)) {
						float dist = (hitPos - muzzle).GetLength();
						if(hitPlayer == NULL ||
						   dist < hitPlayerDistance){
							hitPlayer = other;
							hitPlayerDistance = dist;
							hitPart = HitBodyPart::Head;
						}
					}
					if(hb.torso.RayCast(muzzle, dir, &hitPos)) {
						float dist = (hitPos - muzzle).GetLength();
						if(hitPlayer == NULL ||
						   dist < hitPlayerDistance){
							hitPlayer = other;
							hitPlayerDistance = dist;
							hitPart = HitBodyPart::Torso;
						}
					}
					for(int j = 0; j < 3 ;j++){
						if(hb.limbs[j].RayCast(muzzle, dir, &hitPos)) {
							float dist = (hitPos - muzzle).GetLength();
							if(hitPlayer == NULL ||
							   dist < hitPlayerDistance){
								hitPlayer = other;
								hitPlayerDistance = dist;
								switch(j) {
									case 0: hitPart = HitBodyPart::Limb1; break;
									case 1: hitPart = HitBodyPart::Limb2; break;
									case 2: hitPart = HitBodyPart::Arms;  break;
								}
							}
						}
					}
				}
				
				Vector3 finalHitPos;
				finalHitPos = muzzle + dir * 128.f;
				
				if(hitPlayer == nullptr && !mapResult.hit) {
					// might hit water surface.
					
				}
				
				if(mapResult.hit && (mapResult.hitPos - muzzle).GetLength() < 128.f &&
				   (hitPlayer == NULL || (mapResult.hitPos - muzzle).GetLength() < hitPlayerDistance)){
					IntVector3 outBlockCoord = mapResult.hitBlock;
					// TODO: set correct ray distance
					// FIXME: why ray casting twice?
					
					finalHitPos = mapResult.hitPos;
					
					if(outBlockCoord.x >= 0 && outBlockCoord.y >= 0 && outBlockCoord.z >= 0 &&
					   outBlockCoord.x < map->Width() && outBlockCoord.y < map->Height() &&
					   outBlockCoord.z < map->Depth()){
						if(outBlockCoord.z == 63) {
							if(world->GetListener())
								world->GetListener()->BulletHitBlock(mapResult.hitPos,
																	 mapResult.hitBlock,
																	 mapResult.normal);
						}else if(outBlockCoord.z == 62) {
							// blocks at this level cannot be damaged
							if(world->GetListener())
								world->GetListener()->BulletHitBlock(mapResult.hitPos,
																	 mapResult.hitBlock,
																	 mapResult.normal);
						}else{
							int x = outBlockCoord.x;
							int y = outBlockCoord.y;
							int z = outBlockCoord.z;
							SPAssert(map->IsSolid(x, y, z));
							
							Vector3 blockF = {x + .5f, y + .5f, z + .5f};
							float distance = (blockF - muzzle).GetLength();
							
							uint32_t color = map->GetColor(x, y, z);
							int health = color >> 24;
							health -= weapon->GetDamage(HitTypeBlock, distance);
							if(health <= 0 && !blockDestroyed){
								health = 0;
								blockDestroyed = true;
								//send destroy cmd
								if(world->GetListener() &&
								   world->GetLocalPlayer() == this)
									world->GetListener()->LocalPlayerBlockAction
									(outBlockCoord, BlockActionTool);
								
							}
							color = (color & 0xffffff) | ((uint32_t)health << 24);
							if(map->IsSolid(x, y, z))
								map->Set(x, y, z, true, color);
							
							if(world->GetListener())
								world->GetListener()->BulletHitBlock(mapResult.hitPos,
																	 mapResult.hitBlock,
																	 mapResult.normal);
						}
					}
			    }else if(hitPlayer != NULL){