Core/Units: moved CharmInfo class to an own file
This commit is contained in:
1 parent
254ebe6cbf
commit
bb6a8ac297
19 files changed
+458
-392
No files matched your search
@@ -17,6 +17,7 @@
|
||||
|
||||
#include "PetAI.h"
|
||||
#include "AIException.h"
|
||||
#include "CharmInfo.h"
|
||||
#include "Creature.h"
|
||||
#include "Errors.h"
|
||||
#include "Group.h"
|
||||
|
||||
@@ -18,6 +18,7 @@
|
||||
#include "Creature.h"
|
||||
#include "BattlegroundMgr.h"
|
||||
#include "CellImpl.h"
|
||||
#include "CharmInfo.h"
|
||||
#include "Common.h"
|
||||
#include "Containers.h"
|
||||
#include "CreatureAI.h"
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
*/
|
||||
|
||||
#include "TemporarySummon.h"
|
||||
#include "CharmInfo.h"
|
||||
#include "CreatureAI.h"
|
||||
#include "DBCStructure.h"
|
||||
#include "Log.h"
|
||||
|
||||
@@ -15,6 +15,7 @@
|
||||
* with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "CharmInfo.h"
|
||||
#include "Common.h"
|
||||
#include "DatabaseEnv.h"
|
||||
#include "Log.h"
|
||||
|
||||
@@ -33,6 +33,7 @@
|
||||
#include "CharacterCache.h"
|
||||
#include "CharacterDatabaseCleaner.h"
|
||||
#include "CharacterPackets.h"
|
||||
#include "CharmInfo.h"
|
||||
#include "Chat.h"
|
||||
#include "CinematicMgr.h"
|
||||
#include "CombatPackets.h"
|
||||
|
||||
@@ -0,0 +1,283 @@
|
||||
/*
|
||||
* This file is part of the TrinityCore 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 General Public License as published by the
|
||||
* Free Software Foundation; either version 2 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 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 "SpellInfo.h"
|
||||
#include "SpellMgr.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),
|
||||
_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 (Creature* creature = _unit->ToCreature())
|
||||
{
|
||||
_oldReactState = creature->GetReactState();
|
||||
creature->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 moveTo
|
||||
SetActionBar(ACTION_BAR_INDEX_ATTACK, COMMAND_ATTACK, ACT_COMMAND);
|
||||
SetActionBar(ACTION_BAR_INDEX_FOLLOW, COMMAND_FOLLOW, ACT_COMMAND);
|
||||
SetActionBar(ACTION_BAR_INDEX_MOVE_TO, COMMAND_MOVE_TO, 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
|
||||
SetActionBar(ACTION_BAR_INDEX_ASSIST, REACT_ASSIST, ACT_REACTION);
|
||||
SetActionBar(ACTION_BAR_INDEX_DEFENSIVE, REACT_DEFENSIVE, ACT_REACTION);
|
||||
SetActionBar(ACTION_BAR_INDEX_PASSIVE, REACT_PASSIVE, 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 28511: // Eye of Acherus
|
||||
break;
|
||||
default:
|
||||
InitEmptyActionBar();
|
||||
break;
|
||||
}
|
||||
|
||||
for (uint8 i = 0; i < MAX_CREATURE_SPELLS; ++i)
|
||||
{
|
||||
uint32 spellId = _unit->ToCreature()->m_spells[i];
|
||||
SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(spellId);
|
||||
if (spellInfo)
|
||||
{
|
||||
if (spellInfo->HasAttribute(SPELL_ATTR5_NOT_AVAILABLE_WHILE_CHARMED))
|
||||
continue;
|
||||
|
||||
if (spellInfo->IsPassive())
|
||||
_unit->CastSpell(_unit, spellInfo->Id, true);
|
||||
else
|
||||
AddSpellToActionBar(spellInfo, ACT_PASSIVE, i % MAX_UNIT_ACTION_BAR_INDEX);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
InitEmptyActionBar();
|
||||
}
|
||||
|
||||
void CharmInfo::InitCharmCreateSpells()
|
||||
{
|
||||
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->HasAttribute(SPELL_ATTR5_NOT_AVAILABLE_WHILE_CHARMED))
|
||||
continue;
|
||||
|
||||
if (spellInfo->IsPassive())
|
||||
{
|
||||
_unit->CastSpell(_unit, spellInfo->Id, 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, uint8 preferredSlot)
|
||||
{
|
||||
uint32 spell_id = spellInfo->Id;
|
||||
uint32 first_id = spellInfo->GetFirstRankSpell()->Id;
|
||||
|
||||
ASSERT(preferredSlot < MAX_UNIT_ACTION_BAR_INDEX);
|
||||
// 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)
|
||||
{
|
||||
uint8 j = (preferredSlot + i) % MAX_UNIT_ACTION_BAR_INDEX;
|
||||
if (!PetActionBar[j].GetAction() && PetActionBar[j].IsActionBarForSpell())
|
||||
{
|
||||
SetActionBar(j, spell_id, newstate == ACT_DECIDE ? spellInfo->IsAutocastable() ? ACT_ENABLED : ACT_PASSIVE : newstate);
|
||||
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)
|
||||
{
|
||||
InitPetActionBar();
|
||||
|
||||
Tokenizer tokens(data, ' ');
|
||||
|
||||
if (tokens.size() != (ACTION_BAR_INDEX_END-ACTION_BAR_INDEX_START) * 2)
|
||||
return; // non critical, will reset to default
|
||||
|
||||
uint8 index = ACTION_BAR_INDEX_START;
|
||||
Tokenizer::const_iterator iter = tokens.begin();
|
||||
for (; index < ACTION_BAR_INDEX_END; ++iter, ++index)
|
||||
{
|
||||
// use unsigned cast to avoid sign negative format use at long-> ActiveStates (int) conversion
|
||||
ActiveStates type = ActiveStates(atol(*iter));
|
||||
++iter;
|
||||
uint32 action = atoul(*iter);
|
||||
|
||||
PetActionBar[index].SetActionAndType(action, type);
|
||||
|
||||
// check correctness
|
||||
if (PetActionBar[index].IsActionBarForSpell())
|
||||
{
|
||||
SpellInfo const* spelInfo = sSpellMgr->GetSpellInfo(PetActionBar[index].GetAction());
|
||||
if (!spelInfo)
|
||||
SetActionBar(index, 0, ACT_PASSIVE);
|
||||
else if (!spelInfo->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;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,157 @@
|
||||
/*
|
||||
* This file is part of the TrinityCore 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 General Public License as published by the
|
||||
* Free Software Foundation; either version 2 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 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 "Define.h"
|
||||
#include "UnitDefines.h"
|
||||
|
||||
class SpellInfo;
|
||||
class Unit;
|
||||
class WorldPacket;
|
||||
|
||||
#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
|
||||
ActiveStates GetType() const { return ActiveStates(UNIT_ACTION_BUTTON_TYPE(packedData)); }
|
||||
uint32 GetAction() const { return UNIT_ACTION_BUTTON_ACTION(packedData); }
|
||||
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);
|
||||
}
|
||||
};
|
||||
|
||||
enum CharmType : uint8
|
||||
{
|
||||
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_ATTACK = ACTION_BAR_INDEX_START,
|
||||
ACTION_BAR_INDEX_FOLLOW = 1,
|
||||
ACTION_BAR_INDEX_MOVE_TO = 2,
|
||||
ACTION_BAR_INDEX_PET_SPELL_START = 3,
|
||||
ACTION_BAR_INDEX_PET_SPELL_END = 7,
|
||||
ACTION_BAR_INDEX_ASSIST = ACTION_BAR_INDEX_PET_SPELL_END,
|
||||
ACTION_BAR_INDEX_DEFENSIVE = 8,
|
||||
ACTION_BAR_INDEX_PASSIVE = 9,
|
||||
ACTION_BAR_INDEX_END = 10
|
||||
};
|
||||
|
||||
#define MAX_UNIT_ACTION_BAR_INDEX (ACTION_BAR_INDEX_END-ACTION_BAR_INDEX_START)
|
||||
|
||||
struct TC_GAME_API CharmInfo
|
||||
{
|
||||
public:
|
||||
explicit CharmInfo(Unit* unit);
|
||||
~CharmInfo();
|
||||
void RestoreState();
|
||||
uint32 GetPetNumber() const { return _petnumber; }
|
||||
void SetPetNumber(uint32 petnumber, bool statwindow);
|
||||
|
||||
void SetCommandState(CommandStates st) { _CommandState = st; }
|
||||
CommandStates GetCommandState() const { return _CommandState; }
|
||||
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, uint8 preferredSlot = 0);
|
||||
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);
|
||||
}
|
||||
UnitActionBarEntry const* GetActionBarEntry(uint8 index) const { return &(PetActionBar[index]); }
|
||||
|
||||
void ToggleCreatureAutocast(SpellInfo const* spellInfo, bool apply);
|
||||
|
||||
CharmSpellInfo* GetCharmSpell(uint8 index) { return &(_charmspells[index]); }
|
||||
|
||||
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();
|
||||
void GetStayPosition(float &x, float &y, float &z);
|
||||
|
||||
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;
|
||||
float _stayX;
|
||||
float _stayY;
|
||||
float _stayZ;
|
||||
};
|
||||
|
||||
#endif // _CharmInfo_h__
|
||||
@@ -24,6 +24,7 @@
|
||||
#include "BattlegroundScore.h"
|
||||
#include "CellImpl.h"
|
||||
#include "CharacterCache.h"
|
||||
#include "CharmInfo.h"
|
||||
#include "Chat.h"
|
||||
#include "ChatTextBuilder.h"
|
||||
#include "ChatPackets.h"
|
||||
@@ -9705,268 +9706,6 @@ void Unit::DeleteCharmInfo()
|
||||
m_charmInfo.reset();
|
||||
}
|
||||
|
||||
CharmInfo::CharmInfo(Unit* unit)
|
||||
: _unit(unit), _CommandState(COMMAND_FOLLOW), _petnumber(0), _oldReactState(REACT_PASSIVE),
|
||||
_isCommandAttack(false), _isCommandFollow(false), _isAtStay(false), _isFollowing(false), _isReturning(false),
|
||||
_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 (Creature* creature = _unit->ToCreature())
|
||||
{
|
||||
_oldReactState = creature->GetReactState();
|
||||
creature->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 moveTo
|
||||
SetActionBar(ACTION_BAR_INDEX_ATTACK, COMMAND_ATTACK, ACT_COMMAND);
|
||||
SetActionBar(ACTION_BAR_INDEX_FOLLOW, COMMAND_FOLLOW, ACT_COMMAND);
|
||||
SetActionBar(ACTION_BAR_INDEX_MOVE_TO, COMMAND_MOVE_TO, 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
|
||||
SetActionBar(ACTION_BAR_INDEX_ASSIST, REACT_ASSIST, ACT_REACTION);
|
||||
SetActionBar(ACTION_BAR_INDEX_DEFENSIVE, REACT_DEFENSIVE, ACT_REACTION);
|
||||
SetActionBar(ACTION_BAR_INDEX_PASSIVE, REACT_PASSIVE, 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 28511: // Eye of Acherus
|
||||
break;
|
||||
default:
|
||||
InitEmptyActionBar();
|
||||
break;
|
||||
}
|
||||
|
||||
for (uint8 i = 0; i < MAX_CREATURE_SPELLS; ++i)
|
||||
{
|
||||
uint32 spellId = _unit->ToCreature()->m_spells[i];
|
||||
SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(spellId);
|
||||
if (spellInfo)
|
||||
{
|
||||
if (spellInfo->HasAttribute(SPELL_ATTR5_NOT_AVAILABLE_WHILE_CHARMED))
|
||||
continue;
|
||||
|
||||
if (spellInfo->IsPassive())
|
||||
_unit->CastSpell(_unit, spellInfo->Id, true);
|
||||
else
|
||||
AddSpellToActionBar(spellInfo, ACT_PASSIVE, i % MAX_UNIT_ACTION_BAR_INDEX);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
InitEmptyActionBar();
|
||||
}
|
||||
|
||||
void CharmInfo::InitCharmCreateSpells()
|
||||
{
|
||||
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->HasAttribute(SPELL_ATTR5_NOT_AVAILABLE_WHILE_CHARMED))
|
||||
continue;
|
||||
|
||||
if (spellInfo->IsPassive())
|
||||
{
|
||||
_unit->CastSpell(_unit, spellInfo->Id, 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, uint8 preferredSlot)
|
||||
{
|
||||
uint32 spell_id = spellInfo->Id;
|
||||
uint32 first_id = spellInfo->GetFirstRankSpell()->Id;
|
||||
|
||||
ASSERT(preferredSlot < MAX_UNIT_ACTION_BAR_INDEX);
|
||||
// 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)
|
||||
{
|
||||
uint8 j = (preferredSlot + i) % MAX_UNIT_ACTION_BAR_INDEX;
|
||||
if (!PetActionBar[j].GetAction() && PetActionBar[j].IsActionBarForSpell())
|
||||
{
|
||||
SetActionBar(j, spell_id, newstate == ACT_DECIDE ? spellInfo->IsAutocastable() ? ACT_ENABLED : ACT_PASSIVE : newstate);
|
||||
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)
|
||||
{
|
||||
InitPetActionBar();
|
||||
|
||||
Tokenizer tokens(data, ' ');
|
||||
|
||||
if (tokens.size() != (ACTION_BAR_INDEX_END-ACTION_BAR_INDEX_START) * 2)
|
||||
return; // non critical, will reset to default
|
||||
|
||||
uint8 index = ACTION_BAR_INDEX_START;
|
||||
Tokenizer::const_iterator iter = tokens.begin();
|
||||
for (; index < ACTION_BAR_INDEX_END; ++iter, ++index)
|
||||
{
|
||||
// use unsigned cast to avoid sign negative format use at long-> ActiveStates (int) conversion
|
||||
ActiveStates type = ActiveStates(atol(*iter));
|
||||
++iter;
|
||||
uint32 action = atoul(*iter);
|
||||
|
||||
PetActionBar[index].SetActionAndType(action, type);
|
||||
|
||||
// check correctness
|
||||
if (PetActionBar[index].IsActionBarForSpell())
|
||||
{
|
||||
SpellInfo const* spelInfo = sSpellMgr->GetSpellInfo(PetActionBar[index].GetAction());
|
||||
if (!spelInfo)
|
||||
SetActionBar(index, 0, ACT_PASSIVE);
|
||||
else if (!spelInfo->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);
|
||||
|
||||
@@ -73,6 +73,7 @@ struct SpellValue;
|
||||
class Aura;
|
||||
class AuraApplication;
|
||||
class AuraEffect;
|
||||
class CharmInfo;
|
||||
class Creature;
|
||||
class DynamicObject;
|
||||
class GameClient;
|
||||
@@ -95,6 +96,7 @@ class Vehicle;
|
||||
class VehicleJoinEvent;
|
||||
|
||||
enum ZLiquidStatus : uint32;
|
||||
enum CharmType : uint8;
|
||||
|
||||
namespace Movement
|
||||
{
|
||||
@@ -598,137 +600,8 @@ enum CurrentSpellTypes : uint8
|
||||
#define CURRENT_FIRST_NON_MELEE_SPELL 1
|
||||
#define CURRENT_MAX_SPELL 4
|
||||
|
||||
#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
|
||||
ActiveStates GetType() const { return ActiveStates(UNIT_ACTION_BUTTON_TYPE(packedData)); }
|
||||
uint32 GetAction() const { return UNIT_ACTION_BUTTON_ACTION(packedData); }
|
||||
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_ATTACK = ACTION_BAR_INDEX_START,
|
||||
ACTION_BAR_INDEX_FOLLOW = 1,
|
||||
ACTION_BAR_INDEX_MOVE_TO = 2,
|
||||
ACTION_BAR_INDEX_PET_SPELL_START = 3,
|
||||
ACTION_BAR_INDEX_PET_SPELL_END = 7,
|
||||
ACTION_BAR_INDEX_ASSIST = ACTION_BAR_INDEX_PET_SPELL_END,
|
||||
ACTION_BAR_INDEX_DEFENSIVE = 8,
|
||||
ACTION_BAR_INDEX_PASSIVE = 9,
|
||||
ACTION_BAR_INDEX_END = 10
|
||||
};
|
||||
|
||||
#define MAX_UNIT_ACTION_BAR_INDEX (ACTION_BAR_INDEX_END-ACTION_BAR_INDEX_START)
|
||||
|
||||
struct TC_GAME_API CharmInfo
|
||||
{
|
||||
public:
|
||||
explicit CharmInfo(Unit* unit);
|
||||
~CharmInfo();
|
||||
void RestoreState();
|
||||
uint32 GetPetNumber() const { return _petnumber; }
|
||||
void SetPetNumber(uint32 petnumber, bool statwindow);
|
||||
|
||||
void SetCommandState(CommandStates st) { _CommandState = st; }
|
||||
CommandStates GetCommandState() const { return _CommandState; }
|
||||
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, uint8 preferredSlot = 0);
|
||||
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);
|
||||
}
|
||||
UnitActionBarEntry const* GetActionBarEntry(uint8 index) const { return &(PetActionBar[index]); }
|
||||
|
||||
void ToggleCreatureAutocast(SpellInfo const* spellInfo, bool apply);
|
||||
|
||||
CharmSpellInfo* GetCharmSpell(uint8 index) { return &(_charmspells[index]); }
|
||||
|
||||
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();
|
||||
void GetStayPosition(float &x, float &y, float &z);
|
||||
|
||||
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;
|
||||
float _stayX;
|
||||
float _stayY;
|
||||
float _stayZ;
|
||||
};
|
||||
|
||||
// for clearing special attacks
|
||||
#define REACTIVE_TIMER_START 4000
|
||||
|
||||
|
||||
@@ -388,7 +388,7 @@ struct DeclinedName
|
||||
std::string name[MAX_DECLINED_NAME_CASES];
|
||||
};
|
||||
|
||||
enum ActiveStates
|
||||
enum ActiveStates : uint8
|
||||
{
|
||||
ACT_PASSIVE = 0x01, // 0x01 - passive
|
||||
ACT_DISABLED = 0x81, // 0x80 - castable
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
|
||||
#include "Vehicle.h"
|
||||
#include "Battleground.h"
|
||||
#include "CharmInfo.h"
|
||||
#include "Common.h"
|
||||
#include "CreatureAI.h"
|
||||
#include "DBCStores.h"
|
||||
|
||||
@@ -18,6 +18,7 @@
|
||||
#include "WorldSession.h"
|
||||
#include "Battleground.h"
|
||||
#include "BattlegroundMgr.h"
|
||||
#include "CharmInfo.h"
|
||||
#include "Common.h"
|
||||
#include "Creature.h"
|
||||
#include "CreatureAI.h"
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
*/
|
||||
|
||||
#include "WorldSession.h"
|
||||
#include "CharmInfo.h"
|
||||
#include "Common.h"
|
||||
#include "CreatureAI.h"
|
||||
#include "DatabaseEnv.h"
|
||||
|
||||
@@ -20,6 +20,7 @@
|
||||
#include "BattlefieldMgr.h"
|
||||
#include "Battleground.h"
|
||||
#include "CellImpl.h"
|
||||
#include "CharmInfo.h"
|
||||
#include "Common.h"
|
||||
#include "DBCStores.h"
|
||||
#include "GridNotifiersImpl.h"
|
||||
|
||||
@@ -20,6 +20,7 @@
|
||||
#include "AreaTrigger.h"
|
||||
#include "Battleground.h"
|
||||
#include "CellImpl.h"
|
||||
#include "CharmInfo.h"
|
||||
#include "Common.h"
|
||||
#include "Creature.h"
|
||||
#include "CreatureAI.h"
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
*/
|
||||
|
||||
#include "SpellHistory.h"
|
||||
#include "CharmInfo.h"
|
||||
#include "DatabaseEnv.h"
|
||||
#include "DBCStores.h"
|
||||
#include "Item.h"
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
*/
|
||||
|
||||
#include "ScriptMgr.h"
|
||||
#include "CharmInfo.h"
|
||||
#include "Chat.h"
|
||||
#include "Language.h"
|
||||
#include "Log.h"
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
*/
|
||||
|
||||
#include "ScriptMgr.h"
|
||||
#include "CharmInfo.h"
|
||||
#include "CombatAI.h"
|
||||
#include "CreatureAIImpl.h"
|
||||
#include "GameObject.h"
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
|
||||
#include "ScriptMgr.h"
|
||||
#include "CellImpl.h"
|
||||
#include "CharmInfo.h"
|
||||
#include "CombatAI.h"
|
||||
#include "Containers.h"
|
||||
#include "CreatureTextMgr.h"
|
||||
|
||||
Reference in new issue
Block a user