Merge branch 'Playerbot' of https://github.com/ZhengPeiRu21/azerothcore-wotlk into Playerbot

This commit is contained in:
郑佩茹
2022-06-16 10:06:30 -06:00
125 changed files with 5441 additions and 1838 deletions

View File

@@ -704,7 +704,7 @@ void Creature::Update(uint32 diff)
}
// periodic check to see if the creature has passed an evade boundary
if (IsAIEnabled && !IsInEvadeMode() && IsInCombat())
if (IsAIEnabled && !IsInEvadeMode() && IsEngaged())
{
if (diff >= m_boundaryCheckTime)
{
@@ -1810,6 +1810,21 @@ bool Creature::CanAlwaysSee(WorldObject const* obj) const
return false;
}
bool Creature::IsAlwaysDetectableFor(WorldObject const* seer) const
{
if (Unit::IsAlwaysDetectableFor(seer))
{
return true;
}
if (IsAIEnabled && AI()->CanAlwaysBeDetectable(seer))
{
return true;
}
return false;
}
bool Creature::CanStartAttack(Unit const* who) const
{
if (IsCivilian())
@@ -1839,7 +1854,7 @@ bool Creature::CanStartAttack(Unit const* who) const
// pussywizard: at this point we are either hostile to who or friendly to who->getAttackerForHelper()
// pussywizard: if who is in combat and has an attacker, help him if the distance is right (help because who is hostile or help because attacker is friendly)
bool assist = false;
if (who->IsInCombat() && IsWithinDist(who, ATTACK_DISTANCE))
if (who->IsEngaged() && IsWithinDist(who, ATTACK_DISTANCE))
if (Unit* victim = who->getAttackerForHelper())
if (IsWithinDistInMap(victim, sWorld->getFloatConfig(CONFIG_CREATURE_FAMILY_ASSISTANCE_RADIUS)))
assist = true;
@@ -2358,7 +2373,7 @@ bool Creature::CanAssistTo(Unit const* u, Unit const* enemy, bool checkfaction /
return false;
// skip fighting creature
if (IsInCombat())
if (IsEngaged())
return false;
// only free creature
@@ -2409,11 +2424,10 @@ bool Creature::_IsTargetAcceptable(Unit const* target) const
return false;
}
Unit const* myVictim = getAttackerForHelper();
Unit const* targetVictim = target->getAttackerForHelper();
// if I'm already fighting target, or I'm hostile towards the target, the target is acceptable
if (myVictim == target || targetVictim == this || IsHostileTo(target))
if (IsEngagedBy(target) || IsHostileTo(target))
return true;
// if the target's victim is friendly, and the target is neutral, the target is acceptable

View File

@@ -386,6 +386,8 @@ public:
void ModifyThreatPercentTemp(Unit* victim, int32 percent, Milliseconds duration);
void ResetFaction() { SetFaction(GetCreatureTemplate()->faction); }
protected:
bool CreateFromProto(ObjectGuid::LowType guidlow, uint32 Entry, uint32 vehId, const CreatureData* data = nullptr);
bool InitEntry(uint32 entry, const CreatureData* data = nullptr);
@@ -441,6 +443,7 @@ protected:
[[nodiscard]] bool IsInvisibleDueToDespawn() const override;
bool CanAlwaysSee(WorldObject const* obj) const override;
bool IsAlwaysDetectableFor(WorldObject const* seer) const override;
private:
void ForcedDespawn(uint32 timeMSToDespawn = 0, Seconds forcedRespawnTimer = 0s);

View File

@@ -190,7 +190,7 @@ void CreatureGroup::RemoveMember(Creature* member)
member->SetFormation(nullptr);
}
void CreatureGroup::MemberAttackStart(Creature* member, Unit* target)
void CreatureGroup::MemberEngagingTarget(Creature* member, Unit* target)
{
uint8 const groupAI = sFormationMgr->CreatureGroupMap[member->GetSpawnId()].groupAI;
if (member == m_leader)

View File

@@ -106,7 +106,7 @@ public:
void FormationReset(bool dismiss, bool initMotionMaster);
void LeaderMoveTo(float x, float y, float z, bool run);
void MemberAttackStart(Creature* member, Unit* target);
void MemberEngagingTarget(Creature* member, Unit* target);
void MemberEvaded(Creature* member);
private:

View File

@@ -701,8 +701,8 @@ void GameObject::Update(uint32 diff)
// search unfriendly creature
if (owner && goInfo->trap.autoCloseTime != -1) // hunter trap
{
Acore::AnyUnfriendlyNoTotemUnitInObjectRangeCheck checker(this, owner, radius);
Acore::UnitSearcher<Acore::AnyUnfriendlyNoTotemUnitInObjectRangeCheck> searcher(this, target, checker);
Acore::NearestAttackableNoTotemUnitInObjectRangeCheck checker(this, owner, radius);
Acore::UnitSearcher<Acore::NearestAttackableNoTotemUnitInObjectRangeCheck> searcher(this, target, checker);
Cell::VisitAllObjects(this, searcher, radius);
}
else // environmental trap

View File

@@ -25,6 +25,7 @@
#include "Object.h"
#include "SharedDefines.h"
#include "Unit.h"
#include <array>
class GameObjectAI;
class Transport;
@@ -676,6 +677,7 @@ struct GameObjectTemplateAddon
uint32 flags;
uint32 mingold;
uint32 maxgold;
std::array<uint32, 4> artKits = {};
};
// Benchmarked: Faster than std::map (insert/find)
@@ -736,6 +738,35 @@ enum GOState
#define MAX_GO_STATE 3
enum class GameObjectActions : uint32
{
// Name from client executable // Comments
None, // -NONE-
AnimateCustom0, // Animate Custom0
AnimateCustom1, // Animate Custom1
AnimateCustom2, // Animate Custom2
AnimateCustom3, // Animate Custom3
Disturb, // Disturb // Triggers trap
Unlock, // Unlock // Resets GO_FLAG_LOCKED
Lock, // Lock // Sets GO_FLAG_LOCKED
Open, // Open // Sets GO_STATE_ACTIVE
OpenAndUnlock, // Open + Unlock // Sets GO_STATE_ACTIVE and resets GO_FLAG_LOCKED
Close, // Close // Sets GO_STATE_READY
ToggleOpen, // Toggle Open
Destroy, // Destroy // Sets GO_STATE_DESTROYED
Rebuild, // Rebuild // Resets from GO_STATE_DESTROYED
Creation, // Creation
Despawn, // Despawn
MakeInert, // Make Inert // Disables interactions
MakeActive, // Make Active // Enables interactions
CloseAndLock, // Close + Lock // Sets GO_STATE_READY and sets GO_FLAG_LOCKED
UseArtKit0, // Use ArtKit0 // 46904: 121
UseArtKit1, // Use ArtKit1 // 36639: 81, 46903: 122
UseArtKit2, // Use ArtKit2
UseArtKit3, // Use ArtKit3
SetTapList, // Set Tap List
};
// from `gameobject`
struct GameObjectData
{

View File

@@ -1234,7 +1234,7 @@ Position WorldObject::GetHitSpherePointFor(Position const& dest) const
{
G3D::Vector3 vThis(GetPositionX(), GetPositionY(), GetPositionZ() + GetCollisionHeight());
G3D::Vector3 vObj(dest.GetPositionX(), dest.GetPositionY(), dest.GetPositionZ());
G3D::Vector3 contactPoint = vThis + (vObj - vThis).directionOrZero() * std::min(dest.GetExactDist(this), GetObjectSize());
G3D::Vector3 contactPoint = vThis + (vObj - vThis).directionOrZero() * std::min(dest.GetExactDist(this), GetCombatReach());
return Position(contactPoint.x, contactPoint.y, contactPoint.z, GetAngle(contactPoint.x, contactPoint.y));
}

View File

@@ -1620,7 +1620,11 @@ void Player::ProcessDelayedOperations()
SaveToDB(false, false);
if (m_DelayedOperations & DELAYED_SPELL_CAST_DESERTER)
CastSpell(this, 26013, true); // Deserter
{
Aura* aura = GetAura(26013);
if (!aura || aura->GetDuration() <= 900000)
CastSpell(this, 26013, true);
}
if (m_DelayedOperations & DELAYED_BG_MOUNT_RESTORE)
{
@@ -2139,10 +2143,8 @@ void Player::SetInWater(bool apply)
getHostileRefMgr().updateThreatTables();
}
bool Player::IsInAreaTriggerRadius(const AreaTrigger* trigger) const
bool Player::IsInAreaTriggerRadius(AreaTrigger const* trigger, float delta) const
{
static const float delta = 5.0f;
if (!trigger || GetMapId() != trigger->map)
return false;

View File

@@ -1095,7 +1095,7 @@ public:
[[nodiscard]] bool IsInWater() const override { return m_isInWater; }
[[nodiscard]] bool IsFalling() const;
bool IsInAreaTriggerRadius(const AreaTrigger* trigger) const;
bool IsInAreaTriggerRadius(AreaTrigger const* trigger, float delta = 0.f) const;
void SendInitialPacketsBeforeAddToMap();
void SendInitialPacketsAfterAddToMap();
@@ -2949,7 +2949,15 @@ template <class T> T Player::ApplySpellMod(uint32 spellId, SpellModOp op, T& bas
return;
}
totalflat += mod->value;
int32 flatValue = mod->value;
// SPELL_MOD_THREAT - divide by 100 (in packets we send threat * 100)
if (mod->op == SPELLMOD_THREAT)
{
flatValue /= 100;
}
totalflat += flatValue;
}
else if (mod->type == SPELLMOD_PCT)
{

View File

@@ -277,10 +277,11 @@ void Player::Update(uint32 p_time)
// supposed to be in one
if (HasRestFlag(REST_FLAG_IN_TAVERN))
{
AreaTrigger const* atEntry =
sObjectMgr->GetAreaTrigger(GetInnTriggerId());
if (!atEntry || !IsInAreaTriggerRadius(atEntry))
AreaTrigger const* atEntry = sObjectMgr->GetAreaTrigger(GetInnTriggerId());
if (!atEntry || !IsInAreaTriggerRadius(atEntry, 5.f))
{
RemoveRestFlag(REST_FLAG_IN_TAVERN);
}
}
uint32 newzone, newarea;

View File

@@ -85,6 +85,8 @@ void Totem::InitStats(uint32 duration)
void Totem::InitSummon()
{
Minion::InitSummon();
if (m_type == TOTEM_PASSIVE && GetSpell())
CastSpell(this, GetSpell(), true);

View File

@@ -316,6 +316,8 @@ Unit::Unit(bool isWorldObject) : WorldObject(isWorldObject),
_oldFactionId = 0;
_isWalkingBeforeCharm = false;
_lastExtraAttackSpell = 0;
}
@@ -10482,8 +10484,12 @@ void Unit::SetCharm(Unit* charm, bool apply)
if (!charm->AddGuidValue(UNIT_FIELD_CHARMEDBY, GetGUID()))
LOG_FATAL("entities.unit", "Unit {} is being charmed, but it already has a charmer {}", charm->GetEntry(), charm->GetCharmerGUID().ToString());
if (charm->HasUnitMovementFlag(MOVEMENTFLAG_WALKING))
_isWalkingBeforeCharm = charm->IsWalking();
if (_isWalkingBeforeCharm)
{
charm->SetWalk(false);
charm->SendMovementFlagUpdate();
}
m_Controlled.insert(charm);
}
@@ -10521,6 +10527,12 @@ void Unit::SetCharm(Unit* charm, bool apply)
charm->SetByteValue(UNIT_FIELD_BYTES_2, 1, 0);
}
if (charm->IsWalking() != _isWalkingBeforeCharm)
{
charm->SetWalk(_isWalkingBeforeCharm);
charm->SendMovementFlagUpdate(true); // send packet to self, to update movement state on player.
}
m_Controlled.erase(charm);
}
}
@@ -12422,7 +12434,7 @@ bool Unit::IsImmunedToSpell(SpellInfo const* spellInfo)
{
SpellInfo const* immuneSpellInfo = sSpellMgr->GetSpellInfo(itr->spellId);
if (((itr->type & spellInfo->GetSchoolMask()) == spellInfo->GetSchoolMask())
&& !(immuneSpellInfo && immuneSpellInfo->IsPositive()) && !spellInfo->IsPositive()
&& (!immuneSpellInfo || immuneSpellInfo->IsPositive()) && !spellInfo->IsPositive()
&& !spellInfo->CanPierceImmuneAura(immuneSpellInfo))
return true;
}
@@ -13168,7 +13180,7 @@ void Unit::SetInCombatState(bool PvP, Unit* enemy, uint32 duration)
creature->AI()->EnterCombat(enemy);
if (creature->GetFormation())
creature->GetFormation()->MemberAttackStart(creature, enemy);
creature->GetFormation()->MemberEngagingTarget(creature, enemy);
}
creature->RefreshSwimmingFlag();

