diff --git a/src/server/game/AI/CreatureAI.cpp b/src/server/game/AI/CreatureAI.cpp index 6debb9f127..b917a70610 100644 --- a/src/server/game/AI/CreatureAI.cpp +++ b/src/server/game/AI/CreatureAI.cpp @@ -118,7 +118,7 @@ void CreatureAI::MoveInLineOfSight(Unit* who) if (me->IsEngaged()) return; - if (me->HasReactState(REACT_AGGRESSIVE) && !me->IsIgnoringCombat() && me->CanStartAttack(who, false)) + if (me->HasReactState(REACT_AGGRESSIVE) && me->CanStartAttack(who, false)) me->EngageWithTarget(who); } diff --git a/src/server/game/Entities/Creature/Creature.cpp b/src/server/game/Entities/Creature/Creature.cpp index 4749548f40..dbc1828a60 100644 --- a/src/server/game/Entities/Creature/Creature.cpp +++ b/src/server/game/Entities/Creature/Creature.cpp @@ -656,9 +656,6 @@ bool Creature::UpdateEntry(uint32 entry, CreatureData const* data /*= nullptr*/, } - if (cInfo->flags_extra & CREATURE_FLAG_EXTRA_NO_COMBAT) - SetIgnoringCombat(true); - InitializeMovementCapabilities(); LoadCreaturesAddon(); @@ -1164,7 +1161,7 @@ bool Creature::SetCanFly(bool enable) void Creature::InitializeReactState() { - if (IsTotem() || IsTrigger() || IsCritter() || IsSpiritService()) + if (IsTotem() || IsTrigger() || IsCritter() || IsSpiritService() || _staticFlags.HasFlag(CREATURE_STATIC_FLAG_IGNORE_COMBAT)) SetReactState(REACT_PASSIVE); /* else if (IsCivilian()) diff --git a/src/server/game/Entities/Creature/CreatureData.h b/src/server/game/Entities/Creature/CreatureData.h index e88e053bec..878bfbefc6 100644 --- a/src/server/game/Entities/Creature/CreatureData.h +++ b/src/server/game/Entities/Creature/CreatureData.h @@ -49,7 +49,7 @@ enum CreatureFlagsExtra : uint32 CREATURE_FLAG_EXTRA_GHOST_VISIBILITY = 0x00000400, // creature will be only visible for dead players CREATURE_FLAG_EXTRA_USE_OFFHAND_ATTACK = 0x00000800, // creature will use offhand attacks CREATURE_FLAG_EXTRA_NO_SELL_VENDOR = 0x00001000, // players can't sell items to this vendor - CREATURE_FLAG_EXTRA_NO_COMBAT = 0x00002000, // creature is not allowed to enter combat + CREATURE_FLAG_EXTRA_UNUSED_13 = 0x00002000, CREATURE_FLAG_EXTRA_WORLDEVENT = 0x00004000, // custom flag for world event creatures (left room for merging) CREATURE_FLAG_EXTRA_GUARD = 0x00008000, // Creature is guard CREATURE_FLAG_EXTRA_IGNORE_FEIGN_DEATH = 0x00010000, // creature ignores feign death diff --git a/src/server/game/Entities/Unit/Unit.cpp b/src/server/game/Entities/Unit/Unit.cpp index b589779abd..df1fdad66a 100644 --- a/src/server/game/Entities/Unit/Unit.cpp +++ b/src/server/game/Entities/Unit/Unit.cpp @@ -305,8 +305,7 @@ Unit::Unit(bool isWorldObject) : m_charmer(nullptr), m_charmed(nullptr), i_motionMaster(std::make_unique(this)), m_vehicle(nullptr), m_unitTypeMask(UNIT_MASK_NONE), m_isEngaged(false), m_combatManager(this), m_threatManager(this), - i_AI(nullptr), m_aiLocked(false), m_spellHistory(std::make_unique(this)), - _isIgnoringCombat(false) + i_AI(nullptr), m_aiLocked(false), m_spellHistory(std::make_unique(this)) { m_objectType |= TYPEMASK_UNIT; m_objectTypeId = TYPEID_UNIT; diff --git a/src/server/game/Entities/Unit/Unit.h b/src/server/game/Entities/Unit/Unit.h index 4bf618d073..95b3bc8308 100644 --- a/src/server/game/Entities/Unit/Unit.h +++ b/src/server/game/Entities/Unit/Unit.h @@ -1765,11 +1765,6 @@ class TC_GAME_API Unit : public WorldObject float GetCollisionHeight() const override; - // returns if the unit is allowed to enter combat - bool IsIgnoringCombat() const { return _isIgnoringCombat; } - // enables/disables combat permission of this unit - void SetIgnoringCombat(bool apply) { _isIgnoringCombat = apply; } - // Queues up a spell cast request that has been received via packet and processes it whenever possible. void RequestSpellCast(std::unique_ptr castRequest, SpellInfo const* spellInfo); void CancelPendingCastRequest(); @@ -1931,8 +1926,6 @@ class TC_GAME_API Unit : public WorldObject std::array, AsUnderlyingType(PursuingType::Max)> _unitsPursuingMe; - bool _isIgnoringCombat; - std::unique_ptr _pendingSpellCastRequest; void ProcessPendingSpellCastRequest(); void ProcessItemCast(PendingSpellCastRequest const& castRequest, SpellCastTargets const& targets); diff --git a/src/server/game/Spells/Spell.cpp b/src/server/game/Spells/Spell.cpp index a5ebc58783..9fba9a507b 100644 --- a/src/server/game/Spells/Spell.cpp +++ b/src/server/game/Spells/Spell.cpp @@ -2564,7 +2564,7 @@ void Spell::TargetInfo::PreprocessTarget(Spell* spell) if (spell->m_originalCaster->IsFriendlyTo(unit)) return false; - if (spell->m_originalCaster->IsIgnoringCombat() || !spell->m_spellInfo->CausesInitialThreat()) + if ((spell->m_originalCaster->IsCreature() && spell->m_originalCaster->ToCreature()->HasReactState(REACT_PASSIVE)) || !spell->m_spellInfo->CausesInitialThreat()) return false; return true; @@ -2829,13 +2829,33 @@ void Spell::TargetInfo::DoDamageAndTriggers(Spell* spell) spell->m_needComboPoints = false; // _spellHitTarget can be null if spell is missed in DoSpellHitOnUnit - if (MissCondition != SPELL_MISS_EVADE && _spellHitTarget && !spell->m_caster->IsFriendlyTo(unit) && (!spell->IsPositive() || spell->m_spellInfo->HasEffect(SPELL_EFFECT_DISPEL))) + bool setInCombat = [&]() + { + if (MissCondition == SPELL_MISS_EVADE) + return false; + + if (!_spellHitTarget) + return false; + + if (spell->IsPositive() && !spell->m_spellInfo->HasEffect(SPELL_EFFECT_DISPEL)) + return false; + + if (spell->m_caster->IsFriendlyTo(unit)) + return false; + + if ((spell->m_caster->IsCreature() && spell->m_caster->ToCreature()->HasReactState(REACT_PASSIVE)) || !spell->m_spellInfo->CausesInitialThreat()) + return false; + + return true; + }(); + + if (setInCombat) { if (Unit* unitCaster = spell->m_caster->ToUnit()) { - if (!unitCaster->IsCreature() || !unitCaster->ToCreature()->IsTrigger()) + if (!unitCaster->IsCreature()) { - unitCaster->AtTargetAttacked(unit, spell->m_spellInfo->CausesInitialThreat() && !unitCaster->IsIgnoringCombat()); + unitCaster->AtTargetAttacked(unit, true); if (spell->m_spellInfo->HasAttribute(SPELL_ATTR6_TAPS_IMMEDIATELY)) if (Creature* targetCreature = unit->ToCreature()) @@ -8092,7 +8112,7 @@ void Spell::PreprocessSpellLaunch(TargetInfo& targetInfo) if (m_originalCaster->IsFriendlyTo(targetUnit)) return false; - if (m_originalCaster->IsIgnoringCombat() || !m_spellInfo->CausesInitialThreat()) + if ((m_originalCaster->IsCreature() && m_originalCaster->ToCreature()->HasReactState(REACT_PASSIVE)) || !m_spellInfo->CausesInitialThreat()) return false; return true; diff --git a/src/server/scripts/Commands/cs_npc.cpp b/src/server/scripts/Commands/cs_npc.cpp index f7336cca32..f987b50af0 100644 --- a/src/server/scripts/Commands/cs_npc.cpp +++ b/src/server/scripts/Commands/cs_npc.cpp @@ -203,19 +203,28 @@ EnumName const flagsExtra[] = CREATE_NAMED_ENUM(CREATURE_FLAG_EXTRA_TRIGGER), CREATE_NAMED_ENUM(CREATURE_FLAG_EXTRA_NO_TAUNT), CREATE_NAMED_ENUM(CREATURE_FLAG_EXTRA_UNUSED_9), + CREATE_NAMED_ENUM(CREATURE_FLAG_EXTRA_GHOST_VISIBILITY), + CREATE_NAMED_ENUM(CREATURE_FLAG_EXTRA_USE_OFFHAND_ATTACK), CREATE_NAMED_ENUM(CREATURE_FLAG_EXTRA_NO_SELL_VENDOR), - CREATE_NAMED_ENUM(CREATURE_FLAG_EXTRA_NO_COMBAT), + CREATE_NAMED_ENUM(CREATURE_FLAG_EXTRA_UNUSED_13), CREATE_NAMED_ENUM(CREATURE_FLAG_EXTRA_WORLDEVENT), CREATE_NAMED_ENUM(CREATURE_FLAG_EXTRA_GUARD), + CREATE_NAMED_ENUM(CREATURE_FLAG_EXTRA_IGNORE_FEIGN_DEATH), CREATE_NAMED_ENUM(CREATURE_FLAG_EXTRA_NO_CRIT), CREATE_NAMED_ENUM(CREATURE_FLAG_EXTRA_NO_SKILLGAIN), CREATE_NAMED_ENUM(CREATURE_FLAG_EXTRA_TAUNT_DIMINISH), CREATE_NAMED_ENUM(CREATURE_FLAG_EXTRA_ALL_DIMINISH), CREATE_NAMED_ENUM(CREATURE_FLAG_EXTRA_NO_PLAYER_DAMAGE_REQ), + CREATE_NAMED_ENUM(CREATURE_FLAG_EXTRA_UNUSED_22), + CREATE_NAMED_ENUM(CREATURE_FLAG_EXTRA_UNUSED_23), + CREATE_NAMED_ENUM(CREATURE_FLAG_EXTRA_UNUSED_24), + CREATE_NAMED_ENUM(CREATURE_FLAG_EXTRA_UNUSED_25), + CREATE_NAMED_ENUM(CREATURE_FLAG_EXTRA_UNUSED_26), + CREATE_NAMED_ENUM(CREATURE_FLAG_EXTRA_UNUSED_27), CREATE_NAMED_ENUM(CREATURE_FLAG_EXTRA_DUNGEON_BOSS), CREATE_NAMED_ENUM(CREATURE_FLAG_EXTRA_IGNORE_PATHFINDING), CREATE_NAMED_ENUM(CREATURE_FLAG_EXTRA_IMMUNITY_KNOCKBACK), - CREATE_NAMED_ENUM(CREATURE_FLAG_EXTRA_USE_OFFHAND_ATTACK) + CREATE_NAMED_ENUM(CREATURE_FLAG_EXTRA_UNUSED_31) }; uint32 const FLAGS_EXTRA_COUNT = std::extent::value;