mirror of
https://github.com/mod-playerbots/azerothcore-wotlk.git
synced 2026-01-13 09:17:18 +00:00
refactor(Core/Entities): Cleanup Unit header file (#19622)
* move several enum definitions in a new files * move more things * remove the include comment * move the related code to CharmInfo in this own file *original idea of Ovahlord Co-Authored-By: Ovahlord <18347559+Ovahlord@users.noreply.github.com> * fix clang build errors and few blank lines * missing forward declaration * new tentative to fix gcc/clang build * add several include could be necessary for gcc/clang compilation * . * revert some include since the last AC update * fix some loop inconsistencies * align all enums in UnitDefine.h --------- Co-authored-by: Ovahlord <18347559+Ovahlord@users.noreply.github.com>
This commit is contained in:
@@ -290,6 +290,30 @@ private:
|
||||
|
||||
//=================================================
|
||||
|
||||
struct RedirectThreatInfo
|
||||
{
|
||||
RedirectThreatInfo() = default;
|
||||
ObjectGuid _targetGUID;
|
||||
uint32 _threatPct{ 0 };
|
||||
|
||||
[[nodiscard]] ObjectGuid GetTargetGUID() const { return _targetGUID; }
|
||||
[[nodiscard]] uint32 GetThreatPct() const { return _threatPct; }
|
||||
|
||||
void Set(ObjectGuid guid, uint32 pct)
|
||||
{
|
||||
_targetGUID = guid;
|
||||
_threatPct = pct;
|
||||
}
|
||||
|
||||
void ModifyThreatPct(int32 amount)
|
||||
{
|
||||
amount += _threatPct;
|
||||
_threatPct = uint32(std::max(0, amount));
|
||||
}
|
||||
};
|
||||
|
||||
//=================================================
|
||||
|
||||
namespace Acore
|
||||
{
|
||||
// Binary predicate for sorting HostileReferences based on threat value
|
||||
|
||||
@@ -19,6 +19,7 @@
|
||||
#define AZEROTHCORE_CREATURE_H
|
||||
|
||||
#include "Cell.h"
|
||||
#include "CharmInfo.h"
|
||||
#include "Common.h"
|
||||
#include "CreatureData.h"
|
||||
#include "DatabaseEnv.h"
|
||||
|
||||
@@ -35,6 +35,12 @@ struct ItemSetEffect
|
||||
SpellInfo const* spells[8];
|
||||
};
|
||||
|
||||
enum InventorySlot
|
||||
{
|
||||
NULL_BAG = 0,
|
||||
NULL_SLOT = 255
|
||||
};
|
||||
|
||||
// EnumUtils: DESCRIBE THIS
|
||||
enum InventoryResult : uint8
|
||||
{
|
||||
|
||||
@@ -18,6 +18,7 @@
|
||||
#ifndef AZEROTHCORE_PET_H
|
||||
#define AZEROTHCORE_PET_H
|
||||
|
||||
#include "CharmInfo.h"
|
||||
#include "PetDefines.h"
|
||||
#include "TemporarySummon.h"
|
||||
|
||||
|
||||
@@ -28,6 +28,7 @@
|
||||
#include "BattlegroundAV.h"
|
||||
#include "BattlegroundMgr.h"
|
||||
#include "CellImpl.h"
|
||||
#include "CharmInfo.h"
|
||||
#include "Channel.h"
|
||||
#include "CharacterCache.h"
|
||||
#include "CharacterDatabaseCleaner.h"
|
||||
|
||||
392
src/server/game/Entities/Unit/CharmInfo.cpp
Normal file
392
src/server/game/Entities/Unit/CharmInfo.cpp
Normal file
@@ -0,0 +1,392 @@
|
||||
/*
|
||||
* This file is part of the AzerothCore Project. See AUTHORS file for Copyright information
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU Affero General Public License as published by the
|
||||
* Free Software Foundation; either version 3 of the License, or (at your
|
||||
* option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for
|
||||
* more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "CharmInfo.h"
|
||||
#include "Creature.h"
|
||||
#include "Map.h"
|
||||
#include "SpellInfo.h"
|
||||
#include "Player.h"
|
||||
#include "SpellMgr.h"
|
||||
#include "StringConvert.h"
|
||||
#include "Tokenize.h"
|
||||
#include "Unit.h"
|
||||
|
||||
CharmInfo::CharmInfo(Unit* unit)
|
||||
: _unit(unit), _CommandState(COMMAND_FOLLOW), _petnumber(0), _oldReactState(REACT_PASSIVE),
|
||||
_isCommandAttack(false), _isCommandFollow(false), _isAtStay(false), _isFollowing(false), _isReturning(false),
|
||||
_forcedSpellId(0), _stayX(0.0f), _stayY(0.0f), _stayZ(0.0f)
|
||||
{
|
||||
for (uint8 i = 0; i < MAX_SPELL_CHARM; ++i)
|
||||
_charmspells[i].SetActionAndType(0, ACT_DISABLED);
|
||||
|
||||
if (_unit->GetTypeId() == TYPEID_UNIT)
|
||||
{
|
||||
_oldReactState = _unit->ToCreature()->GetReactState();
|
||||
_unit->ToCreature()->SetReactState(REACT_PASSIVE);
|
||||
}
|
||||
}
|
||||
|
||||
CharmInfo::~CharmInfo() = default;
|
||||
|
||||
void CharmInfo::RestoreState()
|
||||
{
|
||||
if (Creature* creature = _unit->ToCreature())
|
||||
creature->SetReactState(_oldReactState);
|
||||
}
|
||||
|
||||
void CharmInfo::InitPetActionBar()
|
||||
{
|
||||
// the first 3 SpellOrActions are attack, follow and stay
|
||||
for (uint32 i = 0; i < ACTION_BAR_INDEX_PET_SPELL_START - ACTION_BAR_INDEX_START; ++i)
|
||||
SetActionBar(ACTION_BAR_INDEX_START + i, COMMAND_ATTACK - i, ACT_COMMAND);
|
||||
|
||||
// middle 4 SpellOrActions are spells/special attacks/abilities
|
||||
for (uint32 i = 0; i < ACTION_BAR_INDEX_PET_SPELL_END - ACTION_BAR_INDEX_PET_SPELL_START; ++i)
|
||||
SetActionBar(ACTION_BAR_INDEX_PET_SPELL_START + i, 0, ACT_PASSIVE);
|
||||
|
||||
// last 3 SpellOrActions are reactions
|
||||
for (uint32 i = 0; i < ACTION_BAR_INDEX_END - ACTION_BAR_INDEX_PET_SPELL_END; ++i)
|
||||
SetActionBar(ACTION_BAR_INDEX_PET_SPELL_END + i, COMMAND_ATTACK - i, ACT_REACTION);
|
||||
}
|
||||
|
||||
void CharmInfo::InitEmptyActionBar(bool withAttack)
|
||||
{
|
||||
if (withAttack)
|
||||
SetActionBar(ACTION_BAR_INDEX_START, COMMAND_ATTACK, ACT_COMMAND);
|
||||
else
|
||||
SetActionBar(ACTION_BAR_INDEX_START, 0, ACT_PASSIVE);
|
||||
for (uint32 x = ACTION_BAR_INDEX_START + 1; x < ACTION_BAR_INDEX_END; ++x)
|
||||
SetActionBar(x, 0, ACT_PASSIVE);
|
||||
}
|
||||
|
||||
void CharmInfo::InitPossessCreateSpells()
|
||||
{
|
||||
if (_unit->GetTypeId() == TYPEID_UNIT)
|
||||
{
|
||||
// Adding switch until better way is found. Malcrom
|
||||
// Adding entrys to this switch will prevent COMMAND_ATTACK being added to pet bar.
|
||||
switch (_unit->GetEntry())
|
||||
{
|
||||
case 23575: // Mindless Abomination
|
||||
case 24783: // Trained Rock Falcon
|
||||
case 27664: // Crashin' Thrashin' Racer
|
||||
case 40281: // Crashin' Thrashin' Racer
|
||||
case 23109: // Vengeful Spirit
|
||||
break;
|
||||
default:
|
||||
InitEmptyActionBar();
|
||||
break;
|
||||
}
|
||||
|
||||
for (uint32 i = 0; i < MAX_CREATURE_SPELLS; ++i)
|
||||
{
|
||||
uint32 spellId = _unit->ToCreature()->m_spells[i];
|
||||
SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(spellId);
|
||||
if (spellInfo)
|
||||
{
|
||||
if (spellInfo->IsPassive())
|
||||
_unit->CastSpell(_unit, spellInfo, true);
|
||||
else
|
||||
AddSpellToActionBar(spellInfo, ACT_PASSIVE);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
InitEmptyActionBar();
|
||||
}
|
||||
|
||||
void CharmInfo::InitCharmCreateSpells()
|
||||
{
|
||||
InitPetActionBar();
|
||||
|
||||
if (_unit->GetTypeId() == TYPEID_PLAYER) // charmed players don't have spells
|
||||
return;
|
||||
|
||||
for (uint32 i = 0; i < MAX_SPELL_CHARM; ++i)
|
||||
{
|
||||
uint32 spellId = _unit->ToCreature()->m_spells[i];
|
||||
SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(spellId);
|
||||
|
||||
if (!spellInfo)
|
||||
{
|
||||
_charmspells[i].SetActionAndType(spellId, ACT_DISABLED);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (spellInfo->IsPassive())
|
||||
{
|
||||
_unit->CastSpell(_unit, spellInfo, true);
|
||||
_charmspells[i].SetActionAndType(spellId, ACT_PASSIVE);
|
||||
}
|
||||
else
|
||||
{
|
||||
_charmspells[i].SetActionAndType(spellId, ACT_DISABLED);
|
||||
|
||||
ActiveStates newstate = ACT_PASSIVE;
|
||||
|
||||
if (!spellInfo->IsAutocastable())
|
||||
newstate = ACT_PASSIVE;
|
||||
else
|
||||
{
|
||||
if (spellInfo->NeedsExplicitUnitTarget())
|
||||
{
|
||||
newstate = ACT_ENABLED;
|
||||
ToggleCreatureAutocast(spellInfo, true);
|
||||
}
|
||||
else
|
||||
newstate = ACT_DISABLED;
|
||||
}
|
||||
|
||||
AddSpellToActionBar(spellInfo, newstate);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool CharmInfo::AddSpellToActionBar(SpellInfo const* spellInfo, ActiveStates newstate)
|
||||
{
|
||||
uint32 spell_id = spellInfo->Id;
|
||||
uint32 first_id = spellInfo->GetFirstRankSpell()->Id;
|
||||
|
||||
// new spell rank can be already listed
|
||||
for (uint8 i = 0; i < MAX_UNIT_ACTION_BAR_INDEX; ++i)
|
||||
{
|
||||
if (uint32 action = PetActionBar[i].GetAction())
|
||||
{
|
||||
if (PetActionBar[i].IsActionBarForSpell() && sSpellMgr->GetFirstSpellInChain(action) == first_id)
|
||||
{
|
||||
PetActionBar[i].SetAction(spell_id);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// or use empty slot in other case
|
||||
for (uint8 i = 0; i < MAX_UNIT_ACTION_BAR_INDEX; ++i)
|
||||
{
|
||||
if (!PetActionBar[i].GetAction() && PetActionBar[i].IsActionBarForSpell())
|
||||
{
|
||||
SetActionBar(i, spell_id, newstate == ACT_DECIDE ? spellInfo->IsAutocastable() ? ACT_DISABLED : ACT_PASSIVE : newstate);
|
||||
|
||||
if (_unit->GetCharmer() && _unit->GetCharmer()->IsPlayer())
|
||||
{
|
||||
if (Creature* creature = _unit->ToCreature())
|
||||
{
|
||||
// Processing this packet needs to be delayed
|
||||
_unit->m_Events.AddEventAtOffset([creature, spell_id]()
|
||||
{
|
||||
if (uint32 cooldown = creature->GetSpellCooldown(spell_id))
|
||||
{
|
||||
WorldPacket data;
|
||||
creature->BuildCooldownPacket(data, SPELL_COOLDOWN_FLAG_NONE, spell_id, cooldown);
|
||||
if (creature->GetCharmer() && creature->GetCharmer()->IsPlayer())
|
||||
{
|
||||
creature->GetCharmer()->ToPlayer()->SendDirectMessage(&data);
|
||||
}
|
||||
}
|
||||
}, 500ms);
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool CharmInfo::RemoveSpellFromActionBar(uint32 spell_id)
|
||||
{
|
||||
uint32 first_id = sSpellMgr->GetFirstSpellInChain(spell_id);
|
||||
|
||||
for (uint8 i = 0; i < MAX_UNIT_ACTION_BAR_INDEX; ++i)
|
||||
{
|
||||
if (uint32 action = PetActionBar[i].GetAction())
|
||||
{
|
||||
if (PetActionBar[i].IsActionBarForSpell() && sSpellMgr->GetFirstSpellInChain(action) == first_id)
|
||||
{
|
||||
SetActionBar(i, 0, ACT_PASSIVE);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void CharmInfo::ToggleCreatureAutocast(SpellInfo const* spellInfo, bool apply)
|
||||
{
|
||||
if (spellInfo->IsPassive())
|
||||
return;
|
||||
|
||||
for (uint32 i = 0; i < MAX_SPELL_CHARM; ++i)
|
||||
if (spellInfo->Id == _charmspells[i].GetAction())
|
||||
_charmspells[i].SetType(apply ? ACT_ENABLED : ACT_DISABLED);
|
||||
}
|
||||
|
||||
void CharmInfo::SetPetNumber(uint32 petnumber, bool statwindow)
|
||||
{
|
||||
_petnumber = petnumber;
|
||||
if (statwindow)
|
||||
_unit->SetUInt32Value(UNIT_FIELD_PETNUMBER, _petnumber);
|
||||
else
|
||||
_unit->SetUInt32Value(UNIT_FIELD_PETNUMBER, 0);
|
||||
}
|
||||
|
||||
void CharmInfo::LoadPetActionBar(const std::string& data)
|
||||
{
|
||||
std::vector<std::string_view> tokens = Acore::Tokenize(data, ' ', false);
|
||||
|
||||
if (tokens.size() != (ACTION_BAR_INDEX_END - ACTION_BAR_INDEX_START) * 2)
|
||||
return; // non critical, will reset to default
|
||||
|
||||
auto iter = tokens.begin();
|
||||
for (uint8 index = ACTION_BAR_INDEX_START; index < ACTION_BAR_INDEX_END; ++index)
|
||||
{
|
||||
Optional<uint8> type = Acore::StringTo<uint8>(*(iter++));
|
||||
Optional<uint32> action = Acore::StringTo<uint32>(*(iter++));
|
||||
|
||||
if (!type || !action)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
PetActionBar[index].SetActionAndType(*action, static_cast<ActiveStates>(*type));
|
||||
|
||||
// check correctness
|
||||
if (PetActionBar[index].IsActionBarForSpell())
|
||||
{
|
||||
SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(PetActionBar[index].GetAction());
|
||||
if (!spellInfo)
|
||||
{
|
||||
SetActionBar(index, 0, ACT_PASSIVE);
|
||||
}
|
||||
else if (!spellInfo->IsAutocastable())
|
||||
{
|
||||
SetActionBar(index, PetActionBar[index].GetAction(), ACT_PASSIVE);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void CharmInfo::BuildActionBar(WorldPacket* data)
|
||||
{
|
||||
for (uint32 i = 0; i < MAX_UNIT_ACTION_BAR_INDEX; ++i)
|
||||
*data << uint32(PetActionBar[i].packedData);
|
||||
}
|
||||
|
||||
void CharmInfo::SetSpellAutocast(SpellInfo const* spellInfo, bool state)
|
||||
{
|
||||
for (uint8 i = 0; i < MAX_UNIT_ACTION_BAR_INDEX; ++i)
|
||||
{
|
||||
if (spellInfo->Id == PetActionBar[i].GetAction() && PetActionBar[i].IsActionBarForSpell())
|
||||
{
|
||||
PetActionBar[i].SetType(state ? ACT_ENABLED : ACT_DISABLED);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void CharmInfo::SetIsCommandAttack(bool val)
|
||||
{
|
||||
_isCommandAttack = val;
|
||||
}
|
||||
|
||||
bool CharmInfo::IsCommandAttack()
|
||||
{
|
||||
return _isCommandAttack;
|
||||
}
|
||||
|
||||
void CharmInfo::SetIsCommandFollow(bool val)
|
||||
{
|
||||
_isCommandFollow = val;
|
||||
}
|
||||
|
||||
bool CharmInfo::IsCommandFollow()
|
||||
{
|
||||
return _isCommandFollow;
|
||||
}
|
||||
|
||||
void CharmInfo::SaveStayPosition(bool atCurrentPos)
|
||||
{
|
||||
//! At this point a new spline destination is enabled because of Unit::StopMoving()
|
||||
G3D::Vector3 stayPos = G3D::Vector3();
|
||||
|
||||
if (atCurrentPos)
|
||||
{
|
||||
float z = INVALID_HEIGHT;
|
||||
_unit->UpdateAllowedPositionZ(_unit->GetPositionX(), _unit->GetPositionY(), z);
|
||||
stayPos = G3D::Vector3(_unit->GetPositionX(), _unit->GetPositionY(), z != INVALID_HEIGHT ? z : _unit->GetPositionZ());
|
||||
}
|
||||
else
|
||||
stayPos = _unit->movespline->FinalDestination();
|
||||
|
||||
if (_unit->movespline->onTransport)
|
||||
if (TransportBase* transport = _unit->GetDirectTransport())
|
||||
transport->CalculatePassengerPosition(stayPos.x, stayPos.y, stayPos.z);
|
||||
|
||||
_stayX = stayPos.x;
|
||||
_stayY = stayPos.y;
|
||||
_stayZ = stayPos.z;
|
||||
}
|
||||
|
||||
void CharmInfo::GetStayPosition(float& x, float& y, float& z)
|
||||
{
|
||||
x = _stayX;
|
||||
y = _stayY;
|
||||
z = _stayZ;
|
||||
}
|
||||
|
||||
void CharmInfo::RemoveStayPosition()
|
||||
{
|
||||
_stayX = 0.0f;
|
||||
_stayY = 0.0f;
|
||||
_stayZ = 0.0f;
|
||||
}
|
||||
|
||||
bool CharmInfo::HasStayPosition()
|
||||
{
|
||||
return _stayX && _stayY && _stayZ;
|
||||
}
|
||||
|
||||
void CharmInfo::SetIsAtStay(bool val)
|
||||
{
|
||||
_isAtStay = val;
|
||||
}
|
||||
|
||||
bool CharmInfo::IsAtStay()
|
||||
{
|
||||
return _isAtStay;
|
||||
}
|
||||
|
||||
void CharmInfo::SetIsFollowing(bool val)
|
||||
{
|
||||
_isFollowing = val;
|
||||
}
|
||||
|
||||
bool CharmInfo::IsFollowing()
|
||||
{
|
||||
return _isFollowing;
|
||||
}
|
||||
|
||||
void CharmInfo::SetIsReturning(bool val)
|
||||
{
|
||||
_isReturning = val;
|
||||
}
|
||||
|
||||
bool CharmInfo::IsReturning()
|
||||
{
|
||||
return _isReturning;
|
||||
}
|
||||
184
src/server/game/Entities/Unit/CharmInfo.h
Normal file
184
src/server/game/Entities/Unit/CharmInfo.h
Normal file
@@ -0,0 +1,184 @@
|
||||
/*
|
||||
* This file is part of the AzerothCore Project. See AUTHORS file for Copyright information
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU Affero General Public License as published by the
|
||||
* Free Software Foundation; either version 3 of the License, or (at your
|
||||
* option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for
|
||||
* more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef _CHARMINFO_H
|
||||
#define _CHARMINFO_H
|
||||
|
||||
#include "Object.h"
|
||||
|
||||
#define MAX_SPELL_CHARM 4
|
||||
#define MAX_SPELL_VEHICLE 6
|
||||
#define MAX_SPELL_POSSESS 8
|
||||
#define MAX_SPELL_CONTROL_BAR 10
|
||||
|
||||
#define MAX_UNIT_ACTION_BAR_INDEX (ACTION_BAR_INDEX_END-ACTION_BAR_INDEX_START)
|
||||
|
||||
#define UNIT_ACTION_BUTTON_ACTION(X) (uint32(X) & 0x00FFFFFF)
|
||||
#define UNIT_ACTION_BUTTON_TYPE(X) ((uint32(X) & 0xFF000000) >> 24)
|
||||
#define MAKE_UNIT_ACTION_BUTTON(A, T) (uint32(A) | (uint32(T) << 24))
|
||||
|
||||
class GlobalCooldownMgr;
|
||||
class SpellInfo;
|
||||
class Unit;
|
||||
class WorldPacket;
|
||||
|
||||
enum CommandStates : uint8;
|
||||
enum ReactStates : uint8;
|
||||
|
||||
enum CharmType : uint8
|
||||
{
|
||||
CHARM_TYPE_CHARM,
|
||||
CHARM_TYPE_POSSESS,
|
||||
CHARM_TYPE_VEHICLE,
|
||||
CHARM_TYPE_CONVERT,
|
||||
};
|
||||
|
||||
enum ActionBarIndex
|
||||
{
|
||||
ACTION_BAR_INDEX_START = 0,
|
||||
ACTION_BAR_INDEX_PET_SPELL_START = 3,
|
||||
ACTION_BAR_INDEX_PET_SPELL_END = 7,
|
||||
ACTION_BAR_INDEX_END = 10,
|
||||
};
|
||||
|
||||
enum ActiveStates : uint8
|
||||
{
|
||||
ACT_PASSIVE = 0x01, // 0x01 - passive
|
||||
ACT_DISABLED = 0x81, // 0x80 - castable
|
||||
ACT_ENABLED = 0xC1, // 0x40 | 0x80 - auto cast + castable
|
||||
ACT_COMMAND = 0x07, // 0x01 | 0x02 | 0x04
|
||||
ACT_REACTION = 0x06, // 0x02 | 0x04
|
||||
ACT_DECIDE = 0x00 // custom
|
||||
};
|
||||
|
||||
struct UnitActionBarEntry
|
||||
{
|
||||
UnitActionBarEntry() : packedData(uint32(ACT_DISABLED) << 24) {}
|
||||
|
||||
uint32 packedData;
|
||||
|
||||
// helper
|
||||
[[nodiscard]] ActiveStates GetType() const { return ActiveStates(UNIT_ACTION_BUTTON_TYPE(packedData)); }
|
||||
[[nodiscard]] uint32 GetAction() const { return UNIT_ACTION_BUTTON_ACTION(packedData); }
|
||||
[[nodiscard]] bool IsActionBarForSpell() const
|
||||
{
|
||||
ActiveStates Type = GetType();
|
||||
return Type == ACT_DISABLED || Type == ACT_ENABLED || Type == ACT_PASSIVE;
|
||||
}
|
||||
|
||||
void SetActionAndType(uint32 action, ActiveStates type)
|
||||
{
|
||||
packedData = MAKE_UNIT_ACTION_BUTTON(action, type);
|
||||
}
|
||||
|
||||
void SetType(ActiveStates type)
|
||||
{
|
||||
packedData = MAKE_UNIT_ACTION_BUTTON(UNIT_ACTION_BUTTON_ACTION(packedData), type);
|
||||
}
|
||||
|
||||
void SetAction(uint32 action)
|
||||
{
|
||||
packedData = (packedData & 0xFF000000) | UNIT_ACTION_BUTTON_ACTION(action);
|
||||
}
|
||||
};
|
||||
typedef UnitActionBarEntry CharmSpellInfo;
|
||||
|
||||
struct CharmInfo
|
||||
{
|
||||
public:
|
||||
explicit CharmInfo(Unit* unit);
|
||||
~CharmInfo();
|
||||
void RestoreState();
|
||||
[[nodiscard]] uint32 GetPetNumber() const { return _petnumber; }
|
||||
void SetPetNumber(uint32 petnumber, bool statwindow);
|
||||
|
||||
void SetCommandState(CommandStates st) { _CommandState = st; }
|
||||
[[nodiscard]] CommandStates GetCommandState() const { return _CommandState; }
|
||||
[[nodiscard]] bool HasCommandState(CommandStates state) const { return (_CommandState == state); }
|
||||
|
||||
void InitPossessCreateSpells();
|
||||
void InitCharmCreateSpells();
|
||||
void InitPetActionBar();
|
||||
void InitEmptyActionBar(bool withAttack = true);
|
||||
|
||||
//return true if successful
|
||||
bool AddSpellToActionBar(SpellInfo const* spellInfo, ActiveStates newstate = ACT_DECIDE);
|
||||
bool RemoveSpellFromActionBar(uint32 spell_id);
|
||||
void LoadPetActionBar(const std::string& data);
|
||||
void BuildActionBar(WorldPacket* data);
|
||||
void SetSpellAutocast(SpellInfo const* spellInfo, bool state);
|
||||
void SetActionBar(uint8 index, uint32 spellOrAction, ActiveStates type)
|
||||
{
|
||||
PetActionBar[index].SetActionAndType(spellOrAction, type);
|
||||
}
|
||||
[[nodiscard]] UnitActionBarEntry const* GetActionBarEntry(uint8 index) const { return &(PetActionBar[index]); }
|
||||
|
||||
void ToggleCreatureAutocast(SpellInfo const* spellInfo, bool apply);
|
||||
|
||||
CharmSpellInfo* GetCharmSpell(uint8 index) { return &(_charmspells[index]); }
|
||||
|
||||
GlobalCooldownMgr& GetGlobalCooldownMgr() { return *_GlobalCooldownMgr; }
|
||||
|
||||
void SetIsCommandAttack(bool val);
|
||||
bool IsCommandAttack();
|
||||
void SetIsCommandFollow(bool val);
|
||||
bool IsCommandFollow();
|
||||
void SetIsAtStay(bool val);
|
||||
bool IsAtStay();
|
||||
void SetIsFollowing(bool val);
|
||||
bool IsFollowing();
|
||||
void SetIsReturning(bool val);
|
||||
bool IsReturning();
|
||||
void SaveStayPosition(bool atCurrentPos);
|
||||
void GetStayPosition(float& x, float& y, float& z);
|
||||
void RemoveStayPosition();
|
||||
bool HasStayPosition();
|
||||
|
||||
void SetForcedSpell(uint32 id) { _forcedSpellId = id; }
|
||||
int32 GetForcedSpell() { return _forcedSpellId; }
|
||||
void SetForcedTargetGUID(ObjectGuid guid = ObjectGuid::Empty) { _forcedTargetGUID = guid; }
|
||||
ObjectGuid GetForcedTarget() { return _forcedTargetGUID; }
|
||||
|
||||
// Player react states
|
||||
void SetPlayerReactState(ReactStates s) { _oldReactState = s; }
|
||||
[[nodiscard]] ReactStates GetPlayerReactState() const { return _oldReactState; }
|
||||
|
||||
private:
|
||||
Unit* _unit;
|
||||
UnitActionBarEntry PetActionBar[MAX_UNIT_ACTION_BAR_INDEX];
|
||||
CharmSpellInfo _charmspells[4];
|
||||
CommandStates _CommandState;
|
||||
uint32 _petnumber;
|
||||
|
||||
//for restoration after charmed
|
||||
ReactStates _oldReactState;
|
||||
|
||||
bool _isCommandAttack;
|
||||
bool _isCommandFollow;
|
||||
bool _isAtStay;
|
||||
bool _isFollowing;
|
||||
bool _isReturning;
|
||||
int32 _forcedSpellId;
|
||||
ObjectGuid _forcedTargetGUID;
|
||||
float _stayX;
|
||||
float _stayY;
|
||||
float _stayZ;
|
||||
|
||||
std::unique_ptr<GlobalCooldownMgr> _GlobalCooldownMgr;
|
||||
};
|
||||
|
||||
#endif // _CHARMINFO_H
|
||||
@@ -23,6 +23,7 @@
|
||||
#include "Battleground.h"
|
||||
#include "CellImpl.h"
|
||||
#include "CharacterCache.h"
|
||||
#include "CharmInfo.h"
|
||||
#include "Chat.h"
|
||||
#include "ChatPackets.h"
|
||||
#include "ChatTextBuilder.h"
|
||||
@@ -15763,287 +15764,6 @@ void Unit::DeleteCharmInfo()
|
||||
m_charmInfo = nullptr;
|
||||
}
|
||||
|
||||
CharmInfo::CharmInfo(Unit* unit)
|
||||
: _unit(unit), _CommandState(COMMAND_FOLLOW), _petnumber(0), _oldReactState(REACT_PASSIVE),
|
||||
_isCommandAttack(false), _isCommandFollow(false), _isAtStay(false), _isFollowing(false), _isReturning(false),
|
||||
_forcedSpellId(0), _stayX(0.0f), _stayY(0.0f), _stayZ(0.0f)
|
||||
{
|
||||
for (uint8 i = 0; i < MAX_SPELL_CHARM; ++i)
|
||||
_charmspells[i].SetActionAndType(0, ACT_DISABLED);
|
||||
|
||||
if (_unit->GetTypeId() == TYPEID_UNIT)
|
||||
{
|
||||
_oldReactState = _unit->ToCreature()->GetReactState();
|
||||
_unit->ToCreature()->SetReactState(REACT_PASSIVE);
|
||||
}
|
||||
}
|
||||
|
||||
CharmInfo::~CharmInfo()
|
||||
{
|
||||
}
|
||||
|
||||
void CharmInfo::RestoreState()
|
||||
{
|
||||
if (Creature* creature = _unit->ToCreature())
|
||||
creature->SetReactState(_oldReactState);
|
||||
}
|
||||
|
||||
void CharmInfo::InitPetActionBar()
|
||||
{
|
||||
// the first 3 SpellOrActions are attack, follow and stay
|
||||
for (uint32 i = 0; i < ACTION_BAR_INDEX_PET_SPELL_START - ACTION_BAR_INDEX_START; ++i)
|
||||
SetActionBar(ACTION_BAR_INDEX_START + i, COMMAND_ATTACK - i, ACT_COMMAND);
|
||||
|
||||
// middle 4 SpellOrActions are spells/special attacks/abilities
|
||||
for (uint32 i = 0; i < ACTION_BAR_INDEX_PET_SPELL_END - ACTION_BAR_INDEX_PET_SPELL_START; ++i)
|
||||
SetActionBar(ACTION_BAR_INDEX_PET_SPELL_START + i, 0, ACT_PASSIVE);
|
||||
|
||||
// last 3 SpellOrActions are reactions
|
||||
for (uint32 i = 0; i < ACTION_BAR_INDEX_END - ACTION_BAR_INDEX_PET_SPELL_END; ++i)
|
||||
SetActionBar(ACTION_BAR_INDEX_PET_SPELL_END + i, COMMAND_ATTACK - i, ACT_REACTION);
|
||||
}
|
||||
|
||||
void CharmInfo::InitEmptyActionBar(bool withAttack)
|
||||
{
|
||||
if (withAttack)
|
||||
SetActionBar(ACTION_BAR_INDEX_START, COMMAND_ATTACK, ACT_COMMAND);
|
||||
else
|
||||
SetActionBar(ACTION_BAR_INDEX_START, 0, ACT_PASSIVE);
|
||||
for (uint32 x = ACTION_BAR_INDEX_START + 1; x < ACTION_BAR_INDEX_END; ++x)
|
||||
SetActionBar(x, 0, ACT_PASSIVE);
|
||||
}
|
||||
|
||||
void CharmInfo::InitPossessCreateSpells()
|
||||
{
|
||||
if (_unit->GetTypeId() == TYPEID_UNIT)
|
||||
{
|
||||
// Adding switch until better way is found. Malcrom
|
||||
// Adding entrys to this switch will prevent COMMAND_ATTACK being added to pet bar.
|
||||
switch (_unit->GetEntry())
|
||||
{
|
||||
case 23575: // Mindless Abomination
|
||||
case 24783: // Trained Rock Falcon
|
||||
case 27664: // Crashin' Thrashin' Racer
|
||||
case 40281: // Crashin' Thrashin' Racer
|
||||
case 23109: // Vengeful Spirit
|
||||
break;
|
||||
default:
|
||||
InitEmptyActionBar();
|
||||
break;
|
||||
}
|
||||
|
||||
for (uint32 i = 0; i < MAX_CREATURE_SPELLS; ++i)
|
||||
{
|
||||
uint32 spellId = _unit->ToCreature()->m_spells[i];
|
||||
SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(spellId);
|
||||
if (spellInfo)
|
||||
{
|
||||
if (spellInfo->IsPassive())
|
||||
_unit->CastSpell(_unit, spellInfo, true);
|
||||
else
|
||||
AddSpellToActionBar(spellInfo, ACT_PASSIVE);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
InitEmptyActionBar();
|
||||
}
|
||||
|
||||
void CharmInfo::InitCharmCreateSpells()
|
||||
{
|
||||
InitPetActionBar();
|
||||
|
||||
if (_unit->GetTypeId() == TYPEID_PLAYER) // charmed players don't have spells
|
||||
{
|
||||
//InitEmptyActionBar();
|
||||
return;
|
||||
}
|
||||
|
||||
//InitPetActionBar();
|
||||
|
||||
for (uint32 x = 0; x < MAX_SPELL_CHARM; ++x)
|
||||
{
|
||||
uint32 spellId = _unit->ToCreature()->m_spells[x];
|
||||
SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(spellId);
|
||||
|
||||
if (!spellInfo)
|
||||
{
|
||||
_charmspells[x].SetActionAndType(spellId, ACT_DISABLED);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (spellInfo->IsPassive())
|
||||
{
|
||||
_unit->CastSpell(_unit, spellInfo, true);
|
||||
_charmspells[x].SetActionAndType(spellId, ACT_PASSIVE);
|
||||
}
|
||||
else
|
||||
{
|
||||
_charmspells[x].SetActionAndType(spellId, ACT_DISABLED);
|
||||
|
||||
ActiveStates newstate = ACT_PASSIVE;
|
||||
|
||||
if (!spellInfo->IsAutocastable())
|
||||
newstate = ACT_PASSIVE;
|
||||
else
|
||||
{
|
||||
if (spellInfo->NeedsExplicitUnitTarget())
|
||||
{
|
||||
newstate = ACT_ENABLED;
|
||||
ToggleCreatureAutocast(spellInfo, true);
|
||||
}
|
||||
else
|
||||
newstate = ACT_DISABLED;
|
||||
}
|
||||
|
||||
AddSpellToActionBar(spellInfo, newstate);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool CharmInfo::AddSpellToActionBar(SpellInfo const* spellInfo, ActiveStates newstate)
|
||||
{
|
||||
uint32 spell_id = spellInfo->Id;
|
||||
uint32 first_id = spellInfo->GetFirstRankSpell()->Id;
|
||||
|
||||
// new spell rank can be already listed
|
||||
for (uint8 i = 0; i < MAX_UNIT_ACTION_BAR_INDEX; ++i)
|
||||
{
|
||||
if (uint32 action = PetActionBar[i].GetAction())
|
||||
{
|
||||
if (PetActionBar[i].IsActionBarForSpell() && sSpellMgr->GetFirstSpellInChain(action) == first_id)
|
||||
{
|
||||
PetActionBar[i].SetAction(spell_id);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// or use empty slot in other case
|
||||
for (uint8 i = 0; i < MAX_UNIT_ACTION_BAR_INDEX; ++i)
|
||||
{
|
||||
if (!PetActionBar[i].GetAction() && PetActionBar[i].IsActionBarForSpell())
|
||||
{
|
||||
SetActionBar(i, spell_id, newstate == ACT_DECIDE ? spellInfo->IsAutocastable() ? ACT_DISABLED : ACT_PASSIVE : newstate);
|
||||
|
||||
if (_unit->GetCharmer() && _unit->GetCharmer()->IsPlayer())
|
||||
{
|
||||
if (Creature* creature = _unit->ToCreature())
|
||||
{
|
||||
// Processing this packet needs to be delayed
|
||||
_unit->m_Events.AddEventAtOffset([creature, spell_id]()
|
||||
{
|
||||
if (uint32 cooldown = creature->GetSpellCooldown(spell_id))
|
||||
{
|
||||
WorldPacket data;
|
||||
creature->BuildCooldownPacket(data, SPELL_COOLDOWN_FLAG_NONE, spell_id, cooldown);
|
||||
if (creature->GetCharmer() && creature->GetCharmer()->IsPlayer())
|
||||
{
|
||||
creature->GetCharmer()->ToPlayer()->SendDirectMessage(&data);
|
||||
}
|
||||
}
|
||||
}, 500ms);
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool CharmInfo::RemoveSpellFromActionBar(uint32 spell_id)
|
||||
{
|
||||
uint32 first_id = sSpellMgr->GetFirstSpellInChain(spell_id);
|
||||
|
||||
for (uint8 i = 0; i < MAX_UNIT_ACTION_BAR_INDEX; ++i)
|
||||
{
|
||||
if (uint32 action = PetActionBar[i].GetAction())
|
||||
{
|
||||
if (PetActionBar[i].IsActionBarForSpell() && sSpellMgr->GetFirstSpellInChain(action) == first_id)
|
||||
{
|
||||
SetActionBar(i, 0, ACT_PASSIVE);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void CharmInfo::ToggleCreatureAutocast(SpellInfo const* spellInfo, bool apply)
|
||||
{
|
||||
if (spellInfo->IsPassive())
|
||||
return;
|
||||
|
||||
for (uint32 x = 0; x < MAX_SPELL_CHARM; ++x)
|
||||
if (spellInfo->Id == _charmspells[x].GetAction())
|
||||
_charmspells[x].SetType(apply ? ACT_ENABLED : ACT_DISABLED);
|
||||
}
|
||||
|
||||
void CharmInfo::SetPetNumber(uint32 petnumber, bool statwindow)
|
||||
{
|
||||
_petnumber = petnumber;
|
||||
if (statwindow)
|
||||
_unit->SetUInt32Value(UNIT_FIELD_PETNUMBER, _petnumber);
|
||||
else
|
||||
_unit->SetUInt32Value(UNIT_FIELD_PETNUMBER, 0);
|
||||
}
|
||||
|
||||
void CharmInfo::LoadPetActionBar(const std::string& data)
|
||||
{
|
||||
std::vector<std::string_view> tokens = Acore::Tokenize(data, ' ', false);
|
||||
|
||||
if (tokens.size() != (ACTION_BAR_INDEX_END - ACTION_BAR_INDEX_START) * 2)
|
||||
return; // non critical, will reset to default
|
||||
|
||||
auto iter = tokens.begin();
|
||||
for (uint8 index = ACTION_BAR_INDEX_START; index < ACTION_BAR_INDEX_END; ++index)
|
||||
{
|
||||
Optional<uint8> type = Acore::StringTo<uint8>(*(iter++));
|
||||
Optional<uint32> action = Acore::StringTo<uint32>(*(iter++));
|
||||
|
||||
if (!type || !action)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
PetActionBar[index].SetActionAndType(*action, static_cast<ActiveStates>(*type));
|
||||
|
||||
// check correctness
|
||||
if (PetActionBar[index].IsActionBarForSpell())
|
||||
{
|
||||
SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(PetActionBar[index].GetAction());
|
||||
if (!spellInfo)
|
||||
{
|
||||
SetActionBar(index, 0, ACT_PASSIVE);
|
||||
}
|
||||
else if (!spellInfo->IsAutocastable())
|
||||
{
|
||||
SetActionBar(index, PetActionBar[index].GetAction(), ACT_PASSIVE);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void CharmInfo::BuildActionBar(WorldPacket* data)
|
||||
{
|
||||
for (uint32 i = 0; i < MAX_UNIT_ACTION_BAR_INDEX; ++i)
|
||||
*data << uint32(PetActionBar[i].packedData);
|
||||
}
|
||||
|
||||
void CharmInfo::SetSpellAutocast(SpellInfo const* spellInfo, bool state)
|
||||
{
|
||||
for (uint8 i = 0; i < MAX_UNIT_ACTION_BAR_INDEX; ++i)
|
||||
{
|
||||
if (spellInfo->Id == PetActionBar[i].GetAction() && PetActionBar[i].IsActionBarForSpell())
|
||||
{
|
||||
PetActionBar[i].SetType(state ? ACT_ENABLED : ACT_DISABLED);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool Unit::isFrozen() const
|
||||
{
|
||||
return HasAuraState(AURA_STATE_FROZEN);
|
||||
@@ -20534,98 +20254,6 @@ uint32 Unit::GetResistance(SpellSchoolMask mask) const
|
||||
return uint32(resist);
|
||||
}
|
||||
|
||||
void CharmInfo::SetIsCommandAttack(bool val)
|
||||
{
|
||||
_isCommandAttack = val;
|
||||
}
|
||||
|
||||
bool CharmInfo::IsCommandAttack()
|
||||
{
|
||||
return _isCommandAttack;
|
||||
}
|
||||
|
||||
void CharmInfo::SetIsCommandFollow(bool val)
|
||||
{
|
||||
_isCommandFollow = val;
|
||||
}
|
||||
|
||||
bool CharmInfo::IsCommandFollow()
|
||||
{
|
||||
return _isCommandFollow;
|
||||
}
|
||||
|
||||
void CharmInfo::SaveStayPosition(bool atCurrentPos)
|
||||
{
|
||||
//! At this point a new spline destination is enabled because of Unit::StopMoving()
|
||||
G3D::Vector3 stayPos = G3D::Vector3();
|
||||
|
||||
if (atCurrentPos)
|
||||
{
|
||||
float z = INVALID_HEIGHT;
|
||||
_unit->UpdateAllowedPositionZ(_unit->GetPositionX(), _unit->GetPositionY(), z);
|
||||
stayPos = G3D::Vector3(_unit->GetPositionX(), _unit->GetPositionY(), z != INVALID_HEIGHT ? z : _unit->GetPositionZ());
|
||||
}
|
||||
else
|
||||
stayPos = _unit->movespline->FinalDestination();
|
||||
|
||||
if (_unit->movespline->onTransport)
|
||||
if (TransportBase* transport = _unit->GetDirectTransport())
|
||||
transport->CalculatePassengerPosition(stayPos.x, stayPos.y, stayPos.z);
|
||||
|
||||
_stayX = stayPos.x;
|
||||
_stayY = stayPos.y;
|
||||
_stayZ = stayPos.z;
|
||||
}
|
||||
|
||||
void CharmInfo::GetStayPosition(float& x, float& y, float& z)
|
||||
{
|
||||
x = _stayX;
|
||||
y = _stayY;
|
||||
z = _stayZ;
|
||||
}
|
||||
|
||||
void CharmInfo::RemoveStayPosition()
|
||||
{
|
||||
_stayX = 0.0f;
|
||||
_stayY = 0.0f;
|
||||
_stayZ = 0.0f;
|
||||
}
|
||||
|
||||
bool CharmInfo::HasStayPosition()
|
||||
{
|
||||
return _stayX && _stayY && _stayZ;
|
||||
}
|
||||
|
||||
void CharmInfo::SetIsAtStay(bool val)
|
||||
{
|
||||
_isAtStay = val;
|
||||
}
|
||||
|
||||
bool CharmInfo::IsAtStay()
|
||||
{
|
||||
return _isAtStay;
|
||||
}
|
||||
|
||||
void CharmInfo::SetIsFollowing(bool val)
|
||||
{
|
||||
_isFollowing = val;
|
||||
}
|
||||
|
||||
bool CharmInfo::IsFollowing()
|
||||
{
|
||||
return _isFollowing;
|
||||
}
|
||||
|
||||
void CharmInfo::SetIsReturning(bool val)
|
||||
{
|
||||
_isReturning = val;
|
||||
}
|
||||
|
||||
bool CharmInfo::IsReturning()
|
||||
{
|
||||
return _isReturning;
|
||||
}
|
||||
|
||||
void Unit::PetSpellFail(SpellInfo const* spellInfo, Unit* target, uint32 result)
|
||||
{
|
||||
CharmInfo* charmInfo = GetCharmInfo();
|
||||
|
||||
@@ -29,6 +29,8 @@
|
||||
#include "SpellAuraDefines.h"
|
||||
#include "SpellDefines.h"
|
||||
#include "ThreatMgr.h"
|
||||
#include "UnitDefines.h"
|
||||
#include "UnitUtils.h"
|
||||
#include <functional>
|
||||
#include <utility>
|
||||
|
||||
@@ -38,127 +40,43 @@
|
||||
#define BASE_MAXDAMAGE 2.0f
|
||||
#define BASE_ATTACK_TIME 2000
|
||||
|
||||
enum UnitBytes1Offsets : uint8
|
||||
{
|
||||
UNIT_BYTES_1_OFFSET_STAND_STATE = 0,
|
||||
UNIT_BYTES_1_OFFSET_PET_TALENTS = 1,
|
||||
UNIT_BYTES_1_OFFSET_VIS_FLAG = 2,
|
||||
UNIT_BYTES_1_OFFSET_ANIM_TIER = 3
|
||||
};
|
||||
|
||||
// byte value (UNIT_FIELD_BYTES_1, 0)
|
||||
enum UnitStandStateType
|
||||
{
|
||||
UNIT_STAND_STATE_STAND = 0,
|
||||
UNIT_STAND_STATE_SIT = 1,
|
||||
UNIT_STAND_STATE_SIT_CHAIR = 2,
|
||||
UNIT_STAND_STATE_SLEEP = 3,
|
||||
UNIT_STAND_STATE_SIT_LOW_CHAIR = 4,
|
||||
UNIT_STAND_STATE_SIT_MEDIUM_CHAIR = 5,
|
||||
UNIT_STAND_STATE_SIT_HIGH_CHAIR = 6,
|
||||
UNIT_STAND_STATE_DEAD = 7,
|
||||
UNIT_STAND_STATE_KNEEL = 8,
|
||||
UNIT_STAND_STATE_SUBMERGED = 9
|
||||
};
|
||||
|
||||
// byte flag value (UNIT_FIELD_BYTES_1, 2)
|
||||
enum UnitStandFlags
|
||||
{
|
||||
UNIT_STAND_FLAGS_UNK1 = 0x01,
|
||||
UNIT_STAND_FLAGS_CREEP = 0x02,
|
||||
UNIT_STAND_FLAGS_UNTRACKABLE = 0x04,
|
||||
UNIT_STAND_FLAGS_UNK4 = 0x08,
|
||||
UNIT_STAND_FLAGS_UNK5 = 0x10,
|
||||
UNIT_STAND_FLAGS_ALL = 0xFF
|
||||
};
|
||||
|
||||
// byte flags value (UNIT_FIELD_BYTES_1, 3)
|
||||
enum UnitBytes1_Flags
|
||||
{
|
||||
UNIT_BYTE1_FLAG_GROUND = 0x00,
|
||||
UNIT_BYTE1_FLAG_ALWAYS_STAND = 0x01,
|
||||
UNIT_BYTE1_FLAG_HOVER = 0x02,
|
||||
UNIT_BYTE1_FLAG_FLY = 0x03,
|
||||
UNIT_BYTE1_FLAG_SUBMERGED = 0x04,
|
||||
UNIT_BYTE1_FLAG_ALL = 0xFF
|
||||
};
|
||||
|
||||
// high byte (3 from 0..3) of UNIT_FIELD_BYTES_2
|
||||
enum ShapeshiftForm
|
||||
{
|
||||
FORM_NONE = 0x00,
|
||||
FORM_CAT = 0x01,
|
||||
FORM_TREE = 0x02,
|
||||
FORM_TRAVEL = 0x03,
|
||||
FORM_AQUA = 0x04,
|
||||
FORM_BEAR = 0x05,
|
||||
FORM_AMBIENT = 0x06,
|
||||
FORM_GHOUL = 0x07,
|
||||
FORM_DIREBEAR = 0x08,
|
||||
FORM_STEVES_GHOUL = 0x09,
|
||||
FORM_THARONJA_SKELETON = 0x0A,
|
||||
FORM_TEST_OF_STRENGTH = 0x0B,
|
||||
FORM_BLB_PLAYER = 0x0C,
|
||||
FORM_SHADOW_DANCE = 0x0D,
|
||||
FORM_CREATUREBEAR = 0x0E,
|
||||
FORM_CREATURECAT = 0x0F,
|
||||
FORM_GHOSTWOLF = 0x10,
|
||||
FORM_BATTLESTANCE = 0x11,
|
||||
FORM_DEFENSIVESTANCE = 0x12,
|
||||
FORM_BERSERKERSTANCE = 0x13,
|
||||
FORM_TEST = 0x14,
|
||||
FORM_ZOMBIE = 0x15,
|
||||
FORM_METAMORPHOSIS = 0x16,
|
||||
FORM_UNDEAD = 0x19,
|
||||
FORM_MASTER_ANGLER = 0x1A,
|
||||
FORM_FLIGHT_EPIC = 0x1B,
|
||||
FORM_SHADOW = 0x1C,
|
||||
FORM_FLIGHT = 0x1D,
|
||||
FORM_STEALTH = 0x1E,
|
||||
FORM_MOONKIN = 0x1F,
|
||||
FORM_SPIRITOFREDEMPTION = 0x20
|
||||
};
|
||||
|
||||
// low byte (0 from 0..3) of UNIT_FIELD_BYTES_2
|
||||
enum SheathState
|
||||
{
|
||||
SHEATH_STATE_UNARMED = 0, // non prepared weapon
|
||||
SHEATH_STATE_MELEE = 1, // prepared melee weapon
|
||||
SHEATH_STATE_RANGED = 2 // prepared ranged weapon
|
||||
};
|
||||
|
||||
#define MAX_SHEATH_STATE 3
|
||||
|
||||
// byte (1 from 0..3) of UNIT_FIELD_BYTES_2
|
||||
enum UnitPVPStateFlags
|
||||
{
|
||||
UNIT_BYTE2_FLAG_PVP = 0x01,
|
||||
UNIT_BYTE2_FLAG_UNK1 = 0x02,
|
||||
UNIT_BYTE2_FLAG_FFA_PVP = 0x04,
|
||||
UNIT_BYTE2_FLAG_SANCTUARY = 0x08,
|
||||
UNIT_BYTE2_FLAG_UNK4 = 0x10,
|
||||
UNIT_BYTE2_FLAG_UNK5 = 0x20,
|
||||
UNIT_BYTE2_FLAG_UNK6 = 0x40,
|
||||
UNIT_BYTE2_FLAG_UNK7 = 0x80
|
||||
};
|
||||
|
||||
// byte (2 from 0..3) of UNIT_FIELD_BYTES_2
|
||||
enum UnitRename
|
||||
{
|
||||
UNIT_CAN_BE_RENAMED = 0x01,
|
||||
UNIT_CAN_BE_ABANDONED = 0x02,
|
||||
};
|
||||
#define MAX_AGGRO_RADIUS 45.0f // yards
|
||||
|
||||
static constexpr uint32 MAX_CREATURE_SPELLS = 8;
|
||||
static constexpr uint32 infinityCooldownDelay = 0x9A7EC800; // used for set "infinity cooldowns" for spells and check, MONTH*IN_MILLISECONDS
|
||||
static constexpr uint32 infinityCooldownDelayCheck = 0x4D3F6400; // MONTH*IN_MILLISECONDS/2;
|
||||
|
||||
#define MAX_SPELL_CHARM 4
|
||||
#define MAX_SPELL_VEHICLE 6
|
||||
#define MAX_SPELL_POSSESS 8
|
||||
#define MAX_SPELL_CONTROL_BAR 10
|
||||
struct CharmInfo;
|
||||
struct FactionTemplateEntry;
|
||||
struct SpellValue;
|
||||
|
||||
#define MAX_AGGRO_RADIUS 45.0f // yards
|
||||
class AuraApplication;
|
||||
class Aura;
|
||||
class UnitAura;
|
||||
class AuraEffect;
|
||||
class Creature;
|
||||
class Spell;
|
||||
class SpellInfo;
|
||||
class DynamicObject;
|
||||
class GameObject;
|
||||
class Item;
|
||||
class Pet;
|
||||
class PetAura;
|
||||
class Minion;
|
||||
class Guardian;
|
||||
class UnitAI;
|
||||
class Totem;
|
||||
class Transport;
|
||||
class StaticTransport;
|
||||
class MotionTransport;
|
||||
class Vehicle;
|
||||
class TransportBase;
|
||||
class SpellCastTargets;
|
||||
|
||||
typedef std::list<Unit*> UnitList;
|
||||
typedef std::list< std::pair<Aura*, uint8> > DispelChargesList;
|
||||
|
||||
enum CharmType : uint8;
|
||||
|
||||
enum VictimState
|
||||
{
|
||||
@@ -203,42 +121,6 @@ enum HitInfo
|
||||
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
|
||||
enum InventorySlot
|
||||
{
|
||||
NULL_BAG = 0,
|
||||
NULL_SLOT = 255
|
||||
};
|
||||
|
||||
struct FactionTemplateEntry;
|
||||
struct SpellValue;
|
||||
|
||||
class AuraApplication;
|
||||
class Aura;
|
||||
class UnitAura;
|
||||
class AuraEffect;
|
||||
class Creature;
|
||||
class Spell;
|
||||
class SpellInfo;
|
||||
class DynamicObject;
|
||||
class GameObject;
|
||||
class Item;
|
||||
class Pet;
|
||||
class PetAura;
|
||||
class Minion;
|
||||
class Guardian;
|
||||
class UnitAI;
|
||||
class Totem;
|
||||
class Transport;
|
||||
class StaticTransport;
|
||||
class MotionTransport;
|
||||
class Vehicle;
|
||||
class TransportBase;
|
||||
class SpellCastTargets;
|
||||
|
||||
typedef std::list<Unit*> UnitList;
|
||||
typedef std::list< std::pair<Aura*, uint8> > DispelChargesList;
|
||||
|
||||
enum UnitModifierType
|
||||
{
|
||||
BASE_VALUE = 0,
|
||||
@@ -319,74 +201,6 @@ enum class DeathState : uint8
|
||||
JustRespawned = 4,
|
||||
};
|
||||
|
||||
enum UnitState
|
||||
{
|
||||
UNIT_STATE_DIED = 0x00000001, // player has fake death aura
|
||||
UNIT_STATE_MELEE_ATTACKING = 0x00000002, // player is melee attacking someone
|
||||
//UNIT_STATE_MELEE_ATTACK_BY = 0x00000004, // player is melee attack by someone
|
||||
UNIT_STATE_STUNNED = 0x00000008,
|
||||
UNIT_STATE_ROAMING = 0x00000010,
|
||||
UNIT_STATE_CHASE = 0x00000020,
|
||||
//UNIT_STATE_SEARCHING = 0x00000040,
|
||||
UNIT_STATE_FLEEING = 0x00000080,
|
||||
UNIT_STATE_IN_FLIGHT = 0x00000100, // player is in flight mode
|
||||
UNIT_STATE_FOLLOW = 0x00000200,
|
||||
UNIT_STATE_ROOT = 0x00000400,
|
||||
UNIT_STATE_CONFUSED = 0x00000800,
|
||||
UNIT_STATE_DISTRACTED = 0x00001000,
|
||||
UNIT_STATE_ISOLATED = 0x00002000, // area auras do not affect other players
|
||||
UNIT_STATE_ATTACK_PLAYER = 0x00004000,
|
||||
UNIT_STATE_CASTING = 0x00008000,
|
||||
UNIT_STATE_POSSESSED = 0x00010000,
|
||||
UNIT_STATE_CHARGING = 0x00020000,
|
||||
UNIT_STATE_JUMPING = 0x00040000,
|
||||
UNIT_STATE_MOVE = 0x00100000,
|
||||
UNIT_STATE_ROTATING = 0x00200000,
|
||||
UNIT_STATE_EVADE = 0x00400000,
|
||||
UNIT_STATE_ROAMING_MOVE = 0x00800000,
|
||||
UNIT_STATE_CONFUSED_MOVE = 0x01000000,
|
||||
UNIT_STATE_FLEEING_MOVE = 0x02000000,
|
||||
UNIT_STATE_CHASE_MOVE = 0x04000000,
|
||||
UNIT_STATE_FOLLOW_MOVE = 0x08000000,
|
||||
UNIT_STATE_IGNORE_PATHFINDING = 0x10000000, // do not use pathfinding in any MovementGenerator
|
||||
UNIT_STATE_NO_ENVIRONMENT_UPD = 0x20000000, // pussywizard
|
||||
|
||||
UNIT_STATE_ALL_STATE_SUPPORTED = UNIT_STATE_DIED | UNIT_STATE_MELEE_ATTACKING | UNIT_STATE_STUNNED | UNIT_STATE_ROAMING | UNIT_STATE_CHASE
|
||||
| UNIT_STATE_FLEEING | UNIT_STATE_IN_FLIGHT | UNIT_STATE_FOLLOW | UNIT_STATE_ROOT | UNIT_STATE_CONFUSED
|
||||
| UNIT_STATE_DISTRACTED | UNIT_STATE_ISOLATED | UNIT_STATE_ATTACK_PLAYER | UNIT_STATE_CASTING
|
||||
| UNIT_STATE_POSSESSED | UNIT_STATE_CHARGING | UNIT_STATE_JUMPING | UNIT_STATE_MOVE | UNIT_STATE_ROTATING
|
||||
| UNIT_STATE_EVADE | UNIT_STATE_ROAMING_MOVE | UNIT_STATE_CONFUSED_MOVE | UNIT_STATE_FLEEING_MOVE
|
||||
| UNIT_STATE_CHASE_MOVE | UNIT_STATE_FOLLOW_MOVE | UNIT_STATE_IGNORE_PATHFINDING | UNIT_STATE_NO_ENVIRONMENT_UPD,
|
||||
|
||||
UNIT_STATE_UNATTACKABLE = UNIT_STATE_IN_FLIGHT,
|
||||
// for real move using movegen check and stop (except unstoppable flight)
|
||||
UNIT_STATE_MOVING = UNIT_STATE_ROAMING_MOVE | UNIT_STATE_CONFUSED_MOVE | UNIT_STATE_FLEEING_MOVE | UNIT_STATE_CHASE_MOVE | UNIT_STATE_FOLLOW_MOVE,
|
||||
UNIT_STATE_CONTROLLED = (UNIT_STATE_CONFUSED | UNIT_STATE_STUNNED | UNIT_STATE_FLEEING),
|
||||
UNIT_STATE_LOST_CONTROL = (UNIT_STATE_CONTROLLED | UNIT_STATE_JUMPING | UNIT_STATE_CHARGING),
|
||||
UNIT_STATE_SIGHTLESS = (UNIT_STATE_LOST_CONTROL | UNIT_STATE_EVADE),
|
||||
UNIT_STATE_CANNOT_AUTOATTACK = (UNIT_STATE_LOST_CONTROL | UNIT_STATE_CASTING),
|
||||
UNIT_STATE_CANNOT_TURN = (UNIT_STATE_LOST_CONTROL | UNIT_STATE_ROTATING | UNIT_STATE_ROOT),
|
||||
// stay by different reasons
|
||||
UNIT_STATE_NOT_MOVE = UNIT_STATE_ROOT | UNIT_STATE_STUNNED | UNIT_STATE_DIED | UNIT_STATE_DISTRACTED,
|
||||
UNIT_STATE_IGNORE_ANTISPEEDHACK = UNIT_STATE_FLEEING | UNIT_STATE_CONFUSED | UNIT_STATE_CHARGING | UNIT_STATE_DISTRACTED | UNIT_STATE_POSSESSED,
|
||||
UNIT_STATE_ALL_STATE = 0xffffffff //(UNIT_STATE_STOPPED | UNIT_STATE_MOVING | UNIT_STATE_IN_COMBAT | UNIT_STATE_IN_FLIGHT)
|
||||
};
|
||||
|
||||
enum UnitMoveType
|
||||
{
|
||||
MOVE_WALK = 0,
|
||||
MOVE_RUN = 1,
|
||||
MOVE_RUN_BACK = 2,
|
||||
MOVE_SWIM = 3,
|
||||
MOVE_SWIM_BACK = 4,
|
||||
MOVE_TURN_RATE = 5,
|
||||
MOVE_FLIGHT = 6,
|
||||
MOVE_FLIGHT_BACK = 7,
|
||||
MOVE_PITCH_RATE = 8
|
||||
};
|
||||
|
||||
#define MAX_MOVE_TYPE 9
|
||||
|
||||
extern float baseMoveSpeed[MAX_MOVE_TYPE];
|
||||
extern float playerBaseMoveSpeed[MAX_MOVE_TYPE];
|
||||
|
||||
@@ -439,273 +253,6 @@ enum DamageEffectType : uint8
|
||||
SELF_DAMAGE = 5
|
||||
};
|
||||
|
||||
// Used for IsClass hook
|
||||
enum ClassContext : uint8
|
||||
{
|
||||
CLASS_CONTEXT_NONE = 0, // Default
|
||||
CLASS_CONTEXT_INIT = 1,
|
||||
CLASS_CONTEXT_TELEPORT = 2,
|
||||
CLASS_CONTEXT_QUEST = 3,
|
||||
CLASS_CONTEXT_STATS = 4,
|
||||
CLASS_CONTEXT_TAXI = 5,
|
||||
CLASS_CONTEXT_SKILL = 6,
|
||||
CLASS_CONTEXT_TALENT_POINT_CALC = 7,
|
||||
CLASS_CONTEXT_ABILITY = 8,
|
||||
CLASS_CONTEXT_ABILITY_REACTIVE = 9,
|
||||
CLASS_CONTEXT_PET = 10,
|
||||
CLASS_CONTEXT_PET_CHARM = 11,
|
||||
CLASS_CONTEXT_EQUIP_RELIC = 12,
|
||||
CLASS_CONTEXT_EQUIP_SHIELDS = 13,
|
||||
CLASS_CONTEXT_EQUIP_ARMOR_CLASS = 14,
|
||||
CLASS_CONTEXT_WEAPON_SWAP = 15,
|
||||
CLASS_CONTEXT_GRAVEYARD = 16,
|
||||
CLASS_CONTEXT_CLASS_TRAINER = 17
|
||||
};
|
||||
|
||||
// Value masks for UNIT_FIELD_FLAGS
|
||||
// EnumUtils: DESCRIBE THIS
|
||||
enum UnitFlags : uint32
|
||||
{
|
||||
UNIT_FLAG_NONE = 0x00000000,
|
||||
UNIT_FLAG_SERVER_CONTROLLED = 0x00000001, // set only when unit movement is controlled by server - by SPLINE/MONSTER_MOVE packets, together with UNIT_FLAG_STUNNED; only set to units controlled by client; client function CGUnit_C::IsClientControlled returns false when set for owner
|
||||
UNIT_FLAG_NON_ATTACKABLE = 0x00000002, // not attackable
|
||||
UNIT_FLAG_DISABLE_MOVE = 0x00000004,
|
||||
UNIT_FLAG_PLAYER_CONTROLLED = 0x00000008, // controlled by player, use _IMMUNE_TO_PC instead of _IMMUNE_TO_NPC
|
||||
UNIT_FLAG_RENAME = 0x00000010,
|
||||
UNIT_FLAG_PREPARATION = 0x00000020, // don't take reagents for spells with SPELL_ATTR5_NO_REAGENT_COST_WITH_AURA
|
||||
UNIT_FLAG_UNK_6 = 0x00000040,
|
||||
UNIT_FLAG_NOT_ATTACKABLE_1 = 0x00000080, // ?? (UNIT_FLAG_PLAYER_CONTROLLED | UNIT_FLAG_NOT_ATTACKABLE_1) is NON_PVP_ATTACKABLE
|
||||
UNIT_FLAG_IMMUNE_TO_PC = 0x00000100, // disables combat/assistance with PlayerCharacters (PC) - see Unit::_IsValidAttackTarget, Unit::_IsValidAssistTarget
|
||||
UNIT_FLAG_IMMUNE_TO_NPC = 0x00000200, // disables combat/assistance with NonPlayerCharacters (NPC) - see Unit::_IsValidAttackTarget, Unit::_IsValidAssistTarget
|
||||
UNIT_FLAG_LOOTING = 0x00000400, // loot animation
|
||||
UNIT_FLAG_PET_IN_COMBAT = 0x00000800, // in combat?, 2.0.8
|
||||
UNIT_FLAG_PVP = 0x00001000, // changed in 3.0.3
|
||||
UNIT_FLAG_SILENCED = 0x00002000, // silenced, 2.1.1
|
||||
UNIT_FLAG_CANNOT_SWIM = 0x00004000, // 2.0.8
|
||||
UNIT_FLAG_SWIMMING = 0x00008000, // shows swim animation in water
|
||||
UNIT_FLAG_NON_ATTACKABLE_2 = 0x00010000, // removes attackable icon, if on yourself, cannot assist self but can cast TARGET_SELF spells - added by SPELL_AURA_MOD_UNATTACKABLE
|
||||
UNIT_FLAG_PACIFIED = 0x00020000, // 3.0.3 ok
|
||||
UNIT_FLAG_STUNNED = 0x00040000, // 3.0.3 ok
|
||||
UNIT_FLAG_IN_COMBAT = 0x00080000,
|
||||
UNIT_FLAG_TAXI_FLIGHT = 0x00100000, // disable casting at client side spell not allowed by taxi flight (mounted?), probably used with 0x4 flag
|
||||
UNIT_FLAG_DISARMED = 0x00200000, // 3.0.3, disable melee spells casting..., "Required melee weapon" added to melee spells tooltip.
|
||||
UNIT_FLAG_CONFUSED = 0x00400000,
|
||||
UNIT_FLAG_FLEEING = 0x00800000,
|
||||
UNIT_FLAG_POSSESSED = 0x01000000, // under direct client control by a player (possess or vehicle)
|
||||
UNIT_FLAG_NOT_SELECTABLE = 0x02000000,
|
||||
UNIT_FLAG_SKINNABLE = 0x04000000,
|
||||
UNIT_FLAG_MOUNT = 0x08000000,
|
||||
UNIT_FLAG_UNK_28 = 0x10000000,
|
||||
UNIT_FLAG_PREVENT_EMOTES_FROM_CHAT_TEXT = 0x20000000, // Prevent automatically playing emotes from parsing chat text, for example "lol" in /say, ending message with ? or !, or using /yell
|
||||
UNIT_FLAG_SHEATHE = 0x40000000,
|
||||
UNIT_FLAG_IMMUNE = 0x80000000, // Immune to damage
|
||||
};
|
||||
|
||||
DEFINE_ENUM_FLAG(UnitFlags);
|
||||
|
||||
// Value masks for UNIT_FIELD_FLAGS_2
|
||||
enum UnitFlags2 : uint32
|
||||
{
|
||||
UNIT_FLAG2_NONE = 0x00000000,
|
||||
UNIT_FLAG2_FEIGN_DEATH = 0x00000001,
|
||||
UNIT_FLAG2_HIDE_BODY = 0x00000002, // Hide unit model (show only player equip)
|
||||
UNIT_FLAG2_IGNORE_REPUTATION = 0x00000004,
|
||||
UNIT_FLAG2_COMPREHEND_LANG = 0x00000008,
|
||||
UNIT_FLAG2_MIRROR_IMAGE = 0x00000010,
|
||||
UNIT_FLAG2_DO_NOT_FADE_IN = 0x00000020, // Unit model instantly appears when summoned (does not fade in)
|
||||
UNIT_FLAG2_FORCE_MOVEMENT = 0x00000040,
|
||||
UNIT_FLAG2_DISARM_OFFHAND = 0x00000080,
|
||||
UNIT_FLAG2_DISABLE_PRED_STATS = 0x00000100, // Player has disabled predicted stats (Used by raid frames)
|
||||
UNIT_FLAG2_DISARM_RANGED = 0x00000400, // this does not disable ranged weapon display (maybe additional flag needed?)
|
||||
UNIT_FLAG2_REGENERATE_POWER = 0x00000800,
|
||||
UNIT_FLAG2_RESTRICT_PARTY_INTERACTION = 0x00001000, // Restrict interaction to party or raid
|
||||
UNIT_FLAG2_PREVENT_SPELL_CLICK = 0x00002000, // Prevent spellclick
|
||||
UNIT_FLAG2_ALLOW_ENEMY_INTERACT = 0x00004000,
|
||||
UNIT_FLAG2_CANNOT_TURN = 0x00008000,
|
||||
UNIT_FLAG2_UNK2 = 0x00010000,
|
||||
UNIT_FLAG2_PLAY_DEATH_ANIM = 0x00020000, // Plays special death animation upon death
|
||||
UNIT_FLAG2_ALLOW_CHEAT_SPELLS = 0x00040000, // Allows casting spells with AttributesEx7 & SPELL_ATTR7_DEBUG_SPELL
|
||||
UNIT_FLAG2_UNUSED_6 = 0x01000000,
|
||||
};
|
||||
|
||||
DEFINE_ENUM_FLAG(UnitFlags2);
|
||||
|
||||
/// Non Player Character flags
|
||||
// EnumUtils: DESCRIBE THIS
|
||||
enum NPCFlags : uint32
|
||||
{
|
||||
UNIT_NPC_FLAG_NONE = 0x00000000, // SKIP
|
||||
UNIT_NPC_FLAG_GOSSIP = 0x00000001, // TITLE has gossip menu DESCRIPTION 100%
|
||||
UNIT_NPC_FLAG_QUESTGIVER = 0x00000002, // TITLE is quest giver DESCRIPTION guessed, probably ok
|
||||
UNIT_NPC_FLAG_UNK1 = 0x00000004,
|
||||
UNIT_NPC_FLAG_UNK2 = 0x00000008,
|
||||
UNIT_NPC_FLAG_TRAINER = 0x00000010, // TITLE is trainer DESCRIPTION 100%
|
||||
UNIT_NPC_FLAG_TRAINER_CLASS = 0x00000020, // TITLE is class trainer DESCRIPTION 100%
|
||||
UNIT_NPC_FLAG_TRAINER_PROFESSION = 0x00000040, // TITLE is profession trainer DESCRIPTION 100%
|
||||
UNIT_NPC_FLAG_VENDOR = 0x00000080, // TITLE is vendor (generic) DESCRIPTION 100%
|
||||
UNIT_NPC_FLAG_VENDOR_AMMO = 0x00000100, // TITLE is vendor (ammo) DESCRIPTION 100%, general goods vendor
|
||||
UNIT_NPC_FLAG_VENDOR_FOOD = 0x00000200, // TITLE is vendor (food) DESCRIPTION 100%
|
||||
UNIT_NPC_FLAG_VENDOR_POISON = 0x00000400, // TITLE is vendor (poison) DESCRIPTION guessed
|
||||
UNIT_NPC_FLAG_VENDOR_REAGENT = 0x00000800, // TITLE is vendor (reagents) DESCRIPTION 100%
|
||||
UNIT_NPC_FLAG_REPAIR = 0x00001000, // TITLE can repair DESCRIPTION 100%
|
||||
UNIT_NPC_FLAG_FLIGHTMASTER = 0x00002000, // TITLE is flight master DESCRIPTION 100%
|
||||
UNIT_NPC_FLAG_SPIRITHEALER = 0x00004000, // TITLE is spirit healer DESCRIPTION guessed
|
||||
UNIT_NPC_FLAG_SPIRITGUIDE = 0x00008000, // TITLE is spirit guide DESCRIPTION guessed
|
||||
UNIT_NPC_FLAG_INNKEEPER = 0x00010000, // TITLE is innkeeper
|
||||
UNIT_NPC_FLAG_BANKER = 0x00020000, // TITLE is banker DESCRIPTION 100%
|
||||
UNIT_NPC_FLAG_PETITIONER = 0x00040000, // TITLE handles guild/arena petitions DESCRIPTION 100% 0xC0000 = guild petitions, 0x40000 = arena team petitions
|
||||
UNIT_NPC_FLAG_TABARDDESIGNER = 0x00080000, // TITLE is guild tabard designer DESCRIPTION 100%
|
||||
UNIT_NPC_FLAG_BATTLEMASTER = 0x00100000, // TITLE is battlemaster DESCRIPTION 100%
|
||||
UNIT_NPC_FLAG_AUCTIONEER = 0x00200000, // TITLE is auctioneer DESCRIPTION 100%
|
||||
UNIT_NPC_FLAG_STABLEMASTER = 0x00400000, // TITLE is stable master DESCRIPTION 100%
|
||||
UNIT_NPC_FLAG_GUILD_BANKER = 0x00800000, // TITLE is guild banker DESCRIPTION cause client to send 997 opcode
|
||||
UNIT_NPC_FLAG_SPELLCLICK = 0x01000000, // TITLE has spell click enabled DESCRIPTION cause client to send 1015 opcode (spell click)
|
||||
UNIT_NPC_FLAG_PLAYER_VEHICLE = 0x02000000, // TITLE is player vehicle DESCRIPTION players with mounts that have vehicle data should have it set
|
||||
UNIT_NPC_FLAG_MAILBOX = 0x04000000, // TITLE is mailbox
|
||||
|
||||
UNIT_NPC_FLAG_VENDOR_MASK = UNIT_NPC_FLAG_VENDOR | UNIT_NPC_FLAG_VENDOR_AMMO | UNIT_NPC_FLAG_VENDOR_POISON | UNIT_NPC_FLAG_VENDOR_REAGENT
|
||||
};
|
||||
|
||||
DEFINE_ENUM_FLAG(NPCFlags);
|
||||
|
||||
enum MovementFlags
|
||||
{
|
||||
MOVEMENTFLAG_NONE = 0x00000000,
|
||||
MOVEMENTFLAG_FORWARD = 0x00000001,
|
||||
MOVEMENTFLAG_BACKWARD = 0x00000002,
|
||||
MOVEMENTFLAG_STRAFE_LEFT = 0x00000004,
|
||||
MOVEMENTFLAG_STRAFE_RIGHT = 0x00000008,
|
||||
MOVEMENTFLAG_LEFT = 0x00000010,
|
||||
MOVEMENTFLAG_RIGHT = 0x00000020,
|
||||
MOVEMENTFLAG_PITCH_UP = 0x00000040,
|
||||
MOVEMENTFLAG_PITCH_DOWN = 0x00000080,
|
||||
MOVEMENTFLAG_WALKING = 0x00000100, // Walking
|
||||
MOVEMENTFLAG_ONTRANSPORT = 0x00000200, // Used for flying on some creatures
|
||||
MOVEMENTFLAG_DISABLE_GRAVITY = 0x00000400, // Former MOVEMENTFLAG_LEVITATING. This is used when walking is not possible.
|
||||
MOVEMENTFLAG_ROOT = 0x00000800, // Must not be set along with MOVEMENTFLAG_MASK_MOVING
|
||||
MOVEMENTFLAG_FALLING = 0x00001000, // damage dealt on that type of falling
|
||||
MOVEMENTFLAG_FALLING_FAR = 0x00002000,
|
||||
MOVEMENTFLAG_PENDING_STOP = 0x00004000,
|
||||
MOVEMENTFLAG_PENDING_STRAFE_STOP = 0x00008000,
|
||||
MOVEMENTFLAG_PENDING_FORWARD = 0x00010000,
|
||||
MOVEMENTFLAG_PENDING_BACKWARD = 0x00020000,
|
||||
MOVEMENTFLAG_PENDING_STRAFE_LEFT = 0x00040000,
|
||||
MOVEMENTFLAG_PENDING_STRAFE_RIGHT = 0x00080000,
|
||||
MOVEMENTFLAG_PENDING_ROOT = 0x00100000,
|
||||
MOVEMENTFLAG_SWIMMING = 0x00200000, // appears with fly flag also
|
||||
MOVEMENTFLAG_ASCENDING = 0x00400000, // press "space" when flying
|
||||
MOVEMENTFLAG_DESCENDING = 0x00800000,
|
||||
MOVEMENTFLAG_CAN_FLY = 0x01000000, // Appears when unit can fly AND also walk
|
||||
MOVEMENTFLAG_FLYING = 0x02000000, // unit is actually flying. pretty sure this is only used for players. creatures use disable_gravity
|
||||
MOVEMENTFLAG_SPLINE_ELEVATION = 0x04000000, // used for flight paths
|
||||
MOVEMENTFLAG_SPLINE_ENABLED = 0x08000000, // used for flight paths
|
||||
MOVEMENTFLAG_WATERWALKING = 0x10000000, // prevent unit from falling through water
|
||||
MOVEMENTFLAG_FALLING_SLOW = 0x20000000, // active rogue safe fall spell (passive)
|
||||
MOVEMENTFLAG_HOVER = 0x40000000, // hover, cannot jump
|
||||
|
||||
/// @todo: Check if PITCH_UP and PITCH_DOWN really belong here..
|
||||
MOVEMENTFLAG_MASK_MOVING =
|
||||
MOVEMENTFLAG_FORWARD | MOVEMENTFLAG_BACKWARD | MOVEMENTFLAG_STRAFE_LEFT | MOVEMENTFLAG_STRAFE_RIGHT |
|
||||
MOVEMENTFLAG_PITCH_UP | MOVEMENTFLAG_PITCH_DOWN | MOVEMENTFLAG_FALLING | MOVEMENTFLAG_FALLING_FAR | MOVEMENTFLAG_ASCENDING | MOVEMENTFLAG_DESCENDING |
|
||||
MOVEMENTFLAG_SPLINE_ELEVATION,
|
||||
|
||||
MOVEMENTFLAG_MASK_TURNING =
|
||||
MOVEMENTFLAG_LEFT | MOVEMENTFLAG_RIGHT,
|
||||
|
||||
MOVEMENTFLAG_MASK_MOVING_FLY =
|
||||
MOVEMENTFLAG_FLYING | MOVEMENTFLAG_ASCENDING | MOVEMENTFLAG_DESCENDING,
|
||||
|
||||
/// @todo if needed: add more flags to this masks that are exclusive to players
|
||||
MOVEMENTFLAG_MASK_PLAYER_ONLY =
|
||||
MOVEMENTFLAG_FLYING,
|
||||
|
||||
/// Movement flags that have change status opcodes associated for players
|
||||
MOVEMENTFLAG_MASK_HAS_PLAYER_STATUS_OPCODE = MOVEMENTFLAG_DISABLE_GRAVITY | MOVEMENTFLAG_ROOT |
|
||||
MOVEMENTFLAG_CAN_FLY | MOVEMENTFLAG_WATERWALKING | MOVEMENTFLAG_FALLING_SLOW | MOVEMENTFLAG_HOVER
|
||||
};
|
||||
|
||||
enum MovementFlags2
|
||||
{
|
||||
MOVEMENTFLAG2_NONE = 0x00000000,
|
||||
MOVEMENTFLAG2_NO_STRAFE = 0x00000001,
|
||||
MOVEMENTFLAG2_NO_JUMPING = 0x00000002,
|
||||
MOVEMENTFLAG2_UNK3 = 0x00000004, // Overrides various clientside checks
|
||||
MOVEMENTFLAG2_FULL_SPEED_TURNING = 0x00000008,
|
||||
MOVEMENTFLAG2_FULL_SPEED_PITCHING = 0x00000010,
|
||||
MOVEMENTFLAG2_ALWAYS_ALLOW_PITCHING = 0x00000020,
|
||||
MOVEMENTFLAG2_UNK7 = 0x00000040,
|
||||
MOVEMENTFLAG2_UNK8 = 0x00000080,
|
||||
MOVEMENTFLAG2_UNK9 = 0x00000100,
|
||||
MOVEMENTFLAG2_UNK10 = 0x00000200,
|
||||
MOVEMENTFLAG2_INTERPOLATED_MOVEMENT = 0x00000400,
|
||||
MOVEMENTFLAG2_INTERPOLATED_TURNING = 0x00000800,
|
||||
MOVEMENTFLAG2_INTERPOLATED_PITCHING = 0x00001000,
|
||||
MOVEMENTFLAG2_UNK14 = 0x00002000,
|
||||
MOVEMENTFLAG2_UNK15 = 0x00004000,
|
||||
MOVEMENTFLAG2_UNK16 = 0x00008000,
|
||||
};
|
||||
|
||||
enum SplineFlags
|
||||
{
|
||||
SPLINEFLAG_NONE = 0x00000000,
|
||||
SPLINEFLAG_FORWARD = 0x00000001,
|
||||
SPLINEFLAG_BACKWARD = 0x00000002,
|
||||
SPLINEFLAG_STRAFE_LEFT = 0x00000004,
|
||||
SPLINEFLAG_STRAFE_RIGHT = 0x00000008,
|
||||
SPLINEFLAG_TURN_LEFT = 0x00000010,
|
||||
SPLINEFLAG_TURN_RIGHT = 0x00000020,
|
||||
SPLINEFLAG_PITCH_UP = 0x00000040,
|
||||
SPLINEFLAG_PITCH_DOWN = 0x00000080,
|
||||
SPLINEFLAG_DONE = 0x00000100,
|
||||
SPLINEFLAG_FALLING = 0x00000200,
|
||||
SPLINEFLAG_NO_SPLINE = 0x00000400,
|
||||
SPLINEFLAG_TRAJECTORY = 0x00000800,
|
||||
SPLINEFLAG_WALK_MODE = 0x00001000,
|
||||
SPLINEFLAG_FLYING = 0x00002000,
|
||||
SPLINEFLAG_KNOCKBACK = 0x00004000,
|
||||
SPLINEFLAG_FINAL_POINT = 0x00008000,
|
||||
SPLINEFLAG_FINAL_TARGET = 0x00010000,
|
||||
SPLINEFLAG_FINAL_FACING = 0x00020000,
|
||||
SPLINEFLAG_CATMULL_ROM = 0x00040000,
|
||||
SPLINEFLAG_CYCLIC = 0x00080000,
|
||||
SPLINEFLAG_ENTER_CYCLE = 0x00100000,
|
||||
SPLINEFLAG_ANIMATION_TIER = 0x00200000,
|
||||
SPLINEFLAG_FROZEN = 0x00400000,
|
||||
SPLINEFLAG_TRANSPORT = 0x00800000,
|
||||
SPLINEFLAG_TRANSPORT_EXIT = 0x01000000,
|
||||
SPLINEFLAG_UNKNOWN7 = 0x02000000,
|
||||
SPLINEFLAG_UNKNOWN8 = 0x04000000,
|
||||
SPLINEFLAG_ORIENTATION_INVERTED = 0x08000000,
|
||||
SPLINEFLAG_USE_PATH_SMOOTHING = 0x10000000,
|
||||
SPLINEFLAG_ANIMATION = 0x20000000,
|
||||
SPLINEFLAG_UNCOMPRESSED_PATH = 0x40000000,
|
||||
SPLINEFLAG_UNKNOWN10 = 0x80000000,
|
||||
};
|
||||
|
||||
enum SplineType
|
||||
{
|
||||
SPLINETYPE_NORMAL = 0,
|
||||
SPLINETYPE_STOP = 1,
|
||||
SPLINETYPE_FACING_SPOT = 2,
|
||||
SPLINETYPE_FACING_TARGET = 3,
|
||||
SPLINETYPE_FACING_ANGLE = 4,
|
||||
};
|
||||
|
||||
enum UnitTypeMask
|
||||
{
|
||||
UNIT_MASK_NONE = 0x00000000,
|
||||
UNIT_MASK_SUMMON = 0x00000001,
|
||||
UNIT_MASK_MINION = 0x00000002,
|
||||
UNIT_MASK_GUARDIAN = 0x00000004,
|
||||
UNIT_MASK_TOTEM = 0x00000008,
|
||||
UNIT_MASK_PET = 0x00000010,
|
||||
UNIT_MASK_VEHICLE = 0x00000020,
|
||||
UNIT_MASK_PUPPET = 0x00000040,
|
||||
UNIT_MASK_HUNTER_PET = 0x00000080,
|
||||
UNIT_MASK_CONTROLABLE_GUARDIAN = 0x00000100,
|
||||
UNIT_MASK_ACCESSORY = 0x00000200,
|
||||
};
|
||||
|
||||
namespace Movement
|
||||
{
|
||||
class MoveSpline;
|
||||
@@ -978,28 +525,6 @@ struct SpellPeriodicAuraLogInfo
|
||||
void createProcFlags(SpellInfo const* spellInfo, WeaponAttackType attackType, bool positive, uint32& procAttacker, uint32& procVictim);
|
||||
uint32 createProcExtendMask(SpellNonMeleeDamage* damageInfo, SpellMissInfo missCondition);
|
||||
|
||||
struct RedirectThreatInfo
|
||||
{
|
||||
RedirectThreatInfo() = default;
|
||||
ObjectGuid _targetGUID;
|
||||
uint32 _threatPct{0};
|
||||
|
||||
[[nodiscard]] ObjectGuid GetTargetGUID() const { return _targetGUID; }
|
||||
[[nodiscard]] uint32 GetThreatPct() const { return _threatPct; }
|
||||
|
||||
void Set(ObjectGuid guid, uint32 pct)
|
||||
{
|
||||
_targetGUID = guid;
|
||||
_threatPct = pct;
|
||||
}
|
||||
|
||||
void ModifyThreatPct(int32 amount)
|
||||
{
|
||||
amount += _threatPct;
|
||||
_threatPct = uint32(std::max(0, amount));
|
||||
}
|
||||
};
|
||||
|
||||
#define MAX_DECLINED_NAME_CASES 5
|
||||
|
||||
struct DeclinedName
|
||||
@@ -1042,16 +567,6 @@ private:
|
||||
GlobalCooldownList m_GlobalCooldowns;
|
||||
};
|
||||
|
||||
enum ActiveStates : uint8
|
||||
{
|
||||
ACT_PASSIVE = 0x01, // 0x01 - passive
|
||||
ACT_DISABLED = 0x81, // 0x80 - castable
|
||||
ACT_ENABLED = 0xC1, // 0x40 | 0x80 - auto cast + castable
|
||||
ACT_COMMAND = 0x07, // 0x01 | 0x02 | 0x04
|
||||
ACT_REACTION = 0x06, // 0x02 | 0x04
|
||||
ACT_DECIDE = 0x00 // custom
|
||||
};
|
||||
|
||||
enum ReactStates : uint8
|
||||
{
|
||||
REACT_PASSIVE = 0,
|
||||
@@ -1059,7 +574,7 @@ enum ReactStates : uint8
|
||||
REACT_AGGRESSIVE = 2
|
||||
};
|
||||
|
||||
enum CommandStates
|
||||
enum CommandStates : uint8
|
||||
{
|
||||
COMMAND_STAY = 0,
|
||||
COMMAND_FOLLOW = 1,
|
||||
@@ -1067,147 +582,8 @@ enum CommandStates
|
||||
COMMAND_ABANDON = 3
|
||||
};
|
||||
|
||||
#define UNIT_ACTION_BUTTON_ACTION(X) (uint32(X) & 0x00FFFFFF)
|
||||
#define UNIT_ACTION_BUTTON_TYPE(X) ((uint32(X) & 0xFF000000) >> 24)
|
||||
#define MAKE_UNIT_ACTION_BUTTON(A, T) (uint32(A) | (uint32(T) << 24))
|
||||
|
||||
struct UnitActionBarEntry
|
||||
{
|
||||
UnitActionBarEntry() : packedData(uint32(ACT_DISABLED) << 24) {}
|
||||
|
||||
uint32 packedData;
|
||||
|
||||
// helper
|
||||
[[nodiscard]] ActiveStates GetType() const { return ActiveStates(UNIT_ACTION_BUTTON_TYPE(packedData)); }
|
||||
[[nodiscard]] uint32 GetAction() const { return UNIT_ACTION_BUTTON_ACTION(packedData); }
|
||||
[[nodiscard]] bool IsActionBarForSpell() const
|
||||
{
|
||||
ActiveStates Type = GetType();
|
||||
return Type == ACT_DISABLED || Type == ACT_ENABLED || Type == ACT_PASSIVE;
|
||||
}
|
||||
|
||||
void SetActionAndType(uint32 action, ActiveStates type)
|
||||
{
|
||||
packedData = MAKE_UNIT_ACTION_BUTTON(action, type);
|
||||
}
|
||||
|
||||
void SetType(ActiveStates type)
|
||||
{
|
||||
packedData = MAKE_UNIT_ACTION_BUTTON(UNIT_ACTION_BUTTON_ACTION(packedData), type);
|
||||
}
|
||||
|
||||
void SetAction(uint32 action)
|
||||
{
|
||||
packedData = (packedData & 0xFF000000) | UNIT_ACTION_BUTTON_ACTION(action);
|
||||
}
|
||||
};
|
||||
|
||||
typedef std::list<Player*> SharedVisionList;
|
||||
|
||||
enum CharmType
|
||||
{
|
||||
CHARM_TYPE_CHARM,
|
||||
CHARM_TYPE_POSSESS,
|
||||
CHARM_TYPE_VEHICLE,
|
||||
CHARM_TYPE_CONVERT,
|
||||
};
|
||||
|
||||
typedef UnitActionBarEntry CharmSpellInfo;
|
||||
|
||||
enum ActionBarIndex
|
||||
{
|
||||
ACTION_BAR_INDEX_START = 0,
|
||||
ACTION_BAR_INDEX_PET_SPELL_START = 3,
|
||||
ACTION_BAR_INDEX_PET_SPELL_END = 7,
|
||||
ACTION_BAR_INDEX_END = 10,
|
||||
};
|
||||
|
||||
#define MAX_UNIT_ACTION_BAR_INDEX (ACTION_BAR_INDEX_END-ACTION_BAR_INDEX_START)
|
||||
|
||||
struct CharmInfo
|
||||
{
|
||||
public:
|
||||
explicit CharmInfo(Unit* unit);
|
||||
~CharmInfo();
|
||||
void RestoreState();
|
||||
[[nodiscard]] uint32 GetPetNumber() const { return _petnumber; }
|
||||
void SetPetNumber(uint32 petnumber, bool statwindow);
|
||||
|
||||
void SetCommandState(CommandStates st) { _CommandState = st; }
|
||||
[[nodiscard]] CommandStates GetCommandState() const { return _CommandState; }
|
||||
[[nodiscard]] bool HasCommandState(CommandStates state) const { return (_CommandState == state); }
|
||||
|
||||
void InitPossessCreateSpells();
|
||||
void InitCharmCreateSpells();
|
||||
void InitPetActionBar();
|
||||
void InitEmptyActionBar(bool withAttack = true);
|
||||
|
||||
//return true if successful
|
||||
bool AddSpellToActionBar(SpellInfo const* spellInfo, ActiveStates newstate = ACT_DECIDE);
|
||||
bool RemoveSpellFromActionBar(uint32 spell_id);
|
||||
void LoadPetActionBar(const std::string& data);
|
||||
void BuildActionBar(WorldPacket* data);
|
||||
void SetSpellAutocast(SpellInfo const* spellInfo, bool state);
|
||||
void SetActionBar(uint8 index, uint32 spellOrAction, ActiveStates type)
|
||||
{
|
||||
PetActionBar[index].SetActionAndType(spellOrAction, type);
|
||||
}
|
||||
[[nodiscard]] UnitActionBarEntry const* GetActionBarEntry(uint8 index) const { return &(PetActionBar[index]); }
|
||||
|
||||
void ToggleCreatureAutocast(SpellInfo const* spellInfo, bool apply);
|
||||
|
||||
CharmSpellInfo* GetCharmSpell(uint8 index) { return &(_charmspells[index]); }
|
||||
|
||||
GlobalCooldownMgr& GetGlobalCooldownMgr() { return _GlobalCooldownMgr; }
|
||||
|
||||
void SetIsCommandAttack(bool val);
|
||||
bool IsCommandAttack();
|
||||
void SetIsCommandFollow(bool val);
|
||||
bool IsCommandFollow();
|
||||
void SetIsAtStay(bool val);
|
||||
bool IsAtStay();
|
||||
void SetIsFollowing(bool val);
|
||||
bool IsFollowing();
|
||||
void SetIsReturning(bool val);
|
||||
bool IsReturning();
|
||||
void SaveStayPosition(bool atCurrentPos);
|
||||
void GetStayPosition(float& x, float& y, float& z);
|
||||
void RemoveStayPosition();
|
||||
bool HasStayPosition();
|
||||
|
||||
void SetForcedSpell(uint32 id) { _forcedSpellId = id; }
|
||||
int32 GetForcedSpell() { return _forcedSpellId; }
|
||||
void SetForcedTargetGUID(ObjectGuid guid = ObjectGuid::Empty) { _forcedTargetGUID = guid; }
|
||||
ObjectGuid GetForcedTarget() { return _forcedTargetGUID; }
|
||||
|
||||
// Player react states
|
||||
void SetPlayerReactState(ReactStates s) { _oldReactState = s; }
|
||||
[[nodiscard]] ReactStates GetPlayerReactState() const { return _oldReactState; }
|
||||
|
||||
private:
|
||||
Unit* _unit;
|
||||
UnitActionBarEntry PetActionBar[MAX_UNIT_ACTION_BAR_INDEX];
|
||||
CharmSpellInfo _charmspells[4];
|
||||
CommandStates _CommandState;
|
||||
uint32 _petnumber;
|
||||
|
||||
//for restoration after charmed
|
||||
ReactStates _oldReactState;
|
||||
|
||||
bool _isCommandAttack;
|
||||
bool _isCommandFollow;
|
||||
bool _isAtStay;
|
||||
bool _isFollowing;
|
||||
bool _isReturning;
|
||||
int32 _forcedSpellId;
|
||||
ObjectGuid _forcedTargetGUID;
|
||||
float _stayX;
|
||||
float _stayY;
|
||||
float _stayZ;
|
||||
|
||||
GlobalCooldownMgr _GlobalCooldownMgr;
|
||||
};
|
||||
|
||||
struct AttackPosition {
|
||||
AttackPosition(Position pos) : _pos(std::move(pos)), _taken(false) {}
|
||||
bool operator==(const int val)
|
||||
@@ -1274,108 +650,6 @@ typedef std::unordered_map<uint32, uint32> PacketCooldowns;
|
||||
|
||||
struct SpellProcEventEntry; // used only privately
|
||||
|
||||
// pussywizard:
|
||||
class MMapTargetData
|
||||
{
|
||||
public:
|
||||
MMapTargetData() = default;
|
||||
MMapTargetData(uint32 endTime, const Position* o, const Position* t)
|
||||
{
|
||||
_endTime = endTime;
|
||||
_posOwner.Relocate(o);
|
||||
_posTarget.Relocate(t);
|
||||
}
|
||||
MMapTargetData(const MMapTargetData& c)
|
||||
{
|
||||
_endTime = c._endTime;
|
||||
_posOwner.Relocate(c._posOwner);
|
||||
_posTarget.Relocate(c._posTarget);
|
||||
}
|
||||
MMapTargetData(MMapTargetData&&) = default;
|
||||
MMapTargetData& operator=(const MMapTargetData&) = default;
|
||||
MMapTargetData& operator=(MMapTargetData&&) = default;
|
||||
[[nodiscard]] bool PosChanged(const Position& o, const Position& t) const
|
||||
{
|
||||
return _posOwner.GetExactDistSq(&o) > 0.5f * 0.5f || _posTarget.GetExactDistSq(&t) > 0.5f * 0.5f;
|
||||
}
|
||||
uint32 _endTime;
|
||||
Position _posOwner;
|
||||
Position _posTarget;
|
||||
};
|
||||
|
||||
class SafeUnitPointer
|
||||
{
|
||||
public:
|
||||
explicit SafeUnitPointer(Unit* defVal) : ptr(defVal), defaultValue(defVal) {}
|
||||
SafeUnitPointer(const SafeUnitPointer& /*p*/) { ABORT(); }
|
||||
void Initialize(Unit* defVal) { defaultValue = defVal; ptr = defVal; }
|
||||
~SafeUnitPointer();
|
||||
void SetPointedTo(Unit* u);
|
||||
void UnitDeleted();
|
||||
Unit* operator->() const { return ptr; }
|
||||
void operator=(Unit* u) { SetPointedTo(u); }
|
||||
operator Unit* () const { return ptr; }
|
||||
private:
|
||||
Unit* ptr;
|
||||
Unit* defaultValue;
|
||||
};
|
||||
|
||||
// BuildValuesCachePosPointers is marks of the position of some data inside of BuildValue cache.
|
||||
struct BuildValuesCachePosPointers
|
||||
{
|
||||
BuildValuesCachePosPointers() :
|
||||
UnitNPCFlagsPos(-1), UnitFieldAuraStatePos(-1), UnitFieldFlagsPos(-1), UnitFieldDisplayPos(-1),
|
||||
UnitDynamicFlagsPos(-1), UnitFieldBytes2Pos(-1), UnitFieldFactionTemplatePos(-1) {}
|
||||
|
||||
void ApplyOffset(uint32 offset)
|
||||
{
|
||||
if (UnitNPCFlagsPos >= 0)
|
||||
UnitNPCFlagsPos += offset;
|
||||
|
||||
if (UnitFieldAuraStatePos >= 0)
|
||||
UnitFieldAuraStatePos += offset;
|
||||
|
||||
if (UnitFieldFlagsPos >= 0)
|
||||
UnitFieldFlagsPos += offset;
|
||||
|
||||
if (UnitFieldDisplayPos >= 0)
|
||||
UnitFieldDisplayPos += offset;
|
||||
|
||||
if (UnitDynamicFlagsPos >= 0)
|
||||
UnitDynamicFlagsPos += offset;
|
||||
|
||||
if (UnitFieldBytes2Pos >= 0)
|
||||
UnitFieldBytes2Pos += offset;
|
||||
|
||||
if (UnitFieldFactionTemplatePos >= 0)
|
||||
UnitFieldFactionTemplatePos += offset;
|
||||
|
||||
for (auto it = other.begin(); it != other.end(); ++it)
|
||||
it->second += offset;
|
||||
}
|
||||
|
||||
int32 UnitNPCFlagsPos;
|
||||
int32 UnitFieldAuraStatePos;
|
||||
int32 UnitFieldFlagsPos;
|
||||
int32 UnitFieldDisplayPos;
|
||||
int32 UnitDynamicFlagsPos;
|
||||
int32 UnitFieldBytes2Pos;
|
||||
int32 UnitFieldFactionTemplatePos;
|
||||
|
||||
std::unordered_map<uint16 /*index*/, uint32 /*pos*/> other;
|
||||
};
|
||||
|
||||
// BuildValuesCachedBuffer cache for calculated BuildValue.
|
||||
struct BuildValuesCachedBuffer
|
||||
{
|
||||
BuildValuesCachedBuffer(uint32 bufferSize) :
|
||||
buffer(bufferSize), posPointers() {}
|
||||
|
||||
ByteBuffer buffer;
|
||||
|
||||
BuildValuesCachePosPointers posPointers;
|
||||
};
|
||||
|
||||
class Unit : public WorldObject
|
||||
{
|
||||
public:
|
||||
@@ -1881,7 +1155,6 @@ public:
|
||||
virtual bool SetFeatherFall(bool enable, bool packetOnly = false);
|
||||
virtual bool SetHover(bool enable, bool packetOnly = false, bool updateAnimationTier = true);
|
||||
|
||||
// pussywizard:
|
||||
void SendMovementWaterWalking(Player* sendTo);
|
||||
void SendMovementFeatherFall(Player* sendTo);
|
||||
void SendMovementHover(Player* sendTo);
|
||||
@@ -2766,15 +2039,4 @@ protected:
|
||||
AuraEffect* _auraEffect;
|
||||
};
|
||||
|
||||
class VehicleDespawnEvent : public BasicEvent
|
||||
{
|
||||
public:
|
||||
VehicleDespawnEvent(Unit& self, uint32 duration) : _self(self), _duration(duration) { }
|
||||
bool Execute(uint64 e_time, uint32 p_time) override;
|
||||
|
||||
protected:
|
||||
Unit& _self;
|
||||
uint32 _duration;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
462
src/server/game/Entities/Unit/UnitDefines.h
Normal file
462
src/server/game/Entities/Unit/UnitDefines.h
Normal file
@@ -0,0 +1,462 @@
|
||||
/*
|
||||
* This file is part of the AzerothCore Project. See AUTHORS file for Copyright information
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU Affero General Public License as published by the
|
||||
* Free Software Foundation; either version 3 of the License, or (at your
|
||||
* option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for
|
||||
* more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "Define.h"
|
||||
#include "EnumFlag.h"
|
||||
|
||||
enum UnitBytes1Offsets : uint8
|
||||
{
|
||||
UNIT_BYTES_1_OFFSET_STAND_STATE = 0,
|
||||
UNIT_BYTES_1_OFFSET_PET_TALENTS = 1,
|
||||
UNIT_BYTES_1_OFFSET_VIS_FLAG = 2,
|
||||
UNIT_BYTES_1_OFFSET_ANIM_TIER = 3
|
||||
};
|
||||
|
||||
// byte value (UNIT_FIELD_BYTES_1, 0)
|
||||
enum UnitStandStateType
|
||||
{
|
||||
UNIT_STAND_STATE_STAND = 0,
|
||||
UNIT_STAND_STATE_SIT = 1,
|
||||
UNIT_STAND_STATE_SIT_CHAIR = 2,
|
||||
UNIT_STAND_STATE_SLEEP = 3,
|
||||
UNIT_STAND_STATE_SIT_LOW_CHAIR = 4,
|
||||
UNIT_STAND_STATE_SIT_MEDIUM_CHAIR = 5,
|
||||
UNIT_STAND_STATE_SIT_HIGH_CHAIR = 6,
|
||||
UNIT_STAND_STATE_DEAD = 7,
|
||||
UNIT_STAND_STATE_KNEEL = 8,
|
||||
UNIT_STAND_STATE_SUBMERGED = 9
|
||||
};
|
||||
|
||||
// byte flag value (UNIT_FIELD_BYTES_1, 2)
|
||||
enum UnitStandFlags
|
||||
{
|
||||
UNIT_STAND_FLAGS_UNK1 = 0x01,
|
||||
UNIT_STAND_FLAGS_CREEP = 0x02,
|
||||
UNIT_STAND_FLAGS_UNTRACKABLE = 0x04,
|
||||
UNIT_STAND_FLAGS_UNK4 = 0x08,
|
||||
UNIT_STAND_FLAGS_UNK5 = 0x10,
|
||||
UNIT_STAND_FLAGS_ALL = 0xFF
|
||||
};
|
||||
|
||||
// byte flags value (UNIT_FIELD_BYTES_1, 3)
|
||||
enum UnitBytes1_Flags
|
||||
{
|
||||
UNIT_BYTE1_FLAG_GROUND = 0x00,
|
||||
UNIT_BYTE1_FLAG_ALWAYS_STAND = 0x01,
|
||||
UNIT_BYTE1_FLAG_HOVER = 0x02,
|
||||
UNIT_BYTE1_FLAG_FLY = 0x03,
|
||||
UNIT_BYTE1_FLAG_SUBMERGED = 0x04,
|
||||
UNIT_BYTE1_FLAG_ALL = 0xFF
|
||||
};
|
||||
|
||||
// high byte (3 from 0..3) of UNIT_FIELD_BYTES_2
|
||||
enum ShapeshiftForm
|
||||
{
|
||||
FORM_NONE = 0x00,
|
||||
FORM_CAT = 0x01,
|
||||
FORM_TREE = 0x02,
|
||||
FORM_TRAVEL = 0x03,
|
||||
FORM_AQUA = 0x04,
|
||||
FORM_BEAR = 0x05,
|
||||
FORM_AMBIENT = 0x06,
|
||||
FORM_GHOUL = 0x07,
|
||||
FORM_DIREBEAR = 0x08,
|
||||
FORM_STEVES_GHOUL = 0x09,
|
||||
FORM_THARONJA_SKELETON = 0x0A,
|
||||
FORM_TEST_OF_STRENGTH = 0x0B,
|
||||
FORM_BLB_PLAYER = 0x0C,
|
||||
FORM_SHADOW_DANCE = 0x0D,
|
||||
FORM_CREATUREBEAR = 0x0E,
|
||||
FORM_CREATURECAT = 0x0F,
|
||||
FORM_GHOSTWOLF = 0x10,
|
||||
FORM_BATTLESTANCE = 0x11,
|
||||
FORM_DEFENSIVESTANCE = 0x12,
|
||||
FORM_BERSERKERSTANCE = 0x13,
|
||||
FORM_TEST = 0x14,
|
||||
FORM_ZOMBIE = 0x15,
|
||||
FORM_METAMORPHOSIS = 0x16,
|
||||
FORM_UNDEAD = 0x19,
|
||||
FORM_MASTER_ANGLER = 0x1A,
|
||||
FORM_FLIGHT_EPIC = 0x1B,
|
||||
FORM_SHADOW = 0x1C,
|
||||
FORM_FLIGHT = 0x1D,
|
||||
FORM_STEALTH = 0x1E,
|
||||
FORM_MOONKIN = 0x1F,
|
||||
FORM_SPIRITOFREDEMPTION = 0x20
|
||||
};
|
||||
|
||||
// low byte (0 from 0..3) of UNIT_FIELD_BYTES_2
|
||||
enum SheathState
|
||||
{
|
||||
SHEATH_STATE_UNARMED = 0, // non prepared weapon
|
||||
SHEATH_STATE_MELEE = 1, // prepared melee weapon
|
||||
SHEATH_STATE_RANGED = 2 // prepared ranged weapon
|
||||
};
|
||||
|
||||
#define MAX_SHEATH_STATE 3
|
||||
|
||||
// byte (1 from 0..3) of UNIT_FIELD_BYTES_2
|
||||
enum UnitPVPStateFlags
|
||||
{
|
||||
UNIT_BYTE2_FLAG_PVP = 0x01,
|
||||
UNIT_BYTE2_FLAG_UNK1 = 0x02,
|
||||
UNIT_BYTE2_FLAG_FFA_PVP = 0x04,
|
||||
UNIT_BYTE2_FLAG_SANCTUARY = 0x08,
|
||||
UNIT_BYTE2_FLAG_UNK4 = 0x10,
|
||||
UNIT_BYTE2_FLAG_UNK5 = 0x20,
|
||||
UNIT_BYTE2_FLAG_UNK6 = 0x40,
|
||||
UNIT_BYTE2_FLAG_UNK7 = 0x80
|
||||
};
|
||||
|
||||
// byte (2 from 0..3) of UNIT_FIELD_BYTES_2
|
||||
enum UnitRename
|
||||
{
|
||||
UNIT_CAN_BE_RENAMED = 0x01,
|
||||
UNIT_CAN_BE_ABANDONED = 0x02
|
||||
};
|
||||
|
||||
enum UnitTypeMask
|
||||
{
|
||||
UNIT_MASK_NONE = 0x00000000,
|
||||
UNIT_MASK_SUMMON = 0x00000001,
|
||||
UNIT_MASK_MINION = 0x00000002,
|
||||
UNIT_MASK_GUARDIAN = 0x00000004,
|
||||
UNIT_MASK_TOTEM = 0x00000008,
|
||||
UNIT_MASK_PET = 0x00000010,
|
||||
UNIT_MASK_VEHICLE = 0x00000020,
|
||||
UNIT_MASK_PUPPET = 0x00000040,
|
||||
UNIT_MASK_HUNTER_PET = 0x00000080,
|
||||
UNIT_MASK_CONTROLABLE_GUARDIAN = 0x00000100,
|
||||
UNIT_MASK_ACCESSORY = 0x00000200
|
||||
};
|
||||
|
||||
enum UnitState
|
||||
{
|
||||
UNIT_STATE_DIED = 0x00000001, // player has fake death aura
|
||||
UNIT_STATE_MELEE_ATTACKING = 0x00000002, // player is melee attacking someone
|
||||
//UNIT_STATE_MELEE_ATTACK_BY = 0x00000004, // player is melee attack by someone
|
||||
UNIT_STATE_STUNNED = 0x00000008,
|
||||
UNIT_STATE_ROAMING = 0x00000010,
|
||||
UNIT_STATE_CHASE = 0x00000020,
|
||||
//UNIT_STATE_SEARCHING = 0x00000040,
|
||||
UNIT_STATE_FLEEING = 0x00000080,
|
||||
UNIT_STATE_IN_FLIGHT = 0x00000100, // player is in flight mode
|
||||
UNIT_STATE_FOLLOW = 0x00000200,
|
||||
UNIT_STATE_ROOT = 0x00000400,
|
||||
UNIT_STATE_CONFUSED = 0x00000800,
|
||||
UNIT_STATE_DISTRACTED = 0x00001000,
|
||||
UNIT_STATE_ISOLATED = 0x00002000, // area auras do not affect other players
|
||||
UNIT_STATE_ATTACK_PLAYER = 0x00004000,
|
||||
UNIT_STATE_CASTING = 0x00008000,
|
||||
UNIT_STATE_POSSESSED = 0x00010000,
|
||||
UNIT_STATE_CHARGING = 0x00020000,
|
||||
UNIT_STATE_JUMPING = 0x00040000,
|
||||
UNIT_STATE_MOVE = 0x00100000,
|
||||
UNIT_STATE_ROTATING = 0x00200000,
|
||||
UNIT_STATE_EVADE = 0x00400000,
|
||||
UNIT_STATE_ROAMING_MOVE = 0x00800000,
|
||||
UNIT_STATE_CONFUSED_MOVE = 0x01000000,
|
||||
UNIT_STATE_FLEEING_MOVE = 0x02000000,
|
||||
UNIT_STATE_CHASE_MOVE = 0x04000000,
|
||||
UNIT_STATE_FOLLOW_MOVE = 0x08000000,
|
||||
UNIT_STATE_IGNORE_PATHFINDING = 0x10000000, // do not use pathfinding in any MovementGenerator
|
||||
UNIT_STATE_NO_ENVIRONMENT_UPD = 0x20000000,
|
||||
|
||||
UNIT_STATE_ALL_STATE_SUPPORTED = UNIT_STATE_DIED | UNIT_STATE_MELEE_ATTACKING | UNIT_STATE_STUNNED | UNIT_STATE_ROAMING | UNIT_STATE_CHASE
|
||||
| UNIT_STATE_FLEEING | UNIT_STATE_IN_FLIGHT | UNIT_STATE_FOLLOW | UNIT_STATE_ROOT | UNIT_STATE_CONFUSED
|
||||
| UNIT_STATE_DISTRACTED | UNIT_STATE_ISOLATED | UNIT_STATE_ATTACK_PLAYER | UNIT_STATE_CASTING
|
||||
| UNIT_STATE_POSSESSED | UNIT_STATE_CHARGING | UNIT_STATE_JUMPING | UNIT_STATE_MOVE | UNIT_STATE_ROTATING
|
||||
| UNIT_STATE_EVADE | UNIT_STATE_ROAMING_MOVE | UNIT_STATE_CONFUSED_MOVE | UNIT_STATE_FLEEING_MOVE
|
||||
| UNIT_STATE_CHASE_MOVE | UNIT_STATE_FOLLOW_MOVE | UNIT_STATE_IGNORE_PATHFINDING | UNIT_STATE_NO_ENVIRONMENT_UPD,
|
||||
|
||||
UNIT_STATE_UNATTACKABLE = UNIT_STATE_IN_FLIGHT,
|
||||
|
||||
// for real move using movegen check and stop (except unstoppable flight)
|
||||
UNIT_STATE_MOVING = UNIT_STATE_ROAMING_MOVE | UNIT_STATE_CONFUSED_MOVE | UNIT_STATE_FLEEING_MOVE | UNIT_STATE_CHASE_MOVE | UNIT_STATE_FOLLOW_MOVE,
|
||||
UNIT_STATE_CONTROLLED = (UNIT_STATE_CONFUSED | UNIT_STATE_STUNNED | UNIT_STATE_FLEEING),
|
||||
UNIT_STATE_LOST_CONTROL = (UNIT_STATE_CONTROLLED | UNIT_STATE_JUMPING | UNIT_STATE_CHARGING),
|
||||
UNIT_STATE_SIGHTLESS = (UNIT_STATE_LOST_CONTROL | UNIT_STATE_EVADE),
|
||||
UNIT_STATE_CANNOT_AUTOATTACK = (UNIT_STATE_LOST_CONTROL | UNIT_STATE_CASTING),
|
||||
UNIT_STATE_CANNOT_TURN = (UNIT_STATE_LOST_CONTROL | UNIT_STATE_ROTATING | UNIT_STATE_ROOT),
|
||||
|
||||
// stay by different reasons
|
||||
UNIT_STATE_NOT_MOVE = UNIT_STATE_ROOT | UNIT_STATE_STUNNED | UNIT_STATE_DIED | UNIT_STATE_DISTRACTED,
|
||||
UNIT_STATE_IGNORE_ANTISPEEDHACK = UNIT_STATE_FLEEING | UNIT_STATE_CONFUSED | UNIT_STATE_CHARGING | UNIT_STATE_DISTRACTED | UNIT_STATE_POSSESSED,
|
||||
UNIT_STATE_ALL_STATE = 0xffffffff //(UNIT_STATE_STOPPED | UNIT_STATE_MOVING | UNIT_STATE_IN_COMBAT | UNIT_STATE_IN_FLIGHT)
|
||||
};
|
||||
|
||||
// Used for IsClass hook
|
||||
enum ClassContext : uint8
|
||||
{
|
||||
CLASS_CONTEXT_NONE = 0, // Default
|
||||
CLASS_CONTEXT_INIT = 1,
|
||||
CLASS_CONTEXT_TELEPORT = 2,
|
||||
CLASS_CONTEXT_QUEST = 3,
|
||||
CLASS_CONTEXT_STATS = 4,
|
||||
CLASS_CONTEXT_TAXI = 5,
|
||||
CLASS_CONTEXT_SKILL = 6,
|
||||
CLASS_CONTEXT_TALENT_POINT_CALC = 7,
|
||||
CLASS_CONTEXT_ABILITY = 8,
|
||||
CLASS_CONTEXT_ABILITY_REACTIVE = 9,
|
||||
CLASS_CONTEXT_PET = 10,
|
||||
CLASS_CONTEXT_PET_CHARM = 11,
|
||||
CLASS_CONTEXT_EQUIP_RELIC = 12,
|
||||
CLASS_CONTEXT_EQUIP_SHIELDS = 13,
|
||||
CLASS_CONTEXT_EQUIP_ARMOR_CLASS = 14,
|
||||
CLASS_CONTEXT_WEAPON_SWAP = 15,
|
||||
CLASS_CONTEXT_GRAVEYARD = 16,
|
||||
CLASS_CONTEXT_CLASS_TRAINER = 17
|
||||
};
|
||||
|
||||
// Value masks for UNIT_FIELD_FLAGS
|
||||
enum UnitFlags : uint32
|
||||
{
|
||||
UNIT_FLAG_NONE = 0x00000000,
|
||||
UNIT_FLAG_SERVER_CONTROLLED = 0x00000001, // set only when unit movement is controlled by server - by SPLINE/MONSTER_MOVE packets, together with UNIT_FLAG_STUNNED; only set to units controlled by client; client function CGUnit_C::IsClientControlled returns false when set for owner
|
||||
UNIT_FLAG_NON_ATTACKABLE = 0x00000002, // not attackable
|
||||
UNIT_FLAG_DISABLE_MOVE = 0x00000004,
|
||||
UNIT_FLAG_PLAYER_CONTROLLED = 0x00000008, // controlled by player, use _IMMUNE_TO_PC instead of _IMMUNE_TO_NPC
|
||||
UNIT_FLAG_RENAME = 0x00000010,
|
||||
UNIT_FLAG_PREPARATION = 0x00000020, // don't take reagents for spells with SPELL_ATTR5_NO_REAGENT_COST_WITH_AURA
|
||||
UNIT_FLAG_UNK_6 = 0x00000040,
|
||||
UNIT_FLAG_NOT_ATTACKABLE_1 = 0x00000080, // ?? (UNIT_FLAG_PLAYER_CONTROLLED | UNIT_FLAG_NOT_ATTACKABLE_1) is NON_PVP_ATTACKABLE
|
||||
UNIT_FLAG_IMMUNE_TO_PC = 0x00000100, // disables combat/assistance with PlayerCharacters (PC) - see Unit::_IsValidAttackTarget, Unit::_IsValidAssistTarget
|
||||
UNIT_FLAG_IMMUNE_TO_NPC = 0x00000200, // disables combat/assistance with NonPlayerCharacters (NPC) - see Unit::_IsValidAttackTarget, Unit::_IsValidAssistTarget
|
||||
UNIT_FLAG_LOOTING = 0x00000400, // loot animation
|
||||
UNIT_FLAG_PET_IN_COMBAT = 0x00000800, // in combat?, 2.0.8
|
||||
UNIT_FLAG_PVP = 0x00001000, // changed in 3.0.3
|
||||
UNIT_FLAG_SILENCED = 0x00002000, // silenced, 2.1.1
|
||||
UNIT_FLAG_CANNOT_SWIM = 0x00004000, // 2.0.8
|
||||
UNIT_FLAG_SWIMMING = 0x00008000, // shows swim animation in water
|
||||
UNIT_FLAG_NON_ATTACKABLE_2 = 0x00010000, // removes attackable icon, if on yourself, cannot assist self but can cast TARGET_SELF spells - added by SPELL_AURA_MOD_UNATTACKABLE
|
||||
UNIT_FLAG_PACIFIED = 0x00020000, // 3.0.3 ok
|
||||
UNIT_FLAG_STUNNED = 0x00040000, // 3.0.3 ok
|
||||
UNIT_FLAG_IN_COMBAT = 0x00080000,
|
||||
UNIT_FLAG_TAXI_FLIGHT = 0x00100000, // disable casting at client side spell not allowed by taxi flight (mounted?), probably used with 0x4 flag
|
||||
UNIT_FLAG_DISARMED = 0x00200000, // 3.0.3, disable melee spells casting..., "Required melee weapon" added to melee spells tooltip.
|
||||
UNIT_FLAG_CONFUSED = 0x00400000,
|
||||
UNIT_FLAG_FLEEING = 0x00800000,
|
||||
UNIT_FLAG_POSSESSED = 0x01000000, // under direct client control by a player (possess or vehicle)
|
||||
UNIT_FLAG_NOT_SELECTABLE = 0x02000000,
|
||||
UNIT_FLAG_SKINNABLE = 0x04000000,
|
||||
UNIT_FLAG_MOUNT = 0x08000000,
|
||||
UNIT_FLAG_UNK_28 = 0x10000000,
|
||||
UNIT_FLAG_PREVENT_EMOTES_FROM_CHAT_TEXT = 0x20000000, // Prevent automatically playing emotes from parsing chat text, for example "lol" in /say, ending message with ? or !, or using /yell
|
||||
UNIT_FLAG_SHEATHE = 0x40000000,
|
||||
UNIT_FLAG_IMMUNE = 0x80000000 // Immune to damage
|
||||
};
|
||||
DEFINE_ENUM_FLAG(UnitFlags);
|
||||
|
||||
// Value masks for UNIT_FIELD_FLAGS_2
|
||||
enum UnitFlags2 : uint32
|
||||
{
|
||||
UNIT_FLAG2_NONE = 0x00000000,
|
||||
UNIT_FLAG2_FEIGN_DEATH = 0x00000001,
|
||||
UNIT_FLAG2_HIDE_BODY = 0x00000002, // Hide unit model (show only player equip)
|
||||
UNIT_FLAG2_IGNORE_REPUTATION = 0x00000004,
|
||||
UNIT_FLAG2_COMPREHEND_LANG = 0x00000008,
|
||||
UNIT_FLAG2_MIRROR_IMAGE = 0x00000010,
|
||||
UNIT_FLAG2_DO_NOT_FADE_IN = 0x00000020, // Unit model instantly appears when summoned (does not fade in)
|
||||
UNIT_FLAG2_FORCE_MOVEMENT = 0x00000040,
|
||||
UNIT_FLAG2_DISARM_OFFHAND = 0x00000080,
|
||||
UNIT_FLAG2_DISABLE_PRED_STATS = 0x00000100, // Player has disabled predicted stats (Used by raid frames)
|
||||
UNIT_FLAG2_DISARM_RANGED = 0x00000400, // this does not disable ranged weapon display (maybe additional flag needed?)
|
||||
UNIT_FLAG2_REGENERATE_POWER = 0x00000800,
|
||||
UNIT_FLAG2_RESTRICT_PARTY_INTERACTION = 0x00001000, // Restrict interaction to party or raid
|
||||
UNIT_FLAG2_PREVENT_SPELL_CLICK = 0x00002000, // Prevent spellclick
|
||||
UNIT_FLAG2_ALLOW_ENEMY_INTERACT = 0x00004000,
|
||||
UNIT_FLAG2_CANNOT_TURN = 0x00008000,
|
||||
UNIT_FLAG2_UNK2 = 0x00010000,
|
||||
UNIT_FLAG2_PLAY_DEATH_ANIM = 0x00020000, // Plays special death animation upon death
|
||||
UNIT_FLAG2_ALLOW_CHEAT_SPELLS = 0x00040000, // Allows casting spells with AttributesEx7 & SPELL_ATTR7_DEBUG_SPELL
|
||||
UNIT_FLAG2_UNUSED_6 = 0x01000000
|
||||
};
|
||||
DEFINE_ENUM_FLAG(UnitFlags2);
|
||||
|
||||
/// Non Player Character flags
|
||||
enum NPCFlags : uint32
|
||||
{
|
||||
UNIT_NPC_FLAG_NONE = 0x00000000, // SKIP
|
||||
UNIT_NPC_FLAG_GOSSIP = 0x00000001, // TITLE has gossip menu DESCRIPTION 100%
|
||||
UNIT_NPC_FLAG_QUESTGIVER = 0x00000002, // TITLE is quest giver DESCRIPTION guessed, probably ok
|
||||
UNIT_NPC_FLAG_UNK1 = 0x00000004,
|
||||
UNIT_NPC_FLAG_UNK2 = 0x00000008,
|
||||
UNIT_NPC_FLAG_TRAINER = 0x00000010, // TITLE is trainer DESCRIPTION 100%
|
||||
UNIT_NPC_FLAG_TRAINER_CLASS = 0x00000020, // TITLE is class trainer DESCRIPTION 100%
|
||||
UNIT_NPC_FLAG_TRAINER_PROFESSION = 0x00000040, // TITLE is profession trainer DESCRIPTION 100%
|
||||
UNIT_NPC_FLAG_VENDOR = 0x00000080, // TITLE is vendor (generic) DESCRIPTION 100%
|
||||
UNIT_NPC_FLAG_VENDOR_AMMO = 0x00000100, // TITLE is vendor (ammo) DESCRIPTION 100%, general goods vendor
|
||||
UNIT_NPC_FLAG_VENDOR_FOOD = 0x00000200, // TITLE is vendor (food) DESCRIPTION 100%
|
||||
UNIT_NPC_FLAG_VENDOR_POISON = 0x00000400, // TITLE is vendor (poison) DESCRIPTION guessed
|
||||
UNIT_NPC_FLAG_VENDOR_REAGENT = 0x00000800, // TITLE is vendor (reagents) DESCRIPTION 100%
|
||||
UNIT_NPC_FLAG_REPAIR = 0x00001000, // TITLE can repair DESCRIPTION 100%
|
||||
UNIT_NPC_FLAG_FLIGHTMASTER = 0x00002000, // TITLE is flight master DESCRIPTION 100%
|
||||
UNIT_NPC_FLAG_SPIRITHEALER = 0x00004000, // TITLE is spirit healer DESCRIPTION guessed
|
||||
UNIT_NPC_FLAG_SPIRITGUIDE = 0x00008000, // TITLE is spirit guide DESCRIPTION guessed
|
||||
UNIT_NPC_FLAG_INNKEEPER = 0x00010000, // TITLE is innkeeper
|
||||
UNIT_NPC_FLAG_BANKER = 0x00020000, // TITLE is banker DESCRIPTION 100%
|
||||
UNIT_NPC_FLAG_PETITIONER = 0x00040000, // TITLE handles guild/arena petitions DESCRIPTION 100% 0xC0000 = guild petitions, 0x40000 = arena team petitions
|
||||
UNIT_NPC_FLAG_TABARDDESIGNER = 0x00080000, // TITLE is guild tabard designer DESCRIPTION 100%
|
||||
UNIT_NPC_FLAG_BATTLEMASTER = 0x00100000, // TITLE is battlemaster DESCRIPTION 100%
|
||||
UNIT_NPC_FLAG_AUCTIONEER = 0x00200000, // TITLE is auctioneer DESCRIPTION 100%
|
||||
UNIT_NPC_FLAG_STABLEMASTER = 0x00400000, // TITLE is stable master DESCRIPTION 100%
|
||||
UNIT_NPC_FLAG_GUILD_BANKER = 0x00800000, // TITLE is guild banker DESCRIPTION cause client to send 997 opcode
|
||||
UNIT_NPC_FLAG_SPELLCLICK = 0x01000000, // TITLE has spell click enabled DESCRIPTION cause client to send 1015 opcode (spell click)
|
||||
UNIT_NPC_FLAG_PLAYER_VEHICLE = 0x02000000, // TITLE is player vehicle DESCRIPTION players with mounts that have vehicle data should have it set
|
||||
UNIT_NPC_FLAG_MAILBOX = 0x04000000, // TITLE is mailbox
|
||||
|
||||
UNIT_NPC_FLAG_VENDOR_MASK = UNIT_NPC_FLAG_VENDOR | UNIT_NPC_FLAG_VENDOR_AMMO | UNIT_NPC_FLAG_VENDOR_POISON | UNIT_NPC_FLAG_VENDOR_REAGENT
|
||||
};
|
||||
DEFINE_ENUM_FLAG(NPCFlags);
|
||||
|
||||
enum UnitMoveType
|
||||
{
|
||||
MOVE_WALK = 0,
|
||||
MOVE_RUN = 1,
|
||||
MOVE_RUN_BACK = 2,
|
||||
MOVE_SWIM = 3,
|
||||
MOVE_SWIM_BACK = 4,
|
||||
MOVE_TURN_RATE = 5,
|
||||
MOVE_FLIGHT = 6,
|
||||
MOVE_FLIGHT_BACK = 7,
|
||||
MOVE_PITCH_RATE = 8
|
||||
};
|
||||
|
||||
#define MAX_MOVE_TYPE 9
|
||||
|
||||
enum MovementFlags
|
||||
{
|
||||
MOVEMENTFLAG_NONE = 0x00000000,
|
||||
MOVEMENTFLAG_FORWARD = 0x00000001,
|
||||
MOVEMENTFLAG_BACKWARD = 0x00000002,
|
||||
MOVEMENTFLAG_STRAFE_LEFT = 0x00000004,
|
||||
MOVEMENTFLAG_STRAFE_RIGHT = 0x00000008,
|
||||
MOVEMENTFLAG_LEFT = 0x00000010,
|
||||
MOVEMENTFLAG_RIGHT = 0x00000020,
|
||||
MOVEMENTFLAG_PITCH_UP = 0x00000040,
|
||||
MOVEMENTFLAG_PITCH_DOWN = 0x00000080,
|
||||
MOVEMENTFLAG_WALKING = 0x00000100, // Walking
|
||||
MOVEMENTFLAG_ONTRANSPORT = 0x00000200, // Used for flying on some creatures
|
||||
MOVEMENTFLAG_DISABLE_GRAVITY = 0x00000400, // Former MOVEMENTFLAG_LEVITATING. This is used when walking is not possible.
|
||||
MOVEMENTFLAG_ROOT = 0x00000800, // Must not be set along with MOVEMENTFLAG_MASK_MOVING
|
||||
MOVEMENTFLAG_FALLING = 0x00001000, // damage dealt on that type of falling
|
||||
MOVEMENTFLAG_FALLING_FAR = 0x00002000,
|
||||
MOVEMENTFLAG_PENDING_STOP = 0x00004000,
|
||||
MOVEMENTFLAG_PENDING_STRAFE_STOP = 0x00008000,
|
||||
MOVEMENTFLAG_PENDING_FORWARD = 0x00010000,
|
||||
MOVEMENTFLAG_PENDING_BACKWARD = 0x00020000,
|
||||
MOVEMENTFLAG_PENDING_STRAFE_LEFT = 0x00040000,
|
||||
MOVEMENTFLAG_PENDING_STRAFE_RIGHT = 0x00080000,
|
||||
MOVEMENTFLAG_PENDING_ROOT = 0x00100000,
|
||||
MOVEMENTFLAG_SWIMMING = 0x00200000, // appears with fly flag also
|
||||
MOVEMENTFLAG_ASCENDING = 0x00400000, // press "space" when flying
|
||||
MOVEMENTFLAG_DESCENDING = 0x00800000,
|
||||
MOVEMENTFLAG_CAN_FLY = 0x01000000, // Appears when unit can fly AND also walk
|
||||
MOVEMENTFLAG_FLYING = 0x02000000, // unit is actually flying. pretty sure this is only used for players. creatures use disable_gravity
|
||||
MOVEMENTFLAG_SPLINE_ELEVATION = 0x04000000, // used for flight paths
|
||||
MOVEMENTFLAG_SPLINE_ENABLED = 0x08000000, // used for flight paths
|
||||
MOVEMENTFLAG_WATERWALKING = 0x10000000, // prevent unit from falling through water
|
||||
MOVEMENTFLAG_FALLING_SLOW = 0x20000000, // active rogue safe fall spell (passive)
|
||||
MOVEMENTFLAG_HOVER = 0x40000000, // hover, cannot jump
|
||||
|
||||
/// @todo: Check if PITCH_UP and PITCH_DOWN really belong here..
|
||||
MOVEMENTFLAG_MASK_MOVING =
|
||||
MOVEMENTFLAG_FORWARD | MOVEMENTFLAG_BACKWARD | MOVEMENTFLAG_STRAFE_LEFT | MOVEMENTFLAG_STRAFE_RIGHT |
|
||||
MOVEMENTFLAG_PITCH_UP | MOVEMENTFLAG_PITCH_DOWN | MOVEMENTFLAG_FALLING | MOVEMENTFLAG_FALLING_FAR | MOVEMENTFLAG_ASCENDING | MOVEMENTFLAG_DESCENDING |
|
||||
MOVEMENTFLAG_SPLINE_ELEVATION,
|
||||
|
||||
MOVEMENTFLAG_MASK_TURNING =
|
||||
MOVEMENTFLAG_LEFT | MOVEMENTFLAG_RIGHT,
|
||||
|
||||
MOVEMENTFLAG_MASK_MOVING_FLY =
|
||||
MOVEMENTFLAG_FLYING | MOVEMENTFLAG_ASCENDING | MOVEMENTFLAG_DESCENDING,
|
||||
|
||||
/// @todo if needed: add more flags to this masks that are exclusive to players
|
||||
MOVEMENTFLAG_MASK_PLAYER_ONLY =
|
||||
MOVEMENTFLAG_FLYING,
|
||||
|
||||
/// Movement flags that have change status opcodes associated for players
|
||||
MOVEMENTFLAG_MASK_HAS_PLAYER_STATUS_OPCODE = MOVEMENTFLAG_DISABLE_GRAVITY | MOVEMENTFLAG_ROOT |
|
||||
MOVEMENTFLAG_CAN_FLY | MOVEMENTFLAG_WATERWALKING | MOVEMENTFLAG_FALLING_SLOW | MOVEMENTFLAG_HOVER
|
||||
};
|
||||
|
||||
enum MovementFlags2
|
||||
{
|
||||
MOVEMENTFLAG2_NONE = 0x00000000,
|
||||
MOVEMENTFLAG2_NO_STRAFE = 0x00000001,
|
||||
MOVEMENTFLAG2_NO_JUMPING = 0x00000002,
|
||||
MOVEMENTFLAG2_UNK3 = 0x00000004, // Overrides various clientside checks
|
||||
MOVEMENTFLAG2_FULL_SPEED_TURNING = 0x00000008,
|
||||
MOVEMENTFLAG2_FULL_SPEED_PITCHING = 0x00000010,
|
||||
MOVEMENTFLAG2_ALWAYS_ALLOW_PITCHING = 0x00000020,
|
||||
MOVEMENTFLAG2_UNK7 = 0x00000040,
|
||||
MOVEMENTFLAG2_UNK8 = 0x00000080,
|
||||
MOVEMENTFLAG2_UNK9 = 0x00000100,
|
||||
MOVEMENTFLAG2_UNK10 = 0x00000200,
|
||||
MOVEMENTFLAG2_INTERPOLATED_MOVEMENT = 0x00000400,
|
||||
MOVEMENTFLAG2_INTERPOLATED_TURNING = 0x00000800,
|
||||
MOVEMENTFLAG2_INTERPOLATED_PITCHING = 0x00001000,
|
||||
MOVEMENTFLAG2_UNK14 = 0x00002000,
|
||||
MOVEMENTFLAG2_UNK15 = 0x00004000,
|
||||
MOVEMENTFLAG2_UNK16 = 0x00008000
|
||||
};
|
||||
|
||||
enum SplineFlags
|
||||
{
|
||||
SPLINEFLAG_NONE = 0x00000000,
|
||||
SPLINEFLAG_FORWARD = 0x00000001,
|
||||
SPLINEFLAG_BACKWARD = 0x00000002,
|
||||
SPLINEFLAG_STRAFE_LEFT = 0x00000004,
|
||||
SPLINEFLAG_STRAFE_RIGHT = 0x00000008,
|
||||
SPLINEFLAG_TURN_LEFT = 0x00000010,
|
||||
SPLINEFLAG_TURN_RIGHT = 0x00000020,
|
||||
SPLINEFLAG_PITCH_UP = 0x00000040,
|
||||
SPLINEFLAG_PITCH_DOWN = 0x00000080,
|
||||
SPLINEFLAG_DONE = 0x00000100,
|
||||
SPLINEFLAG_FALLING = 0x00000200,
|
||||
SPLINEFLAG_NO_SPLINE = 0x00000400,
|
||||
SPLINEFLAG_TRAJECTORY = 0x00000800,
|
||||
SPLINEFLAG_WALK_MODE = 0x00001000,
|
||||
SPLINEFLAG_FLYING = 0x00002000,
|
||||
SPLINEFLAG_KNOCKBACK = 0x00004000,
|
||||
SPLINEFLAG_FINAL_POINT = 0x00008000,
|
||||
SPLINEFLAG_FINAL_TARGET = 0x00010000,
|
||||
SPLINEFLAG_FINAL_FACING = 0x00020000,
|
||||
SPLINEFLAG_CATMULL_ROM = 0x00040000,
|
||||
SPLINEFLAG_CYCLIC = 0x00080000,
|
||||
SPLINEFLAG_ENTER_CYCLE = 0x00100000,
|
||||
SPLINEFLAG_ANIMATION_TIER = 0x00200000,
|
||||
SPLINEFLAG_FROZEN = 0x00400000,
|
||||
SPLINEFLAG_TRANSPORT = 0x00800000,
|
||||
SPLINEFLAG_TRANSPORT_EXIT = 0x01000000,
|
||||
SPLINEFLAG_UNKNOWN7 = 0x02000000,
|
||||
SPLINEFLAG_UNKNOWN8 = 0x04000000,
|
||||
SPLINEFLAG_ORIENTATION_INVERTED = 0x08000000,
|
||||
SPLINEFLAG_USE_PATH_SMOOTHING = 0x10000000,
|
||||
SPLINEFLAG_ANIMATION = 0x20000000,
|
||||
SPLINEFLAG_UNCOMPRESSED_PATH = 0x40000000,
|
||||
SPLINEFLAG_UNKNOWN10 = 0x80000000
|
||||
};
|
||||
|
||||
enum SplineType
|
||||
{
|
||||
SPLINETYPE_NORMAL = 0,
|
||||
SPLINETYPE_STOP = 1,
|
||||
SPLINETYPE_FACING_SPOT = 2,
|
||||
SPLINETYPE_FACING_TARGET = 3,
|
||||
SPLINETYPE_FACING_ANGLE = 4
|
||||
};
|
||||
117
src/server/game/Entities/Unit/UnitUtils.h
Normal file
117
src/server/game/Entities/Unit/UnitUtils.h
Normal file
@@ -0,0 +1,117 @@
|
||||
/*
|
||||
* This file is part of the AzerothCore Project. See AUTHORS file for Copyright information
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU Affero General Public License as published by the
|
||||
* Free Software Foundation; either version 3 of the License, or (at your
|
||||
* option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for
|
||||
* more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
class MMapTargetData
|
||||
{
|
||||
public:
|
||||
MMapTargetData() = default;
|
||||
MMapTargetData(uint32 endTime, const Position* o, const Position* t)
|
||||
{
|
||||
_endTime = endTime;
|
||||
_posOwner.Relocate(o);
|
||||
_posTarget.Relocate(t);
|
||||
}
|
||||
MMapTargetData(const MMapTargetData& c)
|
||||
{
|
||||
_endTime = c._endTime;
|
||||
_posOwner.Relocate(c._posOwner);
|
||||
_posTarget.Relocate(c._posTarget);
|
||||
}
|
||||
MMapTargetData(MMapTargetData&&) = default;
|
||||
MMapTargetData& operator=(const MMapTargetData&) = default;
|
||||
MMapTargetData& operator=(MMapTargetData&&) = default;
|
||||
[[nodiscard]] bool PosChanged(const Position& o, const Position& t) const
|
||||
{
|
||||
return _posOwner.GetExactDistSq(&o) > 0.5f * 0.5f || _posTarget.GetExactDistSq(&t) > 0.5f * 0.5f;
|
||||
}
|
||||
uint32 _endTime;
|
||||
Position _posOwner;
|
||||
Position _posTarget;
|
||||
};
|
||||
|
||||
class SafeUnitPointer
|
||||
{
|
||||
public:
|
||||
explicit SafeUnitPointer(Unit* defVal) : ptr(defVal), defaultValue(defVal) {}
|
||||
SafeUnitPointer(const SafeUnitPointer& /*p*/) { ABORT(); }
|
||||
void Initialize(Unit* defVal) { defaultValue = defVal; ptr = defVal; }
|
||||
~SafeUnitPointer();
|
||||
void SetPointedTo(Unit* u);
|
||||
void UnitDeleted();
|
||||
Unit* operator->() const { return ptr; }
|
||||
void operator=(Unit* u) { SetPointedTo(u); }
|
||||
operator Unit* () const { return ptr; }
|
||||
private:
|
||||
Unit* ptr;
|
||||
Unit* defaultValue;
|
||||
};
|
||||
|
||||
// BuildValuesCachePosPointers is marks of the position of some data inside of BuildValue cache.
|
||||
struct BuildValuesCachePosPointers
|
||||
{
|
||||
BuildValuesCachePosPointers() :
|
||||
UnitNPCFlagsPos(-1), UnitFieldAuraStatePos(-1), UnitFieldFlagsPos(-1), UnitFieldDisplayPos(-1),
|
||||
UnitDynamicFlagsPos(-1), UnitFieldBytes2Pos(-1), UnitFieldFactionTemplatePos(-1) {}
|
||||
|
||||
void ApplyOffset(uint32 offset)
|
||||
{
|
||||
if (UnitNPCFlagsPos >= 0)
|
||||
UnitNPCFlagsPos += offset;
|
||||
|
||||
if (UnitFieldAuraStatePos >= 0)
|
||||
UnitFieldAuraStatePos += offset;
|
||||
|
||||
if (UnitFieldFlagsPos >= 0)
|
||||
UnitFieldFlagsPos += offset;
|
||||
|
||||
if (UnitFieldDisplayPos >= 0)
|
||||
UnitFieldDisplayPos += offset;
|
||||
|
||||
if (UnitDynamicFlagsPos >= 0)
|
||||
UnitDynamicFlagsPos += offset;
|
||||
|
||||
if (UnitFieldBytes2Pos >= 0)
|
||||
UnitFieldBytes2Pos += offset;
|
||||
|
||||
if (UnitFieldFactionTemplatePos >= 0)
|
||||
UnitFieldFactionTemplatePos += offset;
|
||||
|
||||
for (auto it = other.begin(); it != other.end(); ++it)
|
||||
it->second += offset;
|
||||
}
|
||||
|
||||
int32 UnitNPCFlagsPos;
|
||||
int32 UnitFieldAuraStatePos;
|
||||
int32 UnitFieldFlagsPos;
|
||||
int32 UnitFieldDisplayPos;
|
||||
int32 UnitDynamicFlagsPos;
|
||||
int32 UnitFieldBytes2Pos;
|
||||
int32 UnitFieldFactionTemplatePos;
|
||||
|
||||
std::unordered_map<uint16 /*index*/, uint32 /*pos*/> other;
|
||||
};
|
||||
|
||||
// BuildValuesCachedBuffer cache for calculated BuildValue.
|
||||
struct BuildValuesCachedBuffer
|
||||
{
|
||||
BuildValuesCachedBuffer(uint32 bufferSize) :
|
||||
buffer(bufferSize), posPointers() {}
|
||||
|
||||
ByteBuffer buffer;
|
||||
|
||||
BuildValuesCachePosPointers posPointers;
|
||||
};
|
||||
@@ -96,4 +96,15 @@ private:
|
||||
Status _status;
|
||||
};
|
||||
|
||||
class VehicleDespawnEvent : public BasicEvent
|
||||
{
|
||||
public:
|
||||
VehicleDespawnEvent(Unit& self, uint32 duration) : _self(self), _duration(duration) { }
|
||||
bool Execute(uint64 e_time, uint32 p_time) override;
|
||||
|
||||
protected:
|
||||
Unit& _self;
|
||||
uint32 _duration;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
*/
|
||||
|
||||
#include "Common.h"
|
||||
#include "CharmInfo.h"
|
||||
#include "CreatureAI.h"
|
||||
#include "DisableMgr.h"
|
||||
#include "GameTime.h"
|
||||
|
||||
@@ -19,6 +19,7 @@
|
||||
#include "BattlefieldMgr.h"
|
||||
#include "Battleground.h"
|
||||
#include "CellImpl.h"
|
||||
#include "CharmInfo.h"
|
||||
#include "Common.h"
|
||||
#include "GameTime.h"
|
||||
#include "GridNotifiers.h"
|
||||
|
||||
Reference in New Issue
Block a user