diff options
| author | Shauren <shauren.trinity@gmail.com> | 2022-03-29 11:30:49 +0200 |
|---|---|---|
| committer | Shauren <shauren.trinity@gmail.com> | 2022-03-29 11:30:49 +0200 |
| commit | d611925dc7ab2b3f19c5ee9e0f75b8dfb6de1291 (patch) | |
| tree | 4428ac0728c043ca1cb4fc55427f87268ab4860c /src/server/game/Entities/Unit | |
| parent | c02b829788cb274a68b125aee4dab35b9a56a2b8 (diff) | |
Core/Units: Reduce differences between branches part 1 - unit updatefield accessors
Diffstat (limited to 'src/server/game/Entities/Unit')
| -rw-r--r-- | src/server/game/Entities/Unit/StatSystem.cpp | 58 | ||||
| -rw-r--r-- | src/server/game/Entities/Unit/Unit.cpp | 214 | ||||
| -rw-r--r-- | src/server/game/Entities/Unit/Unit.h | 233 | ||||
| -rw-r--r-- | src/server/game/Entities/Unit/UnitDefines.h | 33 |
4 files changed, 324 insertions, 214 deletions
diff --git a/src/server/game/Entities/Unit/StatSystem.cpp b/src/server/game/Entities/Unit/StatSystem.cpp index c1939f60dd5..142affc27cf 100644 --- a/src/server/game/Entities/Unit/StatSystem.cpp +++ b/src/server/game/Entities/Unit/StatSystem.cpp @@ -341,16 +341,8 @@ void Player::UpdateAttackPowerAndDamage(bool ranged) UnitMods unitMod = ranged ? UNIT_MOD_ATTACK_POWER_RANGED : UNIT_MOD_ATTACK_POWER; - uint16 index = UNIT_FIELD_ATTACK_POWER; - uint16 index_mod = UNIT_FIELD_ATTACK_POWER_MODS; - uint16 index_mult = UNIT_FIELD_ATTACK_POWER_MULTIPLIER; - if (ranged) { - index = UNIT_FIELD_RANGED_ATTACK_POWER; - index_mod = UNIT_FIELD_RANGED_ATTACK_POWER_MODS; - index_mult = UNIT_FIELD_RANGED_ATTACK_POWER_MULTIPLIER; - switch (GetClass()) { case CLASS_HUNTER: @@ -480,9 +472,18 @@ void Player::UpdateAttackPowerAndDamage(bool ranged) float attPowerMultiplier = GetPctModifierValue(unitMod, TOTAL_PCT) - 1.0f; - SetInt32Value(index, (uint32)base_attPower); //UNIT_FIELD_(RANGED)_ATTACK_POWER field - SetInt32Value(index_mod, (uint32)attPowerMod); //UNIT_FIELD_(RANGED)_ATTACK_POWER_MODS field - SetFloatValue(index_mult, attPowerMultiplier); //UNIT_FIELD_(RANGED)_ATTACK_POWER_MULTIPLIER field + if (ranged) + { + SetRangedAttackPower(int32(base_attPower)); + SetRangedAttackPowerModPos(int32(attPowerMod)); + SetRangedAttackPowerMultiplier(attPowerMultiplier); + } + else + { + SetAttackPower(int32(base_attPower)); + SetAttackPowerModPos(int32(attPowerMod)); + SetAttackPowerMultiplier(attPowerMultiplier); + } Pet* pet = GetPet(); //update pet's AP Guardian* guardian = GetGuardianPet(); @@ -1043,24 +1044,22 @@ void Creature::UpdateAttackPowerAndDamage(bool ranged) { UnitMods unitMod = ranged ? UNIT_MOD_ATTACK_POWER_RANGED : UNIT_MOD_ATTACK_POWER; - uint16 index = UNIT_FIELD_ATTACK_POWER; - uint16 indexMod = UNIT_FIELD_ATTACK_POWER_MODS; - uint16 indexMulti = UNIT_FIELD_ATTACK_POWER_MULTIPLIER; - - if (ranged) - { - index = UNIT_FIELD_RANGED_ATTACK_POWER; - indexMod = UNIT_FIELD_RANGED_ATTACK_POWER_MODS; - indexMulti = UNIT_FIELD_RANGED_ATTACK_POWER_MULTIPLIER; - } - float baseAttackPower = GetFlatModifierValue(unitMod, BASE_VALUE) * GetPctModifierValue(unitMod, BASE_PCT); float attackPowerMod = GetFlatModifierValue(unitMod, TOTAL_VALUE); float attackPowerMultiplier = GetPctModifierValue(unitMod, TOTAL_PCT) - 1.0f; - SetInt32Value(index, uint32(baseAttackPower)); // UNIT_FIELD_(RANGED)_ATTACK_POWER - SetInt32Value(indexMod, uint32(attackPowerMod)); // UNIT_FIELD_(RANGED)_ATTACK_POWER_MODS - SetFloatValue(indexMulti, attackPowerMultiplier); // UNIT_FIELD_(RANGED)_ATTACK_POWER_MULTIPLIER + if (ranged) + { + SetRangedAttackPower(int32(baseAttackPower)); + SetRangedAttackPowerModPos(int32(attackPowerMod)); + SetRangedAttackPowerMultiplier(attackPowerMultiplier); + } + else + { + SetAttackPower(int32(baseAttackPower)); + SetAttackPowerModPos(int32(attackPowerMod)); + SetAttackPowerMultiplier(attackPowerMultiplier); + } // automatically update weapon damage after attack power modification if (ranged) @@ -1423,12 +1422,9 @@ void Guardian::UpdateAttackPowerAndDamage(bool ranged) float attPowerMod = GetFlatModifierValue(unitMod, TOTAL_VALUE); float attPowerMultiplier = GetPctModifierValue(unitMod, TOTAL_PCT) - 1.0f; - //UNIT_FIELD_(RANGED)_ATTACK_POWER field - SetInt32Value(UNIT_FIELD_ATTACK_POWER, (int32)base_attPower); - //UNIT_FIELD_(RANGED)_ATTACK_POWER_MODS field - SetInt32Value(UNIT_FIELD_ATTACK_POWER_MODS, (int32)attPowerMod); - //UNIT_FIELD_(RANGED)_ATTACK_POWER_MULTIPLIER field - SetFloatValue(UNIT_FIELD_ATTACK_POWER_MULTIPLIER, attPowerMultiplier); + SetAttackPower(int32(base_attPower)); + SetAttackPowerModPos(int32(attPowerMod)); + SetAttackPowerMultiplier(attPowerMultiplier); //automatically update weapon damage after attack power modification UpdateDamagePhysical(BASE_ATTACK); diff --git a/src/server/game/Entities/Unit/Unit.cpp b/src/server/game/Entities/Unit/Unit.cpp index ba811094c58..13ef25a631d 100644 --- a/src/server/game/Entities/Unit/Unit.cpp +++ b/src/server/game/Entities/Unit/Unit.cpp @@ -301,7 +301,7 @@ Unit::Unit(bool isWorldObject) : m_removedAurasCount(0), m_charmer(nullptr), m_charmed(nullptr), i_motionMaster(new MotionMaster(this)), m_regenTimer(0), m_vehicle(nullptr), m_vehicleKit(nullptr), m_unitTypeMask(UNIT_MASK_NONE), m_Diminishing(), m_combatManager(this), m_threatManager(this), - m_aiLocked(false), m_comboTarget(nullptr), m_comboPoints(0), m_spellHistory(new SpellHistory(this)) + m_aiLocked(false), m_comboTarget(nullptr), m_comboPoints(0), _spellHistory(new SpellHistory(this)) { m_objectType |= TYPEMASK_UNIT; m_objectTypeId = TYPEID_UNIT; @@ -412,7 +412,7 @@ Unit::~Unit() delete i_motionMaster; delete m_charmInfo; delete movespline; - delete m_spellHistory; + delete _spellHistory; ASSERT(!m_duringRemoveFromWorld); ASSERT(!m_attacking); @@ -659,14 +659,14 @@ void Unit::UpdateInterruptMask() m_interruptMask |= spell->m_spellInfo->ChannelInterruptFlags; } -bool Unit::HasAuraTypeWithFamilyFlags(AuraType auraType, uint32 familyName, uint32 familyFlags) const +bool Unit::HasAuraTypeWithFamilyFlags(AuraType auraType, uint32 familyName, flag96 familyFlags) const { if (!HasAuraType(auraType)) return false; AuraEffectList const& auras = GetAuraEffectsByType(auraType); for (AuraEffectList::const_iterator itr = auras.begin(); itr != auras.end(); ++itr) if (SpellInfo const* iterSpellProto = (*itr)->GetSpellInfo()) - if (iterSpellProto->SpellFamilyName == familyName && iterSpellProto->SpellFamilyFlags[0] & familyFlags) + if (iterSpellProto->SpellFamilyName == familyName && iterSpellProto->SpellFamilyFlags & familyFlags) return true; return false; } @@ -1109,7 +1109,7 @@ void Unit::CalculateSpellDamageTaken(SpellNonMeleeDamage* damageInfo, int32 dama damageInfo->damage = dmgInfo.GetDamage(); } -void Unit::DealSpellDamage(SpellNonMeleeDamage* damageInfo, bool durabilityLoss) +void Unit::DealSpellDamage(SpellNonMeleeDamage const* damageInfo, bool durabilityLoss) { if (!damageInfo) return; @@ -2073,7 +2073,7 @@ void Unit::HandleEmoteCommand(Emote emoteId) void Unit::AttackerStateUpdate(Unit* victim, WeaponAttackType attType, bool extra) { - if (HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_PACIFIED)) + if (HasUnitFlag(UNIT_FLAG_PACIFIED)) return; if (HasUnitState(UNIT_STATE_CANNOT_AUTOATTACK) && !extra) @@ -2094,7 +2094,7 @@ void Unit::AttackerStateUpdate(Unit* victim, WeaponAttackType attType, bool extr if (!extra && _lastExtraAttackSpell) _lastExtraAttackSpell = 0; - if (GetTypeId() == TYPEID_UNIT && !HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_POSSESSED) && !HasFlag(UNIT_FIELD_FLAGS_2, UNIT_FLAG2_CANNOT_TURN)) + if (GetTypeId() == TYPEID_UNIT && !HasUnitFlag(UNIT_FLAG_POSSESSED) && !HasUnitFlag2(UNIT_FLAG2_CANNOT_TURN)) SetFacingToObject(victim, false); // update client side facing to face the target (prevents visual glitches when casting untargeted spells) // melee attack spell cast at main hand attack only - no normal melee dmg dealt @@ -2413,11 +2413,11 @@ bool Unit::CanUseAttackType(uint8 attacktype) const switch (attacktype) { case BASE_ATTACK: - return !HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_DISARMED); + return !HasUnitFlag(UNIT_FLAG_DISARMED); case OFF_ATTACK: - return !HasFlag(UNIT_FIELD_FLAGS_2, UNIT_FLAG2_DISARM_OFFHAND); + return !HasUnitFlag2(UNIT_FLAG2_DISARM_OFFHAND); case RANGED_ATTACK: - return !HasFlag(UNIT_FIELD_FLAGS_2, UNIT_FLAG2_DISARM_RANGED); + return !HasUnitFlag2(UNIT_FLAG2_DISARM_RANGED); default: return true; } @@ -2924,7 +2924,7 @@ void Unit::_UpdateSpells(uint32 time) } } - m_spellHistory->Update(); + _spellHistory->Update(); } void Unit::_UpdateAutoRepeatSpell() @@ -5066,17 +5066,20 @@ void Unit::_UnregisterDynObject(DynamicObject* dynObj) m_dynObj.remove(dynObj); } -DynamicObject* Unit::GetDynObject(uint32 spellId) +DynamicObject* Unit::GetDynObject(uint32 spellId) const { - if (m_dynObj.empty()) - return nullptr; - for (DynObjectList::const_iterator i = m_dynObj.begin(); i != m_dynObj.end();++i) - { - DynamicObject* dynObj = *i; - if (dynObj->GetSpellId() == spellId) - return dynObj; - } - return nullptr; + std::vector<DynamicObject*> dynamicobjects = GetDynObjects(spellId); + return dynamicobjects.empty() ? nullptr : dynamicobjects.front(); +} + +std::vector<DynamicObject*> Unit::GetDynObjects(uint32 spellId) const +{ + std::vector<DynamicObject*> dynamicobjects; + for (DynObjectList::const_iterator i = m_dynObj.begin(); i != m_dynObj.end(); ++i) + if ((*i)->GetSpellId() == spellId) + dynamicobjects.push_back(*i); + + return dynamicobjects; } void Unit::RemoveDynObject(uint32 spellId) @@ -5104,11 +5107,18 @@ void Unit::RemoveAllDynObjects() GameObject* Unit::GetGameObject(uint32 spellId) const { + std::vector<GameObject*> gameobjects = GetGameObjects(spellId); + return gameobjects.empty() ? nullptr : gameobjects.front(); +} + +std::vector<GameObject*> Unit::GetGameObjects(uint32 spellId) const +{ + std::vector<GameObject*> gameobjects; for (GameObjectList::const_iterator i = m_gameObj.begin(); i != m_gameObj.end(); ++i) if ((*i)->GetSpellId() == spellId) - return *i; + gameobjects.push_back(*i); - return nullptr; + return gameobjects; } void Unit::AddGameObject(GameObject* gameObj) @@ -5203,7 +5213,7 @@ void Unit::RemoveAllGameObjects() } } -void Unit::SendSpellNonMeleeDamageLog(SpellNonMeleeDamage* log) +void Unit::SendSpellNonMeleeDamageLog(SpellNonMeleeDamage const* log) { WorldPacket data(SMSG_SPELLNONMELEEDAMAGELOG, (16+4+4+4+1+4+4+1+1+4+4+1)); // we guess size data << log->target->GetPackGUID(); @@ -5640,7 +5650,7 @@ bool Unit::Attack(Unit* victim, bool meleeAttack) creature->CallAssistance(); // Remove emote state - will be restored on creature reset - SetUInt32Value(UNIT_NPC_EMOTESTATE, EMOTE_ONESHOT_NONE); + SetEmoteState(EMOTE_ONESHOT_NONE); } // delay offhand weapon attack by 50% of the base attack time @@ -5822,7 +5832,7 @@ void Unit::ModifyAuraState(AuraStateType flag, bool apply) } } -uint32 Unit::BuildAuraStateUpdateForTarget(Unit* target) const +uint32 Unit::BuildAuraStateUpdateForTarget(Unit const* target) const { uint32 auraStates = GetUInt32Value(UNIT_FIELD_AURASTATE) &~(PER_CASTER_AURA_STATE_MASK); for (AuraStateAurasMap::const_iterator itr = m_auraStateAuras.begin(); itr != m_auraStateAuras.end(); ++itr) @@ -5950,7 +5960,7 @@ void Unit::SetMinion(Minion *minion, bool apply) if (GetTypeId() == TYPEID_PLAYER) { minion->m_ControlledByPlayer = true; - minion->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_PLAYER_CONTROLLED); + minion->SetUnitFlag(UNIT_FLAG_PLAYER_CONTROLLED); } // Can only have one pet. If a new one is summoned, dismiss the old one. @@ -5983,7 +5993,7 @@ void Unit::SetMinion(Minion *minion, bool apply) SetCritterGUID(minion->GetGUID()); // PvP, FFAPvP - minion->SetByteValue(UNIT_FIELD_BYTES_2, UNIT_BYTES_2_OFFSET_PVP_FLAG, GetByteValue(UNIT_FIELD_BYTES_2, UNIT_BYTES_2_OFFSET_PVP_FLAG)); + minion->ReplaceAllPvpFlags(GetPvpFlags()); // FIXME: hack, speed must be set only at follow if (GetTypeId() == TYPEID_PLAYER && minion->IsPet()) @@ -6114,13 +6124,13 @@ void Unit::SetCharm(Unit* charm, bool apply) charm->m_ControlledByPlayer = true; /// @todo maybe we can use this flag to check if controlled by player - charm->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_PLAYER_CONTROLLED); + charm->SetUnitFlag(UNIT_FLAG_PLAYER_CONTROLLED); } else charm->m_ControlledByPlayer = false; // PvP, FFAPvP - charm->SetByteValue(UNIT_FIELD_BYTES_2, UNIT_BYTES_2_OFFSET_PVP_FLAG, GetByteValue(UNIT_FIELD_BYTES_2, UNIT_BYTES_2_OFFSET_PVP_FLAG)); + charm->ReplaceAllPvpFlags(GetPvpFlags()); ASSERT_WITH_SIDE_EFFECTS(charm->AddGuidValue(UNIT_FIELD_CHARMEDBY, GetGUID()), "Unit %u is being charmed, but it already has a charmer %s", charm->GetEntry(), charm->GetCharmerGUID().ToString().c_str()); @@ -6153,20 +6163,20 @@ void Unit::SetCharm(Unit* charm, bool apply) if (charm->GetTypeId() == TYPEID_PLAYER) { charm->m_ControlledByPlayer = true; - charm->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_PLAYER_CONTROLLED); + charm->SetUnitFlag(UNIT_FLAG_PLAYER_CONTROLLED); charm->ToPlayer()->UpdatePvPState(); } else if (Player* player = charm->GetCharmerOrOwnerPlayerOrPlayerItself()) { charm->m_ControlledByPlayer = true; - charm->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_PLAYER_CONTROLLED); - charm->SetByteValue(UNIT_FIELD_BYTES_2, UNIT_BYTES_2_OFFSET_PVP_FLAG, player->GetByteValue(UNIT_FIELD_BYTES_2, UNIT_BYTES_2_OFFSET_PVP_FLAG)); + charm->SetUnitFlag(UNIT_FLAG_PLAYER_CONTROLLED); + charm->ReplaceAllPvpFlags(player->GetPvpFlags()); } else { charm->m_ControlledByPlayer = false; - charm->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_PLAYER_CONTROLLED); - charm->SetByteValue(UNIT_FIELD_BYTES_2, UNIT_BYTES_2_OFFSET_PVP_FLAG, 0); + charm->RemoveUnitFlag(UNIT_FLAG_PLAYER_CONTROLLED); + charm->ReplaceAllPvpFlags(UNIT_BYTE2_FLAG_NONE); } if (charm->IsWalking() != _isWalkingBeforeCharm) @@ -6295,7 +6305,7 @@ void Unit::RemoveAllControlled() if (GetCharmedGUID()) TC_LOG_FATAL("entities.unit", "Unit %u is not able to release its charm %s", GetEntry(), GetCharmedGUID().ToString().c_str()); if (!IsPet()) // pets don't use the flag for this - RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_PET_IN_COMBAT); // m_controlled is now empty, so we know none of our minions are in combat + RemoveUnitFlag(UNIT_FLAG_PET_IN_COMBAT); // m_controlled is now empty, so we know none of our minions are in combat } bool Unit::isPossessedByPlayer() const @@ -8148,9 +8158,9 @@ float Unit::GetPPMProcChance(uint32 WeaponSpeed, float PPM, SpellInfo const* spe void Unit::Mount(uint32 mount, uint32 VehicleId, uint32 creatureEntry) { if (mount) - SetUInt32Value(UNIT_FIELD_MOUNTDISPLAYID, mount); + SetMountDisplayId(mount); - SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_MOUNT); + SetUnitFlag(UNIT_FLAG_MOUNT); if (Player* player = ToPlayer()) { @@ -8180,7 +8190,7 @@ void Unit::Mount(uint32 mount, uint32 VehicleId, uint32 creatureEntry) Battleground* bg = ToPlayer()->GetBattleground(); // don't unsummon pet in arena but SetFlag UNIT_FLAG_STUNNED to disable pet's interface if (bg && bg->isArena()) - pet->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_STUNNED); + pet->SetUnitFlag(UNIT_FLAG_STUNNED); else player->UnsummonPetTemporaryIfAny(); } @@ -8188,7 +8198,7 @@ void Unit::Mount(uint32 mount, uint32 VehicleId, uint32 creatureEntry) // if we have charmed npc, stun him also (everywhere) if (Unit* charm = player->GetCharmed()) if (charm->GetTypeId() == TYPEID_UNIT) - charm->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_STUNNED); + charm->SetUnitFlag(UNIT_FLAG_STUNNED); WorldPacket data(SMSG_MOVE_SET_COLLISION_HGT, GetPackGUID().size() + 4 + 4); data << GetPackGUID(); @@ -8205,8 +8215,8 @@ void Unit::Dismount() if (!IsMounted()) return; - SetUInt32Value(UNIT_FIELD_MOUNTDISPLAYID, 0); - RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_MOUNT); + SetMountDisplayId(0); + RemoveUnitFlag(UNIT_FLAG_MOUNT); if (Player* thisPlayer = ToPlayer()) { @@ -8242,22 +8252,22 @@ void Unit::Dismount() { if (Pet* pPet = player->GetPet()) { - if (pPet->HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_STUNNED) && !pPet->HasUnitState(UNIT_STATE_STUNNED)) - pPet->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_STUNNED); + if (pPet->HasUnitFlag(UNIT_FLAG_STUNNED) && !pPet->HasUnitState(UNIT_STATE_STUNNED)) + pPet->RemoveUnitFlag(UNIT_FLAG_STUNNED); } else player->ResummonPetTemporaryUnSummonedIfAny(); // if we have charmed npc, remove stun also if (Unit* charm = player->GetCharmed()) - if (charm->GetTypeId() == TYPEID_UNIT && charm->HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_STUNNED) && !charm->HasUnitState(UNIT_STATE_STUNNED)) - charm->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_STUNNED); + if (charm->GetTypeId() == TYPEID_UNIT && charm->HasUnitFlag(UNIT_FLAG_STUNNED) && !charm->HasUnitState(UNIT_STATE_STUNNED)) + charm->RemoveUnitFlag(UNIT_FLAG_STUNNED); } } bool Unit::IsServiceProvider() const { - return HasFlag(UNIT_NPC_FLAGS, + return HasNpcFlag( UNIT_NPC_FLAG_VENDOR | UNIT_NPC_FLAG_TRAINER | UNIT_NPC_FLAG_FLIGHTMASTER | UNIT_NPC_FLAG_PETITIONER | UNIT_NPC_FLAG_BATTLEMASTER | UNIT_NPC_FLAG_BANKER | UNIT_NPC_FLAG_INNKEEPER | UNIT_NPC_FLAG_SPIRITHEALER | @@ -8279,59 +8289,59 @@ void Unit::SetImmuneToAll(bool apply, bool keepCombat) { if (apply) { - SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_IMMUNE_TO_PC | UNIT_FLAG_IMMUNE_TO_NPC); + SetUnitFlag(UNIT_FLAG_IMMUNE_TO_PC | UNIT_FLAG_IMMUNE_TO_NPC); ValidateAttackersAndOwnTarget(); if (!keepCombat) m_combatManager.EndAllCombat(); } else - RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_IMMUNE_TO_PC | UNIT_FLAG_IMMUNE_TO_NPC); + RemoveUnitFlag(UNIT_FLAG_IMMUNE_TO_PC | UNIT_FLAG_IMMUNE_TO_NPC); } void Unit::SetImmuneToPC(bool apply, bool keepCombat) { if (apply) { - SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_IMMUNE_TO_PC); + SetUnitFlag(UNIT_FLAG_IMMUNE_TO_PC); ValidateAttackersAndOwnTarget(); if (!keepCombat) { std::list<CombatReference*> toEnd; for (auto const& pair : m_combatManager.GetPvECombatRefs()) - if (pair.second->GetOther(this)->HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_PLAYER_CONTROLLED)) + if (pair.second->GetOther(this)->HasUnitFlag(UNIT_FLAG_PLAYER_CONTROLLED)) toEnd.push_back(pair.second); for (auto const& pair : m_combatManager.GetPvPCombatRefs()) - if (pair.second->GetOther(this)->HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_PLAYER_CONTROLLED)) + if (pair.second->GetOther(this)->HasUnitFlag(UNIT_FLAG_PLAYER_CONTROLLED)) toEnd.push_back(pair.second); for (CombatReference* ref : toEnd) ref->EndCombat(); } } else - RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_IMMUNE_TO_PC); + RemoveUnitFlag(UNIT_FLAG_IMMUNE_TO_PC); } void Unit::SetImmuneToNPC(bool apply, bool keepCombat) { if (apply) { - SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_IMMUNE_TO_NPC); + SetUnitFlag(UNIT_FLAG_IMMUNE_TO_NPC); ValidateAttackersAndOwnTarget(); if (!keepCombat) { std::list<CombatReference*> toEnd; for (auto const& pair : m_combatManager.GetPvECombatRefs()) - if (!pair.second->GetOther(this)->HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_PLAYER_CONTROLLED)) + if (!pair.second->GetOther(this)->HasUnitFlag(UNIT_FLAG_PLAYER_CONTROLLED)) toEnd.push_back(pair.second); for (auto const& pair : m_combatManager.GetPvPCombatRefs()) - if (!pair.second->GetOther(this)->HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_PLAYER_CONTROLLED)) + if (!pair.second->GetOther(this)->HasUnitFlag(UNIT_FLAG_PLAYER_CONTROLLED)) toEnd.push_back(pair.second); for (CombatReference* ref : toEnd) ref->EndCombat(); } } else - RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_IMMUNE_TO_NPC); + RemoveUnitFlag(UNIT_FLAG_IMMUNE_TO_NPC); } bool Unit::IsThreatened() const @@ -8344,8 +8354,7 @@ bool Unit::isTargetableForAttack(bool checkFakeDeath) const if (!IsAlive()) return false; - if (HasFlag(UNIT_FIELD_FLAGS, - UNIT_FLAG_NON_ATTACKABLE | UNIT_FLAG_UNINTERACTIBLE)) + if (HasUnitFlag( UNIT_FLAG_NON_ATTACKABLE | UNIT_FLAG_UNINTERACTIBLE)) return false; if (GetTypeId() == TYPEID_PLAYER && ToPlayer()->IsGameMaster()) @@ -8740,14 +8749,14 @@ void Unit::setDeathState(DeathState s) // do not why since in IncreaseMaxHealth currenthealth is checked SetHealth(0); SetPower(GetPowerType(), 0); - SetUInt32Value(UNIT_NPC_EMOTESTATE, 0); + SetEmoteState(EMOTE_ONESHOT_NONE); // players in instance don't have ZoneScript, but they have InstanceScript if (ZoneScript* zoneScript = GetZoneScript() ? GetZoneScript() : GetInstanceScript()) zoneScript->OnUnitDeath(this); } else if (s == JUST_RESPAWNED) - RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_SKINNABLE); // clear skinnable for creature and player (at battleground) + RemoveUnitFlag(UNIT_FLAG_SKINNABLE); // clear skinnable for creature and player (at battleground) } //====================================================================== @@ -8793,9 +8802,9 @@ void Unit::UpdatePetCombatState() } if (state) - SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_PET_IN_COMBAT); + SetUnitFlag(UNIT_FLAG_PET_IN_COMBAT); else - RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_PET_IN_COMBAT); + RemoveUnitFlag(UNIT_FLAG_PET_IN_COMBAT); } //====================================================================== @@ -9908,9 +9917,9 @@ void CharmInfo::SetPetNumber(uint32 petnumber, bool statwindow) { _petnumber = petnumber; if (statwindow) - _unit->SetUInt32Value(UNIT_FIELD_PETNUMBER, _petnumber); + _unit->SetPetNumberForClient(_petnumber); else - _unit->SetUInt32Value(UNIT_FIELD_PETNUMBER, 0); + _unit->SetPetNumberForClient(0); } void CharmInfo::LoadPetActionBar(const std::string& data) @@ -10322,7 +10331,7 @@ bool Unit::IsStandState() const return !IsSitState() && s != UNIT_STAND_STATE_SLEEP && s != UNIT_STAND_STATE_KNEEL; } -void Unit::SetStandState(uint8 state) +void Unit::SetStandState(UnitStandStateType state) { SetByteValue(UNIT_FIELD_BYTES_1, UNIT_BYTES_1_OFFSET_STAND_STATE, state); @@ -10371,7 +10380,7 @@ void Unit::SetDisplayId(uint32 modelId) SetUInt32Value(UNIT_FIELD_DISPLAYID, modelId); // Set Gender by modelId if (CreatureModelInfo const* minfo = sObjectMgr->GetCreatureModelInfo(modelId)) - SetGender(minfo->gender); + SetGender(Gender(minfo->gender)); } void Unit::RestoreDisplayId() @@ -10615,7 +10624,7 @@ void Unit::ApplyCastTimePercentMod(float val, bool apply) else ApplyPercentModFloatVar(amount, -val, apply); - SetFloatValue(UNIT_MOD_CAST_SPEED, amount); + SetModCastingSpeed(amount); } uint32 Unit::GetCastingTimeForBonus(SpellInfo const* spellProto, DamageEffectType damagetype, uint32 CastingTime) const @@ -10868,10 +10877,10 @@ bool Unit::InitTamedPet(Pet* pet, uint8 level, uint32 spell_id) pet->SetCreatorGUID(GetGUID()); pet->SetFaction(GetFaction()); - pet->SetUInt32Value(UNIT_CREATED_BY_SPELL, spell_id); + pet->SetCreatedBySpell(spell_id); if (GetTypeId() == TYPEID_PLAYER) - pet->SetUInt32Value(UNIT_FIELD_FLAGS, UNIT_FLAG_PLAYER_CONTROLLED); + pet->ReplaceAllUnitFlags(UNIT_FLAG_PLAYER_CONTROLLED); if (!pet->InitStatsForLevel(level)) { @@ -11110,7 +11119,7 @@ bool Unit::InitTamedPet(Pet* pet, uint8 level, uint32 spell_id) { // must be after setDeathState which resets dynamic flags if (!creature->loot.isLooted()) - creature->SetFlag(UNIT_DYNAMIC_FLAGS, UNIT_DYNFLAG_LOOTABLE); + creature->SetDynamicFlag(UNIT_DYNFLAG_LOOTABLE); else creature->AllLootRemovedFromCorpse(); } @@ -11320,7 +11329,7 @@ void Unit::SetStunned(bool apply) m_rootTimes++; SetTarget(ObjectGuid::Empty); - SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_STUNNED); + SetUnitFlag(UNIT_FLAG_STUNNED); // MOVEMENTFLAG_ROOT cannot be used in conjunction with MOVEMENTFLAG_MASK_MOVING (tested 3.3.5a) // this will freeze clients. That's why we remove MOVEMENTFLAG_MASK_MOVING before @@ -11356,7 +11365,7 @@ void Unit::SetStunned(bool apply) // don't remove UNIT_FLAG_STUNNED for pet when owner is mounted (disabled pet's interface) Unit* owner = GetCharmerOrOwner(); if (!owner || owner->GetTypeId() != TYPEID_PLAYER || !owner->ToPlayer()->IsMounted()) - RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_STUNNED); + RemoveUnitFlag(UNIT_FLAG_STUNNED); if (!HasUnitState(UNIT_STATE_ROOT)) // prevent moving if it also has root effect { @@ -11615,13 +11624,13 @@ bool Unit::SetCharmedBy(Unit* charmer, CharmType type, AuraApplication const* au switch (type) { case CHARM_TYPE_VEHICLE: - SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_POSSESSED); + SetUnitFlag(UNIT_FLAG_POSSESSED); playerCharmer->SetClientControl(this, true); playerCharmer->VehicleSpellInitialize(); break; case CHARM_TYPE_POSSESS: - SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_POSSESSED); - charmer->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_REMOVE_CLIENT_CONTROL); + SetUnitFlag(UNIT_FLAG_POSSESSED); + charmer->SetUnitFlag(UNIT_FLAG_REMOVE_CLIENT_CONTROL); playerCharmer->SetClientControl(this, true); playerCharmer->PossessSpellInitialize(); AddUnitState(UNIT_STATE_POSSESSED); @@ -11640,7 +11649,7 @@ bool Unit::SetCharmedBy(Unit* charmer, CharmType type, AuraApplication const* au GetCharmInfo()->SetPetNumber(sObjectMgr->GeneratePetNumber(), true); // if charmed two demons the same session, the 2nd gets the 1st one's name - SetUInt32Value(UNIT_FIELD_PET_NAME_TIMESTAMP, uint32(GameTime::GetGameTime())); // cast can't be helped + SetPetNameTimestamp(uint32(GameTime::GetGameTime())); // cast can't be helped } } playerCharmer->CharmSpellInitialize(); @@ -11719,14 +11728,14 @@ void Unit::RemoveCharmedBy(Unit* charmer) case CHARM_TYPE_VEHICLE: playerCharmer->SetClientControl(this, false); playerCharmer->SetClientControl(charmer, true); - RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_POSSESSED); + RemoveUnitFlag(UNIT_FLAG_POSSESSED); break; case CHARM_TYPE_POSSESS: ClearUnitState(UNIT_STATE_POSSESSED); playerCharmer->SetClientControl(this, false); playerCharmer->SetClientControl(charmer, true); - charmer->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_REMOVE_CLIENT_CONTROL); - RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_POSSESSED); + charmer->RemoveUnitFlag(UNIT_FLAG_REMOVE_CLIENT_CONTROL); + RemoveUnitFlag(UNIT_FLAG_POSSESSED); break; case CHARM_TYPE_CHARM: if (GetTypeId() == TYPEID_UNIT && charmer->GetClass() == CLASS_WARLOCK) @@ -11813,7 +11822,7 @@ void Unit::RemoveVehicleKit() m_updateFlag &= ~UPDATEFLAG_VEHICLE; m_unitTypeMask &= ~UNIT_MASK_VEHICLE; - RemoveFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_SPELLCLICK | UNIT_NPC_FLAG_PLAYER_VEHICLE); + RemoveNpcFlag(UNIT_NPC_FLAG_SPELLCLICK | UNIT_NPC_FLAG_PLAYER_VEHICLE); } bool Unit::IsOnVehicle(Unit const* vehicle) const @@ -11954,9 +11963,9 @@ bool Unit::IsContestedGuard() const void Unit::SetPvP(bool state) { if (state) - SetByteFlag(UNIT_FIELD_BYTES_2, UNIT_BYTES_2_OFFSET_PVP_FLAG, UNIT_BYTE2_FLAG_PVP); + SetPvpFlag(UNIT_BYTE2_FLAG_PVP); else - RemoveByteFlag(UNIT_FIELD_BYTES_2, UNIT_BYTES_2_OFFSET_PVP_FLAG, UNIT_BYTE2_FLAG_PVP); + RemovePvpFlag(UNIT_BYTE2_FLAG_PVP); } Aura* Unit::AddAura(uint32 spellId, Unit* target) @@ -12822,15 +12831,15 @@ bool Unit::IsFalling() const bool Unit::CanSwim() const { // Mirror client behavior, if this method returns false then client will not use swimming animation and for players will apply gravity as if there was no water - if (HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_CANNOT_SWIM)) + if (HasUnitFlag(UNIT_FLAG_CANNOT_SWIM)) return false; - if (HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_PLAYER_CONTROLLED)) // is player + if (HasUnitFlag(UNIT_FLAG_PLAYER_CONTROLLED)) // is player return true; - if (HasFlag(UNIT_FIELD_FLAGS_2, 0x1000000)) + if (HasUnitFlag2(UNIT_FLAG2_UNUSED_6)) return false; - if (HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_PET_IN_COMBAT)) + if (HasUnitFlag(UNIT_FLAG_PET_IN_COMBAT)) return true; - return HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_RENAME | UNIT_FLAG_CAN_SWIM); + return HasUnitFlag(UNIT_FLAG_RENAME | UNIT_FLAG_CAN_SWIM); } void Unit::NearTeleportTo(Position const& pos, bool casting /*= false*/) @@ -13164,7 +13173,7 @@ void Unit::SendClearTarget() SendMessageToSet(&data, false); } -uint32 Unit::GetResistance(SpellSchoolMask mask) const +int32 Unit::GetResistance(SpellSchoolMask mask) const { int32 resist = -1; for (int32 i = SPELL_SCHOOL_NORMAL; i < MAX_SPELL_SCHOOL; ++i) @@ -13172,7 +13181,7 @@ uint32 Unit::GetResistance(SpellSchoolMask mask) const resist = int32(GetResistance(SpellSchools(i))); // resist value will never be negative here - return uint32(resist); + return resist; } void CharmInfo::SetIsCommandAttack(bool val) @@ -13390,6 +13399,11 @@ bool Unit::SetHover(bool enable, bool /*packetOnly = false*/, bool /*updateAnimT return true; } +bool Unit::IsSplineEnabled() const +{ + return movespline->Initialized() && !movespline->Finalized(); +} + void Unit::BuildValuesUpdate(uint8 updateType, ByteBuffer* data, Player* target) const { if (!target) @@ -13409,7 +13423,7 @@ void Unit::BuildValuesUpdate(uint8 updateType, ByteBuffer* data, Player* target) if (GetOwnerGUID() == target->GetGUID()) visibleFlag |= UF_FLAG_OWNER; - if (HasFlag(UNIT_DYNAMIC_FLAGS, UNIT_DYNFLAG_SPECIALINFO)) + if (HasDynamicFlag(UNIT_DYNFLAG_SPECIALINFO)) if (HasAuraTypeWithCaster(SPELL_AURA_EMPATHY, target->GetGUID())) visibleFlag |= UF_FLAG_SPECIAL_INFO; @@ -13661,6 +13675,22 @@ void Unit::Whisper(std::string_view text, Language language, Player* target, boo target->SendDirectMessage(&data); } +uint32 Unit::GetVirtualItemId(uint32 slot) const +{ + if (slot >= MAX_EQUIPMENT_ITEMS) + return 0; + + return GetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_ID + slot); +} + +void Unit::SetVirtualItem(uint32 slot, uint32 itemId) +{ + if (slot >= MAX_EQUIPMENT_ITEMS) + return; + + SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_ID + slot, itemId); +} + void Unit::Talk(uint32 textId, ChatMsg msgType, float textRange, WorldObject const* target) { if (!sObjectMgr->GetBroadcastText(textId)) @@ -13715,7 +13745,7 @@ float Unit::GetCollisionHeight() const if (IsMounted()) { - if (CreatureDisplayInfoEntry const* mountDisplayInfo = sCreatureDisplayInfoStore.LookupEntry(GetUInt32Value(UNIT_FIELD_MOUNTDISPLAYID))) + if (CreatureDisplayInfoEntry const* mountDisplayInfo = sCreatureDisplayInfoStore.LookupEntry(GetMountDisplayId())) { if (CreatureModelDataEntry const* mountModelData = sCreatureModelDataStore.LookupEntry(mountDisplayInfo->ModelID)) { diff --git a/src/server/game/Entities/Unit/Unit.h b/src/server/game/Entities/Unit/Unit.h index 1eeb501dc26..bf8e2b2753e 100644 --- a/src/server/game/Entities/Unit/Unit.h +++ b/src/server/game/Entities/Unit/Unit.h @@ -93,8 +93,13 @@ class UnitAura; class Vehicle; class VehicleJoinEvent; -enum ZLiquidStatus : uint32; enum MovementGeneratorType : uint8; +enum ZLiquidStatus : uint32; + +namespace Movement +{ + class MoveSpline; +} typedef std::list<Unit*> UnitList; @@ -367,10 +372,6 @@ enum UnitTypeMask UNIT_MASK_ACCESSORY = 0x00000200 }; -namespace Movement{ - class MoveSpline; -} - struct DiminishingReturn { DiminishingReturn() : stack(0), hitTime(0), hitCount(DIMINISHING_LEVEL_1) { } @@ -787,6 +788,7 @@ class TC_GAME_API Unit : public WorldObject typedef std::list<AuraEffect*> AuraEffectList; typedef std::list<Aura*> AuraList; typedef std::list<AuraApplication*> AuraApplicationList; + typedef std::array<DiminishingReturn, DIMINISHING_MAX> Diminishing; typedef std::vector<std::pair<uint8 /*procEffectMask*/, AuraApplication*>> AuraApplicationProcContainer; @@ -814,6 +816,9 @@ class TC_GAME_API Unit : public WorldObject void CleanupBeforeRemoveFromMap(bool finalCleanup); void CleanupsBeforeDelete(bool finalCleanup = true) override; // used in ~Creature/~Player (or before mass creature delete to remove cross-references to already deleted units) + uint32 GetDynamicFlags() const override { return GetUInt32Value(UNIT_DYNAMIC_FLAGS); } + void ReplaceAllDynamicFlags(uint32 flag) override { SetUInt32Value(UNIT_DYNAMIC_FLAGS, flag); } + virtual bool IsAffectedByDiminishingReturns() const { return (GetCharmerOrOwnerPlayerOrPlayerItself() != nullptr); } DiminishingLevels GetDiminishing(DiminishingGroup group) const; void IncrDiminishing(SpellInfo const* auraSpellInfo, bool triggered); @@ -830,7 +835,10 @@ class TC_GAME_API Unit : public WorldObject bool haveOffhandWeapon() const; bool CanDualWield() const { return m_canDualWield; } virtual void SetCanDualWield(bool value) { m_canDualWield = value; } - float GetCombatReach() const override { return m_floatValues[UNIT_FIELD_COMBATREACH]; } + float GetCombatReach() const override { return GetFloatValue(UNIT_FIELD_COMBATREACH); } + void SetCombatReach(float combatReach) { SetFloatValue(UNIT_FIELD_COMBATREACH, combatReach); } + float GetBoundingRadius() const { return GetFloatValue(UNIT_FIELD_BOUNDINGRADIUS); } + void SetBoundingRadius(float boundingRadius) { SetFloatValue(UNIT_FIELD_BOUNDINGRADIUS, boundingRadius); } bool IsWithinCombatRange(Unit const* obj, float dist2compare) const; bool IsWithinMeleeRange(Unit const* obj) const { return IsWithinMeleeRangeAt(GetPosition(), obj); } bool IsWithinMeleeRangeAt(Position const& pos, Unit const* obj) const; @@ -884,21 +892,21 @@ class TC_GAME_API Unit : public WorldObject void SetRace(uint8 race) { SetByteValue(UNIT_FIELD_BYTES_0, UNIT_BYTES_0_OFFSET_RACE, race); } uint32 GetRaceMask() const { return 1 << (GetRace() - 1); } uint8 GetClass() const { return GetByteValue(UNIT_FIELD_BYTES_0, UNIT_BYTES_0_OFFSET_CLASS); } - void SetClass(uint8 unitClass) { SetByteValue(UNIT_FIELD_BYTES_0, UNIT_BYTES_0_OFFSET_CLASS, unitClass); } + void SetClass(uint8 classId) { SetByteValue(UNIT_FIELD_BYTES_0, UNIT_BYTES_0_OFFSET_CLASS, classId); } uint32 GetClassMask() const { return 1 << (GetClass() - 1); } - uint8 GetGender() const { return GetByteValue(UNIT_FIELD_BYTES_0, UNIT_BYTES_0_OFFSET_GENDER); } - void SetGender(uint8 gender) { SetByteValue(UNIT_FIELD_BYTES_0, UNIT_BYTES_0_OFFSET_GENDER, gender); } - virtual uint8 GetNativeGender() const { return GetGender(); } - virtual void SetNativeGender(uint8 gender) { SetGender(gender); } + Gender GetGender() const { return Gender(GetByteValue(UNIT_FIELD_BYTES_0, UNIT_BYTES_0_OFFSET_GENDER)); } + void SetGender(Gender gender) { SetByteValue(UNIT_FIELD_BYTES_0, UNIT_BYTES_0_OFFSET_GENDER, gender); } + virtual Gender GetNativeGender() const { return GetGender(); } + virtual void SetNativeGender(Gender gender) { SetGender(gender); } float GetStat(Stats stat) const { return float(GetUInt32Value(UNIT_FIELD_STAT0+stat)); } void SetStat(Stats stat, int32 val) { SetStatInt32Value(UNIT_FIELD_STAT0+stat, val); } uint32 GetArmor() const { return GetResistance(SPELL_SCHOOL_NORMAL); } void SetArmor(int32 val) { SetResistance(SPELL_SCHOOL_NORMAL, val); } - uint32 GetResistance(SpellSchools school) const { return GetUInt32Value(UNIT_FIELD_RESISTANCES+school); } - uint32 GetResistance(SpellSchoolMask mask) const; - void SetResistance(SpellSchools school, int32 val) { SetStatInt32Value(UNIT_FIELD_RESISTANCES+school, val); } + int32 GetResistance(SpellSchools school) const { return GetInt32Value(UNIT_FIELD_RESISTANCES + school); } + int32 GetResistance(SpellSchoolMask mask) const; + void SetResistance(SpellSchools school, int32 val) { SetStatInt32Value(UNIT_FIELD_RESISTANCES + school, val); } static float CalculateAverageResistReduction(WorldObject const* caster, SpellSchoolMask schoolMask, Unit const* victim, SpellInfo const* spellInfo = nullptr); uint32 GetHealth() const { return GetUInt32Value(UNIT_FIELD_HEALTH); } @@ -924,6 +932,8 @@ class TC_GAME_API Unit : public WorldObject void UpdateDisplayPower(); uint32 GetPower(Powers power) const { return GetUInt32Value(UNIT_FIELD_POWER1 +power); } uint32 GetMaxPower(Powers power) const { return GetUInt32Value(UNIT_FIELD_MAXPOWER1+power); } + float GetPowerPct(Powers power) const { return GetMaxPower(power) ? 100.f * GetPower(power) / GetMaxPower(power) : 0.0f; } + int32 CountPctFromMaxPower(Powers power, int32 pct) const { return CalculatePct(GetMaxPower(power), pct); } void SetPower(Powers power, uint32 val, bool withPowerUpdate = true); void SetMaxPower(Powers power, uint32 val); inline void SetFullPower(Powers power) { SetPower(power, GetMaxPower(power)); } @@ -935,6 +945,25 @@ class TC_GAME_API Unit : public WorldObject void ApplyAttackTimePercentMod(WeaponAttackType att, float val, bool apply); void ApplyCastTimePercentMod(float val, bool apply); + void SetModCastingSpeed(float castingSpeed) { SetFloatValue(UNIT_MOD_CAST_SPEED, castingSpeed); } + + UnitFlags GetUnitFlags() const { return UnitFlags(GetUInt32Value(UNIT_FIELD_FLAGS)); } + bool HasUnitFlag(UnitFlags flags) const { return HasFlag(UNIT_FIELD_FLAGS, flags); } + void SetUnitFlag(UnitFlags flags) { SetFlag(UNIT_FIELD_FLAGS, flags); } + void RemoveUnitFlag(UnitFlags flags) { RemoveFlag(UNIT_FIELD_FLAGS, flags); } + void ReplaceAllUnitFlags(UnitFlags flags) { SetUInt32Value(UNIT_FIELD_FLAGS, flags); } + + UnitFlags2 GetUnitFlags2() const { return UnitFlags2(GetUInt32Value(UNIT_FIELD_FLAGS_2)); } + bool HasUnitFlag2(UnitFlags2 flags) const { return HasFlag(UNIT_FIELD_FLAGS_2, flags); } + void SetUnitFlag2(UnitFlags2 flags) { SetFlag(UNIT_FIELD_FLAGS_2, flags); } + void RemoveUnitFlag2(UnitFlags2 flags) { RemoveFlag(UNIT_FIELD_FLAGS_2, flags); } + void ReplaceAllUnitFlags2(UnitFlags2 flags) { SetUInt32Value(UNIT_FIELD_FLAGS_2, flags); } + + void SetCreatedBySpell(int32 spellId) { SetUInt32Value(UNIT_CREATED_BY_SPELL, spellId); } + + Emote GetEmoteState() const { return Emote(GetUInt32Value(UNIT_NPC_EMOTESTATE)); } + void SetEmoteState(Emote emote) { SetUInt32Value(UNIT_NPC_EMOTESTATE, emote); } + SheathState GetSheath() const { return SheathState(GetByteValue(UNIT_FIELD_BYTES_2, UNIT_BYTES_2_OFFSET_SHEATH_STATE)); } virtual void SetSheath(SheathState sheathed) { SetByteValue(UNIT_FIELD_BYTES_2, UNIT_BYTES_2_OFFSET_SHEATH_STATE, sheathed); } @@ -946,27 +975,42 @@ class TC_GAME_API Unit : public WorldObject bool IsInRaidWith(Unit const* unit) const; void GetPartyMembers(std::list<Unit*> &units); bool IsContestedGuard() const; - bool IsInSanctuary() const { return HasByteFlag(UNIT_FIELD_BYTES_2, UNIT_BYTES_2_OFFSET_PVP_FLAG, UNIT_BYTE2_FLAG_SANCTUARY); } - bool IsPvP() const { return HasByteFlag(UNIT_FIELD_BYTES_2, UNIT_BYTES_2_OFFSET_PVP_FLAG, UNIT_BYTE2_FLAG_PVP); } - bool IsFFAPvP() const { return HasByteFlag(UNIT_FIELD_BYTES_2, UNIT_BYTES_2_OFFSET_PVP_FLAG, UNIT_BYTE2_FLAG_FFA_PVP); } + + UnitPVPStateFlags GetPvpFlags() const { return UnitPVPStateFlags(GetByteValue(UNIT_FIELD_BYTES_2, UNIT_BYTES_2_OFFSET_PVP_FLAG)); } + bool HasPvpFlag(UnitPVPStateFlags flags) const { return HasByteFlag(UNIT_FIELD_BYTES_2, UNIT_BYTES_2_OFFSET_PVP_FLAG, flags); } + void SetPvpFlag(UnitPVPStateFlags flags) { SetByteFlag(UNIT_FIELD_BYTES_2, UNIT_BYTES_2_OFFSET_PVP_FLAG, flags); } + void RemovePvpFlag(UnitPVPStateFlags flags) { RemoveByteFlag(UNIT_FIELD_BYTES_2, UNIT_BYTES_2_OFFSET_PVP_FLAG, flags); } + void ReplaceAllPvpFlags(UnitPVPStateFlags flags) { SetByteValue(UNIT_FIELD_BYTES_2, UNIT_BYTES_2_OFFSET_PVP_FLAG, flags); } + + bool IsInSanctuary() const { return HasPvpFlag(UNIT_BYTE2_FLAG_SANCTUARY); } + bool IsPvP() const { return HasPvpFlag(UNIT_BYTE2_FLAG_PVP); } + bool IsFFAPvP() const { return HasPvpFlag(UNIT_BYTE2_FLAG_FFA_PVP); } virtual void SetPvP(bool state); + UnitPetFlag GetPetFlags() const { return UnitPetFlag(GetByteValue(UNIT_FIELD_BYTES_2, UNIT_BYTES_2_OFFSET_PET_FLAGS)); } + bool HasPetFlag(UnitPetFlag flags) const { return HasByteFlag(UNIT_FIELD_BYTES_2, UNIT_BYTES_2_OFFSET_PET_FLAGS, flags); } + void SetPetFlag(UnitPetFlag flags) { SetByteFlag(UNIT_FIELD_BYTES_2, UNIT_BYTES_2_OFFSET_PET_FLAGS, flags); } + void RemovePetFlag(UnitPetFlag flags) { RemoveByteFlag(UNIT_FIELD_BYTES_2, UNIT_BYTES_2_OFFSET_PET_FLAGS, flags); } + void ReplaceAllPetFlags(UnitPetFlag flags) { SetByteValue(UNIT_FIELD_BYTES_2, UNIT_BYTES_2_OFFSET_PET_FLAGS, flags); } + uint32 GetCreatureType() const; uint32 GetCreatureTypeMask() const; - uint8 GetStandState() const { return GetByteValue(UNIT_FIELD_BYTES_1, UNIT_BYTES_1_OFFSET_STAND_STATE); } + UnitStandStateType GetStandState() const { return UnitStandStateType(GetByteValue(UNIT_FIELD_BYTES_1, UNIT_BYTES_1_OFFSET_STAND_STATE)); } bool IsSitState() const; bool IsStandState() const; - void SetStandState(uint8 state); + void SetStandState(UnitStandStateType state); - void SetAnimTier(AnimTier tier); - AnimTier GetAnimTier() const { return static_cast<AnimTier>(GetByteValue(UNIT_FIELD_BYTES_1, UNIT_BYTES_1_OFFSET_ANIM_TIER)); } + void SetVisFlag(UnitVisFlags flags) { SetByteFlag(UNIT_FIELD_BYTES_1, UNIT_BYTES_1_OFFSET_VIS_FLAG, flags); } + void RemoveVisFlag(UnitVisFlags flags) { RemoveByteFlag(UNIT_FIELD_BYTES_1, UNIT_BYTES_1_OFFSET_VIS_FLAG, flags); } + void ReplaceAllVisFlags(UnitVisFlags flags) { SetByteValue(UNIT_FIELD_BYTES_1, UNIT_BYTES_1_OFFSET_VIS_FLAG, flags); } - void SetStandFlags(uint8 flags) { SetByteFlag(UNIT_FIELD_BYTES_1, UNIT_BYTES_1_OFFSET_VIS_FLAG, flags); } - void RemoveStandFlags(uint8 flags) { RemoveByteFlag(UNIT_FIELD_BYTES_1, UNIT_BYTES_1_OFFSET_VIS_FLAG, flags); } + AnimTier GetAnimTier() const { return AnimTier(GetByteValue(UNIT_FIELD_BYTES_1, UNIT_BYTES_1_OFFSET_ANIM_TIER)); } + void SetAnimTier(AnimTier animTier); - bool IsMounted() const { return HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_MOUNT); } - uint32 GetMountID() const { return GetUInt32Value(UNIT_FIELD_MOUNTDISPLAYID); } + bool IsMounted() const { return HasUnitFlag(UNIT_FLAG_MOUNT); } + uint32 GetMountDisplayId() const { return GetUInt32Value(UNIT_FIELD_MOUNTDISPLAYID); } + void SetMountDisplayId(uint32 mountDisplayId) { SetUInt32Value(UNIT_FIELD_MOUNTDISPLAYID, mountDisplayId); } void Mount(uint32 mount, uint32 vehicleId = 0, uint32 creatureEntry = 0); void Dismount(); @@ -1001,7 +1045,7 @@ class TC_GAME_API Unit : public WorldObject ObjectGuid GetLastDamagedTargetGuid() const { return _lastDamagedTargetGuid; } void CalculateSpellDamageTaken(SpellNonMeleeDamage* damageInfo, int32 damage, SpellInfo const* spellInfo, WeaponAttackType attackType = BASE_ATTACK, bool crit = false, Spell* spell = nullptr); - void DealSpellDamage(SpellNonMeleeDamage* damageInfo, bool durabilityLoss); + void DealSpellDamage(SpellNonMeleeDamage const* damageInfo, bool durabilityLoss); // player or player's pet resilience (-1%) float GetMeleeCritChanceReduction() const { return GetCombatRatingReduction(CR_CRIT_TAKEN_MELEE); } @@ -1040,27 +1084,34 @@ class TC_GAME_API Unit : public WorldObject uint32 GetShieldBlockValue(uint32 soft_cap, uint32 hard_cap) const; uint32 GetDefenseSkillValue(Unit const* target = nullptr) const; uint32 GetWeaponSkillValue(WeaponAttackType attType, Unit const* target = nullptr) const; + float GetWeaponProcChance() const; float GetPPMProcChance(uint32 WeaponSpeed, float PPM, SpellInfo const* spellProto) const; MeleeHitOutcome RollMeleeOutcomeAgainst(Unit const* victim, WeaponAttackType attType) const; - bool IsVendor() const { return HasFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_VENDOR); } - bool IsTrainer() const { return HasFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_TRAINER); } - bool IsQuestGiver() const { return HasFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_QUESTGIVER); } - bool IsGossip() const { return HasFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_GOSSIP); } - bool IsTaxi() const { return HasFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_FLIGHTMASTER); } - bool IsGuildMaster() const { return HasFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_PETITIONER); } - bool IsBattleMaster() const { return HasFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_BATTLEMASTER); } - bool IsBanker() const { return HasFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_BANKER); } - bool IsInnkeeper() const { return HasFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_INNKEEPER); } - bool IsSpiritHealer() const { return HasFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_SPIRITHEALER); } - bool IsSpiritGuide() const { return HasFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_SPIRITGUIDE); } - bool IsTabardDesigner()const { return HasFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_TABARDDESIGNER); } - bool IsAuctioner() const { return HasFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_AUCTIONEER); } - bool IsArmorer() const { return HasFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_REPAIR); } + NPCFlags GetNpcFlags() const { return NPCFlags(GetUInt32Value(UNIT_NPC_FLAGS)); } + bool HasNpcFlag(NPCFlags flags) const { return HasFlag(UNIT_NPC_FLAGS, flags) != 0; } + void SetNpcFlag(NPCFlags flags) { SetFlag(UNIT_NPC_FLAGS, flags); } + void RemoveNpcFlag(NPCFlags flags) { RemoveFlag(UNIT_NPC_FLAGS, flags); } + void ReplaceAllNpcFlags(NPCFlags flags) { SetUInt32Value(UNIT_NPC_FLAGS, flags); } + + bool IsVendor() const { return HasNpcFlag(UNIT_NPC_FLAG_VENDOR); } + bool IsTrainer() const { return HasNpcFlag(UNIT_NPC_FLAG_TRAINER); } + bool IsQuestGiver() const { return HasNpcFlag(UNIT_NPC_FLAG_QUESTGIVER); } + bool IsGossip() const { return HasNpcFlag(UNIT_NPC_FLAG_GOSSIP); } + bool IsTaxi() const { return HasNpcFlag(UNIT_NPC_FLAG_FLIGHTMASTER); } + bool IsGuildMaster() const { return HasNpcFlag(UNIT_NPC_FLAG_PETITIONER); } + bool IsBattleMaster() const { return HasNpcFlag(UNIT_NPC_FLAG_BATTLEMASTER); } + bool IsBanker() const { return HasNpcFlag(UNIT_NPC_FLAG_BANKER); } + bool IsInnkeeper() const { return HasNpcFlag(UNIT_NPC_FLAG_INNKEEPER); } + bool IsSpiritHealer() const { return HasNpcFlag(UNIT_NPC_FLAG_SPIRITHEALER); } + bool IsSpiritGuide() const { return HasNpcFlag(UNIT_NPC_FLAG_SPIRITGUIDE); } + bool IsTabardDesigner() const { return HasNpcFlag(UNIT_NPC_FLAG_TABARDDESIGNER); } + bool IsAuctioner() const { return HasNpcFlag(UNIT_NPC_FLAG_AUCTIONEER); } + bool IsArmorer() const { return HasNpcFlag(UNIT_NPC_FLAG_REPAIR); } bool IsServiceProvider() const; - bool IsSpiritService() const { return HasFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_SPIRITHEALER | UNIT_NPC_FLAG_SPIRITGUIDE); } + bool IsSpiritService() const { return HasNpcFlag(UNIT_NPC_FLAG_SPIRITHEALER | UNIT_NPC_FLAG_SPIRITGUIDE); } bool IsCritter() const { return GetCreatureType() == CREATURE_TYPE_CRITTER; } bool IsInFlight() const { return HasUnitState(UNIT_STATE_IN_FLIGHT); } @@ -1081,14 +1132,14 @@ class TC_GAME_API Unit : public WorldObject bool IsImmuneToAll() const { return IsImmuneToPC() && IsImmuneToNPC(); } void SetImmuneToAll(bool apply, bool keepCombat); virtual void SetImmuneToAll(bool apply) { SetImmuneToAll(apply, false); } - bool IsImmuneToPC() const { return HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_IMMUNE_TO_PC); } + bool IsImmuneToPC() const { return HasUnitFlag(UNIT_FLAG_IMMUNE_TO_PC); } void SetImmuneToPC(bool apply, bool keepCombat); virtual void SetImmuneToPC(bool apply) { SetImmuneToPC(apply, false); } - bool IsImmuneToNPC() const { return HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_IMMUNE_TO_NPC); } + bool IsImmuneToNPC() const { return HasUnitFlag(UNIT_FLAG_IMMUNE_TO_NPC); } void SetImmuneToNPC(bool apply, bool keepCombat); virtual void SetImmuneToNPC(bool apply) { SetImmuneToNPC(apply, false); } - bool IsInCombat() const { return HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_IN_COMBAT); } + bool IsInCombat() const { return HasUnitFlag(UNIT_FLAG_IN_COMBAT); } bool IsInCombatWith(Unit const* who) const { return who && m_combatManager.IsInCombatWith(who); } void SetInCombatWith(Unit* enemy) { if (enemy) m_combatManager.SetInCombatWith(enemy); } void ClearInCombat() { m_combatManager.EndAllCombat(); } @@ -1104,7 +1155,7 @@ class TC_GAME_API Unit : public WorldObject void SendClearTarget(); - bool HasAuraTypeWithFamilyFlags(AuraType auraType, uint32 familyName, uint32 familyFlags) const; + bool HasAuraTypeWithFamilyFlags(AuraType auraType, uint32 familyName, flag96 familyFlags) const; bool virtual HasSpell(uint32 /*spellID*/) const { return false; } bool HasBreakableByDamageAuraType(AuraType type, uint32 excludeAura = 0) const; bool HasBreakableByDamageCrowdControlAura(Unit* excludeCasterChannel = nullptr) const; @@ -1138,7 +1189,7 @@ class TC_GAME_API Unit : public WorldObject void SendAttackStateUpdate(CalcDamageInfo* damageInfo); void SendAttackStateUpdate(uint32 HitInfo, Unit* target, uint8 SwingType, SpellSchoolMask damageSchoolMask, uint32 Damage, uint32 AbsorbDamage, uint32 Resist, VictimState TargetState, uint32 BlockedAmount); - void SendSpellNonMeleeDamageLog(SpellNonMeleeDamage* log); + void SendSpellNonMeleeDamageLog(SpellNonMeleeDamage const* log); void SendSpellNonMeleeDamageLog(Unit* target, uint32 spellID, uint32 damage, SpellSchoolMask damageSchoolMask, uint32 absorbedDamage, uint32 resist, bool isPeriodic, uint32 blocked, bool criticalHit = false, bool split = false); void SendPeriodicAuraLog(SpellPeriodicAuraLogInfo* pInfo); void SendSpellDamageResist(Unit* target, uint32 spellId); @@ -1158,10 +1209,10 @@ class TC_GAME_API Unit : public WorldObject void JumpTo(WorldObject* obj, float speedZ, bool withOrientation = false); void MonsterMoveWithSpeed(float x, float y, float z, float speed, bool generatePath = false, bool forceDestination = false); - //void SetFacing(float ori, WorldObject* obj = nullptr); - //void SendMonsterMove(float NewPosX, float NewPosY, float NewPosZ, uint8 type, uint32 MovementFlags, uint32 Time, Player* player = nullptr); void SendMovementFlagUpdate(bool self = false); + void SetHoverHeight(float hoverHeight) { SetFloatValue(UNIT_FIELD_HOVERHEIGHT, hoverHeight); } + bool IsGravityDisabled() const { return m_movementInfo.HasMovementFlag(MOVEMENTFLAG_DISABLE_GRAVITY); } bool IsWalking() const { return m_movementInfo.HasMovementFlag(MOVEMENTFLAG_WALKING); } bool IsHovering() const { return m_movementInfo.HasMovementFlag(MOVEMENTFLAG_HOVER); } @@ -1192,10 +1243,10 @@ class TC_GAME_API Unit : public WorldObject void SetCreatorGUID(ObjectGuid creator) { SetGuidValue(UNIT_FIELD_CREATEDBY, creator); } ObjectGuid GetMinionGUID() const { return GetGuidValue(UNIT_FIELD_SUMMON); } void SetMinionGUID(ObjectGuid guid) { SetGuidValue(UNIT_FIELD_SUMMON, guid); } - void SetPetGUID(ObjectGuid guid) { m_SummonSlot[SUMMON_SLOT_PET] = guid; } ObjectGuid GetPetGUID() const { return m_SummonSlot[SUMMON_SLOT_PET]; } - void SetCritterGUID(ObjectGuid guid) { SetGuidValue(UNIT_FIELD_CRITTER, guid); } + void SetPetGUID(ObjectGuid guid) { m_SummonSlot[SUMMON_SLOT_PET] = guid; } ObjectGuid GetCritterGUID() const { return GetGuidValue(UNIT_FIELD_CRITTER); } + void SetCritterGUID(ObjectGuid guid) { SetGuidValue(UNIT_FIELD_CRITTER, guid); } ObjectGuid GetCharmerGUID() const { return GetGuidValue(UNIT_FIELD_CHARMEDBY); } Unit* GetCharmer() const { return m_charmer; } @@ -1235,6 +1286,8 @@ class TC_GAME_API Unit : public WorldObject CharmInfo* GetCharmInfo() { return m_charmInfo; } CharmInfo* InitCharmInfo(); void DeleteCharmInfo(); + void SetPetNumberForClient(uint32 petNumber) { SetUInt32Value(UNIT_FIELD_PETNUMBER, petNumber); } + void SetPetNameTimestamp(uint32 timestamp) { SetUInt32Value(UNIT_FIELD_PET_NAME_TIMESTAMP, timestamp); } // base client control of this unit (possess effects, vehicles and similar). Not affected by temporary CC. bool IsCharmerOrSelfPlayer() const { return GetCharmerOrSelf()->IsPlayer(); } @@ -1328,6 +1381,7 @@ class TC_GAME_API Unit : public WorldObject void _ApplyAllAuraStatMods(); AuraEffectList const& GetAuraEffectsByType(AuraType type) const { return m_modAuras[type]; } + AuraEffectList& GetAuraEffectsByType(AuraType type) { return m_modAuras[type]; } AuraList & GetSingleCastAuras() { return m_scAuras; } AuraList const& GetSingleCastAuras() const { return m_scAuras; } @@ -1400,6 +1454,8 @@ class TC_GAME_API Unit : public WorldObject float GetNegStat(Stats stat) const { return GetFloatValue(UNIT_FIELD_NEGSTAT0+stat); } float GetCreateStat(Stats stat) const { return m_createStats[stat]; } + uint32 GetChannelSpellId() const { return GetUInt32Value(UNIT_CHANNEL_SPELL); } + void SetChannelSpellId(uint32 channelSpellId) { SetUInt32Value(UNIT_CHANNEL_SPELL, channelSpellId); } ObjectGuid GetChannelObjectGuid() const { return GetGuidValue(UNIT_FIELD_CHANNEL_OBJECT); } void SetChannelObjectGuid(ObjectGuid guid) { SetGuidValue(UNIT_FIELD_CHANNEL_OBJECT, guid); } @@ -1424,8 +1480,8 @@ class TC_GAME_API Unit : public WorldObject virtual bool HasSpellFocus(Spell const* /*focusSpell*/ = nullptr) const { return false; } virtual bool IsMovementPreventedByCasting() const; - SpellHistory* GetSpellHistory() { return m_spellHistory; } - SpellHistory const* GetSpellHistory() const { return m_spellHistory; } + SpellHistory* GetSpellHistory() { return _spellHistory; } + SpellHistory const* GetSpellHistory() const { return _spellHistory; } ObjectGuid m_SummonSlot[MAX_SUMMON_SLOT]; ObjectGuid m_ObjectSlot[MAX_GAMEOBJECT_SLOT]; @@ -1443,6 +1499,7 @@ class TC_GAME_API Unit : public WorldObject int32 m_baseSpellCritChance; float m_modAttackSpeedPct[MAX_ATTACK]; + uint32 m_attackTimer[MAX_ATTACK]; // stat system void HandleStatFlatModifier(UnitMods unitMod, UnitModifierFlatType modifierType, float amount, bool apply); @@ -1480,6 +1537,14 @@ class TC_GAME_API Unit : public WorldObject virtual void UpdateMaxHealth() = 0; virtual void UpdateMaxPower(Powers power) = 0; virtual void UpdateAttackPowerAndDamage(bool ranged = false) = 0; + void SetAttackPower(int32 attackPower) { SetInt32Value(UNIT_FIELD_ATTACK_POWER, attackPower); } + void SetAttackPowerModPos(int32 attackPowerMod) { SetInt16Value(UNIT_FIELD_ATTACK_POWER_MODS, 0, attackPowerMod); } + void SetAttackPowerModNeg(int32 attackPowerMod) { SetInt16Value(UNIT_FIELD_ATTACK_POWER_MODS, 1, attackPowerMod); } + void SetAttackPowerMultiplier(float attackPowerMult) { SetFloatValue(UNIT_FIELD_ATTACK_POWER_MULTIPLIER, attackPowerMult); } + void SetRangedAttackPower(int32 attackPower) { SetInt32Value(UNIT_FIELD_RANGED_ATTACK_POWER, attackPower); } + void SetRangedAttackPowerModPos(int32 attackPowerMod) { SetInt16Value(UNIT_FIELD_RANGED_ATTACK_POWER_MODS, 0, attackPowerMod); } + void SetRangedAttackPowerModNeg(int32 attackPowerMod) { SetInt16Value(UNIT_FIELD_RANGED_ATTACK_POWER_MODS, 1, attackPowerMod); } + void SetRangedAttackPowerMultiplier(float attackPowerMult) { SetFloatValue(UNIT_FIELD_RANGED_ATTACK_POWER_MULTIPLIER, attackPowerMult); } virtual void UpdateDamagePhysical(WeaponAttackType attType); float GetTotalAttackPowerValue(WeaponAttackType attType) const; float GetWeaponDamageRange(WeaponAttackType attType, WeaponDamageRange type, uint8 damageIndex = 0) const; @@ -1502,13 +1567,13 @@ class TC_GAME_API Unit : public WorldObject SpellImmuneContainer m_spellImmune[MAX_SPELL_IMMUNITY]; uint32 m_lastSanctuaryTime; - VisibleAuraMap const* GetVisibleAuras() { return &m_visibleAuras; } - AuraApplication * GetVisibleAura(uint8 slot) const; - void SetVisibleAura(uint8 slot, AuraApplication * aur); + VisibleAuraMap const& GetVisibleAuras() const { return m_visibleAuras; } + AuraApplication* GetVisibleAura(uint8 slot) const; + void SetVisibleAura(uint8 slot, AuraApplication* aurApp); void RemoveVisibleAura(uint8 slot); - uint32 GetInterruptMask() const { return m_interruptMask; } - void AddInterruptMask(uint32 mask) { m_interruptMask |= mask; } + bool HasInterruptFlag(uint32 flags) const { return (m_interruptMask & flags) != 0; } + void AddInterruptMask(uint32 flags) { m_interruptMask |= flags; } void UpdateInterruptMask(); virtual float GetNativeObjectScale() const { return 1.0f; } @@ -1517,25 +1582,27 @@ class TC_GAME_API Unit : public WorldObject virtual void SetDisplayId(uint32 modelId); uint32 GetNativeDisplayId() const { return GetUInt32Value(UNIT_FIELD_NATIVEDISPLAYID); } void RestoreDisplayId(); - void SetNativeDisplayId(uint32 modelId) { SetUInt32Value(UNIT_FIELD_NATIVEDISPLAYID, modelId); } + void SetNativeDisplayId(uint32 displayId) { SetUInt32Value(UNIT_FIELD_NATIVEDISPLAYID, displayId); } void SetTransformSpell(uint32 spellid) { m_transformSpell = spellid;} uint32 GetTransformSpell() const { return m_transformSpell;} // DynamicObject management void _RegisterDynObject(DynamicObject* dynObj); void _UnregisterDynObject(DynamicObject* dynObj); - DynamicObject* GetDynObject(uint32 spellId); + DynamicObject* GetDynObject(uint32 spellId) const; + std::vector<DynamicObject*> GetDynObjects(uint32 spellId) const; void RemoveDynObject(uint32 spellId); void RemoveAllDynObjects(); GameObject* GetGameObject(uint32 spellId) const; + std::vector<GameObject*> GetGameObjects(uint32 spellId) const; void AddGameObject(GameObject* gameObj); void RemoveGameObject(GameObject* gameObj, bool del); void RemoveGameObject(uint32 spellid, bool del); void RemoveAllGameObjects(); void ModifyAuraState(AuraStateType flag, bool apply); - uint32 BuildAuraStateUpdateForTarget(Unit* target) const; + uint32 BuildAuraStateUpdateForTarget(Unit const* target) const; bool HasAuraState(AuraStateType flag, SpellInfo const* spellProto = nullptr, Unit const* Caster = nullptr) const; void UnsummonAllTotems(); bool IsMagnet() const; @@ -1606,17 +1673,19 @@ class TC_GAME_API Unit : public WorldObject void PauseMovement(uint32 timer = 0, uint8 slot = 0, bool forced = true); // timer in ms void ResumeMovement(uint32 timer = 0, uint8 slot = 0); // timer in ms - void AddUnitMovementFlag(uint32 f) { m_movementInfo.flags |= f; } - void RemoveUnitMovementFlag(uint32 f) { m_movementInfo.flags &= ~f; } - bool HasUnitMovementFlag(uint32 f) const { return (m_movementInfo.flags & f) == f; } - uint32 GetUnitMovementFlags() const { return m_movementInfo.flags; } - void SetUnitMovementFlags(uint32 f) { m_movementInfo.flags = f; } + void AddUnitMovementFlag(uint32 f) { m_movementInfo.AddMovementFlag(f); } + void RemoveUnitMovementFlag(uint32 f) { m_movementInfo.RemoveMovementFlag(f); } + bool HasUnitMovementFlag(uint32 f) const { return m_movementInfo.HasMovementFlag(f); } + uint32 GetUnitMovementFlags() const { return m_movementInfo.GetMovementFlags(); } + void SetUnitMovementFlags(uint32 f) { m_movementInfo.SetMovementFlags(f); } + + void AddExtraUnitMovementFlag(uint32 f) { m_movementInfo.AddExtraMovementFlag(f); } + void RemoveExtraUnitMovementFlag(uint32 f) { m_movementInfo.RemoveExtraMovementFlag(f); } + bool HasExtraUnitMovementFlag(uint32 f) const { return m_movementInfo.HasExtraMovementFlag(f); } + uint32 GetExtraUnitMovementFlags() const { return m_movementInfo.GetExtraMovementFlags(); } + void SetExtraUnitMovementFlags(uint32 f) { m_movementInfo.SetExtraMovementFlags(f); } - void AddExtraUnitMovementFlag(uint16 f) { m_movementInfo.flags2 |= f; } - void RemoveExtraUnitMovementFlag(uint16 f) { m_movementInfo.flags2 &= ~f; } - uint16 HasExtraUnitMovementFlag(uint16 f) const { return m_movementInfo.flags2 & f; } - uint16 GetExtraUnitMovementFlags() const { return m_movementInfo.flags2; } - void SetExtraUnitMovementFlags(uint16 f) { m_movementInfo.flags2 = f; } + bool IsSplineEnabled() const; void SetControlled(bool apply, UnitState state); void ApplyControlStatesIfNeeded(); @@ -1637,8 +1706,8 @@ class TC_GAME_API Unit : public WorldObject void ClearComboPointHolders(); ///----------Pet responses methods----------------- - void SendPetActionFeedback (uint8 msg); - void SendPetTalk (uint32 pettalk); + void SendPetActionFeedback(uint8 msg); + void SendPetTalk(uint32 pettalk); void SendPetAIReaction(ObjectGuid guid); ///----------End of Pet responses methods---------- @@ -1748,6 +1817,8 @@ class TC_GAME_API Unit : public WorldObject virtual void Whisper(uint32 textId, Player* target, bool isBossWhisper = false); float GetCollisionHeight() const override; + uint32 GetVirtualItemId(uint32 slot) const; + void SetVirtualItem(uint32 slot, uint32 itemId); // returns if the unit can't enter combat bool IsCombatDisallowed() const { return _isCombatDisallowed; } @@ -1755,6 +1826,7 @@ class TC_GAME_API Unit : public WorldObject void SetIsCombatDisallowed(bool apply) { _isCombatDisallowed = apply; } std::string GetDebugInfo() const override; + protected: explicit Unit (bool isWorldObject); @@ -1769,8 +1841,6 @@ class TC_GAME_API Unit : public WorldObject bool m_AutoRepeatFirstCast; - uint32 m_attackTimer[MAX_ATTACK]; - float m_createStats[MAX_STATS]; AttackerSet m_attackers; @@ -1806,6 +1876,7 @@ class TC_GAME_API Unit : public WorldObject float m_auraPctModifiersGroup[UNIT_MOD_END][MODIFIER_TYPE_PCT_END]; float m_weaponDamage[MAX_ATTACK][2][2]; bool m_canModifyStats; + VisibleAuraMap m_visibleAuras; float m_speed_rate[MAX_MOVE_TYPE]; @@ -1856,7 +1927,6 @@ class TC_GAME_API Unit : public WorldObject void ProcSkillsAndReactives(bool isVictim, Unit* procTarget, uint32 typeMask, uint32 hitMask, WeaponAttackType attType); protected: - void SetFeared(bool apply); void SetConfused(bool apply); void SetStunned(bool apply); @@ -1870,7 +1940,7 @@ class TC_GAME_API Unit : public WorldObject uint32 m_lastManaUse; // msecs TimeTracker m_splineSyncTimer; - DiminishingReturn m_Diminishing[DIMINISHING_MAX]; + Diminishing m_Diminishing; // Threat+combat management friend class CombatManager; @@ -1902,7 +1972,8 @@ class TC_GAME_API Unit : public WorldObject uint32 _oldFactionId; ///< faction before charm bool _isWalkingBeforeCharm; ///< Are we walking before we were charmed? - SpellHistory* m_spellHistory; + SpellHistory* _spellHistory; + PositionUpdateInfo _positionUpdateInfo; bool _isCombatDisallowed; @@ -1928,15 +1999,15 @@ namespace Trinity { Unit const* a = objA->ToUnit(); Unit const* b = objB->ToUnit(); - float rA = (a && a->GetMaxPower(_power)) ? float(a->GetPower(_power)) / float(a->GetMaxPower(_power)) : 0.0f; - float rB = (b && b->GetMaxPower(_power)) ? float(b->GetPower(_power)) / float(b->GetMaxPower(_power)) : 0.0f; + float rA = a ? a->GetPowerPct(_power) : 0.0f; + float rB = b ? b->GetPowerPct(_power) : 0.0f; return _ascending ? rA < rB : rA > rB; } bool operator()(Unit const* a, Unit const* b) const { - float rA = a->GetMaxPower(_power) ? float(a->GetPower(_power)) / float(a->GetMaxPower(_power)) : 0.0f; - float rB = b->GetMaxPower(_power) ? float(b->GetPower(_power)) / float(b->GetMaxPower(_power)) : 0.0f; + float rA = a->GetPowerPct(_power); + float rB = b->GetPowerPct(_power); return _ascending ? rA < rB : rA > rB; } diff --git a/src/server/game/Entities/Unit/UnitDefines.h b/src/server/game/Entities/Unit/UnitDefines.h index 269798d99bb..b95c0d4c1ac 100644 --- a/src/server/game/Entities/Unit/UnitDefines.h +++ b/src/server/game/Entities/Unit/UnitDefines.h @@ -19,6 +19,7 @@ #define UnitDefines_h__ #include "Define.h" +#include "EnumFlag.h" #include <string> #define BASE_MINDAMAGE 1.0f @@ -43,14 +44,14 @@ enum UnitStandStateType : uint8 }; // byte flag value (UNIT_FIELD_BYTES_1, 2) -enum UnitStandFlags : uint8 +enum UnitVisFlags : uint8 { - UNIT_STAND_FLAGS_UNK1 = 0x01, - UNIT_STAND_FLAGS_CREEP = 0x02, - UNIT_STAND_FLAGS_UNTRACKABLE = 0x04, - UNIT_STAND_FLAGS_UNK4 = 0x08, - UNIT_STAND_FLAGS_UNK5 = 0x10, - UNIT_STAND_FLAGS_ALL = 0xFF + UNIT_VIS_FLAGS_UNK1 = 0x01, + UNIT_VIS_FLAGS_CREEP = 0x02, + UNIT_VIS_FLAGS_UNTRACKABLE = 0x04, + UNIT_VIS_FLAGS_UNK4 = 0x08, + UNIT_VIS_FLAGS_UNK5 = 0x10, + UNIT_VIS_FLAGS_ALL = 0xFF }; enum UnitBytes0Offsets : uint8 @@ -100,6 +101,7 @@ enum SheathState : uint8 // byte (1 from 0..3) of UNIT_FIELD_BYTES_2 enum UnitPVPStateFlags : uint8 { + UNIT_BYTE2_FLAG_NONE = 0x00, UNIT_BYTE2_FLAG_PVP = 0x01, UNIT_BYTE2_FLAG_UNK1 = 0x02, UNIT_BYTE2_FLAG_FFA_PVP = 0x04, @@ -110,13 +112,18 @@ enum UnitPVPStateFlags : uint8 UNIT_BYTE2_FLAG_UNK7 = 0x80 }; +DEFINE_ENUM_FLAG(UnitPVPStateFlags); + // byte (2 from 0..3) of UNIT_FIELD_BYTES_2 -enum UnitRename : uint8 +enum UnitPetFlag : uint8 { - UNIT_CAN_BE_RENAMED = 0x01, - UNIT_CAN_BE_ABANDONED = 0x02 + UNIT_PET_FLAG_NONE = 0x0, + UNIT_PET_FLAG_CAN_BE_RENAMED = 0x01, + UNIT_PET_FLAG_CAN_BE_ABANDONED = 0x02 }; +DEFINE_ENUM_FLAG(UnitPetFlag); + // Value masks for UNIT_FIELD_FLAGS // EnumUtils: DESCRIBE THIS enum UnitFlags : uint32 @@ -165,6 +172,8 @@ enum UnitFlags : uint32 UNIT_FLAG_ALLOWED = (0xFFFFFFFF & ~UNIT_FLAG_DISALLOWED) }; +DEFINE_ENUM_FLAG(UnitFlags); + // Value masks for UNIT_FIELD_FLAGS_2 enum UnitFlags2 : uint32 { @@ -214,6 +223,8 @@ enum UnitFlags2 : uint32 UNIT_FLAG2_ALLOWED = (0xFFFFFFFF & ~UNIT_FLAG2_DISALLOWED) }; +DEFINE_ENUM_FLAG(UnitFlags2); + /// Non Player Character flags // EnumUtils: DESCRIBE THIS enum NPCFlags : uint32 @@ -248,6 +259,8 @@ enum NPCFlags : uint32 UNIT_NPC_FLAG_MAILBOX = 0x04000000 // TITLE is mailbox }; +DEFINE_ENUM_FLAG(NPCFlags); + enum MovementFlags : uint32 { MOVEMENTFLAG_NONE = 0x00000000, |
