void BattlegroundIC::DoAction(uint32 action, uint64 var)
{
    if (action != ACTION_TELEPORT_PLAYER_TO_TRANSPORT)
        return;

    if (!gunshipAlliance || !gunshipHorde)
        return;

    Player* player = ObjectAccessor::FindPlayer(var);
    if (!player)
        return;

    player->SetTransport(player->GetTeamId() == TEAM_ALLIANCE ? gunshipAlliance : gunshipHorde);

    player->m_movementInfo.t_pos.m_positionX = TransportMovementInfo.GetPositionX();
    player->m_movementInfo.t_pos.m_positionY = TransportMovementInfo.GetPositionY();
    player->m_movementInfo.t_pos.m_positionZ = TransportMovementInfo.GetPositionZ();
    player->m_movementInfo.t_guid = (player->GetTeamId() == TEAM_ALLIANCE ? gunshipAlliance : gunshipHorde)->GetGUID();

    if (player->TeleportTo(GetMapId(), TeleportToTransportPosition.GetPositionX(),
                        TeleportToTransportPosition.GetPositionY(),
                        TeleportToTransportPosition.GetPositionZ(),
                        TeleportToTransportPosition.GetOrientation(),
                        TELE_TO_NOT_LEAVE_TRANSPORT))
    {
        player->CastSpell(player, SPELL_PARACHUTE, true); // this must be changed, there is a trigger in each transport that casts the spell.
        player->CastSpell(player, SPELL_SLOW_FALL, true);
    }
}
		void JustDied(Unit* /*pKiller*/)
		{
			events.Reset();
			summons.DespawnAll();
			Talk(SAY_DEATH);
			if( pInstance )
				pInstance->SetData(TYPE_ANUBARAK, DONE);


			Player* plr = NULL;
			if( !pInstance->instance->GetPlayers().isEmpty() )
				plr = pInstance->instance->GetPlayers().begin()->GetSource();

			if( !plr )
				return;

			// remove loot for the other faction (items are invisible for players, done in conditions), so corpse can be skinned
			for( std::vector<LootItem>::iterator itr = me->loot.items.begin(); itr != me->loot.items.end(); ++itr )
				if( ItemTemplate const *iProto = sObjectMgr->GetItemTemplate((*itr).itemid) )
					if( ((iProto->Flags2 & ITEM_FLAGS_EXTRA_HORDE_ONLY) && plr->GetTeamId() != TEAM_HORDE) || ((iProto->Flags2 & ITEM_FLAGS_EXTRA_ALLIANCE_ONLY) && plr->GetTeamId() != TEAM_ALLIANCE) )
					{
						(*itr).count = 0;
						(*itr).is_looted = true;
						--me->loot.unlootedCount;
					}
		}
Example #3
0
		void Client::FollowNextPlayer(bool reverse) {
			int myTeam = 2;
			if(world->GetLocalPlayer()){
				myTeam = world->GetLocalPlayer()->GetTeamId();
			}
			
			int nextId = followingPlayerId;
			do{
				reverse ? --nextId : ++nextId;
				if(nextId >= static_cast<int>(world->GetNumPlayerSlots()))
					nextId = 0;
				if(nextId < 0)
					nextId = world->GetNumPlayerSlots() - 1;
				
				Player *p = world->GetPlayer(nextId);
				if(p == nullptr)
					continue;
				if(myTeam < 2 && p->GetTeamId() != myTeam)
					continue;
				if(p->GetFront().GetPoweredLength() < .01f)
					continue;
				
				break;
			}while(nextId != followingPlayerId);
			
			followingPlayerId = nextId;
		}
Example #4
0
void Channel::SetOwner(Player const* player, std::string const& newname)
{
    uint64 guid = player->GetGUID();
    uint32 sec = player->GetSession()->GetSecurity();

    if (!IsOn(guid))
    {
        WorldPacket data;
        MakeNotMember(&data);
        SendToOne(&data, guid);
        return;
    }

    bool isGoodConstantModerator = _channelRights.moderators.find(player->GetSession()->GetAccountId()) != _channelRights.moderators.end();
    if (!AccountMgr::IsGMAccount(sec) && guid != _ownerGUID && !isGoodConstantModerator)
    {
        WorldPacket data;
        MakeNotOwner(&data);
        SendToOne(&data, guid);
        return;
    }

    Player* newp = ObjectAccessor::FindPlayerByName(newname, false);
    uint64 victim = newp ? newp->GetGUID() : 0;

    if (!victim || !IsOn(victim) || newp->GetTeamId() != player->GetTeamId())
    {
        WorldPacket data;
        MakePlayerNotFound(&data, newname);
        SendToOne(&data, guid);
        return;
    }

    SetOwner(victim);
}
void WorldSession::HandleGrantLevel(WorldPacket& recvData)
{
    sLog->outDebug(LOG_FILTER_NETWORKIO, "WORLD: CMSG_GRANT_LEVEL");

    uint64 guid;
    recvData.readPackGUID(guid);

    Player* target = ObjectAccessor::GetObjectInWorld(guid, _player);

    // check cheating
    uint8 levels = _player->GetGrantableLevels();
    uint8 error = 0;
    if (!target)
        error = ERR_REFER_A_FRIEND_NO_TARGET;
    else if (levels == 0)
        error = ERR_REFER_A_FRIEND_INSUFFICIENT_GRANTABLE_LEVELS;
    else if (GetRecruiterId() != target->GetSession()->GetAccountId())
        error = ERR_REFER_A_FRIEND_NOT_REFERRED_BY;
    else if (target->GetTeamId() != _player->GetTeamId())
        error = ERR_REFER_A_FRIEND_DIFFERENT_FACTION;
    else if (target->getLevel() >= _player->getLevel())
        error = ERR_REFER_A_FRIEND_TARGET_TOO_HIGH;
    else if (target->getLevel() >= sWorld->getIntConfig(CONFIG_MAX_RECRUIT_A_FRIEND_BONUS_PLAYER_LEVEL))
        error = ERR_REFER_A_FRIEND_GRANT_LEVEL_MAX_I;
    else if (target->GetGroup() != _player->GetGroup())
        error = ERR_REFER_A_FRIEND_NOT_IN_GROUP;

    if (error) {
        WorldPacket data(SMSG_REFER_A_FRIEND_FAILURE, 24);
        data << uint32(error);
        if (error == ERR_REFER_A_FRIEND_NOT_IN_GROUP)
            data << target->GetName();

        SendPacket(&data);
        return;
    }

	ObjectGuid Guid = guid;
    WorldPacket data2(SMSG_PROPOSE_LEVEL_GRANT, 8);

	data2.WriteBit(Guid[6]);
	data2.WriteBit(Guid[7]);
	data2.WriteBit(Guid[2]);
	data2.WriteBit(Guid[5]);
	data2.WriteBit(Guid[3]);
	data2.WriteBit(Guid[0]);
	data2.WriteBit(Guid[1]);
	data2.WriteBit(Guid[4]);

	data2.WriteByteSeq(Guid[2]);
	data2.WriteByteSeq(Guid[5]);
	data2.WriteByteSeq(Guid[6]);
	data2.WriteByteSeq(Guid[7]);
	data2.WriteByteSeq(Guid[1]);
	data2.WriteByteSeq(Guid[4]);
	data2.WriteByteSeq(Guid[3]);
	data2.WriteByteSeq(Guid[0]);

    target->GetSession()->SendPacket(&data2);
}
        void MoveInLineOfSight(Unit* who)
        {
            if (!who || !who->IsInWorld() || who->GetZoneId() != 4395)
                return;

            if (!me->IsWithinDist(who, 5.0f, false))
                return;

            Player* player = who->GetCharmerOrOwnerPlayerOrPlayerItself();

            if (!player || player->IsGameMaster() || player->IsBeingTeleported() || (player->GetPositionZ() > 670 && player->GetVehicle()) ||
                // If player has Disguise aura for quest A Meeting With The Magister or An Audience With The Arcanist, do not teleport it away but let it pass
                player->HasAura(SPELL_SUNREAVER_DISGUISE_FEMALE) || player->HasAura(SPELL_SUNREAVER_DISGUISE_MALE) ||
                player->HasAura(SPELL_SILVER_COVENANT_DISGUISE_FEMALE) || player->HasAura(SPELL_SILVER_COVENANT_DISGUISE_MALE))
                return;

            switch (me->GetEntry())
            {
                case NPC_SILVER_COVENANT_GUARDIAN_MAGE:
                    if (player->GetTeamId() == TEAM_HORDE)              // Horde unit found in Alliance area
                    {
                        if (GetClosestCreatureWithEntry(me, NPC_APPLEBOUGH_A, 32.0f))
                        {
                            if (me->isInBackInMap(who, 12.0f))   // In my line of sight, "outdoors", and behind me
                                DoCast(who, SPELL_TRESPASSER_A); // Teleport the Horde unit out
                        }
                        else                                      // In my line of sight, and "indoors"
                            DoCast(who, SPELL_TRESPASSER_A);     // Teleport the Horde unit out
                    }
                    break;
                case NPC_SUNREAVER_GUARDIAN_MAGE:
                    if (player->GetTeamId() == TEAM_ALLIANCE)           // Alliance unit found in Horde area
                    {
                        if (GetClosestCreatureWithEntry(me, NPC_SWEETBERRY_H, 32.0f))
                        {
                            if (me->isInBackInMap(who, 12.0f))   // In my line of sight, "outdoors", and behind me
                                DoCast(who, SPELL_TRESPASSER_H); // Teleport the Alliance unit out
                        }
                        else                                      // In my line of sight, and "indoors"
                            DoCast(who, SPELL_TRESPASSER_H);     // Teleport the Alliance unit out
                    }
                    break;
            }
            me->SetOrientation(me->GetHomePosition().GetOrientation());
            return;
        }
