refactor(Core/Unit): PC&NPC Immunity (#11986)

* initial

* refactor(Core/Unit): PC & NPC Immunities

Cherry-pick TC: 74af880217

Co-authored-by: Treeston <treeston.nmoc@gmail.com>

* fix builds error

Cherry-pick TC: 74af880217

Co-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:
Maelthyr
2022-06-18 14:16:45 +02:00
committed by GitHub
parent 4bc99f8070
commit d928d8d96a
88 changed files with 450 additions and 328 deletions

View File

@@ -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;
}
}