// returns Guid of lowest percentage health friendly party or raid target within sqrt('dist') yards uint64 Spell::FindLowestHealthRaidMember(Player* Target, uint32 dist) { if(!Target || !Target->IsInWorld()) return 0; uint64 lowestHealthTarget = Target->GetGUID(); uint32 lowestHealthPct = Target->GetHealthPct(); Group *group = Target->GetGroup(); if(group) { group->Lock(); for(uint32 j = 0; j < group->GetSubGroupCount(); ++j) { for(GroupMembersSet::iterator itr = group->GetSubGroup(j)->GetGroupMembersBegin(); itr != group->GetSubGroup(j)->GetGroupMembersEnd(); itr++) { if((*itr)->m_loggedInPlayer && Target->GetDistance2dSq((*itr)->m_loggedInPlayer) <= dist) { uint32 healthPct = (*itr)->m_loggedInPlayer->GetHealthPct(); if(healthPct < lowestHealthPct) { lowestHealthPct = healthPct; lowestHealthTarget = (*itr)->m_loggedInPlayer->GetGUID(); } } } } group->Unlock(); } return lowestHealthTarget; }
// Spell Target Handling for type 56: Target all raid members. (WotLK) void Spell::SpellTargetAllRaid( uint32 i, uint32 j ) { if( !m_caster->IsInWorld() || !m_caster->IsUnit() ) return; TargetsList* tmpMap = &m_targetUnits[i]; SafeAddTarget( tmpMap, m_caster->GetGUID() ); Group * group = static_cast< Unit* >( m_caster )->GetGroup(); if( group == NULL ) return; uint32 count = group->GetSubGroupCount(); // Loop through each raid group. group->Lock(); for( uint8 k = 0; k < count; k++ ) { SubGroup * subgroup = group->GetSubGroup( k ); if( subgroup ) { for( GroupMembersSet::iterator itr = subgroup->GetGroupMembersBegin(); itr != subgroup->GetGroupMembersEnd(); ++itr ) { if( (*itr)->m_loggedInPlayer && (*itr)->m_loggedInPlayer != m_caster) SafeAddTarget( tmpMap,(*itr)->m_loggedInPlayer->GetGUID() ); } } } group->Unlock(); }
void WorldSession::HandleLootOpcode( WorldPacket & recv_data ) { if(!_player->IsInWorld()) return; uint64 guid; recv_data >> guid; if(_player->isCasting()) _player->InterruptSpell(); if(_player->InGroup() && !_player->m_bgInBattleground) { Group * party = _player->GetGroup(); if(party) { if(party->GetMethod() == PARTY_LOOT_MASTER) { WorldPacket data(SMSG_LOOT_MASTER_LIST, 330); // wont be any larger data << (uint8)party->MemberCount(); uint32 real_count = 0; SubGroup *s; GroupMembersSet::iterator itr; for(uint32 i = 0; i < party->GetSubGroupCount(); ++i) { s = party->GetSubGroup(i); for(itr = s->GetGroupMembersBegin(); itr != s->GetGroupMembersEnd(); ++itr) { if(_player->GetZoneId() == (*itr)->GetZoneId()) { data << (*itr)->GetGUID(); ++real_count; } } } *(uint8*)&data.contents()[0] = real_count; party->SendPacketToAll(&data); } /* //this commented code is not used because it was never tested and finished ! else if(party->GetMethod() == PARTY_LOOT_RR) { Creature *target=GetPlayer()->GetMapMgr()->GetCreature(guid); //maybe we should extend this to other object types too if(target) { if(target->TaggerGuid==GetPlayer()->GetGUID()) GetPlayer()->SendLoot(guid,1); else return; } }*/ } } GetPlayer()->SendLoot(guid,1); }
void HonorHandler::OnPlayerKilledUnit( Player *pPlayer, Unit* pVictim ) { if( pVictim == NULL || pPlayer == NULL ) return; if( pPlayer->GetTypeId() != TYPEID_PLAYER || !pVictim->IsUnit() ) return; if( !pVictim->IsPlayer() || static_cast< Player* >( pVictim )->m_honorless ) return; if( pVictim->IsPlayer() ) { if( pPlayer->m_bg ) { if( static_cast< Player* >( pVictim )->m_bgTeam == pPlayer->m_bgTeam ) return; // patch 2.4, players killed >50 times in battlegrounds won't be worth honor for the rest of that bg if( static_cast<Player*>(pVictim)->m_bgScore.Deaths >= 50 ) return; } else { if( pPlayer->GetTeam() == static_cast< Player* >( pVictim )->GetTeam() ) return; } } // Calculate points int32 Points = 0; if(pVictim->IsPlayer() && pPlayer != pVictim) Points = CalculateHonorPointsForKill( pPlayer->getLevel(), pVictim->getLevel() ); if( Points > 0 ) { if( pPlayer->m_bg ) { // hackfix for battlegrounds (since the groups there are disabled, we need to do this manually) vector<Player*> toadd; uint32 t = pPlayer->m_bgTeam; toadd.reserve(15); // shouldn't have more than this pPlayer->m_bg->Lock(); set<Player*> * s = &pPlayer->m_bg->m_players[t]; for(set<Player*>::iterator itr = s->begin(); itr != s->end(); ++itr) { // Also check that the player is in range, and the player is alive. if((*itr) == pPlayer || ((*itr)->isAlive() && (*itr)->isInRange(pPlayer,100.0f))) toadd.push_back(*itr); } if( toadd.size() > 0 ) { uint32 pts = Points / (uint32)toadd.size(); for(vector<Player*>::iterator vtr = toadd.begin(); vtr != toadd.end(); ++vtr) { AddHonorPointsToPlayer(*vtr, pts); (*vtr)->m_killsToday++; (*vtr)->m_killsLifetime++; pPlayer->m_bg->HookOnHK(*vtr); if(pVictim) { // Send PVP credit WorldPacket data(SMSG_PVP_CREDIT, 12); uint32 pvppoints = pts * 10; data << pvppoints << pVictim->GetGUID() << uint32(static_cast< Player* >(pVictim)->GetPVPRank()); (*vtr)->GetSession()->SendPacket(&data); } } } pPlayer->m_bg->Unlock(); } else { set<Player*> contributors; // First loop: Get all the people in the attackermap. pVictim->UpdateOppFactionSet(); for(std::set<Object*>::iterator itr = pVictim->GetInRangeOppFactsSetBegin(); itr != pVictim->GetInRangeOppFactsSetEnd(); itr++) { if(!(*itr)->IsPlayer()) continue; bool added = false; Player * plr = (Player*)(*itr); if(pVictim->CombatStatus.m_attackers.find(plr->GetGUID()) != pVictim->CombatStatus.m_attackers.end()) { added = true; contributors.insert(plr); } if(added && plr->GetGroup()) { Group * pGroup = plr->GetGroup(); uint32 groups = pGroup->GetSubGroupCount(); for(uint32 i = 0; i < groups; i++) { SubGroup * sg = pGroup->GetSubGroup(i); if(!sg) continue; for(GroupMembersSet::iterator itr2 = sg->GetGroupMembersBegin(); itr2 != sg->GetGroupMembersEnd(); itr2++) { PlayerInfo * pi = (*itr2); Player * gm = objmgr.GetPlayer(pi->guid); if(!gm) continue; if(gm->isInRange(pVictim, 100.0f)) contributors.insert(gm); } } } } for(set<Player*>::iterator itr = contributors.begin(); itr != contributors.end(); itr++) { Player * pAffectedPlayer = (*itr); if(!pAffectedPlayer) continue; pAffectedPlayer->m_killsToday++; pAffectedPlayer->m_killsLifetime++; if(pAffectedPlayer->m_bg) pAffectedPlayer->m_bg->HookOnHK(pAffectedPlayer); int32 contributorpts = Points / (int32)contributors.size(); AddHonorPointsToPlayer(pAffectedPlayer, contributorpts); if(pVictim->IsPlayer()) { sHookInterface.OnHonorableKill(pAffectedPlayer, (Player*)pVictim); WorldPacket data(SMSG_PVP_CREDIT, 12); uint32 pvppoints = contributorpts * 10; // Why *10? data << pvppoints << pVictim->GetGUID() << uint32(static_cast< Player* >(pVictim)->GetPVPRank()); pAffectedPlayer->GetSession()->SendPacket(&data); } int PvPToken = 0; Config.OptionalConfig.GetInt("Extra", "PvPToken", &PvPToken); if( PvPToken > 0 ) { int PvPTokenID = 0; Config.OptionalConfig.GetInt("Extra", "PvPTokenID", &PvPTokenID); if( PvPTokenID > 0 ) { Item * PvPTokenItem = objmgr.CreateItem(PvPTokenID, pAffectedPlayer); if( PvPTokenItem ) { PvPTokenItem->SoulBind(); pAffectedPlayer->GetItemInterface()->AddItemToFreeSlot( PvPTokenItem ); } } } if(pAffectedPlayer->GetZoneId() == 3518) { // Add Halaa Battle Token SpellEntry * pvp_token_spell = dbcSpell.LookupEntry(pAffectedPlayer->GetTeam()? 33004 : 33005); pAffectedPlayer->CastSpell(pAffectedPlayer, pvp_token_spell, true); } // If we are in Hellfire Peninsula <http://www.wowwiki.com/Hellfire_Peninsula#World_PvP_-_Hellfire_Fortifications> if(pAffectedPlayer->GetZoneId() == 3483) { // Hellfire Horde Controlled Towers /*if(pAffectedPlayer->GetMapMgr()->GetWorldState(2478) != 3 && pAffectedPlayer->GetTeam() == 1) return; // Hellfire Alliance Controlled Towers if(pAffectedPlayer->GetMapMgr()->GetWorldState(2476) != 3 && pAffectedPlayer->GetTeam() == 0) return; */ // Add Mark of Thrallmar/Honor Hold SpellEntry * pvp_token_spell = dbcSpell.LookupEntry(pAffectedPlayer->GetTeam()? 32158 : 32155); pAffectedPlayer->CastSpell(pAffectedPlayer, pvp_token_spell, true); } } } } }
/*Loot type MUST be 1-corpse, go 2-skinning/herbalism/minning 3-Fishing */ void Player::SendLoot(uint64 guid,uint8 loot_type, uint32 mapid) { Group * m_Group = m_playerInfo->m_Group; if( !IsInWorld() ) return; Loot * pLoot = NULL; uint32 guidtype = GET_TYPE_FROM_GUID(guid); int8 loot_method; if( m_Group != NULL ) loot_method = m_Group->GetMethod(); else loot_method = PARTY_LOOT_FFA; if(guidtype == HIGHGUID_TYPE_UNIT) { Creature* pCreature = GetMapMgr()->GetCreature(GET_LOWGUID_PART(guid)); if(!pCreature)return; pLoot=&pCreature->loot; m_currentLoot = pCreature->GetGUID(); }else if(guidtype == HIGHGUID_TYPE_GAMEOBJECT) { GameObject* pGO = GetMapMgr()->GetGameObject(GET_LOWGUID_PART(guid)); if(!pGO)return; pGO->SetByte(GAMEOBJECT_BYTES_1, 0,0); pLoot=&pGO->loot; m_currentLoot = pGO->GetGUID(); } else if((guidtype == HIGHGUID_TYPE_PLAYER) ) { Player *p=GetMapMgr()->GetPlayer((uint32)guid); if(!p)return; pLoot=&p->loot; m_currentLoot = p->GetGUID(); } else if( (guidtype == HIGHGUID_TYPE_CORPSE)) { Corpse *pCorpse = objmgr.GetCorpse((uint32)guid); if(!pCorpse)return; pLoot=&pCorpse->loot; m_currentLoot = pCorpse->GetGUID(); } else if( (guidtype == HIGHGUID_TYPE_ITEM) ) { Item *pItem = GetItemInterface()->GetItemByGUID(guid); if(!pItem) return; pLoot = pItem->loot; m_currentLoot = pItem->GetGUID(); } if(!pLoot) { // something whack happened.. damn cheaters.. return; } // add to looter set pLoot->looters.insert( GetLowGUID() ); WorldPacket data, data2(32); data.SetOpcode( SMSG_LOOT_RESPONSE ); m_lootGuid = guid; data << uint64( guid ); data << uint8( loot_type );//loot_type; data << uint32( pLoot->gold ); data << uint8( 0 ); //loot size reserve std::vector<__LootItem>::iterator iter=pLoot->items.begin(); uint32 count= 0; uint8 slottype = 0; for(uint32 x= 0;iter!=pLoot->items.end();iter++,x++) { if (iter->iItemsCount == 0) continue; LooterSet::iterator itr = iter->has_looted.find(GetLowGUID()); if (iter->has_looted.end() != itr) continue; ItemPrototype* itemProto =iter->item.itemproto; if (!itemProto) continue; // check if it's on ML if so only quest items and ffa loot should be shown based on mob if ( loot_method == PARTY_LOOT_MASTER && m_Group && m_Group->GetLooter() != m_playerInfo ) // pass on all ffa_loot and the grey / white items if ( !iter->ffa_loot && !(itemProto->Quality < m_Group->GetThreshold()) ) continue; //quest items check. type 4/5 //quest items that don't start quests. if((itemProto->Bonding == ITEM_BIND_QUEST) && !(itemProto->QuestId) && !HasQuestForItem(itemProto->ItemId)) continue; if((itemProto->Bonding == ITEM_BIND_QUEST2) && !(itemProto->QuestId) && !HasQuestForItem(itemProto->ItemId)) continue; //quest items that start quests need special check to avoid drops all the time. if((itemProto->Bonding == ITEM_BIND_QUEST) && (itemProto->QuestId) && GetQuestLogForEntry(itemProto->QuestId)) continue; if((itemProto->Bonding == ITEM_BIND_QUEST2) && (itemProto->QuestId) && GetQuestLogForEntry(itemProto->QuestId)) continue; if((itemProto->Bonding == ITEM_BIND_QUEST) && (itemProto->QuestId) && HasFinishedQuest(itemProto->QuestId)) continue; if((itemProto->Bonding == ITEM_BIND_QUEST2) && (itemProto->QuestId) && HasFinishedQuest(itemProto->QuestId)) continue; //check for starting item quests that need questlines. if((itemProto->QuestId && itemProto->Bonding != ITEM_BIND_QUEST && itemProto->Bonding != ITEM_BIND_QUEST2)) { bool HasRequiredQuests = true; Quest * pQuest = QuestStorage.LookupEntry(itemProto->QuestId); if(pQuest) { uint32 finishedCount = 0; //check if its a questline. for(uint32 i = 0; i < pQuest->count_requiredquests; i++) { if(pQuest->required_quests[i]) { if(!HasFinishedQuest(pQuest->required_quests[i]) || GetQuestLogForEntry(pQuest->required_quests[i])) { if (!(pQuest->quest_flags & QUEST_FLAG_ONLY_ONE_REQUIRED)) { HasRequiredQuests = false; break; } } else { finishedCount++; } } } if (pQuest->quest_flags & QUEST_FLAG_ONLY_ONE_REQUIRED) { if (finishedCount == 0) continue; } else { if(!HasRequiredQuests) continue; } } } slottype = 0; if(m_Group != NULL && loot_type < 2) { switch(loot_method) { case PARTY_LOOT_MASTER: slottype = 2; break; case PARTY_LOOT_GROUP: case PARTY_LOOT_RR: case PARTY_LOOT_NBG: slottype = 1; break; default: slottype = 0; break; } // only quality items are distributed if(itemProto->Quality < m_Group->GetThreshold()) { slottype = 0; } // if all people passed anyone can loot it? :P if(iter->passed) slottype = 0; // All players passed on the loot //if it is ffa loot and not an masterlooter if(iter->ffa_loot) slottype = 0; } data << uint8( x ); data << uint32( itemProto->ItemId ); data << uint32( iter->iItemsCount );//nr of items of this type data << uint32( iter->item.displayid ); if(iter->iRandomSuffix) { data << uint32( Item::GenerateRandomSuffixFactor( itemProto ) ); data << uint32( -int32( iter->iRandomSuffix->id ) ); } else if(iter->iRandomProperty) { data << uint32( 0 ); data << uint32( iter->iRandomProperty->ID ); } else { data << uint32( 0 ); data << uint32( 0 ); } data << slottype; // "still being rolled for" flag if(slottype == 1) { if(iter->roll == NULL && !iter->passed) { int32 ipid = 0; uint32 factor= 0; if(iter->iRandomProperty) ipid=iter->iRandomProperty->ID; else if(iter->iRandomSuffix) { ipid = -int32(iter->iRandomSuffix->id); factor=Item::GenerateRandomSuffixFactor(iter->item.itemproto); } if(iter->item.itemproto) { iter->roll = new LootRoll(60000, (m_Group != NULL ? m_Group->MemberCount() : 1), guid, x, itemProto->ItemId, factor, uint32(ipid), GetMapMgr()); data2.Initialize(SMSG_LOOT_START_ROLL); data2 << guid; data2 << uint32( mapid ); data2 << uint32( x ); data2 << uint32( itemProto->ItemId ); data2 << uint32( factor ); if(iter->iRandomProperty) data2 << uint32(iter->iRandomProperty->ID); else if(iter->iRandomSuffix) data2 << uint32( ipid ); else data2 << uint32( 0 ); data2 << uint32( iter->iItemsCount ); data2 << uint32( 60000 ); // countdown data2 << uint8( 7 ); // some sort of flags that require research } Group * pGroup = m_playerInfo->m_Group; if(pGroup) { pGroup->Lock(); for(uint32 i = 0; i < pGroup->GetSubGroupCount(); ++i) { for(GroupMembersSet::iterator itr2 = pGroup->GetSubGroup(i)->GetGroupMembersBegin(); itr2 != pGroup->GetSubGroup(i)->GetGroupMembersEnd(); ++itr2) { PlayerInfo *pinfo = *itr2; if( pinfo->m_loggedInPlayer && pinfo->m_loggedInPlayer->GetItemInterface()->CanReceiveItem( itemProto, iter->iItemsCount ) == 0 ) { if( pinfo->m_loggedInPlayer->m_passOnLoot ) iter->roll->PlayerRolled( pinfo->m_loggedInPlayer, 3 ); // passed else pinfo->m_loggedInPlayer->SendPacket( &data2 ); } } } pGroup->Unlock(); } else { m_session->SendPacket(&data2); } } } count++; } data.wpos(13); data << uint8( count ); m_session->SendPacket(&data); SetFlag( UNIT_FIELD_FLAGS, UNIT_FLAG_LOOTING ); }
/// Spell Target Handling for type 31: related to scripted effects void Spell::SpellTargetScriptedEffects( uint32 i, uint32 j ) { // Circle of healing or Wild Growth // - target top 5 hp deficient raid members around target. if( GetProto()->NameHash == SPELL_HASH_CIRCLE_OF_HEALING || GetProto()->NameHash == SPELL_HASH_WILD_GROWTH ) { if( p_caster == NULL || !p_caster->IsInWorld() ) return; TargetsList* tmpMap = &m_targetUnits[i]; Unit * pTarget = p_caster->GetMapMgr()->GetUnit( m_targets.m_unitTarget ); if( !pTarget ) return; if( p_caster == pTarget || IsInrange( p_caster->GetPositionX(), p_caster->GetPositionY(), p_caster->GetPositionZ(), pTarget, GetMaxRange( dbcSpellRange.LookupEntry( GetProto()->rangeIndex ) ) ) ) SafeAddTarget( tmpMap, pTarget->GetGUID() ); else { cancastresult = SPELL_FAILED_OUT_OF_RANGE; return; // No point targeting others if the target is not in casting range. } Group * group = p_caster->GetGroup(); if( group == NULL ) return; std::vector<Player*> raidList; std::vector<Player*>::iterator itr; uint32 count = group->GetSubGroupCount(); group->Lock(); for( uint32 k = 0; k < count; k++ ) { SubGroup * subgroup = group->GetSubGroup( k ); if( subgroup ) { for( GroupMembersSet::iterator itr = subgroup->GetGroupMembersBegin(); itr != subgroup->GetGroupMembersEnd(); ++itr ) { if( (*itr)->m_loggedInPlayer && m_caster != (*itr)->m_loggedInPlayer && IsInrange( pTarget->GetPositionX(), pTarget->GetPositionY(), pTarget->GetPositionZ(), (*itr)->m_loggedInPlayer, GetRadius(i) ) ) raidList.push_back( (*itr)->m_loggedInPlayer ); } } } group->Unlock(); std::sort( raidList.begin(), raidList.end(), hpLessThan ); uint32 maxTargets = 4; if( GetProto()->NameHash == SPELL_HASH_CIRCLE_OF_HEALING && p_caster->HasSpell( 55675 ) ) // Glyph of circle of healing maxTargets++; for( itr = raidList.begin(); itr != raidList.end() && maxTargets > 0; ++itr, maxTargets-- ) { SafeAddTarget( tmpMap, (*itr)->GetGUID() ); } } else FillAllTargetsInArea( i, m_targets.m_destX, m_targets.m_destY, m_targets.m_destZ, GetRadius(i) ); }
void HonorHandler::OnPlayerKilledUnit( PlayerPointer pPlayer, UnitPointer pVictim ) { if( pVictim == NULL || pPlayer == NULL || !pVictim->IsPlayer() || !pPlayer->IsPlayer() ) return; if( TO_PLAYER( pVictim )->m_honorless ) return; if( pVictim->IsPlayer() ) { if( pPlayer->m_bg ) { if( TO_PLAYER( pVictim )->m_bgTeam == pPlayer->m_bgTeam ) return; // patch 2.4, players killed >50 times in battlegrounds won't be worth honor for the rest of that bg if( TO_PLAYER(pVictim)->m_bgScore.Deaths >= 50 ) return; } else { if( pPlayer->GetTeam() == TO_PLAYER( pVictim )->GetTeam() ) return; } } // Calculate points int32 Points = CalculateHonorPointsForKill(pPlayer, pVictim); if( Points > 0 ) { if( pPlayer->m_bg ) { // hackfix for battlegrounds (since the gorups there are disabled, we need to do this manually) vector<PlayerPointer > toadd; uint32 t = pPlayer->m_bgTeam; toadd.reserve(15); // shouldnt have more than this pPlayer->m_bg->Lock(); set<PlayerPointer > * s = &pPlayer->m_bg->m_players[t]; for(set<PlayerPointer >::iterator itr = s->begin(); itr != s->end(); ++itr) { if((*itr) == pPlayer || (*itr)->isInRange(pPlayer,40.0f)) toadd.push_back(*itr); } if( toadd.size() > 0 ) { uint32 pts = Points / (uint32)toadd.size(); for(vector<PlayerPointer >::iterator vtr = toadd.begin(); vtr != toadd.end(); ++vtr) { AddHonorPointsToPlayer(*vtr, pts); (*vtr)->GetAchievementInterface()->HandleAchievementCriteriaHonorableKill(); (*vtr)->GetAchievementInterface()->HandleAchievementCriteriaHonorableKillClass( pVictim->getClass() ); (*vtr)->GetAchievementInterface()->HandleAchievementCriteriaHonorableKillRace( pVictim->getRace() ); (*vtr)->m_killsToday++; (*vtr)->m_killsLifetime++; pPlayer->m_bg->HookOnHK(*vtr); if(pVictim) { // Send PVP credit WorldPacket data(SMSG_PVP_CREDIT, 12); uint32 pvppoints = pts * 10; data << pvppoints << pVictim->GetGUID() << uint32(TO_PLAYER(pVictim)->GetPVPRank()); (*vtr)->GetSession()->SendPacket(&data); } } } pPlayer->m_bg->Unlock(); } else if(pPlayer->GetGroup()) { Group *pGroup = pPlayer->GetGroup(); PlayerPointer gPlayer = NULLPLR; int32 GroupPoints; pGroup->Lock(); GroupPoints = (Points / (pGroup->MemberCount() ? pGroup->MemberCount() : 1)); GroupMembersSet::iterator gitr; for(uint32 k = 0; k < pGroup->GetSubGroupCount(); k++) { for(gitr = pGroup->GetSubGroup(k)->GetGroupMembersBegin(); gitr != pGroup->GetSubGroup(k)->GetGroupMembersEnd(); ++gitr) { gPlayer = (*gitr)->m_loggedInPlayer; if(gPlayer && (gPlayer == pPlayer || gPlayer->isInRange(pPlayer,100.0f))) // visible range { gPlayer->GetAchievementInterface()->HandleAchievementCriteriaHonorableKill(); gPlayer->GetAchievementInterface()->HandleAchievementCriteriaHonorableKillClass( pVictim->getClass() ); gPlayer->GetAchievementInterface()->HandleAchievementCriteriaHonorableKillRace( pVictim->getRace() ); gPlayer->m_killsToday++; gPlayer->m_killsLifetime++; if(gPlayer->m_bg) gPlayer->m_bg->HookOnHK(gPlayer); sHookInterface.OnHonorableKill(gPlayer, TO_PLAYER(pVictim)); AddHonorPointsToPlayer(gPlayer, GroupPoints); if(pVictim) { // Send PVP credit WorldPacket data(SMSG_PVP_CREDIT, 12); uint32 pvppoints = GroupPoints * 10; data << pvppoints << pVictim->GetGUID() << uint32(TO_PLAYER(pVictim)->GetPVPRank()); gPlayer->GetSession()->SendPacket(&data); } //patch by emsy // If we are in Halaa if(pPlayer->GetZoneId() == 3518) { // Add Halaa Battle Token SpellEntry * pvp_token_spell = dbcSpell.LookupEntry(gPlayer->GetTeam()? 33004 : 33005); gPlayer->CastSpell(gPlayer, pvp_token_spell, true); } // If we are in Hellfire Peninsula if(pPlayer->GetZoneId() == 3483) { // Add Mark of Thrallmar/Honor Hold SpellEntry * pvp_token_spell = dbcSpell.LookupEntry(gPlayer->GetTeam()? 32158 : 32155); gPlayer->CastSpell(gPlayer, pvp_token_spell, true); } } } } pGroup->Unlock(); } else { pPlayer->GetAchievementInterface()->HandleAchievementCriteriaHonorableKill(); pPlayer->GetAchievementInterface()->HandleAchievementCriteriaHonorableKillClass( pVictim->getClass() ); pPlayer->GetAchievementInterface()->HandleAchievementCriteriaHonorableKillRace( pVictim->getRace() ); pPlayer->m_killsToday++; pPlayer->m_killsLifetime++; AddHonorPointsToPlayer(pPlayer, Points); if(pPlayer->m_bg) pPlayer->m_bg->HookOnHK(pPlayer); sHookInterface.OnHonorableKill(pPlayer, TO_PLAYER(pVictim)); if(pVictim) { // Send PVP credit WorldPacket data(SMSG_PVP_CREDIT, 12); uint32 pvppoints = Points * 10; data << pvppoints << pVictim->GetGUID() << uint32(TO_PLAYER(pVictim)->GetPVPRank()); pPlayer->GetSession()->SendPacket(&data); } //patch by emsy // If we are in Halaa if(pPlayer->GetZoneId() == 3518) { // Add Halaa Battle Token SpellEntry * halaa_spell = dbcSpell.LookupEntry(pPlayer->GetTeam()? 33004 : 33005); pPlayer->CastSpell(pPlayer, halaa_spell, true); } } } }
void CBattlegroundManager::HandleArenaJoin(WorldSession * m_session, uint32 BattlegroundType, uint8 as_group, uint8 rated_match) { uint32 pguid = m_session->GetPlayer()->GetLowGUID(); uint32 lgroup = GetLevelGrouping(m_session->GetPlayer()->getLevel()); if(as_group && m_session->GetPlayer()->GetGroup() == NULL) return; Group * pGroup = m_session->GetPlayer()->GetGroup(); if(as_group) { if(pGroup->GetSubGroupCount() != 1) { m_session->SystemMessage("Sorry, raid groups joining battlegrounds are currently unsupported."); return; } if(pGroup->GetLeader() != m_session->GetPlayer()->m_playerInfo) { m_session->SystemMessage("You must be the party leader to add a group to an arena."); return; } GroupMembersSet::iterator itx; if(!rated_match) { /* add all players normally.. bleh ;P */ pGroup->Lock(); for(itx = pGroup->GetSubGroup(0)->GetGroupMembersBegin(); itx != pGroup->GetSubGroup(0)->GetGroupMembersEnd(); ++itx) { if((*itx)->m_loggedInPlayer && !(*itx)->m_loggedInPlayer->m_bgIsQueued && !(*itx)->m_loggedInPlayer->m_bg) HandleArenaJoin((*itx)->m_loggedInPlayer->GetSession(), BattlegroundType, 0, 0); } pGroup->Unlock(); return; } else { /* make sure all players are 70 */ uint32 maxplayers; uint32 arenateamtype; switch(BattlegroundType) { case BATTLEGROUND_ARENA_2V2: arenateamtype=0; maxplayers=2; break; case BATTLEGROUND_ARENA_3V3: arenateamtype=1; maxplayers=3; break; case BATTLEGROUND_ARENA_5V5: arenateamtype=2; maxplayers=5; break; default: arenateamtype=0; maxplayers=2; break; } uint32 team_id = 0; pGroup->Lock(); for(itx = pGroup->GetSubGroup(0)->GetGroupMembersBegin(); itx != pGroup->GetSubGroup(0)->GetGroupMembersEnd(); ++itx) { if( maxplayers == 0 ) { m_session->SystemMessage("You have too many players in your party to join this type of arena."); pGroup->Unlock(); return; } if((*itx)->lastLevel < 70) { m_session->SystemMessage("Sorry, some of your party members are not level 70."); pGroup->Unlock(); return; } if((*itx)->m_loggedInPlayer) { ArenaTeam * t = (*itx)->m_loggedInPlayer->m_arenaTeams[arenateamtype]; if( t != NULL ) { if ( team_id == 0 ) team_id = t->m_id; if ( team_id != t->m_id ) { m_session->SystemMessage("Sorry, not all your party members are in same arena team."); pGroup->Unlock(); return; } } else { m_session->SystemMessage("Sorry, not all your party members are in same arena team."); pGroup->Unlock(); return; } if( (*itx)->m_loggedInPlayer->m_bgIsQueued ) BattlegroundManager.RemovePlayerFromQueues((*itx)->m_loggedInPlayer); /* if((*itx)->m_loggedInPlayer->m_bg || (*itx)->m_loggedInPlayer->m_bg || (*itx)->m_loggedInPlayer->m_bgIsQueued) { m_session->SystemMessage("One or more of your party members are already queued or inside a battleground."); pGroup->Unlock(); return; } */ --maxplayers; } } if( maxplayers > 0 ) { m_session->SystemMessage("Sorry, you have too few valid arena members in your group."); pGroup->Unlock(); return; } WorldPacket data(SMSG_GROUP_JOINED_BATTLEGROUND, 4); data << uint32(6); // all arenas for(itx = pGroup->GetSubGroup(0)->GetGroupMembersBegin(); itx != pGroup->GetSubGroup(0)->GetGroupMembersEnd(); ++itx) { if((*itx)->m_loggedInPlayer) { SendBattlefieldStatus((*itx)->m_loggedInPlayer, 1, BattlegroundType, 0 , 0, 0,1); (*itx)->m_loggedInPlayer->m_bgIsQueued = true; (*itx)->m_loggedInPlayer->m_bgQueueInstanceId = 0; (*itx)->m_loggedInPlayer->m_bgQueueType = BattlegroundType; (*itx)->m_loggedInPlayer->GetSession()->SendPacket(&data); (*itx)->m_loggedInPlayer->m_bgEntryPointX=(*itx)->m_loggedInPlayer->GetPositionX(); (*itx)->m_loggedInPlayer->m_bgEntryPointY=(*itx)->m_loggedInPlayer->GetPositionY(); (*itx)->m_loggedInPlayer->m_bgEntryPointZ=(*itx)->m_loggedInPlayer->GetPositionZ(); (*itx)->m_loggedInPlayer->m_bgEntryPointMap=(*itx)->m_loggedInPlayer->GetMapId(); } } pGroup->Unlock(); m_queueLock.Acquire(); m_queuedGroups[BattlegroundType].push_back(pGroup->GetID()); m_queueLock.Release(); Log.Success("BattlegroundMgr", "Group %u is now in battleground queue for arena type %u", pGroup->GetID(), BattlegroundType); /* send the battleground status packet */ return; } } /* Queue him! */ m_queueLock.Acquire(); m_queuedPlayers[BattlegroundType][lgroup].push_back(pguid); Log.Success("BattlegroundMgr", "Player %u is now in battleground queue for {Arena %u}", m_session->GetPlayer()->GetLowGUID(), BattlegroundType ); /* send the battleground status packet */ SendBattlefieldStatus(m_session->GetPlayer(), 1, BattlegroundType, 0 , 0, 0,0); m_session->GetPlayer()->m_bgIsQueued = true; m_session->GetPlayer()->m_bgQueueInstanceId = 0; m_session->GetPlayer()->m_bgQueueType = BattlegroundType; /* Set battleground entry point */ m_session->GetPlayer()->m_bgEntryPointX = m_session->GetPlayer()->GetPositionX(); m_session->GetPlayer()->m_bgEntryPointY = m_session->GetPlayer()->GetPositionY(); m_session->GetPlayer()->m_bgEntryPointZ = m_session->GetPlayer()->GetPositionZ(); m_session->GetPlayer()->m_bgEntryPointMap = m_session->GetPlayer()->GetMapId(); m_session->GetPlayer()->m_bgEntryPointInstance = m_session->GetPlayer()->GetInstanceID(); m_queueLock.Release(); }
void WorldSession::HandleLootMoneyOpcode( WorldPacket & recv_data ) { if(!_player->IsInWorld()) return; Loot * pLoot = NULL; uint64 lootguid=GetPlayer()->GetLootGUID(); if(!lootguid) return; // duno why this happens if(_player->isCasting()) _player->InterruptSpell(); WorldPacket pkt; Unit * pt = 0; if(UINT32_LOPART(GUID_HIPART(lootguid)) == HIGHGUID_UNIT) { Creature* pCreature = _player->GetMapMgr()->GetCreature(lootguid); if(!pCreature)return; pLoot=&pCreature->loot; pt = pCreature; } else if(UINT32_LOPART(GUID_HIPART(lootguid)) == HIGHGUID_GAMEOBJECT) { GameObject* pGO = _player->GetMapMgr()->GetGameObject(lootguid); if(!pGO)return; pLoot=&pGO->loot; } else if(UINT32_LOPART(GUID_HIPART(lootguid)) == HIGHGUID_CORPSE) { Corpse *pCorpse = objmgr.GetCorpse((uint32)lootguid); if(!pCorpse)return; pLoot=&pCorpse->loot; } else if(UINT32_LOPART(GUID_HIPART(lootguid)) == HIGHGUID_PLAYER) { Player * pPlayer = _player->GetMapMgr()->GetPlayer(lootguid); if(!pPlayer) return; pLoot = &pPlayer->loot; pPlayer->bShouldHaveLootableOnCorpse = false; pt = pPlayer; } else if( (UINT32_LOPART(GUID_HIPART(lootguid)) == HIGHGUID_ITEM) ) { Item *pItem = _player->GetItemInterface()->GetItemByGUID(lootguid); if(!pItem) return; pLoot = pItem->loot; } if (!pLoot) { //bitch about cheating maybe? return; } uint32 money = pLoot->gold; pLoot->gold=0; WorldPacket data(1); data.SetOpcode(SMSG_LOOT_CLEAR_MONEY); // send to all looters Player * plr; for(LooterSet::iterator itr = pLoot->looters.begin(); itr != pLoot->looters.end(); ++itr) { if((plr = _player->GetMapMgr()->GetPlayer(*itr))) plr->GetSession()->SendPacket(&data); } if(!_player->InGroup()) { if(money) { GetPlayer()->ModUInt32Value( PLAYER_FIELD_COINAGE , money); sHookInterface.OnLoot(_player, pt, money, 0); } } else { //this code is wrong mustbe party not raid! Group* party = _player->GetGroup(); if(party) { /*uint32 share = money/party->MemberCount();*/ vector<Player*> targets; targets.reserve(party->MemberCount()); GroupMembersSet::iterator itr; SubGroup * sgrp; for(uint32 i = 0; i < party->GetSubGroupCount(); i++) { sgrp = party->GetSubGroup(i); for(itr = sgrp->GetGroupMembersBegin(); itr != sgrp->GetGroupMembersEnd(); ++itr) { if((*itr)->GetZoneId() == _player->GetZoneId() && _player->GetInstanceID() == (*itr)->GetInstanceID()) targets.push_back((*itr)); } } if(!targets.size()) return; uint32 share = money / targets.size(); pkt.SetOpcode(SMSG_LOOT_MONEY_NOTIFY); pkt << share; for(vector<Player*>::iterator itr = targets.begin(); itr != targets.end(); ++itr) { (*itr)->ModUInt32Value(PLAYER_FIELD_COINAGE, share); (*itr)->GetSession()->SendPacket(&pkt); } } } }
void CBattlegroundManager::HandleArenaJoin(WorldSession* m_session, uint32 BattlegroundType, uint8 as_group, uint8 rated_match) { uint32 pguid = m_session->GetPlayer()->GetLowGUID(); uint32 lgroup = GetLevelGrouping(m_session->GetPlayer()->getLevel()); if (as_group && m_session->GetPlayer()->GetGroup() == NULL) return; Group* pGroup = m_session->GetPlayer()->GetGroup(); if (as_group) { if (pGroup->GetSubGroupCount() != 1) { m_session->SystemMessage(m_session->LocalizedWorldSrv(55)); return; } if (pGroup->GetLeader() != m_session->GetPlayer()->getPlayerInfo()) { m_session->SystemMessage(m_session->LocalizedWorldSrv(56)); return; } GroupMembersSet::iterator itx; if (!rated_match) { /* add all players normally.. bleh ;P */ pGroup->Lock(); for (itx = pGroup->GetSubGroup(0)->GetGroupMembersBegin(); itx != pGroup->GetSubGroup(0)->GetGroupMembersEnd(); ++itx) { if ((*itx)->m_loggedInPlayer && !(*itx)->m_loggedInPlayer->m_bgIsQueued && !(*itx)->m_loggedInPlayer->m_bg) HandleArenaJoin((*itx)->m_loggedInPlayer->GetSession(), BattlegroundType, 0, 0); } pGroup->Unlock(); return; } else { /* make sure all players are 70 */ uint32 maxplayers; uint32 type = BattlegroundType - BATTLEGROUND_ARENA_2V2; switch (BattlegroundType) { case BATTLEGROUND_ARENA_3V3: maxplayers = 3; break; case BATTLEGROUND_ARENA_5V5: maxplayers = 5; break; case BATTLEGROUND_ARENA_2V2: default: maxplayers = 2; break; } if (pGroup->GetLeader()->m_loggedInPlayer && pGroup->GetLeader()->m_loggedInPlayer->m_arenaTeams[type] == NULL) { m_session->SendNotInArenaTeamPacket(uint8(maxplayers)); return; } pGroup->Lock(); for (itx = pGroup->GetSubGroup(0)->GetGroupMembersBegin(); itx != pGroup->GetSubGroup(0)->GetGroupMembersEnd(); ++itx) { if (maxplayers == 0) { m_session->SystemMessage(m_session->LocalizedWorldSrv(58)); pGroup->Unlock(); return; } if ((*itx)->lastLevel < PLAYER_ARENA_MIN_LEVEL) { m_session->SystemMessage(m_session->LocalizedWorldSrv(59)); pGroup->Unlock(); return; } if ((*itx)->m_loggedInPlayer) { if ((*itx)->m_loggedInPlayer->m_bg || (*itx)->m_loggedInPlayer->m_bgIsQueued) { m_session->SystemMessage(m_session->LocalizedWorldSrv(60)); pGroup->Unlock(); return; }; if ((*itx)->m_loggedInPlayer->m_arenaTeams[type] != pGroup->GetLeader()->m_loggedInPlayer->m_arenaTeams[type]) { m_session->SystemMessage(m_session->LocalizedWorldSrv(61)); pGroup->Unlock(); return; } --maxplayers; } } WorldPacket data(SMSG_GROUP_JOINED_BATTLEGROUND, 4); data << uint32(6); // all arenas for (itx = pGroup->GetSubGroup(0)->GetGroupMembersBegin(); itx != pGroup->GetSubGroup(0)->GetGroupMembersEnd(); ++itx) { if ((*itx)->m_loggedInPlayer) { SendBattlefieldStatus((*itx)->m_loggedInPlayer, BGSTATUS_INQUEUE, BattlegroundType, 0, 0, 0, 1); (*itx)->m_loggedInPlayer->m_bgIsQueued = true; (*itx)->m_loggedInPlayer->m_bgQueueInstanceId = 0; (*itx)->m_loggedInPlayer->m_bgQueueType = BattlegroundType; (*itx)->m_loggedInPlayer->GetSession()->SendPacket(&data); (*itx)->m_loggedInPlayer->m_bgEntryPointX = (*itx)->m_loggedInPlayer->GetPositionX(); (*itx)->m_loggedInPlayer->m_bgEntryPointY = (*itx)->m_loggedInPlayer->GetPositionY(); (*itx)->m_loggedInPlayer->m_bgEntryPointZ = (*itx)->m_loggedInPlayer->GetPositionZ(); (*itx)->m_loggedInPlayer->m_bgEntryPointMap = (*itx)->m_loggedInPlayer->GetMapId(); } } pGroup->Unlock(); m_queueLock.Acquire(); m_queuedGroups[BattlegroundType].push_back(pGroup->GetID()); m_queueLock.Release(); Log.Notice("BattlegroundMgr", "Group %u is now in battleground queue for arena type %u", pGroup->GetID(), BattlegroundType); /* send the battleground status packet */ return; } } /* Queue him! */ m_queueLock.Acquire(); m_queuedPlayers[BattlegroundType][lgroup].push_back(pguid); Log.Notice("BattlegroundMgr", "Player %u is now in battleground queue for {Arena %u}", m_session->GetPlayer()->GetLowGUID(), BattlegroundType); /* send the battleground status packet */ SendBattlefieldStatus(m_session->GetPlayer(), BGSTATUS_INQUEUE, BattlegroundType, 0, 0, 0, 0); m_session->GetPlayer()->m_bgIsQueued = true; m_session->GetPlayer()->m_bgQueueInstanceId = 0; m_session->GetPlayer()->m_bgQueueType = BattlegroundType; /* Set battleground entry point */ m_session->GetPlayer()->m_bgEntryPointX = m_session->GetPlayer()->GetPositionX(); m_session->GetPlayer()->m_bgEntryPointY = m_session->GetPlayer()->GetPositionY(); m_session->GetPlayer()->m_bgEntryPointZ = m_session->GetPlayer()->GetPositionZ(); m_session->GetPlayer()->m_bgEntryPointMap = m_session->GetPlayer()->GetMapId(); m_session->GetPlayer()->m_bgEntryPointInstance = m_session->GetPlayer()->GetInstanceID(); m_queueLock.Release(); }