Example #7
0
void Channel::Invite(Player const* player, std::string const& newname)
{
    uint64 guid = player->GetGUID();

    if (!IsOn(guid))
    {
        WorldPacket data;
        MakeNotMember(&data);
        SendToOne(&data, guid);
        return;
    }

    Player* newp = ObjectAccessor::FindPlayerByName(newname, false);
    if (!newp || !newp->isGMVisible())
    {
        WorldPacket data;
        MakePlayerNotFound(&data, newname);
        SendToOne(&data, guid);
        return;
    }

    if (IsBanned(newp->GetGUID()))
    {
        WorldPacket data;
        MakePlayerInviteBanned(&data, newname);
        SendToOne(&data, guid);
        return;
    }

    if (newp->GetTeamId() != player->GetTeamId())
    {
        WorldPacket data;
        MakeInviteWrongFaction(&data);
        SendToOne(&data, guid);
        return;
    }

    if (IsOn(newp->GetGUID()))
    {
        WorldPacket data;
        MakePlayerAlreadyMember(&data, newp->GetGUID());
        SendToOne(&data, guid);
        return;
    }

    if (!newp->GetSocial()->HasIgnore(GUID_LOPART(guid)))
    {
        WorldPacket data;
        MakeInvite(&data, guid);
        SendToOne(&data, newp->GetGUID());
        data.clear();
    }

    WorldPacket data;
    MakePlayerInvited(&data, newp->GetName());
    SendToOne(&data, guid);
}
Example #8
0
void BattlegroundIC::DoAction(uint32 action, uint64 guid)
{
    if (action != ACTION_TELEPORT_PLAYER_TO_TRANSPORT)
        return;

    if (!gunshipAlliance || !gunshipHorde)
        return;

	Player* player = ObjectAccessor::GetPlayer(*gunshipAlliance, guid);
    if (!player)
        return;

	MotionTransport* transport = player->GetTeamId() == TEAM_ALLIANCE ? gunshipAlliance : gunshipHorde;
	float x = BG_IC_HangarTrigger[player->GetTeamId()].GetPositionX();
	float y = BG_IC_HangarTrigger[player->GetTeamId()].GetPositionY();
	float z = BG_IC_HangarTrigger[player->GetTeamId()].GetPositionZ();
    transport->CalculatePassengerPosition(x, y, z);

    player->TeleportTo(GetMapId(), x, y, z, player->GetOrientation(), TELE_TO_NOT_LEAVE_TRANSPORT);
}
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;
		}
        void WaypointReached(uint32 waypointId)
        {
            Player* player = GetPlayerForEscort();
            if (!player)
                return;

            switch (waypointId)
            {
                case 0:
                    if (GameObject* Cage = me->FindNearestGameObject(GO_CAGE, 10))
                        Cage->SetGoState(GO_STATE_ACTIVE);
                    break;
                case 2:
                    Talk(SAY_PROGRESS_1, player);
                    break;
                case 5:
                    Talk(SAY_PROGRESS_2, player);
                    break;
                case 6:
                    Talk(SAY_PROGRESS_3, player);
                    break;
                case 29:
                    Talk(SAY_PROGRESS_4, player);
                    if (player->GetTeamId() == TEAM_ALLIANCE)
                        player->GroupEventHappens(QUEST_EFTW_A, me);
                    else if (player->GetTeamId() == TEAM_HORDE)
                        player->GroupEventHappens(QUEST_EFTW_H, me);
                    me->SetInFront(player);
                    break;
                case 30:
                    me->HandleEmoteCommand(EMOTE_ONESHOT_WAVE);
                    break;
                case 31:
                    DoCast(me, SPELL_CAT);
                    me->SetWalk(false);
                    break;
            }
        }
Example #11
0
        void MoveInLineOfSight(Unit* who)
        {
            if (!who || who->GetTypeId() != TYPEID_PLAYER)
                return;

            if (who->ToPlayer()->isGameMaster())
                return;

            Player* player = who->ToPlayer();

            if (OutdoorPvPWG *pvpWG = (OutdoorPvPWG*)sOutdoorPvPMgr->GetOutdoorPvPToZoneId(4197))
                if (me->IsWithinDistInMap(player, 18, false))
                    if (player->GetTeamId() == pvpWG->getAttackerTeam() && !pvpWG->MaingateDestroyed)
                        player->TeleportTo(571, 4608.08f, 2844.69f, 396.9f, 0.0f);
        }
    static bool HandleBoutiqueFactionCommand(ChatHandler *handler, const char *args) {
        Player* target = handler->GetSession()->GetPlayer();

        const char* reqcount = "SELECT id FROM boutique_service_achat WHERE accountId='%u' AND type=4 AND recup=0 LIMIT 1";

        sLog->outDebug(LOG_FILTER_NETWORKIO, reqcount, handler->GetSession()->GetAccountId());
        QueryResult resultcount = LoginDatabase.PQuery(reqcount, handler->GetSession()->GetAccountId());        
        if (!resultcount) {
            //Vous ne disposez actuellement d'aucun service de ce type. Vous pouvez acheter ce service sur la boutique
            handler->PSendSysMessage(11016);
            return true;
        }

        Field* fieldscount = resultcount->Fetch();
		
        const char* qmask = "SELECT 1 FROM boutique_service WHERE realmMask & '%u' != 0 and type = 4";
        QueryResult reqmask = LoginDatabase.PQuery(qmask, (1<<(realmID-1)));        
        if (!reqmask) {
            //Ce produit ou service n'est pas disponible pour ce royaume.
            handler->PSendSysMessage(11018);
            return true;
        }
		
        const char* reqallowed = "SELECT value FROM data WHERE RealmID = %u AND identifier = 'lowestFaction';";
        sLog->outDebug(LOG_FILTER_NETWORKIO, reqallowed, realmID);
        QueryResult resultallowed = LoginDatabase.PQuery(reqallowed, realmID);
        Field* fieldsallowed = resultallowed->Fetch();
        if (fieldsallowed[0].GetInt32()==target->GetTeamId()) {
            //Changement impossible vers l'autre faction car trop peuplée
            handler->PSendSysMessage(12007);
            return true;
        }

        if (target)
        {
            //Le changement de faction est valide. Vous pourrez effectuer le changement sur l'ecran des personnages
            handler->PSendSysMessage(12008);
            target->SetAtLoginFlag(AT_LOGIN_CHANGE_FACTION);
            CharacterDatabase.PExecute("UPDATE characters SET at_login = at_login | '64' WHERE guid = '%u'", target->GetGUIDLow());

            target->SaveToDB();
            const char* requpdate = "UPDATE boutique_service_achat SET realmID = '%u', recup='%u' WHERE id='%u'";
            LoginDatabase.PExecute(requpdate, realmID, (uint32)handler->GetSession()->GetPlayer()->GetGUID(), fieldscount[0].GetInt32());
        }

        return true;
    }
Example #13
0
		void Client::SpawnPressed() {
			WeaponType weap = limbo->GetSelectedWeapon();
			int team = limbo->GetSelectedTeam();
			inGameLimbo = false;
			if(team == 2)
				team = 255;
			
			if(!world->GetLocalPlayer()){
				// join
				net->SendJoin(team, weap,
							  playerName, lastKills);
			}else{
				Player *p = world->GetLocalPlayer();
				if(p->GetTeamId() != team){
					net->SendTeamChange(team);
				}
				if(team != 2 && p->GetWeapon()->GetWeaponType() != weap){
					net->SendWeaponChange(weap);
				}
			}
		}
// Sent any time a guild master sets an option in the interface and when listing / unlisting his guild
void WorldSession::HandleGuildFinderSetGuildPost(WorldPacket& recvPacket)
{
    sLog->outDebug(LOG_FILTER_NETWORKIO, "WORLD: Received CMSG_LF_GUILD_SET_GUILD_POST");

    uint32 classRoles = 0;
    uint32 availability = 0;
    uint32 guildInterests =  0;
    uint32 level = 0;

    recvPacket >> guildInterests >> availability >> level >> classRoles;
    bool listed = recvPacket.ReadBit();
    // Level sent is zero if untouched, force to any (from interface). Idk why
    if (!level)
        level = ANY_FINDER_LEVEL;

    uint16 length = recvPacket.ReadBits(11);
    std::string comment = recvPacket.ReadString(length);

    if (!(classRoles & GUILDFINDER_ALL_ROLES) || classRoles > GUILDFINDER_ALL_ROLES)
        return;
    if (!(availability & ALL_WEEK) || availability > ALL_WEEK)
        return;
    if (!(guildInterests & ALL_INTERESTS) || guildInterests > ALL_INTERESTS)
        return;
    if (!(level & ALL_GUILDFINDER_LEVELS) || level > ALL_GUILDFINDER_LEVELS)
        return;

    Player* player = GetPlayer();

    if (!player->GetGuildId()) // Player must be in guild
        return;

    if (Guild* guild = sGuildMgr->GetGuildById(player->GetGuildId())) // Player must be guild master
        if (guild->GetLeaderGUID() != player->GetGUID())
            return;

    LFGuildSettings settings(listed, player->GetTeamId(), player->GetGuildId(), classRoles, availability, guildInterests, level, comment);
    sGuildFinderMgr->SetGuildSettings(player->GetGuildId(), settings);
}
void WorldSession::HandleGrantLevel(WorldPackets::RaF::GrantLevel& grantLevel)
{
    Player* target = ObjectAccessor::GetPlayer(*_player, grantLevel.Target);

    // check cheating
    uint8 levels = _player->GetGrantableLevels();
    uint8 error = 0;
    if (!target)
        error = ERR_REFER_A_FRIEND_NO_TARGET;
    else if (levels == 0)
        error = ERR_REFER_A_FRIEND_INSUFFICIENT_GRANTABLE_LEVELS;
    else if (GetRecruiterId() != target->GetSession()->GetAccountId())
        error = ERR_REFER_A_FRIEND_NOT_REFERRED_BY;
    else if (target->GetTeamId() != _player->GetTeamId())
        error = ERR_REFER_A_FRIEND_DIFFERENT_FACTION;
    else if (target->getLevel() >= _player->getLevel())
        error = ERR_REFER_A_FRIEND_TARGET_TOO_HIGH;
    else if (target->getLevel() >= sWorld->getIntConfig(CONFIG_MAX_RECRUIT_A_FRIEND_BONUS_PLAYER_LEVEL))
        error = ERR_REFER_A_FRIEND_GRANT_LEVEL_MAX_I;
    else if (target->GetGroup() != _player->GetGroup())
        error = ERR_REFER_A_FRIEND_NOT_IN_GROUP;
    else if (target->getLevel() >= GetMaxLevelForExpansion(target->GetSession()->GetExpansion()))
        error = ERR_REFER_A_FRIEND_INSUF_EXPAN_LVL;

    if (error)
    {
        WorldPackets::RaF::ReferAFriendFailure failure;
        failure.Reason = error;
        if (error == ERR_REFER_A_FRIEND_NOT_IN_GROUP)
            failure.Str = target->GetName();

        SendPacket(failure.Write());
        return;
    }

    WorldPackets::RaF::ProposeLevelGrant proposeLevelGrant;
    proposeLevelGrant.Sender = _player->GetGUID();
    target->SendDirectMessage(proposeLevelGrant.Write());
}
        void EnterEvadeMode()
        {
            if (defenderCredit)
            {
                std::list<Player*> playerList;
                Trinity::AnyPlayerInObjectRangeCheck checker(me, me->GetMap()->GetVisibilityRange(), false);
                Trinity::PlayerListSearcher<Trinity::AnyPlayerInObjectRangeCheck> searcher(me, playerList, checker);
                me->VisitNearbyWorldObject(me->GetMap()->GetVisibilityRange(), searcher);
                sLog->outInfo(LOG_FILTER_TSCR, "PvP Boss %s (%d) was protected and Players in Range for Defender Credit are:", me->GetName(), me->GetEntry());
                for (std::list<Player*>::const_iterator itr = playerList.begin(); itr != playerList.end(); ++itr)
                {
                    Player* player = (*itr);
                    if (player->GetTeamId() != TEAM_HORDE)
                        continue; // only same faction

                    if (!player->IsPvP())
                    {
                        sLog->outInfo(LOG_FILTER_TSCR, "[ ] %s (not flagged for PvP)", player->GetName());
                        continue; // Do not reward players who are not flagged for pvp ("no pain, no gain")
                    }

                    if (player->GetQuestStatus(QUEST_DEFENDING_HORDE) == QUEST_STATUS_INCOMPLETE)
                    {
                        sLog->outInfo(LOG_FILTER_TSCR, "[x] %s (rewarded)", player->GetName());
                        player->CompleteQuest(QUEST_DEFENDING_HORDE);
                    } else
                        sLog->outInfo(LOG_FILTER_TSCR, "[ ] %s (did not have quest %d at evade)", player->GetName(), QUEST_DEFENDING_HORDE);
                }
            } else
                sLog->outInfo(LOG_FILTER_TSCR, "PvP Boss %s (%d) was protected but did not qualify for Defender Credit (Anti-Farm Rule)", me->GetName(), me->GetEntry());

            if (appliedScaling)
                if (me->HasAura(appliedScaling))
                    me->RemoveAura(appliedScaling);

            Talk(1);
            ScriptedAI::EnterEvadeMode();
        }
