void Pet::UpdateSpellPower() { Unit* owner = GetOwner(); if(!owner ||owner->GetTypeId()!=TYPEID_PLAYER || !owner->IsInWorld()) return; MAPLOCK_READ(owner,MAP_LOCK_TYPE_AURAS); // Only for displaying in client! owner->SetUInt32Value(PLAYER_PET_SPELL_POWER, SpellBaseDamageBonusDone(SPELL_SCHOOL_MASK_SPELL)); }
void ThreatManager::addThreatDirectly(Unit* pVictim, float threat) { MAPLOCK_READ(pVictim, MAP_LOCK_TYPE_THREAT); HostileReference* ref = iThreatContainer.addThreat(pVictim, threat); // Ref is online if (ref) iUpdateNeed = true; // Ref is not in the online refs, search the offline refs next else ref = iThreatOfflineContainer.addThreat(pVictim, threat); if(!ref) // there was no ref => create a new one { MAPLOCK_READ(pVictim, MAP_LOCK_TYPE_DEFAULT); // threat has to be 0 here HostileReference* hostileReference = new HostileReference(pVictim, this, 0); iThreatContainer.addReference(hostileReference); hostileReference->addThreat(threat); // now we add the real threat iUpdateNeed = true; if(pVictim->GetTypeId() == TYPEID_PLAYER && ((Player*)pVictim)->isGameMaster()) hostileReference->setOnlineOfflineState(false); // GM is always offline } }
void ActionInfo::Finalize(UnitStateMgr* mgr) { if (!HasFlag(ACTION_STATE_INITIALIZED) || HasFlag(ACTION_STATE_FINALIZED)) return; MAPLOCK_READ(mgr->GetOwner(), MAP_LOCK_TYPE_MOVEMENT); AddFlag(ACTION_STATE_FINALIZED); RemoveFlag(ACTION_STATE_ACTIVE); DEBUG_FILTER_LOG(LOG_FILTER_AI_AND_MOVEGENSS, "ActionInfo: %s finalize action %s", mgr->GetOwnerStr().c_str(), TypeName()); if (Action()) Action()->Finalize(*mgr->GetOwner()); }
Aura* VehicleKit::GetControlAura(Unit* passenger) { if (!passenger) return NULL; ObjectGuid casterGuid = passenger->GetObjectGuid(); MAPLOCK_READ(GetBase(),MAP_LOCK_TYPE_AURAS); Unit::AuraList& auras = GetBase()->GetAurasByType(SPELL_AURA_CONTROL_VEHICLE); for (Unit::AuraList::iterator itr = auras.begin(); itr != auras.end(); ++itr) { if (!itr->IsEmpty() && (*itr)->GetCasterGuid() == casterGuid) return (*itr)(); } return NULL; }
void ActionInfo::Initialize(UnitStateMgr* mgr) { if (HasFlag(ACTION_STATE_FINALIZED)) return; MAPLOCK_READ(mgr->GetOwner(), MAP_LOCK_TYPE_MOVEMENT); if (!HasFlag(ACTION_STATE_INITIALIZED) && Action()) { DEBUG_FILTER_LOG(LOG_FILTER_AI_AND_MOVEGENSS, "ActionInfo: %s initialize action %s", mgr->GetOwnerStr().c_str(), TypeName()); Action()->Initialize(*mgr->GetOwner()); AddFlag(ACTION_STATE_INITIALIZED); } else if (Action()) { DEBUG_FILTER_LOG(LOG_FILTER_AI_AND_MOVEGENSS, "ActionInfo: %s reset action %s", mgr->GetOwnerStr().c_str(), TypeName()); Action()->Reset(*mgr->GetOwner()); RemoveFlag(ACTION_STATE_INTERRUPTED); } RemoveFlag(ACTION_STATE_INTERRUPTED); }
// Update the global positions of all passengers void TransportBase::UpdateGlobalPositions() { WorldLocation pos = m_owner->GetPosition(); // Calculate new direction multipliers if (MapManager::NormalizeOrientation(pos.o - m_lastPosition.o) > 0.01f) { m_sinO = sin(pos.o); m_cosO = cos(pos.o); } if (!m_passengers.empty()) { MAPLOCK_READ(GetOwner(), MAP_LOCK_TYPE_MOVEMENT); // Update global positions for (PassengerMap::const_iterator itr = m_passengers.begin(); itr != m_passengers.end(); ++itr) UpdateGlobalPositionOf(itr->first, itr->second.GetLocalPosition()); } m_lastPosition = pos; }
/*this procedure handles clients CMSG_REQUEST_PARTY_MEMBER_STATS request*/ void WorldSession::HandleRequestPartyMemberStatsOpcode( WorldPacket &recv_data ) { DEBUG_LOG("WORLD: Received CMSG_REQUEST_PARTY_MEMBER_STATS"); ObjectGuid guid; recv_data >> guid; Player * player = HashMapHolder<Player>::Find(guid); if(!player) { WorldPacket data(SMSG_PARTY_MEMBER_STATS_FULL, 3+4+2); data << uint8(0); // only for SMSG_PARTY_MEMBER_STATS_FULL, probably arena/bg related data << guid.WriteAsPacked(); data << uint32(GROUP_UPDATE_FLAG_STATUS); data << uint16(MEMBER_STATUS_OFFLINE); SendPacket(&data); return; } Pet *pet = player->GetPet(); WorldPacket data(SMSG_PARTY_MEMBER_STATS_FULL, 4+2+2+2+1+2*6+8+1+8); data << uint8(0); // only for SMSG_PARTY_MEMBER_STATS_FULL, probably arena/bg related data << player->GetPackGUID(); uint32 mask1 = 0x00040BFF; // common mask, real flags used 0x000040BFF if(pet) mask1 = 0x7FFFFFFF; // for hunters and other classes with pets uint16 online_status = MEMBER_STATUS_ONLINE; Powers powerType = player->getPowerType(); data << uint32(mask1); // group update mask data << uint16(online_status); // member's online status data << uint32(player->GetHealth()); // GROUP_UPDATE_FLAG_CUR_HP data << uint32(player->GetMaxHealth()); // GROUP_UPDATE_FLAG_MAX_HP data << uint8(powerType); // GROUP_UPDATE_FLAG_POWER_TYPE data << uint16(player->GetPower(powerType)); // GROUP_UPDATE_FLAG_CUR_POWER data << uint16(player->GetMaxPower(powerType)); // GROUP_UPDATE_FLAG_MAX_POWER data << uint16(player->getLevel()); // GROUP_UPDATE_FLAG_LEVEL //verify player coordinates and zoneid to send to teammates uint16 iZoneId = 0; uint16 iCoordX = 0; uint16 iCoordY = 0; if (player->IsInWorld()) { iZoneId = player->GetZoneId(); iCoordX = player->GetPositionX(); iCoordY = player->GetPositionY(); } else if (player->IsBeingTeleported()) // Player is in teleportation { WorldLocation& loc = player->GetTeleportDest(); // So take teleportation destination iZoneId = sTerrainMgr.GetZoneId(loc.mapid, loc.coord_x, loc.coord_y, loc.coord_z); iCoordX = loc.coord_x; iCoordY = loc.coord_y; } else { //unknown player status. } data << uint16(iZoneId); // GROUP_UPDATE_FLAG_ZONE data << uint16(iCoordX); // GROUP_UPDATE_FLAG_POSITION data << uint16(iCoordY); // GROUP_UPDATE_FLAG_POSITION uint64 auramask = 0; size_t maskPos = data.wpos(); data << uint64(auramask); // placeholder for(uint8 i = 0; i < MAX_AURAS; ++i) { MAPLOCK_READ(player,MAP_LOCK_TYPE_AURAS); if(uint32 aura = player->GetVisibleAura(i)) { auramask |= (uint64(1) << i); data << uint32(aura); data << uint8(1); } } data.put<uint64>(maskPos, auramask); // GROUP_UPDATE_FLAG_AURAS if(pet) { Powers petpowertype = pet->getPowerType(); data << pet->GetObjectGuid(); // GROUP_UPDATE_FLAG_PET_GUID data << pet->GetName(); // GROUP_UPDATE_FLAG_PET_NAME data << uint16(pet->GetDisplayId()); // GROUP_UPDATE_FLAG_PET_MODEL_ID data << uint32(pet->GetHealth()); // GROUP_UPDATE_FLAG_PET_CUR_HP data << uint32(pet->GetMaxHealth()); // GROUP_UPDATE_FLAG_PET_MAX_HP data << uint8(petpowertype); // GROUP_UPDATE_FLAG_PET_POWER_TYPE data << uint16(pet->GetPower(petpowertype)); // GROUP_UPDATE_FLAG_PET_CUR_POWER data << uint16(pet->GetMaxPower(petpowertype)); // GROUP_UPDATE_FLAG_PET_MAX_POWER uint64 petauramask = 0; size_t petMaskPos = data.wpos(); data << uint64(petauramask); // placeholder for(uint8 i = 0; i < MAX_AURAS; ++i) { MAPLOCK_READ(pet,MAP_LOCK_TYPE_AURAS); if(uint32 petaura = pet->GetVisibleAura(i)) { petauramask |= (uint64(1) << i); data << uint32(petaura); data << uint8(1); } } data.put<uint64>(petMaskPos, petauramask); // GROUP_UPDATE_FLAG_PET_AURAS } else { data << uint8(0); // GROUP_UPDATE_FLAG_PET_NAME data << uint64(0); // GROUP_UPDATE_FLAG_PET_AURAS } SendPacket(&data); }
void WorldSession::BuildPartyMemberStatsChangedPacket(Player *player, WorldPacket *data) { uint32 mask = player->GetGroupUpdateFlag(); if (mask & GROUP_UPDATE_FLAG_POWER_TYPE) // if update power type, update current/max power also mask |= (GROUP_UPDATE_FLAG_CUR_POWER | GROUP_UPDATE_FLAG_MAX_POWER); if (mask & GROUP_UPDATE_FLAG_PET_POWER_TYPE) // same for pets mask |= (GROUP_UPDATE_FLAG_PET_CUR_POWER | GROUP_UPDATE_FLAG_PET_MAX_POWER); uint32 byteCount = 0; for (int i = 1; i < GROUP_UPDATE_FLAGS_COUNT; ++i) if (mask & (1 << i)) byteCount += GroupUpdateLength[i]; data->Initialize(SMSG_PARTY_MEMBER_STATS, 8 + 4 + byteCount); *data << player->GetPackGUID(); *data << uint32(mask); if (mask & GROUP_UPDATE_FLAG_STATUS) { if (player) { if (player->IsPvP()) *data << uint16(MEMBER_STATUS_ONLINE | MEMBER_STATUS_PVP); else *data << uint16(MEMBER_STATUS_ONLINE); } else *data << uint16(MEMBER_STATUS_OFFLINE); } if (mask & GROUP_UPDATE_FLAG_CUR_HP) *data << uint32(player->GetHealth()); if (mask & GROUP_UPDATE_FLAG_MAX_HP) *data << uint32(player->GetMaxHealth()); Powers powerType = player->getPowerType(); if (mask & GROUP_UPDATE_FLAG_POWER_TYPE) *data << uint8(powerType); if (mask & GROUP_UPDATE_FLAG_CUR_POWER) *data << uint16(player->GetPower(powerType)); if (mask & GROUP_UPDATE_FLAG_MAX_POWER) *data << uint16(player->GetMaxPower(powerType)); if (mask & GROUP_UPDATE_FLAG_LEVEL) *data << uint16(player->getLevel()); if (mask & GROUP_UPDATE_FLAG_ZONE) *data << uint16(player->GetZoneId()); if (mask & GROUP_UPDATE_FLAG_POSITION) *data << uint16(player->GetPositionX()) << uint16(player->GetPositionY()); if (mask & GROUP_UPDATE_FLAG_AURAS) { MAPLOCK_READ(player,MAP_LOCK_TYPE_AURAS); const uint64& auramask = player->GetAuraUpdateMask(); *data << uint64(auramask); for(uint32 i = 0; i < MAX_AURAS; ++i) { if(auramask & (uint64(1) << i)) { *data << uint32(player->GetVisibleAura(i)); *data << uint8(1); } } } Pet *pet = player->GetPet(); if (mask & GROUP_UPDATE_FLAG_PET_GUID) *data << (pet ? pet->GetObjectGuid() : ObjectGuid()); if (mask & GROUP_UPDATE_FLAG_PET_NAME) { if(pet) *data << pet->GetName(); else *data << uint8(0); } if (mask & GROUP_UPDATE_FLAG_PET_MODEL_ID) { if(pet) *data << uint16(pet->GetDisplayId()); else *data << uint16(0); } if (mask & GROUP_UPDATE_FLAG_PET_CUR_HP) { if(pet) *data << uint32(pet->GetHealth()); else *data << uint32(0); } if (mask & GROUP_UPDATE_FLAG_PET_MAX_HP) { if(pet) *data << uint32(pet->GetMaxHealth()); else *data << uint32(0); } if (mask & GROUP_UPDATE_FLAG_PET_POWER_TYPE) { if(pet) *data << uint8(pet->getPowerType()); else *data << uint8(0); } if (mask & GROUP_UPDATE_FLAG_PET_CUR_POWER) { if(pet) *data << uint16(pet->GetPower(pet->getPowerType())); else *data << uint16(0); } if (mask & GROUP_UPDATE_FLAG_PET_MAX_POWER) { if(pet) *data << uint16(pet->GetMaxPower(pet->getPowerType())); else *data << uint16(0); } if (mask & GROUP_UPDATE_FLAG_PET_AURAS) { if(pet) { MAPLOCK_READ(pet,MAP_LOCK_TYPE_AURAS); const uint64& auramask = pet->GetAuraUpdateMask(); *data << uint64(auramask); for(uint32 i = 0; i < MAX_AURAS; ++i) { if(auramask & (uint64(1) << i)) { *data << uint32(pet->GetVisibleAura(i)); *data << uint8(1); } } } else *data << uint64(0); } if (mask & GROUP_UPDATE_FLAG_VEHICLE_SEAT) *data << uint32(player->m_movementInfo.GetTransportDBCSeat()); }
HostileReference* ThreatContainer::selectNextVictim(Creature* pAttacker, HostileReference* pCurrentVictim) { HostileReference* pCurrentRef = NULL; bool found = false; bool onlySecondChoiceTargetsFound = false; bool checkedCurrentVictim = false; ThreatList::const_iterator lastRef = iThreatList.end(); lastRef--; for (ThreatList::const_iterator iter = iThreatList.begin(); iter != iThreatList.end() && !found;) { pCurrentRef = (*iter); Unit* pTarget = pCurrentRef->getTarget(); // MANGOS_ASSERT(pTarget); // if the ref has status online the target must be there! if (!pTarget) continue; MAPLOCK_READ(pTarget, MAP_LOCK_TYPE_DEFAULT); // some units are prefered in comparison to others // if (checkThreatArea) consider IsOutOfThreatArea - expected to be only set for pCurrentVictim // This prevents dropping valid targets due to 1.1 or 1.3 threat rule vs invalid current target if (!onlySecondChoiceTargetsFound && pAttacker->IsSecondChoiceTarget(pTarget, pCurrentRef == pCurrentVictim)) { if (iter != lastRef) ++iter; else { // if we reached to this point, everyone in the threatlist is a second choice target. In such a situation the target with the highest threat should be attacked. onlySecondChoiceTargetsFound = true; iter = iThreatList.begin(); } // current victim is a second choice target, so don't compare threat with it below if (pCurrentRef == pCurrentVictim) pCurrentVictim = NULL; // second choice targets are only handled threat dependend if we have only have second choice targets continue; } if (!pAttacker->IsOutOfThreatArea(pTarget)) // skip non attackable currently targets { if (pCurrentVictim) // select 1.3/1.1 better target in comparison current target { // normal case: pCurrentRef is still valid and most hated if (pCurrentVictim == pCurrentRef) { found = true; break; } // we found a valid target, but only compare its threat if the currect victim is also a valid target // Additional check to prevent unneeded comparision in case of valid current victim if (!checkedCurrentVictim) { Unit* pCurrentTarget = pCurrentVictim->getTarget(); MANGOS_ASSERT(pCurrentTarget); if (pAttacker->IsSecondChoiceTarget(pCurrentTarget, true)) { // CurrentVictim is invalid, so return CurrentRef found = true; break; } checkedCurrentVictim = true; } // list sorted and and we check current target, then this is best case if (pCurrentRef->getThreat() <= 1.1f * pCurrentVictim->getThreat()) { pCurrentRef = pCurrentVictim; found = true; break; } if (pCurrentRef->getThreat() > 1.3f * pCurrentVictim->getThreat() || (pCurrentRef->getThreat() > 1.1f * pCurrentVictim->getThreat() && pAttacker->CanReachWithMeleeAttack(pTarget))) { // implement 110% threat rule for targets in melee range found = true; // and 130% rule for targets in ranged distances break; // for selecting alive targets } } else // select any { found = true; break; } } ++iter; } if (!found) pCurrentRef = NULL; return pCurrentRef; }
void WorldSession::BuildPartyMemberStatsChangedPacket(Player* player, WorldPacket* data) { uint32 mask = player->GetGroupUpdateFlag(); if (mask & GROUP_UPDATE_FLAG_POWER_TYPE) // if update power type, update current/max power also mask |= (GROUP_UPDATE_FLAG_CUR_POWER | GROUP_UPDATE_FLAG_MAX_POWER); if (mask & GROUP_UPDATE_FLAG_PET_POWER_TYPE) // same for pets mask |= (GROUP_UPDATE_FLAG_PET_CUR_POWER | GROUP_UPDATE_FLAG_PET_MAX_POWER); uint32 byteCount = 0; for (int i = 1; i < GROUP_UPDATE_FLAGS_COUNT; ++i) { if (mask & (1 << i)) byteCount += GroupUpdateLength[i]; } data->Initialize(SMSG_PARTY_MEMBER_STATS, 8 + 4 + byteCount); *data << player->GetPackGUID(); *data << uint32(mask); if (mask & GROUP_UPDATE_FLAG_STATUS) { uint16 playerStatus = MEMBER_STATUS_ONLINE; if (player->IsPvP()) playerStatus |= MEMBER_STATUS_PVP; if (!player->isAlive()) { if (player->HasFlag(PLAYER_FLAGS, PLAYER_FLAGS_GHOST)) playerStatus |= MEMBER_STATUS_GHOST; else playerStatus |= MEMBER_STATUS_DEAD; } if (player->HasByteFlag(UNIT_FIELD_BYTES_2, 1, UNIT_BYTE2_FLAG_FFA_PVP)) playerStatus |= MEMBER_STATUS_PVP_FFA; if (player->isAFK()) playerStatus |= MEMBER_STATUS_AFK; if (player->isDND()) playerStatus |= MEMBER_STATUS_DND; *data << uint16(playerStatus); } if (mask & GROUP_UPDATE_FLAG_CUR_HP) *data << uint32(player->GetHealth()); if (mask & GROUP_UPDATE_FLAG_MAX_HP) *data << uint32(player->GetMaxHealth()); Powers powerType = player->getPowerType(); if (mask & GROUP_UPDATE_FLAG_POWER_TYPE) *data << uint8(powerType); if (mask & GROUP_UPDATE_FLAG_CUR_POWER) *data << uint16(player->GetPower(powerType)); if (mask & GROUP_UPDATE_FLAG_MAX_POWER) *data << uint16(player->GetMaxPower(powerType)); if (mask & GROUP_UPDATE_FLAG_LEVEL) *data << uint16(player->getLevel()); if (mask & GROUP_UPDATE_FLAG_ZONE) *data << uint16(player->GetZoneId()); if (mask & GROUP_UPDATE_FLAG_POSITION) *data << uint16(player->GetPositionX()) << uint16(player->GetPositionY()); if (mask & GROUP_UPDATE_FLAG_AURAS) { const uint64& auraMask = player->GetAuraUpdateMask(); *data << uint64(auraMask); for (uint32 i = 0; i < MAX_AURAS; ++i) { if (auraMask & (uint64(1) << i)) { SpellAuraHolderPtr holder = player->GetVisibleAura(i); *data << uint32(holder ? holder->GetId() : 0); *data << uint8(holder ? holder->GetAuraFlags() : 0); } } } Pet* pet = player->GetPet(); if (mask & GROUP_UPDATE_FLAG_PET_GUID) *data << (pet ? pet->GetObjectGuid() : ObjectGuid()); if (mask & GROUP_UPDATE_FLAG_PET_NAME) *data << (pet ? pet->GetName() : uint8(0)); if (mask & GROUP_UPDATE_FLAG_PET_MODEL_ID) *data << uint16(pet ? pet->GetDisplayId() : 0); if (mask & GROUP_UPDATE_FLAG_PET_CUR_HP) *data << uint32(pet ? pet->GetHealth() : 0); if (mask & GROUP_UPDATE_FLAG_PET_MAX_HP) *data << uint32(pet ? pet->GetMaxHealth() : 0); if (mask & GROUP_UPDATE_FLAG_PET_POWER_TYPE) *data << uint8(pet ? pet->getPowerType() : 0); if (mask & GROUP_UPDATE_FLAG_PET_CUR_POWER) *data << uint16(pet ? pet->GetPower(pet->getPowerType()) : 0); if (mask & GROUP_UPDATE_FLAG_PET_MAX_POWER) *data << uint16(pet ? pet->GetMaxPower(pet->getPowerType()) : 0); if (mask & GROUP_UPDATE_FLAG_PET_AURAS) { if (pet) { MAPLOCK_READ(pet, MAP_LOCK_TYPE_AURAS); const uint64& auramask = pet->GetAuraUpdateMask(); *data << uint64(auramask); for (uint32 i = 0; i < MAX_AURAS; ++i) { if (auramask & (uint64(1) << i)) { SpellAuraHolderPtr holder = pet->GetVisibleAura(i); *data << uint32(holder ? holder->GetId() : 0); *data << uint8(holder ? holder->GetAuraFlags() : 0); } } } else *data << uint64(0); } if (mask & GROUP_UPDATE_FLAG_VEHICLE_SEAT) *data << uint32(player->m_movementInfo.GetTransportDBCSeat()); }