diff options
| author | Vincent_Michael <Vincent_Michael@gmx.de> | 2013-02-03 23:11:48 +0100 |
|---|---|---|
| committer | Vincent_Michael <Vincent_Michael@gmx.de> | 2013-02-03 23:11:48 +0100 |
| commit | 66dfcd2b43286829a200a52aac83d57aac88f140 (patch) | |
| tree | 8b650e6e13676d191d9848ceff4410005accaff0 /src/server/game | |
| parent | 06041bc42309320323a1d18864c53e2388f9f42b (diff) | |
| parent | 0d1e199e1fdc096c7d88915b78611856c6934631 (diff) | |
Merge branch 'master' of github.com:TrinityCore/TrinityCore into 4.3.4
Conflicts:
src/server/game/Entities/Object/Object.cpp
src/server/game/Movement/Spline/MovementPacketBuilder.cpp
Diffstat (limited to 'src/server/game')
| -rw-r--r-- | src/server/game/AI/CoreAI/ReactorAI.cpp | 23 | ||||
| -rw-r--r-- | src/server/game/AI/CoreAI/ReactorAI.h | 4 | ||||
| -rw-r--r-- | src/server/game/AI/CoreAI/UnitAI.cpp | 11 | ||||
| -rw-r--r-- | src/server/game/AI/CreatureAIImpl.h | 333 | ||||
| -rw-r--r-- | src/server/game/AI/ScriptedAI/ScriptedCreature.cpp | 8 | ||||
| -rw-r--r-- | src/server/game/AI/ScriptedAI/ScriptedCreature.h | 9 | ||||
| -rw-r--r-- | src/server/game/Entities/Object/Object.cpp | 77 | ||||
| -rw-r--r-- | src/server/game/Entities/Object/Object.h | 4 | ||||
| -rw-r--r-- | src/server/game/Loot/LootMgr.cpp | 33 | ||||
| -rw-r--r-- | src/server/game/Movement/Spline/MovementPacketBuilder.cpp | 2 | ||||
| -rw-r--r-- | src/server/game/Spells/Auras/SpellAuraEffects.cpp | 7 |
11 files changed, 307 insertions, 204 deletions
diff --git a/src/server/game/AI/CoreAI/ReactorAI.cpp b/src/server/game/AI/CoreAI/ReactorAI.cpp index 31b9a82c534..b9c235176bc 100644 --- a/src/server/game/AI/CoreAI/ReactorAI.cpp +++ b/src/server/game/AI/CoreAI/ReactorAI.cpp @@ -23,10 +23,7 @@ #include "ObjectAccessor.h" #include "CreatureAIImpl.h" -#define REACTOR_VISIBLE_RANGE (26.46f) - -int -ReactorAI::Permissible(const Creature* creature) +int ReactorAI::Permissible(const Creature* creature) { if (creature->isCivilian() || creature->IsNeutralToAll()) return PERMIT_BASE_REACTIVE; @@ -34,24 +31,10 @@ ReactorAI::Permissible(const Creature* creature) return PERMIT_BASE_NO; } -void -ReactorAI::MoveInLineOfSight(Unit*) -{ -} - -void -ReactorAI::UpdateAI(const uint32 /*time_diff*/) +void ReactorAI::UpdateAI(uint32 const /*diff*/) { - // update i_victimGuid if me->getVictim() !=0 and changed if (!UpdateVictim()) return; - if (me->isAttackReady()) - { - if (me->IsWithinMeleeRange(me->getVictim())) - { - me->AttackerStateUpdate(me->getVictim()); - me->resetAttackTimer(); - } - } + DoMeleeAttackIfReady(); } diff --git a/src/server/game/AI/CoreAI/ReactorAI.h b/src/server/game/AI/CoreAI/ReactorAI.h index 39af09c4a9d..f7de3b99565 100644 --- a/src/server/game/AI/CoreAI/ReactorAI.h +++ b/src/server/game/AI/CoreAI/ReactorAI.h @@ -29,9 +29,9 @@ class ReactorAI : public CreatureAI explicit ReactorAI(Creature* c) : CreatureAI(c) {} - void MoveInLineOfSight(Unit*); + void MoveInLineOfSight(Unit*) {} + void UpdateAI(uint32 const diff); - void UpdateAI(const uint32); static int Permissible(const Creature*); }; #endif diff --git a/src/server/game/AI/CoreAI/UnitAI.cpp b/src/server/game/AI/CoreAI/UnitAI.cpp index 09ba2cc19b1..7f0d387c2f1 100644 --- a/src/server/game/AI/CoreAI/UnitAI.cpp +++ b/src/server/game/AI/CoreAI/UnitAI.cpp @@ -103,8 +103,7 @@ void UnitAI::DoAddAuraToAllHostilePlayers(uint32 spellid) if (unit->GetTypeId() == TYPEID_PLAYER) me->AddAura(spellid, unit); } - }else - return; + } } void UnitAI::DoCastToAllHostilePlayers(uint32 spellid, bool triggered) @@ -118,8 +117,7 @@ void UnitAI::DoCastToAllHostilePlayers(uint32 spellid, bool triggered) if (unit->GetTypeId() == TYPEID_PLAYER) me->CastSpell(unit, spellid, triggered); } - }else - return; + } } void UnitAI::DoCast(uint32 spellId) @@ -240,7 +238,10 @@ void UnitAI::FillAISpellInfo() } //Enable PlayerAI when charmed -void PlayerAI::OnCharmed(bool apply) { me->IsAIEnabled = apply; } +void PlayerAI::OnCharmed(bool apply) +{ + me->IsAIEnabled = apply; +} void SimpleCharmedAI::UpdateAI(const uint32 /*diff*/) { diff --git a/src/server/game/AI/CreatureAIImpl.h b/src/server/game/AI/CreatureAIImpl.h index bf5ab9703e0..7121a031ec2 100644 --- a/src/server/game/AI/CreatureAIImpl.h +++ b/src/server/game/AI/CreatureAIImpl.h @@ -313,110 +313,177 @@ const T& RAND(const T& v1, const T& v2, const T& v3, const T& v4, const T& v5, c class EventMap { - typedef std::map<uint32, uint32> StorageType; + /** + * Internal storage type. + * Key: Time as uint32 when the event should occur. + * Value: The event data as uint32. + * + * Structure of event data: + * - Bit 0 - 15: Event Id. + * - Bit 16 - 23: Group + * - Bit 24 - 31: Phase + * - Pattern: 0xPPGGEEEE + */ + typedef std::multimap<uint32, uint32> EventStore; public: EventMap() : _time(0), _phase(0) {} - // Returns current timer value, does not represent real dates/times - uint32 GetTimer() const { return _time; } - - // Removes all events and clears phase + /** + * @name Reset + * @brief Removes all scheduled events and resets time and phase. + */ void Reset() { - _eventMap.clear(); _time = 0; _phase = 0; + _eventMap.clear(); + _time = 0; + _phase = 0; } - void Update(uint32 time) { _time += time; } + /** + * @name Update + * @brief Updates the timer of the event map. + * @param time Value to be added to time. + */ + void Update(uint32 time) + { + _time += time; + } - uint32 GetPhaseMask() const { return (_phase >> 24) & 0xFF; } + /** + * @name GetTimer + * @return Current timer value. + */ + uint32 GetTimer() const + { + return _time; + } - bool Empty() const { return _eventMap.empty(); } + /** + * @name GetPhaseMask + * @return Active phases as mask. + */ + uint8 GetPhaseMask() const + { + return _phase; + } - // Sets event phase, must be in range 1 - 8 - void SetPhase(uint32 phase) + /** + * @name Empty + * @return True, if there are no events scheduled. + */ + bool Empty() const { - if (phase && phase <= 8) - _phase = (1 << (phase + 23)); - else if (!phase) + return _eventMap.empty(); + } + + /** + * @name SetPhase + * @brief Sets the phase of the map (absolute). + * @param phase Phase which should be set. Values: 1 - 8. 0 resets phase. + */ + void SetPhase(uint8 phase) + { + if (!phase) _phase = 0; + else if (phase <= 8) + _phase = (1 << (phase - 1)); } - // Activates event phase, must be in range 1 - 8 - void AddPhase(uint32 phase) + /** + * @name AddPhase + * @brief Activates the given phase (bitwise). + * @param phase Phase which should be activated. Values: 1 - 8 + */ + void AddPhase(uint8 phase) { if (phase && phase <= 8) - _phase |= (1 << (phase + 23)); + _phase |= (1 << (phase - 1)); } - // Deactivates event phase, must be in range 1 - 8 - void RemovePhase(uint32 phase) + /** + * @name RemovePhase + * @brief Deactivates the given phase (bitwise). + * @param phase Phase which should be deactivated. Values: 1 - 8. + */ + void RemovePhase(uint8 phase) { if (phase && phase <= 8) - _phase &= ~(1 << (phase + 23)); + _phase &= ~(1 << (phase - 1)); } - // Creates new event entry in map with given id, time, group if given (1 - 8) and phase if given (1 - 8) - // 0 for group/phase means it belongs to no group or runs in all phases - void ScheduleEvent(uint32 eventId, uint32 time, uint32 groupId = 0, uint32 phase = 0) + /** + * @name ScheduleEvent + * @brief Creates new event entry in map. + * @param eventId The id of the new event. + * @param time The time in milliseconds until the event occurs. + * @param group The group which the event is associated to. Has to be between 1 and 8. 0 means it has no group. + * @param phase The phase in which the event can occur. Has to be between 1 and 8. 0 means it can occur in all phases. + */ + void ScheduleEvent(uint32 eventId, uint32 time, uint32 group = 0, uint8 phase = 0) { - time += _time; - if (groupId && groupId < 9) - eventId |= (1 << (groupId + 15)); - if (phase && phase < 8) + if (group && group <= 8) + eventId |= (1 << (group + 15)); + + if (phase && phase <= 8) eventId |= (1 << (phase + 23)); - StorageType::const_iterator itr = _eventMap.find(time); - while (itr != _eventMap.end()) - { - ++time; - itr = _eventMap.find(time); - } - _eventMap.insert(StorageType::value_type(time, eventId)); + _eventMap.insert(EventStore::value_type(_time + time, eventId)); } - // Removes event with specified id and creates new entry for it - void RescheduleEvent(uint32 eventId, uint32 time, uint32 groupId = 0, uint32 phase = 0) + /** + * @name RescheduleEvent + * @brief Cancels the given event and reschedules it. + * @param eventId The id of the event. + * @param time The time in milliseconds until the event occurs. + * @param group The group which the event is associated to. Has to be between 1 and 8. 0 means it has no group. + * @param phase The phase in which the event can occur. Has to be between 1 and 8. 0 means it can occur in all phases. + */ + void RescheduleEvent(uint32 eventId, uint32 time, uint32 group = 0, uint8 phase = 0) { CancelEvent(eventId); - ScheduleEvent(eventId, time, groupId, phase); + ScheduleEvent(eventId, time, group, phase); } - // Reschedules closest event + /** + * @name RepeatEvent + * @brief Cancels the closest event and reschedules it. + * @param time Time until the event occurs. + */ void RepeatEvent(uint32 time) { - if (_eventMap.empty()) + if (Empty()) return; - + uint32 eventId = _eventMap.begin()->second; _eventMap.erase(_eventMap.begin()); - time += _time; - StorageType::const_iterator itr = _eventMap.find(time); - while (itr != _eventMap.end()) - { - ++time; - itr = _eventMap.find(time); - } - - _eventMap.insert(StorageType::value_type(time, eventId)); + ScheduleEvent(eventId, time); } - // Removes first event + /** + * @name PopEvent + * @brief Remove the first event in the map. + */ void PopEvent() { - if (!_eventMap.empty()) + if (!Empty()) _eventMap.erase(_eventMap.begin()); } - // Gets next event id to execute and removes it from map + /** + * @name ExecuteEvent + * @brief Returns the next event to execute and removes it from map. + * @return Id of the event to execute. + */ uint32 ExecuteEvent() { - while (!_eventMap.empty()) + while (!Empty()) { - StorageType::iterator itr = _eventMap.begin(); + EventStore::iterator itr = _eventMap.begin(); + if (itr->first > _time) return 0; - else if (_phase && (itr->second & 0xFF000000) && !(itr->second & _phase)) + else if (_phase && (itr->second & 0xFF000000) && !((itr->second >> 24) & _phase)) _eventMap.erase(itr); else { @@ -425,114 +492,176 @@ class EventMap return eventId; } } + return 0; } - // Gets next event id to execute + /** + * @name GetEvent + * @brief Returns the next event to execute. + * @return Id of the event to execute. + */ uint32 GetEvent() { - while (!_eventMap.empty()) + while (!Empty()) { - StorageType::iterator itr = _eventMap.begin(); + EventStore::iterator itr = _eventMap.begin(); + if (itr->first > _time) return 0; - else if (_phase && (itr->second & 0xFF000000) && !(itr->second & _phase)) + else if (_phase && (itr->second & 0xFF000000) && !(itr->second & (_phase << 24))) _eventMap.erase(itr); else return (itr->second & 0x0000FFFF); } - + return 0; } - // Delay all events + /** + * @name DelayEvents + * @brief Delays all events in the map. If delay is greater than or equal internal timer, delay will be 0. + * @param delay Amount of delay. + */ void DelayEvents(uint32 delay) { - if (delay < _time) - _time -= delay; - else - _time = 0; + _time = delay < _time ? _time - delay : 0; } - // Delay all events having the specified Group - void DelayEvents(uint32 delay, uint32 groupId) + /** + * @name DelayEvents + * @brief Delay all events of the same group. + * @param delay Amount of delay. + * @param group Group of the events. + */ + void DelayEvents(uint32 delay, uint32 group) { - if (!groupId || groupId > 8) + if (!group || group > 8 || Empty()) return; + + EventStore delayed; - uint32 nextTime = _time + delay; - uint32 groupMask = (1 << (groupId + 15)); - - for (StorageType::iterator itr = _eventMap.begin(); itr != _eventMap.end() && itr->first < nextTime;) + for (EventStore::iterator itr = _eventMap.begin(); itr != _eventMap.end();) { - if (itr->second & groupMask) + if (itr->second & (1 << (group + 15))) { - ScheduleEvent(itr->second, itr->first - _time + delay); - _eventMap.erase(itr); - itr = _eventMap.begin(); + delayed.insert(EventStore::value_type(itr->first + delay, itr->second)); + _eventMap.erase(itr++); } else ++itr; } + + _eventMap.insert(delayed.begin(), delayed.end()); } - // Cancel events with specified id + /** + * @name CancelEvent + * @brief Cancels all events of the specified id. + * @param eventId Event id to cancel. + */ void CancelEvent(uint32 eventId) { - for (StorageType::iterator itr = _eventMap.begin(); itr != _eventMap.end();) + if (Empty()) + return; + + for (EventStore::iterator itr = _eventMap.begin(); itr != _eventMap.end();) { if (eventId == (itr->second & 0x0000FFFF)) - { - _eventMap.erase(itr); - itr = _eventMap.begin(); - } + _eventMap.erase(itr++); else ++itr; } } - // Cancel events belonging to specified group - void CancelEventGroup(uint32 groupId) + /** + * @name CancelEventGroup + * @brief Cancel events belonging to specified group. + * @param group Group to cancel. + */ + void CancelEventGroup(uint32 group) { - if (!groupId || groupId > 8) + if (!group || group > 8 || Empty()) return; - uint32 groupMask = (1 << (groupId + 15)); - - for (StorageType::iterator itr = _eventMap.begin(); itr != _eventMap.end();) + for (EventStore::iterator itr = _eventMap.begin(); itr != _eventMap.end();) { - if (itr->second & groupMask) - { - _eventMap.erase(itr); - itr = _eventMap.begin(); - } + if (itr->second & (1 << (group + 15))) + _eventMap.erase(itr++); else ++itr; } } - // Returns time of next event to execute - // To get how much time remains substract _time + /** + * @name GetNextEventTime + * @brief Returns closest occurence of specified event. + * @param eventId Wanted event id. + * @return Time of found event. + */ uint32 GetNextEventTime(uint32 eventId) const { - for (StorageType::const_iterator itr = _eventMap.begin(); itr != _eventMap.end(); ++itr) + if (Empty()) + return 0; + + for (EventStore::const_iterator itr = _eventMap.begin(); itr != _eventMap.end(); ++itr) if (eventId == (itr->second & 0x0000FFFF)) return itr->first; return 0; } + + /** + * @name GetNextEventTime + * @return Time of next event. + */ + uint32 GetNextEventTime() const + { + return Empty() ? 0 : _eventMap.begin()->first; + } - // Returns wether the eventmap is in the given phase or not. - bool IsInPhase(uint32 phase) + /** + * @name IsInPhase + * @brief Returns wether event map is in specified phase or not. + * @param phase Wanted phase. + * @return True, if phase of event map contains specified phase. + */ + bool IsInPhase(uint8 phase) { - return phase <= 8 && (!phase || _phase & (1 << (phase + 23))); + return phase <= 8 && (!phase || _phase & (1 << (phase - 1))); } private: + /** + * @name _time + * @brief Internal timer. + * + * This does not represent the real date/time value. + * It's more like a stopwatch: It can run, it can be stopped, + * it can be resetted and so on. Events occur when this timer + * has reached their time value. Its value is changed in the + * Update method. + */ uint32 _time; - uint32 _phase; - - StorageType _eventMap; + + /** + * @name _phase + * @brief Phase mask of the event map. + * + * Contains the phases the event map is in. Multiple + * phases from 1 to 8 can be set with SetPhase or + * AddPhase. RemovePhase deactives a phase. + */ + uint8 _phase; + + /** + * @name _eventMap + * @brief Internal event storage map. Contains the scheduled events. + * + * See typedef at the beginning of the class for more + * details. + */ + EventStore _eventMap; }; enum AITarget diff --git a/src/server/game/AI/ScriptedAI/ScriptedCreature.cpp b/src/server/game/AI/ScriptedAI/ScriptedCreature.cpp index 72f4d011948..315cb52f4de 100644 --- a/src/server/game/AI/ScriptedAI/ScriptedCreature.cpp +++ b/src/server/game/AI/ScriptedAI/ScriptedCreature.cpp @@ -108,6 +108,14 @@ void ScriptedAI::AttackStartNoMove(Unit* who) DoStartNoMovement(who); } +void ScriptedAI::AttackStart(Unit* who) +{ + if (IsCombatMovementAllowed()) + CreatureAI::AttackStart(who); + else + AttackStartNoMove(who); +} + void ScriptedAI::UpdateAI(uint32 const /*diff*/) { //Check if we have a current target diff --git a/src/server/game/AI/ScriptedAI/ScriptedCreature.h b/src/server/game/AI/ScriptedAI/ScriptedCreature.h index f3a13060ad8..9dc1bc06a94 100644 --- a/src/server/game/AI/ScriptedAI/ScriptedCreature.h +++ b/src/server/game/AI/ScriptedAI/ScriptedCreature.h @@ -136,6 +136,9 @@ struct ScriptedAI : public CreatureAI //Called at creature aggro either by MoveInLOS or Attack Start void EnterCombat(Unit* /*victim*/) {} + // Called before EnterCombat even before the creature is in combat. + void AttackStart(Unit* /*target*/); + // ************* //AI Helper Functions // ************* @@ -191,7 +194,11 @@ struct ScriptedAI : public CreatureAI void SetEquipmentSlots(bool loadDefault, int32 mainHand = EQUIP_NO_CHANGE, int32 offHand = EQUIP_NO_CHANGE, int32 ranged = EQUIP_NO_CHANGE); - //Generally used to control if MoveChase() is to be used or not in AttackStart(). Some creatures does not chase victims + // Used to control if MoveChase() is to be used or not in AttackStart(). Some creatures does not chase victims + // NOTE: If you use SetCombatMovement while the creature is in combat, it will do NOTHING - This only affects AttackStart + // You should make the necessary to make it happen so. + // Remember that if you modified _isCombatMovementAllowed (e.g: using SetCombatMovement) it will not be reset at Reset(). + // It will keep the last value you set. void SetCombatMovement(bool allowMovement); bool IsCombatMovementAllowed() const { return _isCombatMovementAllowed; } diff --git a/src/server/game/Entities/Object/Object.cpp b/src/server/game/Entities/Object/Object.cpp index 292554620e4..0be9002e1d8 100644 --- a/src/server/game/Entities/Object/Object.cpp +++ b/src/server/game/Entities/Object/Object.cpp @@ -921,64 +921,57 @@ void Object::BuildFieldsUpdate(Player* player, UpdateDataMapType& data_map) cons BuildValuesUpdateBlockForPlayer(&iter->second, iter->first); } -void Object::GetUpdateFieldData(Player const* target, uint32*& flags, bool& isOwner, bool& isItemOwner, bool& hasSpecialInfo, bool& isPartyMember) const +uint32 Object::GetUpdateFieldData(Player const* target, uint32*& flags) const { - // This function assumes updatefield index is always valid + uint32 visibleFlag = UF_FLAG_PUBLIC; + + if (target == this) + visibleFlag |= UF_FLAG_PRIVATE; + switch (GetTypeId()) { case TYPEID_ITEM: case TYPEID_CONTAINER: flags = ItemUpdateFieldFlags; - isOwner = isItemOwner = ((Item*)this)->GetOwnerGUID() == target->GetGUID(); + if (((Item*)this)->GetOwnerGUID() == target->GetGUID()) + visibleFlag |= UF_FLAG_OWNER | UF_FLAG_ITEM_OWNER; break; case TYPEID_UNIT: case TYPEID_PLAYER: { Player* plr = ToUnit()->GetCharmerOrOwnerPlayerOrPlayerItself(); flags = UnitUpdateFieldFlags; - isOwner = ToUnit()->GetOwnerGUID() == target->GetGUID(); - hasSpecialInfo = ToUnit()->HasAuraTypeWithCaster(SPELL_AURA_EMPATHY, target->GetGUID()); - isPartyMember = plr && plr->IsInSameGroupWith(target); + if (ToUnit()->GetOwnerGUID() == target->GetGUID()) + visibleFlag |= UF_FLAG_OWNER; + + if (HasFlag(UNIT_DYNAMIC_FLAGS, UNIT_DYNFLAG_SPECIALINFO)) + if (ToUnit()->HasAuraTypeWithCaster(SPELL_AURA_EMPATHY, target->GetGUID())) + visibleFlag |= UF_FLAG_SPECIAL_INFO; + + if (plr && plr->IsInSameRaidWith(target)) + visibleFlag |= UF_FLAG_PARTY_MEMBER; break; } case TYPEID_GAMEOBJECT: flags = GameObjectUpdateFieldFlags; - isOwner = ToGameObject()->GetOwnerGUID() == target->GetGUID(); + if (ToGameObject()->GetOwnerGUID() == target->GetGUID()) + visibleFlag |= UF_FLAG_OWNER; break; case TYPEID_DYNAMICOBJECT: flags = DynamicObjectUpdateFieldFlags; - isOwner = ((DynamicObject*)this)->GetCasterGUID() == target->GetGUID(); + if (((DynamicObject*)this)->GetCasterGUID() == target->GetGUID()) + visibleFlag |= UF_FLAG_OWNER; break; case TYPEID_CORPSE: flags = CorpseUpdateFieldFlags; - isOwner = ToCorpse()->GetOwnerGUID() == target->GetGUID(); + if (ToCorpse()->GetOwnerGUID() == target->GetGUID()) + visibleFlag |= UF_FLAG_OWNER; break; case TYPEID_OBJECT: break; } -} - -bool Object::IsUpdateFieldVisible(uint32 flags, bool isSelf, bool isOwner, bool isItemOwner, bool isPartyMember) const -{ - if (flags == UF_FLAG_NONE) - return false; - - if (flags & UF_FLAG_PUBLIC) - return true; - - if (flags & UF_FLAG_PRIVATE && isSelf) - return true; - if (flags & UF_FLAG_OWNER && isOwner) - return true; - - if (flags & UF_FLAG_ITEM_OWNER && isItemOwner) - return true; - - if (flags & UF_FLAG_PARTY_MEMBER && isPartyMember) - return true; - - return false; + return visibleFlag; } void Object::_LoadIntoDataField(std::string const& data, uint32 startOffset, uint32 count) @@ -1001,20 +994,13 @@ void Object::_LoadIntoDataField(std::string const& data, uint32 startOffset, uin void Object::_SetUpdateBits(UpdateMask* updateMask, Player* target) const { uint32* flags = NULL; - bool isSelf = target == this; - bool isOwner = false; - bool isItemOwner = false; - bool hasSpecialInfo = false; - bool isPartyMember = false; - - GetUpdateFieldData(target, flags, isOwner, isItemOwner, hasSpecialInfo, isPartyMember); - + uint32 visibleFlag = GetUpdateFieldData(target, flags); uint32 valCount = m_valuesCount; if (GetTypeId() == TYPEID_PLAYER && target != this) valCount = PLAYER_END_NOT_SELF; for (uint16 index = 0; index < valCount; ++index) - if (_fieldNotifyFlags & flags[index] || (flags[index] & UF_FLAG_SPECIAL_INFO && hasSpecialInfo) || (_changesMask.GetBit(index) && IsUpdateFieldVisible(flags[index], isSelf, isOwner, isItemOwner, isPartyMember))) + if (_fieldNotifyFlags & flags[index] || ((flags[index] & visibleFlag) & UF_FLAG_SPECIAL_INFO) || (_changesMask.GetBit(index) && (flags[index] & visibleFlag))) updateMask->SetBit(index); } @@ -1022,20 +1008,13 @@ void Object::_SetCreateBits(UpdateMask* updateMask, Player* target) const { uint32* value = m_uint32Values; uint32* flags = NULL; - bool isSelf = target == this; - bool isOwner = false; - bool isItemOwner = false; - bool hasSpecialInfo = false; - bool isPartyMember = false; - - GetUpdateFieldData(target, flags, isOwner, isItemOwner, hasSpecialInfo, isPartyMember); - + uint32 visibleFlag = GetUpdateFieldData(target, flags); uint32 valCount = m_valuesCount; if (GetTypeId() == TYPEID_PLAYER && target != this) valCount = PLAYER_END_NOT_SELF; for (uint16 index = 0; index < valCount; ++index, ++value) - if (_fieldNotifyFlags & flags[index] || (flags[index] & UF_FLAG_SPECIAL_INFO && hasSpecialInfo) || (*value && IsUpdateFieldVisible(flags[index], isSelf, isOwner, isItemOwner, isPartyMember))) + if (_fieldNotifyFlags & flags[index] || ((flags[index] & visibleFlag) & UF_FLAG_SPECIAL_INFO) || (*value && (flags[index] & visibleFlag))) updateMask->SetBit(index); } diff --git a/src/server/game/Entities/Object/Object.h b/src/server/game/Entities/Object/Object.h index 3ec5146f876..8b61b6ec2c8 100644 --- a/src/server/game/Entities/Object/Object.h +++ b/src/server/game/Entities/Object/Object.h @@ -386,9 +386,7 @@ class Object std::string _ConcatFields(uint16 startIndex, uint16 size) const; void _LoadIntoDataField(std::string const& data, uint32 startOffset, uint32 count); - void GetUpdateFieldData(Player const* target, uint32*& flags, bool& isOwner, bool& isItemOwner, bool& hasSpecialInfo, bool& isPartyMember) const; - - bool IsUpdateFieldVisible(uint32 flags, bool isSelf, bool isOwner, bool isItemOwner, bool isPartyMember) const; + uint32 GetUpdateFieldData(Player const* target, uint32*& flags) const; void _SetUpdateBits(UpdateMask* updateMask, Player* target) const; void _SetCreateBits(UpdateMask* updateMask, Player* target) const; diff --git a/src/server/game/Loot/LootMgr.cpp b/src/server/game/Loot/LootMgr.cpp index 5bdda34a428..94aea40f511 100644 --- a/src/server/game/Loot/LootMgr.cpp +++ b/src/server/game/Loot/LootMgr.cpp @@ -351,7 +351,6 @@ LootItem::LootItem(LootStoreItem const& li) needs_quest = li.needs_quest; - count = urand(li.mincountOrRef, li.maxcount); // constructor called for mincountOrRef > 0 only randomSuffix = GenerateEnchSuffixFactor(itemid); randomPropertyId = Item::GenerateItemRandomPropertyId(itemid); is_looted = 0; @@ -400,26 +399,30 @@ void LootItem::AddAllowedLooter(const Player* player) // // Inserts the item into the loot (called by LootTemplate processors) -void Loot::AddItem(LootStoreItem const & item) +void Loot::AddItem(LootStoreItem const& item) { - if (item.needs_quest) // Quest drop - { - if (quest_items.size() < MAX_NR_QUEST_ITEMS) - quest_items.push_back(LootItem(item)); - } - else if (items.size() < MAX_NR_LOOT_ITEMS) // Non-quest drop + ItemTemplate const* proto = sObjectMgr->GetItemTemplate(item.itemid); + if (!proto) + return; + + uint32 count = urand(item.mincountOrRef, item.maxcount); + uint32 stacks = count / proto->GetMaxStackSize() + (count % proto->GetMaxStackSize() ? 1 : 0); + + std::vector<LootItem>& lootItems = item.needs_quest ? quest_items : items; + uint32 limit = item.needs_quest ? MAX_NR_QUEST_ITEMS : MAX_NR_LOOT_ITEMS; + + for (uint32 i = 0; i < stacks && lootItems.size() < limit; ++i) { - items.push_back(LootItem(item)); + LootItem generatedLoot(item); + generatedLoot.count = std::min(count, proto->GetMaxStackSize()); + lootItems.push_back(generatedLoot); + count -= proto->GetMaxStackSize(); // non-conditional one-player only items are counted here, // free for all items are counted in FillFFALoot(), // non-ffa conditionals are counted in FillNonQuestNonFFAConditionalLoot() - if (item.conditions.empty()) - { - ItemTemplate const* proto = sObjectMgr->GetItemTemplate(item.itemid); - if (!proto || (proto->Flags & ITEM_PROTO_FLAG_PARTY_LOOT) == 0) - ++unlootedCount; - } + if (!item.needs_quest && item.conditions.empty() && !(proto->Flags & ITEM_PROTO_FLAG_PARTY_LOOT)) + ++unlootedCount; } } diff --git a/src/server/game/Movement/Spline/MovementPacketBuilder.cpp b/src/server/game/Movement/Spline/MovementPacketBuilder.cpp index f2dc8897532..eb3d45bb0ec 100644 --- a/src/server/game/Movement/Spline/MovementPacketBuilder.cpp +++ b/src/server/game/Movement/Spline/MovementPacketBuilder.cpp @@ -192,7 +192,7 @@ namespace Movement { if (!moveSpline.Finalized()) { - MoveSplineFlag splineFlags = moveSpline.splineflags; + MoveSplineFlag const& splineFlags = moveSpline.splineflags; if ((splineFlags & MoveSplineFlag::Parabolic) && moveSpline.effect_start_time < moveSpline.Duration()) data << moveSpline.vertical_acceleration; // added in 3.1 diff --git a/src/server/game/Spells/Auras/SpellAuraEffects.cpp b/src/server/game/Spells/Auras/SpellAuraEffects.cpp index 43e31c34919..5f93551a099 100644 --- a/src/server/game/Spells/Auras/SpellAuraEffects.cpp +++ b/src/server/game/Spells/Auras/SpellAuraEffects.cpp @@ -5082,10 +5082,6 @@ void AuraEffect::HandleAuraEmpathy(AuraApplication const* aurApp, uint8 mode, bo return; Unit* target = aurApp->GetTarget(); - - if (target->GetTypeId() != TYPEID_UNIT) - return; - if (!apply) { // do not remove unit flag if there are more than this auraEffect of that kind on unit on unit @@ -5093,8 +5089,7 @@ void AuraEffect::HandleAuraEmpathy(AuraApplication const* aurApp, uint8 mode, bo return; } - CreatureTemplate const* ci = sObjectMgr->GetCreatureTemplate(target->GetEntry()); - if (ci && ci->type == CREATURE_TYPE_BEAST) + if (target->GetCreatureType() == CREATURE_TYPE_BEAST) target->ApplyModUInt32Value(UNIT_DYNAMIC_FLAGS, UNIT_DYNFLAG_SPECIALINFO, apply); } |
