mirror of
https://github.com/mod-playerbots/azerothcore-wotlk.git
synced 2026-01-18 11:25:42 +00:00
Fix corrupt item cache crashes, bot whispers, trade crashes
This commit is contained in:
@@ -206,7 +206,7 @@ Creature::Creature(bool isWorldObject): Unit(isWorldObject), MovableMapObject(),
|
||||
m_transportCheckTimer(1000), lootPickPocketRestoreTime(0), m_reactState(REACT_AGGRESSIVE), m_defaultMovementType(IDLE_MOTION_TYPE),
|
||||
m_spawnId(0), m_equipmentId(0), m_originalEquipmentId(0), m_AlreadyCallAssistance(false),
|
||||
m_AlreadySearchedAssistance(false), m_regenHealth(true), m_AI_locked(false), m_meleeDamageSchoolMask(SPELL_SCHOOL_MASK_NORMAL), m_originalEntry(0), m_moveInLineOfSightDisabled(false), m_moveInLineOfSightStrictlyDisabled(false),
|
||||
m_homePosition(), m_transportHomePosition(), m_creatureInfo(nullptr), m_creatureData(nullptr), m_detectionDistance(20.0f), m_waypointID(0), m_path_id(0), m_formation(nullptr), _lastDamagedTime(nullptr), m_cannotReachTarget(false), m_cannotReachTimer(0),
|
||||
m_homePosition(), m_transportHomePosition(), m_creatureInfo(nullptr), m_creatureData(nullptr), m_detectionDistance(20.0f), m_waypointID(0), m_path_id(0), m_formation(nullptr), _lastDamagedTime(nullptr), m_cannotReachTimer(0),
|
||||
_isMissingSwimmingFlagOutOfCombat(false), m_assistanceTimer(0)
|
||||
{
|
||||
m_regenTimer = CREATURE_REGEN_INTERVAL;
|
||||
@@ -1299,6 +1299,7 @@ void Creature::SaveToDB(uint32 mapid, uint8 spawnMask, uint32 phaseMask)
|
||||
m_spawnId = sObjectMgr->GenerateCreatureSpawnId();
|
||||
|
||||
CreatureData& data = sObjectMgr->NewOrExistCreatureData(m_spawnId);
|
||||
data.spawnId = m_spawnId;
|
||||
|
||||
uint32 displayId = GetNativeDisplayId();
|
||||
uint32 npcflag = GetUInt32Value(UNIT_NPC_FLAGS);
|
||||
@@ -3420,15 +3421,19 @@ bool Creature::IsMovementPreventedByCasting() const
|
||||
return false;
|
||||
}
|
||||
|
||||
void Creature::SetCannotReachTarget(bool cannotReach)
|
||||
bool Creature::SetCannotReachTarget(bool cannotReach, bool isChase /*= true*/)
|
||||
{
|
||||
if (cannotReach == m_cannotReachTarget)
|
||||
return;
|
||||
m_cannotReachTarget = cannotReach;
|
||||
if (!isChase || !Unit::SetCannotReachTarget(cannotReach))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
m_cannotReachTimer = 0;
|
||||
|
||||
if (cannotReach)
|
||||
LOG_DEBUG("entities.unit", "Creature::SetCannotReachTarget() called with true. Details: {}", GetDebugInfo());
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
time_t Creature::GetLastDamagedTime() const
|
||||
|
||||
@@ -359,6 +359,7 @@ typedef std::unordered_map<uint32, EquipmentInfoContainerInternal> EquipmentInfo
|
||||
struct CreatureData
|
||||
{
|
||||
CreatureData() = default;
|
||||
ObjectGuid::LowType spawnId{0};
|
||||
uint32 id1{0}; // entry in creature_template
|
||||
uint32 id2{0}; // entry in creature_template
|
||||
uint32 id3{0}; // entry in creature_template
|
||||
|
||||
@@ -1009,6 +1009,7 @@ void GameObject::SaveToDB(uint32 mapid, uint8 spawnMask, uint32 phaseMask, bool
|
||||
|
||||
// update in loaded data (changing data only in this place)
|
||||
GameObjectData& data = sObjectMgr->NewGOData(m_spawnId);
|
||||
data.spawnId = m_spawnId;
|
||||
|
||||
data.id = GetEntry();
|
||||
data.mapid = mapid;
|
||||
|
||||
@@ -721,6 +721,7 @@ enum GOState
|
||||
struct GameObjectData
|
||||
{
|
||||
explicit GameObjectData() = default;
|
||||
ObjectGuid::LowType spawnId{0};
|
||||
uint32 id{0}; // entry in gamobject_template
|
||||
uint16 mapid{0};
|
||||
uint32 phaseMask{0};
|
||||
|
||||
@@ -12005,11 +12005,21 @@ bool Player::GetBGAccessByLevel(BattlegroundTypeId bgTypeId) const
|
||||
|
||||
float Player::GetReputationPriceDiscount(Creature const* creature) const
|
||||
{
|
||||
FactionTemplateEntry const* vendor_faction = creature->GetFactionTemplateEntry();
|
||||
if (!vendor_faction || !vendor_faction->faction)
|
||||
FactionTemplateEntry const* vendorFaction = creature->GetFactionTemplateEntry();
|
||||
if (!vendorFaction)
|
||||
{
|
||||
return 1.0f;
|
||||
}
|
||||
|
||||
return GetReputationPriceDiscount(vendorFaction);
|
||||
}
|
||||
|
||||
float Player::GetReputationPriceDiscount(FactionTemplateEntry const* vendorFaction) const
|
||||
{
|
||||
if (!vendorFaction->faction)
|
||||
return 1.0f;
|
||||
|
||||
ReputationRank rank = GetReputationRank(vendor_faction->faction);
|
||||
ReputationRank rank = GetReputationRank(vendorFaction->faction);
|
||||
if (rank <= REP_NEUTRAL)
|
||||
return 1.0f;
|
||||
|
||||
@@ -15935,3 +15945,9 @@ uint32 Player::GetSpellCooldownDelay(uint32 spell_id) const
|
||||
SpellCooldowns::const_iterator itr = m_spellCooldowns.find(spell_id);
|
||||
return uint32(itr != m_spellCooldowns.end() && itr->second.end > getMSTime() ? itr->second.end - getMSTime() : 0);
|
||||
}
|
||||
|
||||
void Player::ResetSpeakTimers()
|
||||
{
|
||||
m_speakTime = 0;
|
||||
m_speakCount = 0;
|
||||
}
|
||||
|
||||
@@ -662,7 +662,7 @@ enum PlayerSlots
|
||||
|
||||
#define INVENTORY_SLOT_BAG_0 255
|
||||
|
||||
enum EquipmentSlots // 19 slots
|
||||
enum EquipmentSlots : uint32 // 19 slots
|
||||
{
|
||||
EQUIPMENT_SLOT_START = 0,
|
||||
EQUIPMENT_SLOT_HEAD = 0,
|
||||
@@ -1323,6 +1323,7 @@ public:
|
||||
bool _StoreOrEquipNewItem(uint32 vendorslot, uint32 item, uint8 count, uint8 bag, uint8 slot, int32 price, ItemTemplate const* pProto, Creature* pVendor, VendorItem const* crItem, bool bStore);
|
||||
|
||||
float GetReputationPriceDiscount(Creature const* creature) const;
|
||||
float GetReputationPriceDiscount(FactionTemplateEntry const* vendorFaction) const;
|
||||
|
||||
[[nodiscard]] Player* GetTrader() const { return m_trade ? m_trade->GetTrader() : nullptr; }
|
||||
[[nodiscard]] TradeData* GetTradeData() const { return m_trade; }
|
||||
@@ -2538,6 +2539,8 @@ public:
|
||||
[[nodiscard]] PlayerSetting GetPlayerSetting(std::string source, uint8 index);
|
||||
void UpdatePlayerSetting(std::string source, uint8 index, uint32 value);
|
||||
|
||||
void ResetSpeakTimers();
|
||||
|
||||
protected:
|
||||
// Gamemaster whisper whitelist
|
||||
WhisperListContainer WhisperList;
|
||||
|
||||
@@ -212,6 +212,7 @@ Unit::Unit(bool isWorldObject) : WorldObject(isWorldObject),
|
||||
m_vehicleKit(nullptr),
|
||||
m_unitTypeMask(UNIT_MASK_NONE),
|
||||
m_HostileRefMgr(this),
|
||||
m_cannotReachTarget(false),
|
||||
m_comboTarget(nullptr),
|
||||
m_comboPoints(0)
|
||||
{
|
||||
@@ -9704,15 +9705,32 @@ ReputationRank Unit::GetFactionReactionTo(FactionTemplateEntry const* factionTem
|
||||
}
|
||||
}
|
||||
|
||||
return GetFactionReactionTo(factionTemplateEntry, targetFactionTemplateEntry);
|
||||
}
|
||||
|
||||
ReputationRank Unit::GetFactionReactionTo(FactionTemplateEntry const* factionTemplateEntry, FactionTemplateEntry const* targetFactionTemplateEntry)
|
||||
{
|
||||
// common faction based check
|
||||
if (factionTemplateEntry->IsHostileTo(*targetFactionTemplateEntry))
|
||||
{
|
||||
return REP_HOSTILE;
|
||||
}
|
||||
|
||||
if (factionTemplateEntry->IsFriendlyTo(*targetFactionTemplateEntry))
|
||||
{
|
||||
return REP_FRIENDLY;
|
||||
}
|
||||
|
||||
if (targetFactionTemplateEntry->IsFriendlyTo(*factionTemplateEntry))
|
||||
{
|
||||
return REP_FRIENDLY;
|
||||
}
|
||||
|
||||
if (factionTemplateEntry->factionFlags & FACTION_TEMPLATE_FLAG_HATES_ALL_EXCEPT_FRIENDS)
|
||||
{
|
||||
return REP_HOSTILE;
|
||||
}
|
||||
|
||||
// neutral by default
|
||||
return REP_NEUTRAL;
|
||||
}
|
||||
@@ -18304,11 +18322,23 @@ void Unit::SendPlaySpellVisual(uint32 id)
|
||||
SendMessageToSet(&data, true);
|
||||
}
|
||||
|
||||
void Unit::SendPlaySpellVisual(ObjectGuid guid, uint32 id)
|
||||
{
|
||||
WorldPacket data(SMSG_PLAY_SPELL_VISUAL, 8 + 4);
|
||||
data << guid;
|
||||
data << uint32(id); // SpellVisualKit.dbc index
|
||||
SendMessageToSet(&data, true);
|
||||
}
|
||||
|
||||
void Unit::SendPlaySpellImpact(ObjectGuid guid, uint32 id)
|
||||
{
|
||||
WorldPacket data(SMSG_PLAY_SPELL_IMPACT, 8 + 4);
|
||||
data << guid; // target
|
||||
data << uint32(id); // SpellVisualKit.dbc index
|
||||
|
||||
if (IsPlayer())
|
||||
ToPlayer()->SendDirectMessage(&data);
|
||||
else
|
||||
SendMessageToSet(&data, true);
|
||||
}
|
||||
|
||||
@@ -20529,3 +20559,15 @@ bool Unit::CanRestoreMana(SpellInfo const* spellInfo) const
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool Unit::SetCannotReachTarget(bool cannotReach, bool /*isChase = true*/)
|
||||
{
|
||||
if (cannotReach == m_cannotReachTarget)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
m_cannotReachTarget = cannotReach;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -1442,6 +1442,7 @@ public:
|
||||
|
||||
ReputationRank GetReactionTo(Unit const* target, bool checkOriginalFaction = false) const;
|
||||
ReputationRank GetFactionReactionTo(FactionTemplateEntry const* factionTemplateEntry, Unit const* target) const;
|
||||
static ReputationRank GetFactionReactionTo(FactionTemplateEntry const* factionTemplateEntry, FactionTemplateEntry const* targetFactionTemplateEntry);
|
||||
|
||||
bool IsHostileTo(Unit const* unit) const;
|
||||
[[nodiscard]] bool IsHostileToPlayers() const;
|
||||
@@ -1662,6 +1663,7 @@ public:
|
||||
Aura* AddAura(SpellInfo const* spellInfo, uint8 effMask, Unit* target);
|
||||
void SetAuraStack(uint32 spellId, Unit* target, uint32 stack);
|
||||
void SendPlaySpellVisual(uint32 id);
|
||||
void SendPlaySpellVisual(ObjectGuid guid, uint32 id);
|
||||
void SendPlaySpellImpact(ObjectGuid guid, uint32 id);
|
||||
void BuildCooldownPacket(WorldPacket& data, uint8 flags, uint32 spellId, uint32 cooldown);
|
||||
void BuildCooldownPacket(WorldPacket& data, uint8 flags, PacketCooldowns const& cooldowns);
|
||||
@@ -2381,6 +2383,9 @@ public:
|
||||
|
||||
[[nodiscard]] bool CanRestoreMana(SpellInfo const* spellInfo) const;
|
||||
|
||||
virtual bool SetCannotReachTarget(bool cannotReach, bool isChase = true);
|
||||
[[nodiscard]] bool CanNotReachTarget() const { return m_cannotReachTarget; }
|
||||
|
||||
protected:
|
||||
explicit Unit (bool isWorldObject);
|
||||
|
||||
@@ -2463,6 +2468,8 @@ protected:
|
||||
bool IsAlwaysDetectableFor(WorldObject const* seer) const override;
|
||||
bool _instantCast;
|
||||
|
||||
bool m_cannotReachTarget;
|
||||
|
||||
private:
|
||||
bool IsTriggeredAtSpellProcEvent(Unit* victim, Aura* aura, WeaponAttackType attType, bool isVictim, bool active, SpellProcEventEntry const*& spellProcEvent, ProcEventInfo const& eventInfo);
|
||||
bool HandleDummyAuraProc(Unit* victim, uint32 damage, AuraEffect* triggeredByAura, SpellInfo const* procSpell, uint32 procFlag, uint32 procEx, uint32 cooldown);
|
||||
|
||||
Reference in New Issue
Block a user