diff options
author | Manuel Carrasco <mgcarrasco2012@gmail.com> | 2016-10-20 13:42:13 -0300 |
---|---|---|
committer | Shauren <shauren.trinity@gmail.com> | 2016-10-20 18:42:13 +0200 |
commit | 7fa191f77425fe5f1c532f47a36dba302ec8da6f (patch) | |
tree | 2c6cd5e3f2a3a11c19bf6fe6dae9e51d5ad88998 /src | |
parent | 4881e45688c3d8f64cf2efaa7553ecbc02a0884a (diff) |
Core/AI: initial support for monster sparring (#17673)
(cherry picked from commit 303066509d907d4836a935371492092f05d47c7e)
Diffstat (limited to 'src')
-rw-r--r-- | src/server/game/AI/CoreAI/UnitAI.cpp | 13 | ||||
-rw-r--r-- | src/server/game/DataStores/DB2Structure.h | 1 | ||||
-rw-r--r-- | src/server/game/DataStores/DBCEnums.h | 1 | ||||
-rw-r--r-- | src/server/game/Entities/Unit/Unit.cpp | 44 | ||||
-rw-r--r-- | src/server/game/Entities/Unit/Unit.h | 18 |
5 files changed, 67 insertions, 10 deletions
diff --git a/src/server/game/AI/CoreAI/UnitAI.cpp b/src/server/game/AI/CoreAI/UnitAI.cpp index 28f1308b57f..52a6aaff65e 100644 --- a/src/server/game/AI/CoreAI/UnitAI.cpp +++ b/src/server/game/AI/CoreAI/UnitAI.cpp @@ -56,16 +56,25 @@ void UnitAI::DoMeleeAttackIfReady() if (!me->IsWithinMeleeRange(victim)) return; + bool sparAttack = me->GetFactionTemplateEntry()->ShouldSparAttack() && victim->GetFactionTemplateEntry()->ShouldSparAttack(); //Make sure our attack is ready and we aren't currently casting before checking distance if (me->isAttackReady()) { - me->AttackerStateUpdate(victim); + if (sparAttack) + me->FakeAttackerStateUpdate(victim); + else + me->AttackerStateUpdate(victim); + me->resetAttackTimer(); } if (me->haveOffhandWeapon() && me->isAttackReady(OFF_ATTACK)) { - me->AttackerStateUpdate(victim, OFF_ATTACK); + if (sparAttack) + me->FakeAttackerStateUpdate(victim, OFF_ATTACK); + else + me->AttackerStateUpdate(victim, OFF_ATTACK); + me->resetAttackTimer(OFF_ATTACK); } } diff --git a/src/server/game/DataStores/DB2Structure.h b/src/server/game/DataStores/DB2Structure.h index f889b4e5410..8a06351d288 100644 --- a/src/server/game/DataStores/DB2Structure.h +++ b/src/server/game/DataStores/DB2Structure.h @@ -913,6 +913,7 @@ struct FactionTemplateEntry return EnemyMask == 0 && FriendMask == 0; } bool IsContestedGuardFaction() const { return (Flags & FACTION_TEMPLATE_FLAG_CONTESTED_GUARD) != 0; } + bool ShouldSparAttack() const { return (Flags & FACTION_TEMPLATE_ENEMY_SPAR) != 0; } }; struct GameObjectsEntry diff --git a/src/server/game/DataStores/DBCEnums.h b/src/server/game/DataStores/DBCEnums.h index fe529ed3076..5903be4f347 100644 --- a/src/server/game/DataStores/DBCEnums.h +++ b/src/server/game/DataStores/DBCEnums.h @@ -535,6 +535,7 @@ enum SpawnMask enum FactionTemplateFlags { + FACTION_TEMPLATE_ENEMY_SPAR = 0x00000020, // guessed, sparring with enemies? FACTION_TEMPLATE_FLAG_PVP = 0x00000800, // flagged for PvP FACTION_TEMPLATE_FLAG_CONTESTED_GUARD = 0x00001000, // faction will attack players that were involved in PvP combats FACTION_TEMPLATE_FLAG_HOSTILE_BY_DEFAULT= 0x00002000 diff --git a/src/server/game/Entities/Unit/Unit.cpp b/src/server/game/Entities/Unit/Unit.cpp index 75222e078b0..750643ec126 100644 --- a/src/server/game/Entities/Unit/Unit.cpp +++ b/src/server/game/Entities/Unit/Unit.cpp @@ -1895,6 +1895,50 @@ void Unit::AttackerStateUpdate (Unit* victim, WeaponAttackType attType, bool ext } } +void Unit::FakeAttackerStateUpdate(Unit* victim, WeaponAttackType attType /*= BASE_ATTACK*/) +{ + if (HasUnitState(UNIT_STATE_CANNOT_AUTOATTACK) || HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_PACIFIED)) + return; + + if (!victim->IsAlive()) + return; + + if ((attType == BASE_ATTACK || attType == OFF_ATTACK) && !IsWithinLOSInMap(victim)) + return; + + CombatStart(victim); + RemoveAurasWithInterruptFlags(AURA_INTERRUPT_FLAG_MELEE_ATTACK); + + if (attType != BASE_ATTACK && attType != OFF_ATTACK) + return; // ignore ranged case + + if (GetTypeId() == TYPEID_UNIT && !HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_PLAYER_CONTROLLED)) + SetFacingToObject(victim); // update client side facing to face the target (prevents visual glitches when casting untargeted spells) + + CalcDamageInfo damageInfo; + damageInfo.attacker = this; + damageInfo.target = victim; + damageInfo.damageSchoolMask = GetMeleeDamageSchoolMask(); + damageInfo.attackType = attType; + damageInfo.damage = 0; + damageInfo.cleanDamage = 0; + damageInfo.absorb = 0; + damageInfo.resist = 0; + damageInfo.blocked_amount = 0; + + damageInfo.TargetState = VICTIMSTATE_HIT; + damageInfo.HitInfo = HITINFO_AFFECTS_VICTIM | HITINFO_NORMALSWING | HITINFO_FAKE_DAMAGE; + if (attType == OFF_ATTACK) + damageInfo.HitInfo |= HITINFO_OFFHAND; + + damageInfo.procAttacker = PROC_FLAG_NONE; + damageInfo.procVictim = PROC_FLAG_NONE; + damageInfo.procEx = PROC_EX_NONE; + damageInfo.hitOutCome = MELEE_HIT_NORMAL; + + SendAttackStateUpdate(&damageInfo); +} + void Unit::HandleProcExtraAttackFor(Unit* victim) { while (m_extraAttacks) diff --git a/src/server/game/Entities/Unit/Unit.h b/src/server/game/Entities/Unit/Unit.h index 1cc7536ea8c..58cab981dfc 100644 --- a/src/server/game/Entities/Unit/Unit.h +++ b/src/server/game/Entities/Unit/Unit.h @@ -362,20 +362,21 @@ enum HitInfo HITINFO_FULL_RESIST = 0x00000080, HITINFO_PARTIAL_RESIST = 0x00000100, HITINFO_CRITICALHIT = 0x00000200, // critical hit - // 0x00000400 - // 0x00000800 + HITINFO_UNK10 = 0x00000400, + HITINFO_UNK11 = 0x00000800, HITINFO_UNK12 = 0x00001000, HITINFO_BLOCK = 0x00002000, // blocked damage - // 0x00004000 // Hides worldtext for 0 damage - // 0x00008000 // Related to blood visual + HITINFO_UNK14 = 0x00004000, // set only if meleespellid is present// no world text when victim is hit for 0 dmg(HideWorldTextForNoDamage?) + HITINFO_UNK15 = 0x00008000, // player victim?// something related to blod sprut visual (BloodSpurtInBack?) HITINFO_GLANCING = 0x00010000, HITINFO_CRUSHING = 0x00020000, HITINFO_NO_ANIMATION = 0x00040000, - // 0x00080000 - // 0x00100000 + HITINFO_UNK19 = 0x00080000, + HITINFO_UNK20 = 0x00100000, HITINFO_SWINGNOHITSOUND = 0x00200000, // unused? - // 0x00400000 - HITINFO_RAGE_GAIN = 0x00800000 + HITINFO_UNK22 = 0x00400000, + HITINFO_RAGE_GAIN = 0x00800000, + HITINFO_FAKE_DAMAGE = 0x01000000 // enables damage animation even if no damage done, set only if no damage }; //i would like to remove this: (it is defined in item.h @@ -1549,6 +1550,7 @@ class TC_GAME_API Unit : public WorldObject void HandleEmoteCommand(uint32 anim_id); void AttackerStateUpdate (Unit* victim, WeaponAttackType attType = BASE_ATTACK, bool extra = false); + void FakeAttackerStateUpdate(Unit* victim, WeaponAttackType attType = BASE_ATTACK); void CalculateMeleeDamage(Unit* victim, uint32 damage, CalcDamageInfo* damageInfo, WeaponAttackType attackType = BASE_ATTACK); void DealMeleeDamage(CalcDamageInfo* damageInfo, bool durabilityLoss); |