Example #17
0
void SocialMgr::GetFriendInfo(Player* player, uint32 friendGUID, FriendInfo &friendInfo)
{
    if (!player)
        return;

    friendInfo.Status = FRIEND_STATUS_OFFLINE;
    friendInfo.Area = 0;
    friendInfo.Level = 0;
    friendInfo.Class = 0;

    Player* pFriend = ObjectAccessor::FindPlayerInOrOutOfWorld(friendGUID);
    if (!pFriend || AccountMgr::IsGMAccount(pFriend->GetSession()->GetSecurity()))
        return;

    TeamId teamId = player->GetTeamId();
    AccountTypes security = player->GetSession()->GetSecurity();
    bool allowTwoSideWhoList = sWorld->getBoolConfig(CONFIG_ALLOW_TWO_SIDE_WHO_LIST);
    AccountTypes gmLevelInWhoList = AccountTypes(sWorld->getIntConfig(CONFIG_GM_LEVEL_IN_WHO_LIST));

    PlayerSocialMap::iterator itr = player->GetSocial()->m_playerSocialMap.find(friendGUID);
    if (itr != player->GetSocial()->m_playerSocialMap.end())
        friendInfo.Note = itr->second.Note;

    // PLAYER see his team only and PLAYER can't see MODERATOR, GAME MASTER, ADMINISTRATOR characters
    // MODERATOR, GAME MASTER, ADMINISTRATOR can see all
    if (pFriend && (!AccountMgr::IsPlayerAccount(security) || ((pFriend->GetTeamId() == teamId || allowTwoSideWhoList) && pFriend->GetSession()->GetSecurity() <= gmLevelInWhoList)) && pFriend->IsVisibleGloballyFor(player))
    {
        friendInfo.Status = FRIEND_STATUS_ONLINE;
        if (pFriend->isAFK())
            friendInfo.Status = FRIEND_STATUS_AFK;
        if (pFriend->isDND())
            friendInfo.Status = FRIEND_STATUS_DND;
        friendInfo.Area = pFriend->GetZoneId();
        friendInfo.Level = pFriend->getLevel();
        friendInfo.Class = pFriend->getClass();
    }
}
Example #18
0
void SocialMgr::BroadcastToFriendListers(Player* player, WorldPacket* packet)
{
    if (!player)
        return;

    TeamId teamId = player->GetTeamId();
    AccountTypes security = player->GetSession()->GetSecurity();
    uint32 guid = player->GetGUIDLow();
    bool allowTwoSideWhoList = sWorld->getBoolConfig(CONFIG_ALLOW_TWO_SIDE_WHO_LIST);
    AccountTypes gmLevelInWhoList = AccountTypes(sWorld->getIntConfig(CONFIG_GM_LEVEL_IN_WHO_LIST));

    for (SocialMap::const_iterator itr = m_socialMap.begin(); itr != m_socialMap.end(); ++itr)
    {
        PlayerSocialMap::const_iterator itr2 = itr->second.m_playerSocialMap.find(guid);
        if (itr2 != itr->second.m_playerSocialMap.end() && (itr2->second.Flags & SOCIAL_FLAG_FRIEND))
        {
            Player* pFriend = ObjectAccessor::FindPlayer(MAKE_NEW_GUID(itr->first, 0, HIGHGUID_PLAYER));

            // PLAYER see his team only and PLAYER can't see MODERATOR, GAME MASTER, ADMINISTRATOR characters
            // MODERATOR, GAME MASTER, ADMINISTRATOR can see all
            if (pFriend && (!AccountMgr::IsPlayerAccount(pFriend->GetSession()->GetSecurity()) || ((pFriend->GetTeamId() == teamId || allowTwoSideWhoList) && security <= gmLevelInWhoList)) && player->IsVisibleGloballyFor(pFriend))
                pFriend->GetSession()->SendPacket(packet);
        }
    }
}
Example #19
0
void Channel::SetMode(Player const* player, std::string const& p2n, bool mod, bool set)
{
    uint64 guid = player->GetGUID();
    uint32 sec = player->GetSession()->GetSecurity();

    if (!IsOn(guid))
    {
        WorldPacket data;
        MakeNotMember(&data);
        SendToOne(&data, guid);
        return;
    }

    if (!playersStore[guid].IsModerator() && !AccountMgr::IsGMAccount(sec))
    {
        WorldPacket data;
        MakeNotModerator(&data);
        SendToOne(&data, guid);
        return;
    }

    if (guid == _ownerGUID && std::string(p2n) == player->GetName() && mod)
        return;

    Player* newp = ObjectAccessor::FindPlayerByName(p2n, false);
    uint64 victim = newp ? newp->GetGUID() : 0;

    if (!victim || !IsOn(victim) ||
        // allow make moderator from another team only if both is GMs
        // at this moment this only way to show channel post for GM from another team
        ((!AccountMgr::IsGMAccount(sec) || !AccountMgr::IsGMAccount(newp->GetSession()->GetSecurity())) && player->GetTeamId() != newp->GetTeamId()))
    {
        WorldPacket data;
        MakePlayerNotFound(&data, p2n);
        SendToOne(&data, guid);
        return;
    }

    if (_ownerGUID == victim && _ownerGUID != guid)
    {
        WorldPacket data;
        MakeNotOwner(&data);
        SendToOne(&data, guid);
        return;
    }

    if (mod)
    {
        bool isBadConstantModerator = _channelRights.moderators.find(newp->GetSession()->GetAccountId()) != _channelRights.moderators.end();
        if (!isBadConstantModerator)
            SetModerator(newp->GetGUID(), set);
    }
    else
    {
        bool isGoodConstantModerator = _channelRights.moderators.find(player->GetSession()->GetAccountId()) != _channelRights.moderators.end();
        if (!AccountMgr::IsGMAccount(sec) && !isGoodConstantModerator)
        {
            if (_channelRights.flags & CHANNEL_RIGHT_CANT_MUTE)
            {
                WorldPacket data;
                MakeNotModerator(&data);
                SendToOne(&data, guid);
                return;
            }
        }

        SetMute(newp->GetGUID(), set);
    }
}
Example #20
0
void WorldSession::HandleGroupInviteOpcode(WorldPacket& recvData)
{
    ;//sLog->outDebug(LOG_FILTER_NETWORKIO, "WORLD: Received CMSG_GROUP_INVITE");

    std::string membername;
    recvData >> membername;
    recvData.read_skip<uint32>();

    // attempt add selected player

    // cheating
    if (!normalizePlayerName(membername))
    {
        SendPartyResult(PARTY_OP_INVITE, membername, ERR_BAD_PLAYER_NAME_S);
        return;
    }

    Player* player = ObjectAccessor::FindPlayerByName(membername, false);

    // no player
    if (!player)
    {
        SendPartyResult(PARTY_OP_INVITE, membername, ERR_BAD_PLAYER_NAME_S);
        return;
    }

	if (GetPlayer()->IsSpectator() || player->IsSpectator())
	{
        SendPartyResult(PARTY_OP_INVITE, membername, ERR_INVITE_RESTRICTED);
		return;
	}

    // restrict invite to GMs
    if (!sWorld->getBoolConfig(CONFIG_ALLOW_GM_GROUP) && !GetPlayer()->IsGameMaster() && player->IsGameMaster())
    {
        SendPartyResult(PARTY_OP_INVITE, membername, ERR_BAD_PLAYER_NAME_S);
        return;
    }

    // can't group with
    if (!GetPlayer()->IsGameMaster() && !sWorld->getBoolConfig(CONFIG_ALLOW_TWO_SIDE_INTERACTION_GROUP) && GetPlayer()->GetTeamId() != player->GetTeamId())
    {
        SendPartyResult(PARTY_OP_INVITE, membername, ERR_PLAYER_WRONG_FACTION);
        return;
    }
    if (GetPlayer()->GetInstanceId() != 0 && player->GetInstanceId() != 0 && GetPlayer()->GetInstanceId() != player->GetInstanceId() && GetPlayer()->GetMapId() == player->GetMapId())
    {
        SendPartyResult(PARTY_OP_INVITE, membername, ERR_TARGET_NOT_IN_INSTANCE_S);
        return;
    }
    // just ignore us
    if (player->GetInstanceId() != 0 && player->GetDungeonDifficulty() != GetPlayer()->GetDungeonDifficulty())
    {
        SendPartyResult(PARTY_OP_INVITE, membername, ERR_IGNORING_YOU_S);
        return;
    }

    if (player->GetSocial()->HasIgnore(GetPlayer()->GetGUIDLow()))
    {
        SendPartyResult(PARTY_OP_INVITE, membername, ERR_IGNORING_YOU_S);
        return;
    }

    Group* group = GetPlayer()->GetGroup();
    if (group && (group->isBGGroup() || group->isBFGroup()))
        group = GetPlayer()->GetOriginalGroup();

    Group* group2 = player->GetGroup();
    if (group2 && (group2->isBGGroup() || group2->isBFGroup()))
        group2 = player->GetOriginalGroup();
    // player already in another group or invited
    if (group2 || player->GetGroupInvite())
    {
        SendPartyResult(PARTY_OP_INVITE, membername, ERR_ALREADY_IN_GROUP_S);

        if (group2)
        {
            // tell the player that they were invited but it failed as they were already in a group
            WorldPacket data(SMSG_GROUP_INVITE, 25);                // guess size
            data << uint8(0);                                       // invited/already in group flag
            data << GetPlayer()->GetName();                         // max len 48
            data << uint32(0);                                      // unk
            data << uint8(0);                                       // count
            data << uint32(0);                                      // unk
            player->GetSession()->SendPacket(&data);
        }

        return;
    }

    if (group)
    {
        // not have permissions for invite
        if (!group->IsLeader(GetPlayer()->GetGUID()) && !group->IsAssistant(GetPlayer()->GetGUID()))
        {
            SendPartyResult(PARTY_OP_INVITE, "", ERR_NOT_LEADER);
            return;
        }
        // not have place
        if (group->IsFull())
        {
            SendPartyResult(PARTY_OP_INVITE, "", ERR_GROUP_FULL);
            return;
        }
    }

    // xinef: if player has no group, check group invite
    if (!group && GetPlayer()->GetGroupInvite() && GetPlayer()->GetGroupInvite()->GetLeaderGUID() == GetPlayer()->GetGUID())
        group = GetPlayer()->GetGroupInvite();

    // ok, but group not exist, start a new group
    // but don't create and save the group to the DB until
    // at least one person joins
    if (!group)
    {
        group = new Group;
        // new group: if can't add then delete
        if (!group->AddLeaderInvite(GetPlayer()))
        {
            delete group;
            return;
        }
        if (!group->AddInvite(player))
        {
            delete group;
            return;
        }
    }
    else
    {
        // already existed group: if can't add then just leave
        if (!group->AddInvite(player))
        {
            return;
        }
    }

    // ok, we do it
    WorldPacket data(SMSG_GROUP_INVITE, 10);                // guess size
    data << uint8(1);                                       // invited/already in group flag
    data << GetPlayer()->GetName();                         // max len 48
    data << uint32(0);                                      // unk
    data << uint8(0);                                       // count
    data << uint32(0);                                      // unk
    player->GetSession()->SendPacket(&data);

    SendPartyResult(PARTY_OP_INVITE, membername, ERR_PARTY_RESULT_OK);
}
Example #21
0
void WorldSession::HandleOfferPetitionOpcode(WorldPacket & recvData)
{
    ;//sLog->outDebug(LOG_FILTER_NETWORKIO, "Received opcode CMSG_OFFER_PETITION");   // ok

    uint64 petitionguid, plguid;
    uint32 junk;
    Player* player;
    recvData >> junk;                                      // this is not petition type!
    recvData >> petitionguid;                              // petition guid
    recvData >> plguid;                                    // player guid

    player = ObjectAccessor::FindPlayerInOrOutOfWorld(plguid);
    if (!player)
        return;

	Petition const* petition = sPetitionMgr->GetPetition(GUID_LOPART(petitionguid));
	if (!petition)
		return;

    if (GetPlayer()->GetTeamId() != player->GetTeamId())
    {
		if (petition->petitionType != GUILD_CHARTER_TYPE)
            SendArenaTeamCommandResult(ERR_ARENA_TEAM_INVITE_SS, "", "", ERR_ARENA_TEAM_NOT_ALLIED);
        else
            Guild::SendCommandResult(this, GUILD_COMMAND_CREATE, ERR_GUILD_NOT_ALLIED);
        return;
    }

    if (petition->petitionType != GUILD_CHARTER_TYPE)
    {
        if (player->getLevel() < sWorld->getIntConfig(CONFIG_MAX_PLAYER_LEVEL))
        {
            // player is too low level to join an arena team
            SendArenaTeamCommandResult(ERR_ARENA_TEAM_CREATE_S, player->GetName().c_str(), "", ERR_ARENA_TEAM_TARGET_TOO_LOW_S);
            return;
        }

        uint8 slot = ArenaTeam::GetSlotByType(petition->petitionType);
        if (slot >= MAX_ARENA_SLOT)
            return;

        if (player->GetArenaTeamId(slot))
        {
            // player is already in an arena team
            SendArenaTeamCommandResult(ERR_ARENA_TEAM_CREATE_S, player->GetName().c_str(), "", ERR_ALREADY_IN_ARENA_TEAM_S);
            return;
        }

        if (player->GetArenaTeamIdInvited())
        {
            SendArenaTeamCommandResult(ERR_ARENA_TEAM_INVITE_SS, "", _player->GetName().c_str(), ERR_ALREADY_INVITED_TO_ARENA_TEAM_S);
            return;
        }
    }
    else
    {
        if (player->GetGuildId())
        {
            Guild::SendCommandResult(this, GUILD_COMMAND_INVITE, ERR_ALREADY_IN_GUILD_S, _player->GetName());
            return;
        }

        if (player->GetGuildIdInvited())
        {
            Guild::SendCommandResult(this, GUILD_COMMAND_INVITE, ERR_ALREADY_INVITED_TO_GUILD_S, _player->GetName());
            return;
        }
    }

	Signatures const* signatures = sPetitionMgr->GetSignature(GUID_LOPART(petitionguid));
	uint8 signs = signatures ? signatures->signatureMap.size() : 0;

    WorldPacket data(SMSG_PETITION_SHOW_SIGNATURES, (8+8+4+signs+signs*12));
    data << uint64(petitionguid);                           // petition guid
    data << uint64(_player->GetGUID());                     // owner guid
    data << uint32(GUID_LOPART(petitionguid));              // guild guid
    data << uint8(signs);                                   // sign's count

	if (signs)
		for (SignatureMap::const_iterator itr = signatures->signatureMap.begin(); itr != signatures->signatureMap.end(); ++itr)
		{
			data << uint64(MAKE_NEW_GUID(itr->first, 0, HIGHGUID_PLAYER)); // Player GUID
			data << uint32(0);                                  // there 0 ...
		}

    player->GetSession()->SendPacket(&data);
}
Example #22
0
void WorldSession::HandleMessagechatOpcode(WorldPacket & recvData)
{
    uint32 type;
    uint32 lang;

    recvData >> type;
    recvData >> lang;

    if (type >= MAX_CHAT_MSG_TYPE)
    {
        sLog->outError("CHAT: Wrong message type received: %u", type);
        recvData.rfinish();
        return;
    }

    Player* sender = GetPlayer();

    //sLog->outDebug("CHAT: packet received. type %u, lang %u", type, lang);

    // pussywizard: chatting on most chat types requires 2 hours played to prevent spam/abuse
    if (AccountMgr::IsPlayerAccount(GetSecurity()))
        switch (type)
        {
        case CHAT_MSG_ADDON:
        case CHAT_MSG_PARTY:
        case CHAT_MSG_RAID:
        case CHAT_MSG_GUILD:
        case CHAT_MSG_OFFICER:
        case CHAT_MSG_AFK:
        case CHAT_MSG_DND:
        case CHAT_MSG_RAID_LEADER:
        case CHAT_MSG_RAID_WARNING:
        case CHAT_MSG_BATTLEGROUND:
        case CHAT_MSG_BATTLEGROUND_LEADER:
        case CHAT_MSG_PARTY_LEADER:
            break;
        default:
            if (sender->GetTotalPlayedTime() < 2*HOUR)
            {
                SendNotification("Speaking is allowed after playing for at least 2 hours. You may use party and guild chat.");
                recvData.rfinish();
                return;
            }
        }

    // pussywizard:
    switch (type)
    {
    case CHAT_MSG_SAY:
    case CHAT_MSG_YELL:
    case CHAT_MSG_EMOTE:
    case CHAT_MSG_TEXT_EMOTE:
    case CHAT_MSG_AFK:
    case CHAT_MSG_DND:
        if (sender->IsSpectator())
        {
            recvData.rfinish();
            return;
        }
    }

    // prevent talking at unknown language (cheating)
    LanguageDesc const* langDesc = GetLanguageDescByID(lang);
    if (!langDesc)
    {
        SendNotification(LANG_UNKNOWN_LANGUAGE);
        recvData.rfinish();
        return;
    }
    if (langDesc->skill_id != 0 && !sender->HasSkill(langDesc->skill_id))
    {
        // also check SPELL_AURA_COMPREHEND_LANGUAGE (client offers option to speak in that language)
        Unit::AuraEffectList const& langAuras = sender->GetAuraEffectsByType(SPELL_AURA_COMPREHEND_LANGUAGE);
        bool foundAura = false;
        for (Unit::AuraEffectList::const_iterator i = langAuras.begin(); i != langAuras.end(); ++i)
        {
            if ((*i)->GetMiscValue() == int32(lang))
            {
                foundAura = true;
                break;
            }
        }
        if (!foundAura)
        {
            SendNotification(LANG_NOT_LEARNED_LANGUAGE);
            recvData.rfinish();
            return;
        }
    }

    if (lang == LANG_ADDON)
    {
        // LANG_ADDON is only valid for the following message types
        switch (type)
        {
        case CHAT_MSG_PARTY:
        case CHAT_MSG_RAID:
        case CHAT_MSG_GUILD:
        case CHAT_MSG_BATTLEGROUND:
        case CHAT_MSG_WHISPER:
            // check if addon messages are disabled
            if (!sWorld->getBoolConfig(CONFIG_ADDON_CHANNEL))
            {
                recvData.rfinish();
                return;
            }
            break;
        default:
            sLog->outError("Player %s (GUID: %u) sent a chatmessage with an invalid language/message type combination",
                           GetPlayer()->GetName().c_str(), GetPlayer()->GetGUIDLow());

            recvData.rfinish();
            return;
        }
    }
    // LANG_ADDON should not be changed nor be affected by flood control
    else
    {
        uint32 specialMessageLimit = 0;
        // send in universal language if player in .gmon mode (ignore spell effects)
        if (sender->IsGameMaster())
            lang = LANG_UNIVERSAL;
        else
        {
            // send in universal language in two side iteration allowed mode
            if (sWorld->getBoolConfig(CONFIG_ALLOW_TWO_SIDE_INTERACTION_CHAT))
                lang = LANG_UNIVERSAL;
            else
            {
                switch (type)
                {
                case CHAT_MSG_PARTY:
                case CHAT_MSG_PARTY_LEADER:
                case CHAT_MSG_RAID:
                case CHAT_MSG_RAID_LEADER:
                case CHAT_MSG_RAID_WARNING:
                    // allow two side chat at group channel if two side group allowed
                    if (sWorld->getBoolConfig(CONFIG_ALLOW_TWO_SIDE_INTERACTION_GROUP))
                        lang = LANG_UNIVERSAL;

                    specialMessageLimit = 35;
                    break;
                case CHAT_MSG_GUILD:
                case CHAT_MSG_OFFICER:
                    // allow two side chat at guild channel if two side guild allowed
                    if (sWorld->getBoolConfig(CONFIG_ALLOW_TWO_SIDE_INTERACTION_GUILD))
                        lang = LANG_UNIVERSAL;

                    specialMessageLimit = 15;
                    break;
                case CHAT_MSG_WHISPER:
                    if (sender->getLevel() >= 80)
                        specialMessageLimit = 15;
                    break;
                }
            }
            // but overwrite it by SPELL_AURA_MOD_LANGUAGE auras (only single case used)
            Unit::AuraEffectList const& ModLangAuras = sender->GetAuraEffectsByType(SPELL_AURA_MOD_LANGUAGE);
            if (!ModLangAuras.empty())
                lang = ModLangAuras.front()->GetMiscValue();
        }

        if (type != CHAT_MSG_AFK && type != CHAT_MSG_DND)
            sender->UpdateSpeakTime(specialMessageLimit);
    }

    // pussywizard: optimization
    /*if (sender->HasAura(1852) && type != CHAT_MSG_WHISPER)
    {
        SendNotification(GetTrinityString(LANG_GM_SILENCE), sender->GetName().c_str());
        recvData.rfinish();
        return;
    }*/

    std::string to, channel, msg;
    bool ignoreChecks = false;
    switch (type)
    {
    case CHAT_MSG_SAY:
    case CHAT_MSG_EMOTE:
    case CHAT_MSG_YELL:
    case CHAT_MSG_PARTY:
    case CHAT_MSG_PARTY_LEADER:
    case CHAT_MSG_GUILD:
    case CHAT_MSG_OFFICER:
    case CHAT_MSG_RAID:
    case CHAT_MSG_RAID_LEADER:
    case CHAT_MSG_RAID_WARNING:
    case CHAT_MSG_BATTLEGROUND:
    case CHAT_MSG_BATTLEGROUND_LEADER:
        recvData >> msg;
        break;
    case CHAT_MSG_WHISPER:
        recvData >> to;
        recvData >> msg;
        break;
    case CHAT_MSG_CHANNEL:
        recvData >> channel;
        recvData >> msg;
        break;
    case CHAT_MSG_AFK:
    case CHAT_MSG_DND:
        recvData >> msg;
        ignoreChecks = true;
        break;
    }

    // Strip invisible characters for non-addon messages
    if (lang != LANG_ADDON && sWorld->getBoolConfig(CONFIG_CHAT_FAKE_MESSAGE_PREVENTING))
        stripLineInvisibleChars(msg);

    // pussywizard:
    if (lang != LANG_ADDON && msg.find("|0") != std::string::npos)
        return;

    if (!ignoreChecks)
    {
        if (msg.empty())
            return;

        if (ChatHandler(this).ParseCommands(msg.c_str()))
            return;

        if (!_player->CanSpeak())
        {
            std::string timeStr = secsToTimeString(m_muteTime - time(NULL));
            SendNotification(GetTrinityString(LANG_WAIT_BEFORE_SPEAKING), timeStr.c_str());
            return;
        }

        if (lang != LANG_ADDON)
        {
            if (sWorld->getIntConfig(CONFIG_CHAT_STRICT_LINK_CHECKING_SEVERITY) && !ChatHandler(this).isValidChatMessage(msg.c_str()))
            {
                //sLog->outError("Player %s (GUID: %u) sent a chatmessage with an invalid link: %s", GetPlayer()->GetName().c_str(),
                //    GetPlayer()->GetGUIDLow(), msg.c_str());

                if (sWorld->getIntConfig(CONFIG_CHAT_STRICT_LINK_CHECKING_KICK))
                    KickPlayer();

                return;
            }
        }
    }

    // exploit
    size_t found1 = msg.find("|Hquest");
    if (found1 != std::string::npos)
    {
        size_t found2 = msg.find(":", found1+8);
        size_t found3 = msg.find("|", found1+8);
        if (found3 != std::string::npos)
        {
            if (found2 == std::string::npos)
                return;
            if (found2 > found3)
                return;
        }
    }


    switch (type)
    {
    case CHAT_MSG_SAY:
    case CHAT_MSG_EMOTE:
    case CHAT_MSG_YELL:
    {
        // Prevent cheating
        if (!sender->IsAlive())
            return;

        if (sender->getLevel() < sWorld->getIntConfig(CONFIG_CHAT_SAY_LEVEL_REQ))
        {
            SendNotification(GetTrinityString(LANG_SAY_REQ), sWorld->getIntConfig(CONFIG_CHAT_SAY_LEVEL_REQ));
            return;
        }

        if (type == CHAT_MSG_SAY)
            sender->Say(msg, lang);
        else if (type == CHAT_MSG_EMOTE)
            sender->TextEmote(msg);
        else if (type == CHAT_MSG_YELL)
            sender->Yell(msg, lang);
    }
    break;
    case CHAT_MSG_WHISPER:
    {
        if (sender->getLevel() < sWorld->getIntConfig(CONFIG_CHAT_WHISPER_LEVEL_REQ))
        {
            SendNotification(GetTrinityString(LANG_WHISPER_REQ), sWorld->getIntConfig(CONFIG_CHAT_WHISPER_LEVEL_REQ));
            return;
        }

        if (!normalizePlayerName(to))
        {
            SendPlayerNotFoundNotice(to);
            break;
        }

        Player* receiver = ObjectAccessor::FindPlayerByName(to, false);
        bool senderIsPlayer = AccountMgr::IsPlayerAccount(GetSecurity());
        bool receiverIsPlayer = AccountMgr::IsPlayerAccount(receiver ? receiver->GetSession()->GetSecurity() : SEC_PLAYER);
        if (!receiver || (senderIsPlayer && !receiverIsPlayer && !receiver->isAcceptWhispers() && !receiver->IsInWhisperWhiteList(sender->GetGUID())))
        {
            SendPlayerNotFoundNotice(to);
            return;
        }

        if (!sWorld->getBoolConfig(CONFIG_ALLOW_TWO_SIDE_INTERACTION_CHAT) && senderIsPlayer && receiverIsPlayer)
            if (GetPlayer()->GetTeamId() != receiver->GetTeamId())
            {
                SendWrongFactionNotice();
                return;
            }

        // pussywizard: optimization
        /*if (GetPlayer()->HasAura(1852) && !receiver->IsGameMaster())
        {
            SendNotification(GetTrinityString(LANG_GM_SILENCE), GetPlayer()->GetName().c_str());
            return;
        }*/

        // If player is a Gamemaster and doesn't accept whisper, we auto-whitelist every player that the Gamemaster is talking to
        if (!senderIsPlayer && !sender->isAcceptWhispers() && !sender->IsInWhisperWhiteList(receiver->GetGUID()))
            sender->AddWhisperWhiteList(receiver->GetGUID());

        GetPlayer()->Whisper(msg, lang, receiver->GetGUID());
    }
    break;
    case CHAT_MSG_PARTY:
    case CHAT_MSG_PARTY_LEADER:
    {
        // if player is in battleground, he cannot say to battleground members by /p
        Group* group = GetPlayer()->GetOriginalGroup();
        if (!group)
        {
            group = sender->GetGroup();
            if (!group || group->isBGGroup())
                return;
        }

        if (type == CHAT_MSG_PARTY_LEADER && !group->IsLeader(sender->GetGUID()))
            return;

        WorldPacket data;
        ChatHandler::BuildChatPacket(data, ChatMsg(type), Language(lang), sender, NULL, msg);
        group->BroadcastPacket(&data, false, group->GetMemberGroup(GetPlayer()->GetGUID()));
    }
    break;
    case CHAT_MSG_GUILD:
    {
        if (GetPlayer()->GetGuildId())
        {
            if (Guild* guild = sGuildMgr->GetGuildById(GetPlayer()->GetGuildId()))
            {
                guild->BroadcastToGuild(this, false, msg, lang == LANG_ADDON ? LANG_ADDON : LANG_UNIVERSAL);
            }
        }
    }
    break;
    case CHAT_MSG_OFFICER:
    {
        if (GetPlayer()->GetGuildId())
        {
            if (Guild* guild = sGuildMgr->GetGuildById(GetPlayer()->GetGuildId()))
            {
                guild->BroadcastToGuild(this, true, msg, lang == LANG_ADDON ? LANG_ADDON : LANG_UNIVERSAL);
            }
        }
    }
    break;
    case CHAT_MSG_RAID:
    {
        // if player is in battleground, he cannot say to battleground members by /ra
        Group* group = GetPlayer()->GetOriginalGroup();
        if (!group)
        {
            group = GetPlayer()->GetGroup();
            if (!group || group->isBGGroup() || !group->isRaidGroup())
                return;
        }

        WorldPacket data;
        ChatHandler::BuildChatPacket(data, CHAT_MSG_RAID, Language(lang), sender, NULL, msg);
        group->BroadcastPacket(&data, false);
    }
    break;
    case CHAT_MSG_RAID_LEADER:
    {
        // if player is in battleground, he cannot say to battleground members by /ra
        Group* group = GetPlayer()->GetOriginalGroup();
        if (!group)
        {
            group = GetPlayer()->GetGroup();
            if (!group || group->isBGGroup() || !group->isRaidGroup() || !group->IsLeader(sender->GetGUID()))
                return;
        }

        WorldPacket data;
        ChatHandler::BuildChatPacket(data, CHAT_MSG_RAID_LEADER, Language(lang), sender, NULL, msg);
        group->BroadcastPacket(&data, false);
    }
    break;
    case CHAT_MSG_RAID_WARNING:
    {
        Group* group = GetPlayer()->GetGroup();
        if (!group || !group->isRaidGroup() || !(group->IsLeader(GetPlayer()->GetGUID()) || group->IsAssistant(GetPlayer()->GetGUID())) || group->isBGGroup())
            return;

        WorldPacket data;
        //in battleground, raid warning is sent only to players in battleground - code is ok
        ChatHandler::BuildChatPacket(data, CHAT_MSG_RAID_WARNING, Language(lang), sender, NULL, msg);
        group->BroadcastPacket(&data, false);
    }
    break;
    case CHAT_MSG_BATTLEGROUND:
    {
        //battleground raid is always in Player->GetGroup(), never in GetOriginalGroup()
        Group* group = GetPlayer()->GetGroup();
        if (!group || !group->isBGGroup())
            return;

        WorldPacket data;
        ChatHandler::BuildChatPacket(data, CHAT_MSG_BATTLEGROUND, Language(lang), sender, NULL, msg);
        group->BroadcastPacket(&data, false);
    }
    break;
    case CHAT_MSG_BATTLEGROUND_LEADER:
    {
        // battleground raid is always in Player->GetGroup(), never in GetOriginalGroup()
        Group* group = GetPlayer()->GetGroup();
        if (!group || !group->isBGGroup() || !group->IsLeader(GetPlayer()->GetGUID()))
            return;

        WorldPacket data;
        ChatHandler::BuildChatPacket(data, CHAT_MSG_BATTLEGROUND_LEADER, Language(lang), sender, NULL, msg);
        group->BroadcastPacket(&data, false);
    }
    break;
    case CHAT_MSG_CHANNEL:
    {
        if (AccountMgr::IsPlayerAccount(GetSecurity()))
        {
            if (sender->getLevel() < sWorld->getIntConfig(CONFIG_CHAT_CHANNEL_LEVEL_REQ))
            {
                SendNotification(GetTrinityString(LANG_CHANNEL_REQ), sWorld->getIntConfig(CONFIG_CHAT_CHANNEL_LEVEL_REQ));
                return;
            }
        }

        if (ChannelMgr* cMgr = ChannelMgr::forTeam(sender->GetTeamId()))
        {
            if (Channel* chn = cMgr->GetChannel(channel, sender))
            {
                chn->Say(sender->GetGUID(), msg.c_str(), lang);
            }
        }
    }
    break;
    case CHAT_MSG_AFK:
    {
        if (!sender->IsInCombat())
        {
            if (sender->isAFK())                       // Already AFK
            {
                if (msg.empty())
                    sender->ToggleAFK();               // Remove AFK
                else
                    sender->autoReplyMsg = msg;        // Update message
            }
            else                                        // New AFK mode
            {
                sender->autoReplyMsg = msg.empty() ? GetTrinityString(LANG_PLAYER_AFK_DEFAULT) : msg;

                if (sender->isDND())
                    sender->ToggleDND();

                sender->ToggleAFK();
            }
        }
        break;
    }
    case CHAT_MSG_DND:
    {
        if (sender->isDND())                           // Already DND
        {
            if (msg.empty())
                sender->ToggleDND();                   // Remove DND
            else
                sender->autoReplyMsg = msg;            // Update message
        }
        else                                            // New DND mode
        {
            sender->autoReplyMsg = msg.empty() ? GetTrinityString(LANG_PLAYER_DND_DEFAULT) : msg;

            if (sender->isAFK())
                sender->ToggleAFK();

            sender->ToggleDND();
        }

        break;
    }
    default:
        sLog->outError("CHAT: unknown message type %u, lang: %u", type, lang);
        break;
    }
}
Example #23
0
void WorldSession::HandleSendMail(WorldPacket & recvData)
{
    uint64 mailbox, unk3;
    std::string receiver, subject, body;
    uint32 unk1, unk2, money, COD;
    uint8 unk4;
    recvData >> mailbox;
    recvData >> receiver;

    recvData >> subject;

    recvData >> body;

    recvData >> unk1;                                      // stationery?
    recvData >> unk2;                                      // 0x00000000

    uint8 items_count;
    recvData >> items_count;                               // attached items count

    if (items_count > MAX_MAIL_ITEMS)                       // client limit
    {
        GetPlayer()->SendMailResult(0, MAIL_SEND, MAIL_ERR_TOO_MANY_ATTACHMENTS);
        recvData.rfinish();                   // set to end to avoid warnings spam
        return;
    }

    uint64 itemGUIDs[MAX_MAIL_ITEMS];

    for (uint8 i = 0; i < items_count; ++i)
    {
        recvData.read_skip<uint8>();                       // item slot in mail, not used
        recvData >> itemGUIDs[i];
    }

    recvData >> money >> COD;                              // money and cod
    recvData >> unk3;                                      // const 0
    recvData >> unk4;                                      // const 0

    // packet read complete, now do check

    if (!CanOpenMailBox(mailbox))
        return;

    if (receiver.empty())
        return;

    Player* player = _player;

    if (player->getLevel() < sWorld->getIntConfig(CONFIG_MAIL_LEVEL_REQ))
    {
        SendNotification(GetTrinityString(LANG_MAIL_SENDER_REQ), sWorld->getIntConfig(CONFIG_MAIL_LEVEL_REQ));
        return;
    }

    uint64 rc = 0;
    if (normalizePlayerName(receiver))
        rc = sObjectMgr->GetPlayerGUIDByName(receiver);

    if (!rc)
    {
        ;//sLog->outDetail("Player %u is sending mail to %s (GUID: not existed!) with subject %s and body %s includes %u items, %u copper and %u COD copper with unk1 = %u, unk2 = %u",
        //    player->GetGUIDLow(), receiver.c_str(), subject.c_str(), body.c_str(), items_count, money, COD, unk1, unk2);
        player->SendMailResult(0, MAIL_SEND, MAIL_ERR_RECIPIENT_NOT_FOUND);
        return;
    }

    ;//sLog->outDetail("Player %u is sending mail to %s (GUID: %u) with subject %s and body %s includes %u items, %u copper and %u COD copper with unk1 = %u, unk2 = %u", player->GetGUIDLow(), receiver.c_str(), GUID_LOPART(rc), subject.c_str(), body.c_str(), items_count, money, COD, unk1, unk2);

    if (player->GetGUID() == rc)
    {
        player->SendMailResult(0, MAIL_SEND, MAIL_ERR_CANNOT_SEND_TO_SELF);
        return;
    }

    uint32 cost = items_count ? 30 * items_count : 30;  // price hardcoded in client

    uint32 reqmoney = cost + money;
  
    // Check for overflow
    if (reqmoney < money)
    {
        player->SendMailResult(0, MAIL_SEND, MAIL_ERR_NOT_ENOUGH_MONEY);
        return;
    }

    if (!player->HasEnoughMoney(reqmoney))
    {
        player->SendMailResult(0, MAIL_SEND, MAIL_ERR_NOT_ENOUGH_MONEY);
        return;
    }

    Player* receive = ObjectAccessor::FindPlayerInOrOutOfWorld(rc);

    uint32 rc_teamId = TEAM_NEUTRAL;
    uint16 mails_count = 0;                                  //do not allow to send to one player more than 100 mails

    if (receive)
    {
        rc_teamId = receive->GetTeamId();
        mails_count = receive->GetMailSize();
    }
    else
    {
		// xinef: get data from global storage
		if (GlobalPlayerData const* playerData = sWorld->GetGlobalPlayerData(GUID_LOPART(rc)))
		{
			rc_teamId = Player::TeamIdForRace(playerData->race);
			mails_count = playerData->mailCount;
        }
    }
    //do not allow to have more than 100 mails in mailbox.. mails count is in opcode uint8!!! - so max can be 255..
    if (mails_count > 100)
    {
        player->SendMailResult(0, MAIL_SEND, MAIL_ERR_RECIPIENT_CAP_REACHED);
        return;
    }
    // test the receiver's Faction... or all items are account bound
	// Xinef: check for boa items, not used currently
    /*bool accountBound = items_count && !money && !COD ? true : false;
    for (uint8 i = 0; i < items_count; ++i)
    {
        Item* item = player->GetItemByGuid(itemGUIDs[i]);
        if (item)
        {
            ItemTemplate const* itemProto = item->GetTemplate();
            if (!itemProto || !(itemProto->Flags & ITEM_PROTO_FLAG_BIND_TO_ACCOUNT))
            {
                accountBound = false;
                break;
            }
        }
    }*/

    uint32 rc_account = receive
        ? receive->GetSession()->GetAccountId()
        : sObjectMgr->GetPlayerAccountIdByGUID(rc);

	if (/*!accountBound*/ GetAccountId() != rc_account && !sWorld->getBoolConfig(CONFIG_ALLOW_TWO_SIDE_INTERACTION_MAIL) && player->GetTeamId() != rc_teamId && AccountMgr::IsPlayerAccount(GetSecurity()))
    {
        player->SendMailResult(0, MAIL_SEND, MAIL_ERR_NOT_YOUR_TEAM);
        return;
    }

    Item* items[MAX_MAIL_ITEMS];

    for (uint8 i = 0; i < items_count; ++i)
    {
        if (!itemGUIDs[i])
        {
            player->SendMailResult(0, MAIL_SEND, MAIL_ERR_MAIL_ATTACHMENT_INVALID);
            return;
        }

        Item* item = player->GetItemByGuid(itemGUIDs[i]);

        // prevent sending bag with items (cheat: can be placed in bag after adding equipped empty bag to mail)
        if (!item)
        {
            player->SendMailResult(0, MAIL_SEND, MAIL_ERR_MAIL_ATTACHMENT_INVALID);
            return;
        }

        if (!item->CanBeTraded(true))
        {
            player->SendMailResult(0, MAIL_SEND, MAIL_ERR_EQUIP_ERROR, EQUIP_ERR_MAIL_BOUND_ITEM);
            return;
        }

        if (item->IsBoundAccountWide() && item->IsSoulBound() && GetAccountId() != rc_account)
        {
            player->SendMailResult(0, MAIL_SEND, MAIL_ERR_EQUIP_ERROR, EQUIP_ERR_ARTEFACTS_ONLY_FOR_OWN_CHARACTERS);
            return;
        }

        if (item->GetTemplate()->Flags & ITEM_PROTO_FLAG_CONJURED || item->GetUInt32Value(ITEM_FIELD_DURATION))
        {
            player->SendMailResult(0, MAIL_SEND, MAIL_ERR_EQUIP_ERROR, EQUIP_ERR_MAIL_BOUND_ITEM);
            return;
        }

        if (COD && item->HasFlag(ITEM_FIELD_FLAGS, ITEM_FLAG_WRAPPED))
        {
            player->SendMailResult(0, MAIL_SEND, MAIL_ERR_CANT_SEND_WRAPPED_COD);
            return;
        }

        if (item->IsNotEmptyBag())
        {
            player->SendMailResult(0, MAIL_SEND, MAIL_ERR_EQUIP_ERROR, EQUIP_ERR_CAN_ONLY_DO_WITH_EMPTY_BAGS);
            return;
        }

        items[i] = item;
    }

    player->SendMailResult(0, MAIL_SEND, MAIL_OK);

    player->ModifyMoney(-int32(reqmoney));
    player->UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_GOLD_SPENT_FOR_MAIL, cost);

    bool needItemDelay = false;

    MailDraft draft(subject, body);

    SQLTransaction trans = CharacterDatabase.BeginTransaction();

    if (items_count > 0 || money > 0)
    {
        if (items_count > 0)
        {
            for (uint8 i = 0; i < items_count; ++i)
            {
                Item* item = items[i];

                item->SetNotRefundable(GetPlayer()); // makes the item no longer refundable
                player->MoveItemFromInventory(items[i]->GetBagSlot(), item->GetSlot(), true);

                item->DeleteFromInventoryDB(trans);     // deletes item from character's inventory
				if (item->GetState() == ITEM_UNCHANGED)
					item->FSetState(ITEM_CHANGED);		// pussywizard: so the item will be saved and owner will be updated in database
                item->SetOwnerGUID(rc);
                item->SaveToDB(trans);                  // recursive and not have transaction guard into self, item not in inventory and can be save standalone

                draft.AddItem(item);
            }

            // if item send to character at another account, then apply item delivery delay
            needItemDelay = GetAccountId() != rc_account;
        }

		if( money >= 10*GOLD )
		{
			CleanStringForMysqlQuery(subject);
			CharacterDatabase.PExecute("INSERT INTO log_money VALUES(%u, %u, \"%s\", \"%s\", %u, \"%s\", %u, \"<MAIL> %s\", NOW())", GetAccountId(), player->GetGUIDLow(), player->GetName().c_str(), player->GetSession()->GetRemoteAddress().c_str(), rc_account, receiver.c_str(), money, subject.c_str());
		}
    }

    // If theres is an item, there is a one hour delivery delay if sent to another account's character.
    uint32 deliver_delay = needItemDelay ? sWorld->getIntConfig(CONFIG_MAIL_DELIVERY_DELAY) : 0;
  
    // don't ask for COD if there are no items
    if (items_count == 0)
        COD = 0;

    // will delete item or place to receiver mail list
    draft
        .AddMoney(money)
        .AddCOD(COD)
        .SendMailTo(trans, MailReceiver(receive, GUID_LOPART(rc)), MailSender(player), body.empty() ? MAIL_CHECK_MASK_COPIED : MAIL_CHECK_MASK_HAS_BODY, deliver_delay);

    player->SaveInventoryAndGoldToDB(trans);
    CharacterDatabase.CommitTransaction(trans);
}
void BattlefieldWG::OnCreatureCreate(Creature* creature)
{
    // Accessing to db spawned creatures
    switch (creature->GetEntry())
    {
        case NPC_DWARVEN_SPIRIT_GUIDE:
        case NPC_TAUNKA_SPIRIT_GUIDE:
        {
            TeamId teamId = (creature->GetEntry() == NPC_DWARVEN_SPIRIT_GUIDE ? TEAM_ALLIANCE : TEAM_HORDE);
            uint8 graveyardId = GetSpiritGraveyardId(creature->GetAreaId());
            if (m_GraveyardList[graveyardId])
                m_GraveyardList[graveyardId]->SetSpirit(creature, teamId);
            break;
        }
    }

    // untested code - not sure if it is valid.
    if (IsWarTime())
    {
        switch (creature->GetEntry())
        {
            case NPC_WINTERGRASP_SIEGE_ENGINE_ALLIANCE:
            case NPC_WINTERGRASP_SIEGE_ENGINE_HORDE:
            case NPC_WINTERGRASP_CATAPULT:
            case NPC_WINTERGRASP_DEMOLISHER:
            {
                if (!creature->ToTempSummon() || !creature->ToTempSummon()->GetSummonerGUID() || !sObjectAccessor->FindPlayer(creature->ToTempSummon()->GetSummonerGUID()))
                {
                    creature->DespawnOrUnsummon();
                    return;
                }

                Player* creator = sObjectAccessor->FindPlayer(creature->ToTempSummon()->GetSummonerGUID());
                TeamId team = creator->GetTeamId();

                if (team == TEAM_HORDE)
                {
                    if (GetData(BATTLEFIELD_WG_DATA_VEHICLE_H) < GetData(BATTLEFIELD_WG_DATA_MAX_VEHICLE_H))
                    {
                        UpdateData(BATTLEFIELD_WG_DATA_VEHICLE_H, 1);
                        creature->AddAura(SPELL_HORDE_FLAG, creature);
                        m_vehicles[team].insert(creature->GetGUID());
                        UpdateVehicleCountWG();
                    }
                    else
                    {
                        creature->DespawnOrUnsummon();
                        return;
                    }
                }
                else
                {
                    if (GetData(BATTLEFIELD_WG_DATA_VEHICLE_A) < GetData(BATTLEFIELD_WG_DATA_MAX_VEHICLE_A))
                    {
                        UpdateData(BATTLEFIELD_WG_DATA_VEHICLE_A, 1);
                        creature->AddAura(SPELL_ALLIANCE_FLAG, creature);
                        m_vehicles[team].insert(creature->GetGUID());
                        UpdateVehicleCountWG();
                    }
                    else
                    {
                        creature->DespawnOrUnsummon();
                        return;
                    }
                }

                creature->CastSpell(creator, SPELL_GRAB_PASSENGER, true);
                break;
            }
        }
    }
}
Example #25
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 #26
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){
void WorldSession::HandleGuildFinderBrowse(WorldPacket& recvPacket)
{
    sLog->outDebug(LOG_FILTER_NETWORKIO, "WORLD: Received CMSG_LF_GUILD_BROWSE");

    uint32 classRoles = 0;
    uint32 availability = 0;
    uint32 guildInterests = 0;
    uint32 playerLevel = 0; // Raw player level (1-90), do they use MAX_FINDER_LEVEL when on level 90 ?

	recvPacket >> playerLevel >> availability >> classRoles >> guildInterests;

    Player* player = GetPlayer();

    LFGuildPlayer settings(player->GetGUIDLow(), classRoles, availability, guildInterests, ANY_FINDER_LEVEL);
    LFGuildStore guildList = sGuildFinderMgr->GetGuildsMatchingSetting(settings, player->GetTeamId());
    uint32 guildCount = guildList.size();

    if (guildCount == 0)
    {
        WorldPacket packet(SMSG_LF_GUILD_BROWSE_UPDATED);
        packet.WriteBits(0, 18);
        player->SendDirectMessage(&packet);
        return;
    }

    bool returned = false;

    if (!(classRoles & GUILDFINDER_ALL_ROLES) || classRoles > GUILDFINDER_ALL_ROLES)
        returned = true;
    if (!(availability & ALL_WEEK) || availability > ALL_WEEK)
        returned = true;
    if (!(guildInterests & ALL_INTERESTS) || guildInterests > ALL_INTERESTS)
        returned = true;
    if (playerLevel > sWorld->getIntConfig(CONFIG_MAX_PLAYER_LEVEL) || playerLevel < 1)
        returned = true;

    if (returned)
    {
        WorldPacket packet(SMSG_LF_GUILD_BROWSE_UPDATED);
        packet.WriteBits(0, 18);
        player->SendDirectMessage(&packet);
        return;
    }

    ByteBuffer bufferData;
    WorldPacket data(SMSG_LF_GUILD_BROWSE_UPDATED);

    data.WriteBits(guildCount, 18);

    for (LFGuildStore::const_iterator itr = guildList.begin(); itr != guildList.end(); ++itr)
    {
        LFGuildSettings guildSettings = itr->second;
        Guild* guild = sGuildMgr->GetGuildById(itr->first);

        ObjectGuid guildGUID = ObjectGuid(guild->GetGUID());

		data.WriteBit(guildGUID[6]);
		data.WriteBit(guildGUID[5]);
        data.WriteBit(guildGUID[4]);
        data.WriteBit(guildGUID[0]);
        data.WriteBit(guildGUID[1]);
        data.WriteBits(guildSettings.GetComment().size(), 10);
        data.WriteBit(guildGUID[3]);

		data.WriteBits(guild->GetName().size(), 7);

        data.WriteBit(guildGUID[7]);
        data.WriteBit(guildGUID[2]);

		bufferData.WriteByteSeq(guildGUID[3]);
		bufferData << uint32(guild->GetEmblemInfo().GetStyle());
		bufferData << uint8(sGuildFinderMgr->HasRequest(player->GetGUIDLow(), guild->GetGUID()));

		bufferData.WriteByteSeq(guildGUID[0]);

		bufferData << uint32(guild->GetAchievementMgr().GetAchievementPoints());

		bufferData.WriteByteSeq(guildGUID[2]);

		bufferData << uint32(guildSettings.GetInterests());
		bufferData << int32(guild->GetEmblemInfo().GetBackgroundColor());
		bufferData << guild->GetLevel();
		bufferData << uint32(guildSettings.GetAvailability());
		bufferData << uint32(guildSettings.GetClassRoles());

		bufferData.WriteByteSeq(guildGUID[5]);
		bufferData << uint32(0);                                                              // Unk

		if (guild->GetName().size() > 0)
			bufferData.append(guild->GetName().c_str(), guild->GetName().size());

		bufferData << uint32(0);                                                              // Unk
		bufferData << uint32(guild->GetEmblemInfo().GetBorderStyle());
		bufferData.WriteByteSeq(guildGUID[7]);
		bufferData << uint32(guild->GetEmblemInfo().GetColor());
		bufferData.WriteByteSeq(guildGUID[6]);
		bufferData << uint32(0);                                                              // Unk

		if (guildSettings.GetComment().size() > 0)
			bufferData.append(guildSettings.GetComment().c_str(), guildSettings.GetComment().size());

		bufferData << uint32(guild->GetEmblemInfo().GetBorderColor());
		bufferData << uint32(guild->GetMembersCount());

        bufferData.WriteByteSeq(guildGUID[1]);
        bufferData.WriteByteSeq(guildGUID[4]);

    }

    data.FlushBits();
    data.append(bufferData);

    player->SendDirectMessage(&data);
}
Example #28
0
void WorldSession::HandleGuildFinderBrowse(WorldPacket& recvPacket)
{
    TC_LOG_DEBUG("network", "WORLD: Received CMSG_LF_GUILD_BROWSE");

    uint32 classRoles = 0;
    uint32 availability = 0;
    uint32 guildInterests = 0;
    uint32 playerLevel = 0;

    recvPacket >> playerLevel >> guildInterests >> availability >> classRoles;

    Player* player = GetPlayer();

    LFGuildPlayer settings(player->GetGUIDLow(), classRoles, availability, guildInterests, ANY_FINDER_LEVEL);
    LFGuildStore guildList = sGuildFinderMgr->GetGuildsMatchingSetting(settings, player->GetTeamId());
    uint32 guildCount = guildList.size();

    if (guildCount == 0)
    {
        WorldPacket packet(SMSG_LF_GUILD_BROWSE_UPDATED);
        packet.WriteBits(0, 18);
        packet.FlushBits();
        player->SendDirectMessage(&packet);
        return;
    }

    bool returned = false;

    if (!(classRoles & GUILDFINDER_ALL_ROLES) || classRoles > GUILDFINDER_ALL_ROLES)
        returned = true;
    if (!(availability & ALL_WEEK) || availability > ALL_WEEK)
        returned = true;
    if (!(guildInterests & ALL_INTERESTS) || guildInterests > ALL_INTERESTS)
        returned = true;
    if (playerLevel > sWorld->getIntConfig(CONFIG_MAX_PLAYER_LEVEL) || playerLevel < 1)
        returned = true;

    if (returned)
    {
        WorldPacket packet(SMSG_LF_GUILD_BROWSE_UPDATED);
        packet.WriteBits(0, 18);
        packet.FlushBits();
        player->SendDirectMessage(&packet);
        return;
    }

    ByteBuffer bufferData;
    WorldPacket data(SMSG_LF_GUILD_BROWSE_UPDATED);

    data.WriteBits(guildCount, 18);

    for (LFGuildStore::const_iterator itr = guildList.begin(); itr != guildList.end(); ++itr)
    {
        LFGuildSettings guildSettings = itr->second;
        Guild* guild = sGuildMgr->GetGuildById(itr->first);

        ObjectGuid guildGUID = ObjectGuid(guild->GetGUID());

        data.WriteBitSeq<4>(guildGUID);
        data.WriteBits(guild->GetName().size(), 7);
        data.WriteBitSeq<0, 1>(guildGUID);
        data.WriteBits(guildSettings.GetComment().size(), 10);
        data.WriteBitSeq<2, 7, 3, 6, 5>(guildGUID);

        bufferData << uint8(sGuildFinderMgr->HasRequest(player->GetGUIDLow(), guild->GetGUID()));
        bufferData << uint32(guild->GetLevel());
        bufferData << uint32(guildSettings.GetInterests());
        bufferData << uint32(0);                                                                    // Unk
        bufferData << uint32(guild->GetEmblemInfo().GetBorderStyle());
        bufferData.WriteByteSeq<1, 4>(guildGUID);
        bufferData << uint32(guild->GetEmblemInfo().GetStyle());
        bufferData.WriteByteSeq<3>(guildGUID);
        bufferData << uint32(50397223);                                                             // Unk Flags
        bufferData << uint32(guild->GetEmblemInfo().GetColor());
        bufferData.WriteString(guild->GetName());
        bufferData << uint32(guildSettings.GetClassRoles());
        bufferData << uint32(guildSettings.GetAvailability());
        bufferData.WriteString(guildSettings.GetComment());
        bufferData.WriteByteSeq<6, 7>(guildGUID);
        bufferData << uint8(0);                                                                     // Cached
        bufferData.WriteByteSeq<5, 0>(guildGUID);
        bufferData << uint32(guild->GetEmblemInfo().GetBorderColor());
        bufferData << uint32(guild->GetMembersCount());
        bufferData << uint32(guild->GetAchievementMgr().GetAchievementPoints());
        bufferData.WriteByteSeq<2>(guildGUID);
        bufferData << int32(guild->GetEmblemInfo().GetBackgroundColor());
    }

    data.FlushBits();
    data.append(bufferData);

    player->SendDirectMessage(&data);
}
Example #29
0
		void Player::FireWeapon() {
			SPADES_MARK_FUNCTION();
			
			Vector3 muzzle = GetEye();
			muzzle += GetFront() * 0.01f;/*
			muzzle += GetRight() * 0.4f;
			muzzle -= GetUp() * 0.3f;*/
			
			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() * 2.f - 1.f) * spread;
				dir2.y += (GetRandom() * 2.f - 1.f) * spread;
				dir2.z += (GetRandom() * 2.f - 1.f) * spread;
				Vector3 dir = dir2.Normalize();
				
				// first do map raycast
				GameMap::RayCastResult mapResult;
				mapResult = map->CastRay2(muzzle,
										  dir,
										  500);
				
				Player *hitPlayer = NULL;
				float hitPlayerDistance = 0.f;
				int hitFlag = 0;
				
				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;
					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){
							if(hitPlayer != other){
								hitPlayer = other;
								hitFlag = 0;
							}
							hitPlayerDistance = dist;
							hitFlag = 1; // head
						}
					}
					if(hb.torso.RayCast(muzzle, dir, &hitPos)) {
						float dist = (hitPos - muzzle).GetLength();
						if(hitPlayer == NULL ||
						   dist < hitPlayerDistance){
							if(hitPlayer != other){
								hitPlayer = other;
								hitFlag = 0;
							}
							hitPlayerDistance = dist;
							hitFlag = 2; // 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){
								if(hitPlayer != other){
									hitPlayer = other;
									hitFlag = 0;
								}
								hitPlayerDistance = dist;
								if(j == 2)
									hitFlag = 8; // arms
								else
									hitFlag = 4; // leg
							}
						}
					}
				}
				
				Vector3 finalHitPos;
				finalHitPos = muzzle + dir * 128.f;
				
				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 < 62){
							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){
Example #30
0
		World::WeaponRayCastResult World::WeaponRayCast(spades::Vector3 startPos,
														spades::Vector3 dir,
														Player *exclude) {
			WeaponRayCastResult result;
			Player *hitPlayer = NULL;
			float hitPlayerDistance = 0.f;
			int hitFlag = 0;
			
			for(int i = 0; i < (int)players.size(); i++){
				Player *p = players[i];
				if(p == NULL || p == exclude)
					continue;
				if(p->GetTeamId() >= 2 || !p->IsAlive())
					continue;
				if(!p->RayCastApprox(startPos, dir))
					continue;
				
				Player::HitBoxes hb = p->GetHitBoxes();
				Vector3 hitPos;
				
				if(hb.head.RayCast(startPos, dir, &hitPos)) {
					float dist = (hitPos - startPos).GetLength();
					if(hitPlayer == NULL ||
					   dist < hitPlayerDistance){
						if(hitPlayer != p){
							hitPlayer = p;
							hitFlag = 0;
						}
						hitPlayerDistance = dist;
						hitFlag |= 1; // head
					}
				}
				if(hb.torso.RayCast(startPos, dir, &hitPos)) {
					float dist = (hitPos - startPos).GetLength();
					if(hitPlayer == NULL ||
					   dist < hitPlayerDistance){
						if(hitPlayer != p){
							hitPlayer = p;
							hitFlag = 0;
						}
						hitPlayerDistance = dist;
						hitFlag |= 2; // torso
					}
				}
				for(int j = 0; j < 3 ;j++){
					if(hb.limbs[j].RayCast(startPos, dir, &hitPos)) {
						float dist = (hitPos - startPos).GetLength();
						if(hitPlayer == NULL ||
						   dist < hitPlayerDistance){
							if(hitPlayer != p){
								hitPlayer = p;
								hitFlag = 0;
							}
							hitPlayerDistance = dist;
							if(j == 2)
								hitFlag |= 8; // arms
							else
								hitFlag |= 4; // leg
						}
					}
				}
			}
			
			// map raycast
			GameMap::RayCastResult res2;
			res2 = map->CastRay2(startPos, dir, 256);
			
			if(res2.hit && (hitPlayer == NULL ||
							(res2.hitPos - startPos).GetLength() <
							hitPlayerDistance)){
				result.hit = true;
				result.startSolid = res2.startSolid;
				result.player = NULL;
				result.blockPos = res2.hitBlock;
				result.hitPos = res2.hitPos;
			}else if(hitPlayer) {
				result.hit = true;
				result.startSolid = false; // FIXME: startSolid for player
				result.player = hitPlayer;
				result.hitPos = startPos + dir * hitPlayerDistance;
			}else{
				result.hit = false;
			}
			
			return result;
		}