This commit is contained in:
郑佩茹
2022-06-21 09:19:50 -06:00
125 changed files with 1505 additions and 851 deletions

View File

@@ -1000,7 +1000,11 @@ uint32 Unit::DealDamage(Unit* attacker, Unit* victim, uint32 damage, CleanDamage
victim->ToCreature()->SetLootRecipient(attacker);
if (!attacker || attacker->IsControlledByPlayer() || attacker->IsCreatedByPlayer())
victim->ToCreature()->LowerPlayerDamageReq(health < damage ? health : damage);
{
uint32 unDamage = health < damage ? health : damage;
bool damagedByPlayer = unDamage && attacker && attacker->m_movedByPlayer != nullptr;
victim->ToCreature()->LowerPlayerDamageReq(unDamage, damagedByPlayer);
}
}
if (health <= damage)
@@ -3867,7 +3871,11 @@ bool Unit::isInAccessiblePlaceFor(Creature const* c) const
return false;
}
if (IsInWater())
LiquidStatus liquidStatus = GetLiquidData().Status;
bool isInWater = (liquidStatus & MAP_LIQUID_STATUS_SWIMMING) != 0;
// In water or jumping in water
if (isInWater || (liquidStatus == LIQUID_MAP_ABOVE_WATER && (IsFalling() || (ToPlayer() && ToPlayer()->IsFalling()))))
{
return c->CanEnterWater();
}
@@ -13045,6 +13053,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
@@ -13158,8 +13184,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;
@@ -13225,7 +13251,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))
@@ -13269,7 +13295,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())
@@ -13324,11 +13350,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
@@ -13443,12 +13469,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;
}
}
@@ -15737,9 +15763,9 @@ void Unit::ProcDamageAndSpellFor(bool isVictim, Unit* target, uint32 procFlag, u
else // For attacker
{
// Overpower on victim dodge
if (procExtra & PROC_EX_DODGE )
if (procExtra & PROC_EX_DODGE)
{
if (GetTypeId() == TYPEID_PLAYER && getClass() == CLASS_WARRIOR)
if (getClass() == CLASS_WARRIOR)
{
AddComboPoints(target, 1);
StartReactiveTimer(REACTIVE_OVERPOWER);
@@ -16530,8 +16556,10 @@ void Unit::UpdateReactives(uint32 p_time)
ModifyAuraState(AURA_STATE_HUNTER_PARRY, false);
break;
case REACTIVE_OVERPOWER:
if (getClass() == CLASS_WARRIOR && GetTypeId() == TYPEID_PLAYER)
if (getClass() == CLASS_WARRIOR)
{
ClearComboPoints();
}
break;
case REACTIVE_WOLVERINE_BITE:
if (IsHunterPet())

View File

@@ -1648,6 +1648,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); }