View File

@@ -1326,6 +1326,7 @@ public:
bool IsWithinCombatRange(Unit const* obj, float dist2compare) const;
bool IsWithinMeleeRange(Unit const* obj, float dist = 0.f) const;
float GetMeleeRange(Unit const* target) const;
[[nodiscard]] virtual SpellSchoolMask GetMeleeDamageSchoolMask() const;
bool GetRandomContactPoint(Unit const* target, float& x, float& y, float& z, bool force = false) const;
uint32 m_extraAttacks;
bool m_canDualWield;
@@ -1343,6 +1344,9 @@ public:
if (GetVictim() != nullptr)
return GetVictim();
if (!IsEngaged())
return nullptr;
if (!m_attackers.empty())
return *(m_attackers.begin());
@@ -1644,6 +1648,9 @@ public:
[[nodiscard]] bool IsInFlight() const { return HasUnitState(UNIT_STATE_IN_FLIGHT); }
bool IsEngaged() const { return IsInCombat(); }
bool IsEngagedBy(Unit const* who) const { return IsInCombatWith(who); }
[[nodiscard]] bool IsInCombat() const { return HasUnitFlag(UNIT_FLAG_IN_COMBAT); }
bool IsInCombatWith(Unit const* who) const;
@@ -2105,6 +2112,7 @@ public:
void TauntApply(Unit* victim);
void TauntFadeOut(Unit* taunter);
ThreatMgr& GetThreatMgr() { return m_ThreatMgr; }
ThreatMgr const& GetThreatMgr() const { return m_ThreatMgr; }
void addHatedBy(HostileReference* pHostileReference) { m_HostileRefMgr.insertFirst(pHostileReference); };
void removeHatedBy(HostileReference* /*pHostileReference*/) { /* nothing to do yet */ }
HostileRefMgr& getHostileRefMgr() { return m_HostileRefMgr; }
@@ -2478,8 +2486,6 @@ protected:
CharmInfo* m_charmInfo;
SharedVisionList m_sharedVision;
[[nodiscard]] virtual SpellSchoolMask GetMeleeDamageSchoolMask() const;
MotionMaster* i_motionMaster;
uint32 m_reactiveTimer[MAX_REACTIVE];
@@ -2549,6 +2555,7 @@ private:
bool m_duringRemoveFromWorld; // lock made to not add stuff after begining removing from world
uint32 _oldFactionId; ///< faction before charm
bool _isWalkingBeforeCharm; ///< Are we walking before we were charmed?
[[nodiscard]] float processDummyAuras(float TakenTotalMod) const;