mirror of
https://github.com/mod-playerbots/azerothcore-wotlk.git
synced 2026-01-27 15:46:24 +00:00
refactor(Core/Unit): PC&NPC Immunity (#11986)
* initial * refactor(Core/Unit): PC & NPC Immunities Cherry-pick TC:74af880217Co-authored-by: Treeston <treeston.nmoc@gmail.com> * fix builds error Cherry-pick TC:74af880217Co-authored-by: Treeston <treeston.nmoc@gmail.com> * Fix nef combat, and replace SetFlag by SetUnitFlag * fix combat with jedoga Co-authored-by: Treeston <treeston.nmoc@gmail.com>
This commit is contained in:
@@ -1830,14 +1830,14 @@ bool Creature::CanStartAttack(Unit const* who) const
|
||||
return false;
|
||||
|
||||
// This set of checks is should be done only for creatures
|
||||
if ((HasUnitFlag(UNIT_FLAG_IMMUNE_TO_NPC) && who->GetTypeId() != TYPEID_PLAYER) || // flag is valid only for non player characters
|
||||
(HasUnitFlag(UNIT_FLAG_IMMUNE_TO_PC) && who->GetTypeId() == TYPEID_PLAYER)) // immune to PC and target is a player, return false
|
||||
if ((IsImmuneToNPC() && who->GetTypeId() != TYPEID_PLAYER) || // flag is valid only for non player characters
|
||||
(IsImmuneToPC() && who->GetTypeId() == TYPEID_PLAYER)) // immune to PC and target is a player, return false
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (Unit* owner = who->GetOwner())
|
||||
if (owner->GetTypeId() == TYPEID_PLAYER && HasUnitFlag(UNIT_FLAG_IMMUNE_TO_PC)) // immune to PC and target has player owner
|
||||
if (owner->GetTypeId() == TYPEID_PLAYER && IsImmuneToPC()) // immune to PC and target has player owner
|
||||
return false;
|
||||
|
||||
// Do not attack non-combat pets
|
||||
@@ -2368,7 +2368,7 @@ bool Creature::CanAssistTo(Unit const* u, Unit const* enemy, bool checkfaction /
|
||||
if (IsCivilian())
|
||||
return false;
|
||||
|
||||
if (HasUnitFlag(UNIT_FLAG_NON_ATTACKABLE | UNIT_FLAG_NOT_SELECTABLE | UNIT_FLAG_IMMUNE_TO_NPC))
|
||||
if (HasUnitFlag(UNIT_FLAG_NON_ATTACKABLE | UNIT_FLAG_NOT_SELECTABLE) || IsImmuneToNPC())
|
||||
return false;
|
||||
|
||||
// skip fighting creature
|
||||
|
||||
@@ -2088,7 +2088,7 @@ void GameObject::CastSpell(Unit* target, uint32 spellId)
|
||||
trigger->SetByteFlag(UNIT_FIELD_BYTES_2, 1, UNIT_BYTE2_FLAG_FFA_PVP);
|
||||
|
||||
// xinef: Remove Immunity flags
|
||||
trigger->RemoveUnitFlag(UNIT_FLAG_IMMUNE_TO_NPC);
|
||||
trigger->SetImmuneToNPC(false);
|
||||
// xinef: set proper orientation, fixes cast against stealthed targets
|
||||
if (target)
|
||||
trigger->SetInFront(target);
|
||||
|
||||
@@ -2643,12 +2643,13 @@ void Player::InitStatsForLevel(bool reapplyMods)
|
||||
|
||||
// cleanup unit flags (will be re-applied if need at aura load).
|
||||
RemoveFlag(UNIT_FIELD_FLAGS,
|
||||
UNIT_FLAG_NON_ATTACKABLE | UNIT_FLAG_DISABLE_MOVE | UNIT_FLAG_NOT_ATTACKABLE_1 |
|
||||
UNIT_FLAG_IMMUNE_TO_PC | UNIT_FLAG_IMMUNE_TO_NPC | UNIT_FLAG_LOOTING |
|
||||
UNIT_FLAG_PET_IN_COMBAT | UNIT_FLAG_SILENCED | UNIT_FLAG_PACIFIED |
|
||||
UNIT_FLAG_STUNNED | UNIT_FLAG_IN_COMBAT | UNIT_FLAG_DISARMED |
|
||||
UNIT_FLAG_CONFUSED | UNIT_FLAG_FLEEING | UNIT_FLAG_NOT_SELECTABLE |
|
||||
UNIT_FLAG_SKINNABLE | UNIT_FLAG_MOUNT | UNIT_FLAG_TAXI_FLIGHT );
|
||||
UNIT_FLAG_NON_ATTACKABLE | UNIT_FLAG_DISABLE_MOVE | UNIT_FLAG_NOT_ATTACKABLE_1 |
|
||||
UNIT_FLAG_LOOTING | UNIT_FLAG_PET_IN_COMBAT | UNIT_FLAG_SILENCED |
|
||||
UNIT_FLAG_PACIFIED | UNIT_FLAG_STUNNED | UNIT_FLAG_IN_COMBAT |
|
||||
UNIT_FLAG_DISARMED | UNIT_FLAG_CONFUSED | UNIT_FLAG_FLEEING |
|
||||
UNIT_FLAG_NOT_SELECTABLE | UNIT_FLAG_SKINNABLE | UNIT_FLAG_MOUNT |
|
||||
UNIT_FLAG_TAXI_FLIGHT);
|
||||
SetImmuneToAll(false);
|
||||
SetUnitFlag(UNIT_FLAG_PLAYER_CONTROLLED); // must be set
|
||||
|
||||
SetUnitFlag2(UNIT_FLAG2_REGENERATE_POWER);// must be set
|
||||
|
||||
@@ -13027,6 +13027,24 @@ void Unit::SetInCombatWith(Unit* enemy, uint32 duration)
|
||||
SetInCombatState(false, enemy, duration);
|
||||
}
|
||||
|
||||
void Unit::SetImmuneToPC(bool apply, bool keepCombat)
|
||||
{
|
||||
(void)keepCombat;
|
||||
if (apply)
|
||||
SetUnitFlag(UNIT_FLAG_IMMUNE_TO_PC);
|
||||
else
|
||||
RemoveUnitFlag(UNIT_FLAG_IMMUNE_TO_PC);
|
||||
}
|
||||
|
||||
void Unit::SetImmuneToNPC(bool apply, bool keepCombat)
|
||||
{
|
||||
(void)keepCombat;
|
||||
if (apply)
|
||||
SetUnitFlag(UNIT_FLAG_IMMUNE_TO_NPC);
|
||||
else
|
||||
RemoveUnitFlag(UNIT_FLAG_IMMUNE_TO_NPC);
|
||||
}
|
||||
|
||||
void Unit::CombatStart(Unit* victim, bool initialAggro)
|
||||
{
|
||||
// Xinef: Dont allow to start combat with triggers
|
||||
@@ -13140,8 +13158,8 @@ void Unit::SetInCombatState(bool PvP, Unit* enemy, uint32 duration)
|
||||
return;
|
||||
|
||||
// xinef: if we somehow engage in combat (scripts, dunno) with player, remove this flag so he can fight back
|
||||
if (GetTypeId() == TYPEID_UNIT && enemy && HasUnitFlag(UNIT_FLAG_IMMUNE_TO_PC) && enemy->GetCharmerOrOwnerPlayerOrPlayerItself())
|
||||
RemoveUnitFlag(UNIT_FLAG_IMMUNE_TO_PC); // unit has engaged in combat, remove immunity so players can fight back
|
||||
if (GetTypeId() == TYPEID_UNIT && enemy && IsImmuneToPC() && enemy->GetCharmerOrOwnerPlayerOrPlayerItself())
|
||||
SetImmuneToPC(true); // unit has engaged in combat, remove immunity so players can fight back
|
||||
|
||||
if (IsInCombat())
|
||||
return;
|
||||
@@ -13207,7 +13225,7 @@ void Unit::ClearInCombat()
|
||||
if (Creature* creature = ToCreature())
|
||||
{
|
||||
if (creature->GetCreatureTemplate() && creature->GetCreatureTemplate()->unit_flags & UNIT_FLAG_IMMUNE_TO_PC)
|
||||
SetUnitFlag(UNIT_FLAG_IMMUNE_TO_PC); // set immunity state to the one from db on evade
|
||||
SetImmuneToPC(true); // set immunity state to the one from db on evade
|
||||
|
||||
ClearUnitState(UNIT_STATE_ATTACK_PLAYER);
|
||||
if (HasDynamicFlag(UNIT_DYNFLAG_TAPPED))
|
||||
@@ -13251,7 +13269,7 @@ bool Unit::isTargetableForAttack(bool checkFakeDeath, Unit const* byWho) const
|
||||
if (HasUnitFlag(UNIT_FLAG_NON_ATTACKABLE | UNIT_FLAG_NOT_SELECTABLE))
|
||||
return false;
|
||||
|
||||
if (HasUnitFlag(UNIT_FLAG_IMMUNE_TO_PC) && byWho && byWho->GetCharmerOrOwnerPlayerOrPlayerItself())
|
||||
if (IsImmuneToPC() && byWho && byWho->GetCharmerOrOwnerPlayerOrPlayerItself())
|
||||
return false;
|
||||
|
||||
if (GetTypeId() == TYPEID_PLAYER && ToPlayer()->IsGameMaster())
|
||||
@@ -13306,11 +13324,11 @@ bool Unit::_IsValidAttackTarget(Unit const* target, SpellInfo const* bySpell, Wo
|
||||
}
|
||||
// check flags
|
||||
if (target->HasUnitFlag(UNIT_FLAG_NON_ATTACKABLE | UNIT_FLAG_TAXI_FLIGHT | UNIT_FLAG_NOT_ATTACKABLE_1 | UNIT_FLAG_NON_ATTACKABLE_2)
|
||||
|| (!HasUnitFlag(UNIT_FLAG_PLAYER_CONTROLLED) && target->HasUnitFlag(UNIT_FLAG_IMMUNE_TO_NPC))
|
||||
|| (!target->HasUnitFlag(UNIT_FLAG_PLAYER_CONTROLLED) && HasUnitFlag(UNIT_FLAG_IMMUNE_TO_NPC))
|
||||
|| (HasUnitFlag(UNIT_FLAG_PLAYER_CONTROLLED) && target->HasUnitFlag(UNIT_FLAG_IMMUNE_TO_PC))
|
||||
|| (!HasUnitFlag(UNIT_FLAG_PLAYER_CONTROLLED) && target->IsImmuneToNPC())
|
||||
|| (!target->HasUnitFlag(UNIT_FLAG_PLAYER_CONTROLLED) && IsImmuneToNPC())
|
||||
|| (HasUnitFlag(UNIT_FLAG_PLAYER_CONTROLLED) && target->IsImmuneToPC())
|
||||
// check if this is a world trigger cast - GOs are using world triggers to cast their spells, so we need to ignore their immunity flag here, this is a temp workaround, needs removal when go cast is implemented properly
|
||||
|| ((GetEntry() != WORLD_TRIGGER && (!obj || !obj->isType(TYPEMASK_GAMEOBJECT | TYPEMASK_DYNAMICOBJECT))) && target->HasUnitFlag(UNIT_FLAG_PLAYER_CONTROLLED) && HasUnitFlag(UNIT_FLAG_IMMUNE_TO_PC)))
|
||||
|| ((GetEntry() != WORLD_TRIGGER && (!obj || !obj->isType(TYPEMASK_GAMEOBJECT | TYPEMASK_DYNAMICOBJECT))) && target->HasUnitFlag(UNIT_FLAG_PLAYER_CONTROLLED) && IsImmuneToPC()))
|
||||
return false;
|
||||
|
||||
// CvC case - can attack each other only when one of them is hostile
|
||||
@@ -13425,12 +13443,12 @@ bool Unit::_IsValidAssistTarget(Unit const* target, SpellInfo const* bySpell) co
|
||||
|
||||
if (HasUnitFlag(UNIT_FLAG_PLAYER_CONTROLLED))
|
||||
{
|
||||
if (target->HasUnitFlag(UNIT_FLAG_IMMUNE_TO_PC))
|
||||
if (target->IsImmuneToPC())
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (target->HasUnitFlag(UNIT_FLAG_IMMUNE_TO_NPC))
|
||||
if (target->IsImmuneToNPC())
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1647,6 +1647,13 @@ public:
|
||||
|
||||
[[nodiscard]] bool IsInFlight() const { return HasUnitState(UNIT_STATE_IN_FLIGHT); }
|
||||
|
||||
void SetImmuneToAll(bool apply, bool keepCombat = false) { SetImmuneToPC(apply, keepCombat); SetImmuneToNPC(apply, keepCombat); }
|
||||
bool IsImmuneToAll() const { return IsImmuneToPC() && IsImmuneToNPC(); }
|
||||
void SetImmuneToPC(bool apply, bool keepCombat = false);
|
||||
bool IsImmuneToPC() const { return HasUnitFlag(UNIT_FLAG_IMMUNE_TO_PC); }
|
||||
void SetImmuneToNPC(bool apply, bool keepCombat = false);
|
||||
bool IsImmuneToNPC() const { return HasUnitFlag(UNIT_FLAG_IMMUNE_TO_NPC); }
|
||||
|
||||
bool IsEngaged() const { return IsInCombat(); }
|
||||
bool IsEngagedBy(Unit const* who) const { return IsInCombatWith(who); }
|
||||
|
||||
|
||||
Reference in New Issue
Block a user