diff --git a/src/server/game/AI/ScriptedAI/ScriptedCreature.cpp b/src/server/game/AI/ScriptedAI/ScriptedCreature.cpp index 043fa814b..30373f2f6 100644 --- a/src/server/game/AI/ScriptedAI/ScriptedCreature.cpp +++ b/src/server/game/AI/ScriptedAI/ScriptedCreature.cpp @@ -531,10 +531,6 @@ void ScriptedAI::SetEquipmentSlots(bool loadDefault, int32 mainHand /*= EQUIP_NO if (loadDefault) { me->LoadEquipment(me->GetOriginalEquipmentId(), true); - if (me->HasWeapon(OFF_ATTACK)) - me->SetCanDualWield(true); - else - me->SetCanDualWield(false); return; } @@ -547,10 +543,6 @@ void ScriptedAI::SetEquipmentSlots(bool loadDefault, int32 mainHand /*= EQUIP_NO if (offHand >= 0) { me->SetVirtualItem(1, uint32(offHand)); - if (offHand >= 1) - me->SetCanDualWield(true); - else - me->SetCanDualWield(false); } if (ranged >= 0) diff --git a/src/server/game/Entities/Creature/Creature.cpp b/src/server/game/Entities/Creature/Creature.cpp index a77e194bf..122efb856 100644 --- a/src/server/game/Entities/Creature/Creature.cpp +++ b/src/server/game/Entities/Creature/Creature.cpp @@ -525,7 +525,8 @@ bool Creature::InitEntry(uint32 Entry, const CreatureData* data) SetFloatValue(UNIT_FIELD_HOVERHEIGHT, cinfo->HoverHeight); - SetCanDualWield(cinfo->HasFlagsExtra(CREATURE_FLAG_EXTRA_USE_OFFHAND_ATTACK)); + if (cinfo->HasFlagsExtra(CREATURE_FLAG_EXTRA_USE_OFFHAND_ATTACK)) + SetDualWieldMode(DualWieldMode::ENABLED); // checked at loading m_defaultMovementType = MovementGeneratorType(cinfo->MovementType); @@ -571,7 +572,8 @@ bool Creature::UpdateEntry(uint32 Entry, const CreatureData* data, bool changele ReplaceAllDynamicFlags(dynamicflags); - SetCanDualWield(cInfo->HasFlagsExtra(CREATURE_FLAG_EXTRA_USE_OFFHAND_ATTACK)); + if (cInfo->HasFlagsExtra(CREATURE_FLAG_EXTRA_USE_OFFHAND_ATTACK)) + SetDualWieldMode(DualWieldMode::ENABLED); SetAttackTime(BASE_ATTACK, cInfo->BaseAttackTime); SetAttackTime(OFF_ATTACK, cInfo->BaseAttackTime); @@ -3196,10 +3198,23 @@ bool Creature::IsImmuneToKnockback() const bool Creature::HasWeapon(WeaponAttackType type) const { + if (type == OFF_ATTACK) + { + switch (_dualWieldMode) + { + case DualWieldMode::ENABLED: + return true; + case DualWieldMode::DISABLED: + return false; + case DualWieldMode::AUTO: + default: + break; + } + } + const uint8 slot = uint8(type); ItemEntry const* item = sItemStore.LookupEntry(GetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_ID + slot)); - - return ((item && item->ClassID == ITEM_CLASS_WEAPON) || (type == OFF_ATTACK && CanDualWield())); + return (item && item->ClassID == ITEM_CLASS_WEAPON); } /** diff --git a/src/server/game/Entities/Player/Player.cpp b/src/server/game/Entities/Player/Player.cpp index 4ad3c464c..68bedb318 100644 --- a/src/server/game/Entities/Player/Player.cpp +++ b/src/server/game/Entities/Player/Player.cpp @@ -3802,7 +3802,7 @@ bool Player::resetTalents(bool noResetCost) if (m_canTitanGrip) SetCanTitanGrip(false); // xinef: remove dual wield if player does not have dual wield spell (shamans) - if (!HasSpell(674) && m_canDualWield) + if (!HasSpell(674) && CanDualWield()) SetCanDualWield(false); AutoUnequipOffhandIfNeed(); @@ -15281,7 +15281,7 @@ void Player::ActivateSpec(uint8 spec) if (!HasTalent(46917, GetActiveSpec()) && m_canTitanGrip) SetCanTitanGrip(false); // xinef: remove dual wield if player does not have dual wield spell (shamans) - if (!HasSpell(674) && m_canDualWield) + if (!HasSpell(674) && CanDualWield()) SetCanDualWield(false); AutoUnequipOffhandIfNeed(); diff --git a/src/server/game/Entities/Unit/Unit.cpp b/src/server/game/Entities/Unit/Unit.cpp index d20731079..5690ac81d 100644 --- a/src/server/game/Entities/Unit/Unit.cpp +++ b/src/server/game/Entities/Unit/Unit.cpp @@ -242,7 +242,7 @@ Unit::Unit() : WorldObject(), m_modAttackSpeedPct[OFF_ATTACK] = 1.0f; m_modAttackSpeedPct[RANGED_ATTACK] = 1.0f; - m_canDualWield = false; + _dualWieldMode = DualWieldMode::AUTO; m_rootTimes = 0; diff --git a/src/server/game/Entities/Unit/Unit.h b/src/server/game/Entities/Unit/Unit.h index 91ab18fd5..5ad52f5fc 100644 --- a/src/server/game/Entities/Unit/Unit.h +++ b/src/server/game/Entities/Unit/Unit.h @@ -567,6 +567,13 @@ enum class SearchMethod typedef std::list SharedVisionList; +enum class DualWieldMode : uint8 +{ + AUTO = 0, // non-player units must have a valid offhand weapon to enable dual wield + DISABLED = 1, + ENABLED = 2, +}; + struct AttackPosition { AttackPosition(Position pos) : _pos(std::move(pos)), _taken(false) {} bool operator==(const int val) @@ -917,8 +924,9 @@ public: // Weapons systems [[nodiscard]] bool haveOffhandWeapon() const; - [[nodiscard]] bool CanDualWield() const { return m_canDualWield; } - virtual void SetCanDualWield(bool value) { m_canDualWield = value; } + [[nodiscard]] bool CanDualWield() const { return _dualWieldMode == DualWieldMode::ENABLED; } + virtual void SetCanDualWield(bool value) { _dualWieldMode = value ? DualWieldMode::ENABLED : DualWieldMode::DISABLED; } + virtual void SetDualWieldMode(DualWieldMode mode) { _dualWieldMode = mode; } virtual bool HasWeapon(WeaponAttackType type) const = 0; inline bool HasMainhandWeapon() const { return HasWeapon(BASE_ATTACK); } @@ -1994,7 +2002,7 @@ public: //----------- Public variables ----------// uint32 m_extraAttacks; - bool m_canDualWield; + DualWieldMode _dualWieldMode; ControlSet m_Controlled; diff --git a/src/server/scripts/Northrend/Gundrak/boss_moorabi.cpp b/src/server/scripts/Northrend/Gundrak/boss_moorabi.cpp index a85172a2d..e0be1dd9d 100644 --- a/src/server/scripts/Northrend/Gundrak/boss_moorabi.cpp +++ b/src/server/scripts/Northrend/Gundrak/boss_moorabi.cpp @@ -83,6 +83,7 @@ public: BossAI::Reset(); events2.Reset(); events2.ScheduleEvent(EVENT_PHANTOM, 21s); + me->SetCanDualWield(true); } void JustEngagedWith(Unit* who) override @@ -104,6 +105,7 @@ public: me->RemoveAurasDueToSpell(SPELL_MOJO_FRENZY); events.CancelEvent(EVENT_TRANSFORMATION); Talk(EMOTE_TRANSFORMED); + me->SetCanDualWield(false); } }