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; } }
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; }
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; }
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); }
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); }
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; } }
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; }
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(); }
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(); } }
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); } } }
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); } }
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); }
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); }
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; } }
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; } } } }
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); } } }
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); }
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); }
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){
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; }