*Backup your DB!

[8098] Support uint32 spell ids in code. Author: VladimirMangos

    * Propertly work with uint32 spell ids in player action bar
    * Fix in same time bug with not save equipment set button with id==0
    * Merge misc field in character_action and playercreateinfo_action to action field as 3 byte
    * Propertly load uint32 spell ids from character_spell
    * Fixed types for some pet/creature related structure for spell id storing.

--HG--
branch : trunk
This commit is contained in:
megamage
2009-07-01 18:07:20 -05:00
parent 8122a15f46
commit e1d93bd00f
16 changed files with 635 additions and 571 deletions
+1 -1
View File
@@ -73,7 +73,7 @@ bool LoginQueryHolder::Initialize()
res &= SetPQuery(PLAYER_LOGIN_QUERY_LOADDAILYQUESTSTATUS,"SELECT quest,time FROM character_queststatus_daily WHERE guid = '%u'", GUID_LOPART(m_guid));
res &= SetPQuery(PLAYER_LOGIN_QUERY_LOADREPUTATION, "SELECT faction,standing,flags FROM character_reputation WHERE guid = '%u'", GUID_LOPART(m_guid));
res &= SetPQuery(PLAYER_LOGIN_QUERY_LOADINVENTORY, "SELECT data,bag,slot,item,item_template FROM character_inventory JOIN item_instance ON character_inventory.item = item_instance.guid WHERE character_inventory.guid = '%u' ORDER BY bag,slot", GUID_LOPART(m_guid));
res &= SetPQuery(PLAYER_LOGIN_QUERY_LOADACTIONS, "SELECT button,action,type,misc FROM character_action WHERE guid = '%u' ORDER BY button", GUID_LOPART(m_guid));
res &= SetPQuery(PLAYER_LOGIN_QUERY_LOADACTIONS, "SELECT button,action,type FROM character_action WHERE guid = '%u' ORDER BY button", GUID_LOPART(m_guid));
res &= SetPQuery(PLAYER_LOGIN_QUERY_LOADMAILCOUNT, "SELECT COUNT(id) FROM mail WHERE receiver = '%u' AND (checked & 1)=0 AND deliver_time <= '" UI64FMTD "'", GUID_LOPART(m_guid),(uint64)time(NULL));
res &= SetPQuery(PLAYER_LOGIN_QUERY_LOADMAILDATE, "SELECT MIN(deliver_time) FROM mail WHERE receiver = '%u' AND (checked & 1)=0", GUID_LOPART(m_guid));
res &= SetPQuery(PLAYER_LOGIN_QUERY_LOADSOCIALLIST, "SELECT friend,flags,note FROM character_social WHERE guid = '%u' LIMIT 255", GUID_LOPART(m_guid));
+3 -3
View File
@@ -319,7 +319,7 @@ struct CreatureData
struct CreatureDataAddonAura
{
uint16 spell_id;
uint32 spell_id;
uint8 effect_idx;
};
@@ -702,10 +702,10 @@ class TRINITY_DLL_SPEC Creature : public Unit
virtual uint8 GetPetAutoSpellSize() const { return CREATURE_MAX_SPELLS; }
virtual uint32 GetPetAutoSpellOnPos(uint8 pos) const
{
if (pos >= CREATURE_MAX_SPELLS || m_charmInfo->GetCharmSpell(pos)->active != ACT_ENABLED)
if (pos >= CREATURE_MAX_SPELLS || m_charmInfo->GetCharmSpell(pos)->GetType() != ACT_ENABLED)
return 0;
else
return m_charmInfo->GetCharmSpell(pos)->spellId;
return m_charmInfo->GetCharmSpell(pos)->GetAction();
}
void SetHomePosition(float x, float y, float z, float ori) { mHome_X = x; mHome_Y = y; mHome_Z = z; mHome_O = ori;}
+27 -26
View File
@@ -1040,40 +1040,41 @@ void WorldSession::HandleSetActionButtonOpcode(WorldPacket& recv_data)
CHECK_PACKET_SIZE(recv_data,1+2+1+1);
sLog.outDebug( "WORLD: Received CMSG_SET_ACTION_BUTTON" );
uint8 button, misc, type;
uint16 action;
recv_data >> button >> action >> misc >> type;
sLog.outDetail( "BUTTON: %u ACTION: %u TYPE: %u MISC: %u", button, action, type, misc );
if(action==0)
uint8 button;
uint32 packetData;
recv_data >> button >> packetData;
uint32 action = ACTION_BUTTON_ACTION(packetData);
uint8 type = ACTION_BUTTON_TYPE(packetData);
sLog.outDetail( "BUTTON: %u ACTION: %u TYPE: %u", button, action, type );
if (!packetData)
{
sLog.outDetail( "MISC: Remove action from button %u", button );
GetPlayer()->removeActionButton(button);
}
else
{
if(type==ACTION_BUTTON_MACRO || type==ACTION_BUTTON_CMACRO)
switch(type)
{
sLog.outDetail( "MISC: Added Macro %u into button %u", action, button );
GetPlayer()->addActionButton(button,action,type,misc);
case ACTION_BUTTON_MACRO:
case ACTION_BUTTON_CMACRO:
sLog.outDetail( "MISC: Added Macro %u into button %u", action, button );
break;
case ACTION_BUTTON_EQSET:
sLog.outDetail( "MISC: Added EquipmentSet %u into button %u", action, button );
break;
case ACTION_BUTTON_SPELL:
sLog.outDetail( "MISC: Added Spell %u into button %u", action, button );
break;
case ACTION_BUTTON_ITEM:
sLog.outDetail( "MISC: Added Item %u into button %u", action, button );
break;
default:
sLog.outError( "MISC: Unknown action button type %u for action %u into button %u", type, action, button );
return;
}
else if(type==ACTION_BUTTON_EQSET)
{
sLog.outDetail( "MISC: Added EquipmentSet %u into button %u", action, button );
GetPlayer()->addActionButton(button,action,type,misc);
}
else if(type==ACTION_BUTTON_SPELL)
{
sLog.outDetail( "MISC: Added Spell %u into button %u", action, button );
GetPlayer()->addActionButton(button,action,type,misc);
}
else if(type==ACTION_BUTTON_ITEM)
{
sLog.outDetail( "MISC: Added Item %u into button %u", action, button );
GetPlayer()->addActionButton(button,action,type,misc);
}
else
sLog.outError( "MISC: Unknown action button type %u for action %u into button %u", type, action, button );
GetPlayer()->addActionButton(button,action,type);
}
}
+3 -6
View File
@@ -2712,8 +2712,8 @@ void ObjectMgr::LoadPlayerInfo()
// Load playercreate actions
{
// 0 1 2 3 4 5
QueryResult *result = WorldDatabase.Query("SELECT race, class, button, action, type, misc FROM playercreateinfo_action");
// 0 1 2 3 4
QueryResult *result = WorldDatabase.Query("SELECT race, class, button, action, type FROM playercreateinfo_action");
uint32 count = 0;
@@ -2748,10 +2748,7 @@ void ObjectMgr::LoadPlayerInfo()
}
PlayerInfo* pInfo = &playerInfo[current_race][current_class];
pInfo->action[0].push_back(fields[2].GetUInt16());
pInfo->action[1].push_back(fields[3].GetUInt16());
pInfo->action[2].push_back(fields[4].GetUInt16());
pInfo->action[3].push_back(fields[5].GetUInt16());
pInfo->action.push_back(PlayerCreateInfoAction(fields[2].GetUInt8(),fields[3].GetUInt32(),fields[4].GetUInt8()));
bar.step();
++count;
+12 -12
View File
@@ -412,8 +412,8 @@ void Pet::SavePetToDB(PetSaveMode mode)
// save only spell slots from action bar
for(uint32 i = ACTION_BAR_INDEX_PET_SPELL_START; i < ACTION_BAR_INDEX_PET_SPELL_END; ++i)
{
ss << uint32(m_charmInfo->GetActionBarEntry(i)->Type) << " "
<< uint32(m_charmInfo->GetActionBarEntry(i)->SpellOrAction) << " ";
ss << uint32(m_charmInfo->GetActionBarEntry(i)->GetType()) << " "
<< uint32(m_charmInfo->GetActionBarEntry(i)->GetAction()) << " ";
};
ss << "', "
@@ -1064,7 +1064,7 @@ void Pet::_LoadSpells()
{
Field *fields = result->Fetch();
addSpell(fields[0].GetUInt32(), ActiveStates(fields[1].GetUInt16()), PETSPELL_UNCHANGED);
addSpell(fields[0].GetUInt32(), ActiveStates(fields[1].GetUInt8()), PETSPELL_UNCHANGED);
}
while( result->NextRow() );
@@ -1329,8 +1329,8 @@ bool Pet::learnSpell(uint32 spell_id)
if(!m_loading)
{
WorldPacket data(SMSG_PET_LEARNED_SPELL, 2);
data << uint16(spell_id);
WorldPacket data(SMSG_PET_LEARNED_SPELL, 4);
data << uint32(spell_id);
m_owner->GetSession()->SendPacket(&data);
m_owner->PetSpellInitialize();
}
@@ -1382,8 +1382,8 @@ bool Pet::unlearnSpell(uint32 spell_id, bool learn_prev, bool clear_ab)
{
if(!m_loading)
{
WorldPacket data(SMSG_PET_REMOVED_SPELL, 2);
data << uint16(spell_id);
WorldPacket data(SMSG_PET_REMOVED_SPELL, 4);
data << uint32(spell_id);
m_owner->GetSession()->SendPacket(&data);
}
return true;
@@ -1447,12 +1447,12 @@ void Pet::CleanupActionBar()
{
for(uint8 i = 0; i < MAX_UNIT_ACTION_BAR_INDEX; ++i)
if(UnitActionBarEntry const* ab = m_charmInfo->GetActionBarEntry(i))
if(ab->SpellOrAction && ab->IsActionBarForSpell())
if(ab->GetAction() && ab->IsActionBarForSpell())
{
if(!HasSpell(ab->SpellOrAction))
if(!HasSpell(ab->GetAction()))
m_charmInfo->SetActionBar(i, 0, ACT_PASSIVE);
else if(ab->Type == ACT_ENABLED)
ToggleAutocast(ab->SpellOrAction, true);
else if(ab->GetType() == ACT_ENABLED)
ToggleAutocast(ab->GetAction(), true);
}
}
@@ -1832,7 +1832,7 @@ void Pet::CastPetAuras(bool current)
void Pet::CastPetAura(PetAura const* aura)
{
uint16 auraId = aura->GetAura(GetEntry());
uint32 auraId = aura->GetAura(GetEntry());
if(!auraId)
return;
+25 -23
View File
@@ -37,17 +37,18 @@ void WorldSession::HandlePetAction( WorldPacket & recv_data )
CHECK_PACKET_SIZE(recv_data, 8+2+2+8);
uint64 guid1;
uint16 spellid;
uint16 flag;
uint32 data;
uint64 guid2;
recv_data >> guid1; //pet guid
recv_data >> spellid;
recv_data >> flag; //delete = 0x0700 CastSpell = C100
recv_data >> data;
recv_data >> guid2; //tag guid
uint32 spellid = UNIT_ACTION_BUTTON_ACTION(data);
uint8 flag = UNIT_ACTION_BUTTON_TYPE(data); //delete = 0x07 CastSpell = C1
// used also for charmed creature
Unit* pet= ObjectAccessor::GetUnit(*_player, guid1);
sLog.outDetail("HandlePetAction.Pet %u flag is %u, spellid is %u, target %u.", uint32(GUID_LOPART(guid1)), flag, spellid, uint32(GUID_LOPART(guid2)) );
sLog.outDetail("HandlePetAction.Pet %u flag is %u, spellid is %u, target %u.", uint32(GUID_LOPART(guid1)), uint32(flag), spellid, uint32(GUID_LOPART(guid2)) );
if(!pet)
{
sLog.outError( "Pet %u not exist.", uint32(GUID_LOPART(guid1)) );
@@ -89,7 +90,7 @@ void WorldSession::HandlePetActionHelper(Unit *pet, uint64 guid1, uint16 spellid
switch(flag)
{
case ACT_COMMAND: //0x0700
case ACT_COMMAND: //0x07
switch(spellid)
{
case COMMAND_STAY: //flat=1792 //STAY
@@ -151,7 +152,7 @@ void WorldSession::HandlePetActionHelper(Unit *pet, uint64 guid1, uint16 spellid
pet->SendPetAIReaction(guid1);
}
}
else // charmed player
else // charmed player
{
if(pet->getVictim() && pet->getVictim() != TargetUnit)
pet->AttackStop();
@@ -183,10 +184,10 @@ void WorldSession::HandlePetActionHelper(Unit *pet, uint64 guid1, uint16 spellid
}
break;
default:
sLog.outError("WORLD: unknown PET flag Action %i and spellid %i.", flag, spellid);
sLog.outError("WORLD: unknown PET flag Action %i and spellid %i.", uint32(flag), spellid);
}
break;
case ACT_REACTION: // 0x600
case ACT_REACTION: // 0x6
switch(spellid)
{
case REACT_PASSIVE: //passive
@@ -197,9 +198,9 @@ void WorldSession::HandlePetActionHelper(Unit *pet, uint64 guid1, uint16 spellid
break;
}
break;
case ACT_DISABLED: // 0x8100 spell (disabled), ignore
case ACT_PASSIVE: // 0x0100
case ACT_ENABLED: // 0xC100 spell
case ACT_DISABLED: // 0x81 spell (disabled), ignore
case ACT_PASSIVE: // 0x01
case ACT_ENABLED: // 0xC1 spell
{
Unit* unit_target = NULL;
if (((Creature*)pet)->GetGlobalCooldown() > 0)
@@ -299,7 +300,7 @@ void WorldSession::HandlePetActionHelper(Unit *pet, uint64 guid1, uint16 spellid
break;
}
default:
sLog.outError("WORLD: unknown PET flag Action %i and spellid %i.", flag, spellid);
sLog.outError("WORLD: unknown PET flag Action %i and spellid %i.", uint32(flag), spellid);
}
}
@@ -350,9 +351,6 @@ void WorldSession::HandlePetSetAction( WorldPacket & recv_data )
sLog.outDetail( "HandlePetSetAction. CMSG_PET_SET_ACTION" );
uint64 petguid;
uint32 position;
uint16 spell_id;
uint16 act_state;
uint8 count;
recv_data >> petguid;
@@ -375,11 +373,16 @@ void WorldSession::HandlePetSetAction( WorldPacket & recv_data )
count = (recv_data.size() == 24) ? 2 : 1;
for(uint8 i = 0; i < count; ++i)
{
recv_data >> position;
recv_data >> spell_id;
recv_data >> act_state;
uint32 position;
uint32 data;
sLog.outDetail( "Player %s has changed pet spell action. Position: %u, Spell: %u, State: 0x%X", _player->GetName(), position, spell_id, act_state);
recv_data >> position;
recv_data >> data;
uint32 spell_id = UNIT_ACTION_BUTTON_ACTION(data);
uint8 act_state = UNIT_ACTION_BUTTON_TYPE(data);
sLog.outDetail( "Player %s has changed pet spell action. Position: %u, Spell: %u, State: 0x%X", _player->GetName(), position, spell_id, uint32(act_state));
//ignore invalid position
if(position >= MAX_UNIT_ACTION_BAR_INDEX)
@@ -551,10 +554,9 @@ void WorldSession::HandlePetSpellAutocastOpcode( WorldPacket& recvPacket )
sLog.outDetail("CMSG_PET_SPELL_AUTOCAST");
uint64 guid;
uint16 spellid;
uint16 spellid2; //maybe second spell, automatically toggled off when first toggled on?
uint32 spellid;
uint8 state; //1 for on, 0 for off
recvPacket >> guid >> spellid >> spellid2 >> state;
recvPacket >> guid >> spellid >> state;
if(!_player->GetGuardianPet() && !_player->GetCharm())
return;
+56 -67
View File
@@ -704,21 +704,8 @@ bool Player::Create( uint32 guidlow, const std::string& name, uint8 race, uint8
learnDefaultSpells();
// original action bar
std::list<uint16>::const_iterator action_itr[4];
for(uint8 i=0; i<4; i++)
action_itr[i] = info->action[i].begin();
for (; action_itr[0]!=info->action[0].end() && action_itr[1]!=info->action[1].end();)
{
uint16 taction[4];
for(uint8 i=0; i<4 ;i++)
taction[i] = (*action_itr[i]);
addActionButton((uint8)taction[0], taction[1], (uint8)taction[2], (uint8)taction[3]);
for(uint8 i=0; i<4 ;i++)
++action_itr[i];
}
for (PlayerCreateInfoActions::const_iterator action_itr = info->action.begin(); action_itr != info->action.end(); ++action_itr)
addActionButton(action_itr->button,action_itr->action,action_itr->type);
// original items
CharStartOutfitEntry const* oEntry = NULL;
@@ -5559,65 +5546,69 @@ void Player::SendInitialActionButtons() const
sLog.outDetail( "Initializing Action Buttons for '%u'", GetGUIDLow() );
WorldPacket data(SMSG_ACTION_BUTTONS, 1+(MAX_ACTION_BUTTONS*4));
data << uint8(0); // can be 0, 1, 2
data << uint8(0); // can be 0, 1, 2 (talent spec)
for(int button = 0; button < MAX_ACTION_BUTTONS; ++button)
{
ActionButtonList::const_iterator itr = m_actionButtons.find(button);
if(itr != m_actionButtons.end() && itr->second.uState != ACTIONBUTTON_DELETED)
{
data << uint16(itr->second.action);
data << uint8(itr->second.misc);
data << uint8(itr->second.type);
}
data << uint32(itr->second.packedData);
else
{
data << uint32(0);
}
}
GetSession()->SendPacket( &data );
sLog.outDetail( "Action Buttons for '%u' Initialized", GetGUIDLow() );
}
bool Player::addActionButton(const uint8 button, const uint16 action, const uint8 type, const uint8 misc)
ActionButton* Player::addActionButton(uint8 button, uint32 action, uint8 type)
{
if(button >= MAX_ACTION_BUTTONS)
{
sLog.outError( "Action %u not added into button %u for player %s: button must be < 132", action, button, GetName() );
return false;
return NULL;
}
// check cheating with adding non-known spells to action bar
if(type==ACTION_BUTTON_SPELL)
if(action >= MAX_ACTION_BUTTON_ACTION_VALUE)
{
if(!sSpellStore.LookupEntry(action))
{
sLog.outError( "Action %u not added into button %u for player %s: spell not exist", action, button, GetName() );
return false;
}
if(!HasSpell(action))
{
sLog.outError( "Action %u not added into button %u for player %s: player don't known this spell", action, button, GetName() );
return false;
}
sLog.outError( "Action %u not added into button %u for player %s: action must be < %u", action, button, GetName(), MAX_ACTION_BUTTON_ACTION_VALUE );
return NULL;
}
ActionButtonList::iterator buttonItr = m_actionButtons.find(button);
switch(type)
{
case ACTION_BUTTON_SPELL:
if(!sSpellStore.LookupEntry(action))
{
sLog.outError( "Action %u not added into button %u for player %s: spell not exist", action, button, GetName() );
return NULL;
}
if (buttonItr==m_actionButtons.end())
{ // just add new button
m_actionButtons[button] = ActionButton(action,type,misc);
if(!HasSpell(action))
{
sLog.outError( "Action %u not added into button %u for player %s: player don't known this spell", action, button, GetName() );
return NULL;
}
break;
case ACTION_BUTTON_ITEM:
if(!objmgr.GetItemPrototype(action))
{
sLog.outError( "Action %u not added into button %u for player %s: item not exist", action, button, GetName() );
return NULL;
}
break;
default:
break; // pther cases not checked at this moment
}
else
{ // change state of current button
ActionButtonUpdateState uState = buttonItr->second.uState;
buttonItr->second = ActionButton(action,type,misc);
if (uState != ACTIONBUTTON_NEW) buttonItr->second.uState = ACTIONBUTTON_CHANGED;
};
sLog.outDetail( "Player '%u' Added Action '%u' to Button '%u'", GetGUIDLow(), action, button );
return true;
// it create new button (NEW state) if need or return existed
ActionButton& ab = m_actionButtons[button];
// set data and update to CHANGED if not NEW
ab.SetActionAndType(action,ActionButtonType(type));
sLog.outDetail( "Player '%u' Added Action '%u' (type %u) to Button '%u'", GetGUIDLow(), action, uint32(type), button );
return &ab;
}
void Player::removeActionButton(uint8 button)
@@ -14981,7 +14972,7 @@ void Player::_LoadActions(QueryResult *result)
{
m_actionButtons.clear();
//QueryResult *result = CharacterDatabase.PQuery("SELECT button,action,type,misc FROM character_action WHERE guid = '%u' ORDER BY button",GetGUIDLow());
//QueryResult *result = CharacterDatabase.PQuery("SELECT button,action,type FROM character_action WHERE guid = '%u' ORDER BY button",GetGUIDLow());
if(result)
{
@@ -14990,9 +14981,11 @@ void Player::_LoadActions(QueryResult *result)
Field *fields = result->Fetch();
uint8 button = fields[0].GetUInt8();
uint32 action = fields[1].GetUInt32();
uint8 type = fields[2].GetUInt8();
if(addActionButton(button, fields[1].GetUInt16(), fields[2].GetUInt8(), fields[3].GetUInt8()))
m_actionButtons[button].uState = ACTIONBUTTON_UNCHANGED;
if(ActionButton* ab = addActionButton(button, action, type))
ab->uState = ACTIONBUTTON_UNCHANGED;
else
{
sLog.outError( " ...at loading, and will deleted in DB also");
@@ -15561,7 +15554,7 @@ void Player::_LoadSpells(QueryResult *result)
{
Field *fields = result->Fetch();
addSpell(fields[0].GetUInt16(), fields[1].GetBool(), false, false, fields[2].GetBool());
addSpell(fields[0].GetUInt32(), fields[1].GetBool(), false, false, fields[2].GetBool());
}
while( result->NextRow() );
@@ -16148,14 +16141,14 @@ void Player::_SaveActions()
switch (itr->second.uState)
{
case ACTIONBUTTON_NEW:
CharacterDatabase.PExecute("INSERT INTO character_action (guid,button,action,type,misc) VALUES ('%u', '%u', '%u', '%u', '%u')",
GetGUIDLow(), (uint32)itr->first, (uint32)itr->second.action, (uint32)itr->second.type, (uint32)itr->second.misc );
CharacterDatabase.PExecute("INSERT INTO character_action (guid,button,action,type) VALUES ('%u', '%u', '%u', '%u')",
GetGUIDLow(), (uint32)itr->first, (uint32)itr->second.GetAction(), (uint32)itr->second.GetType() );
itr->second.uState = ACTIONBUTTON_UNCHANGED;
++itr;
break;
case ACTIONBUTTON_CHANGED:
CharacterDatabase.PExecute("UPDATE character_action SET action = '%u', type = '%u', misc= '%u' WHERE guid= '%u' AND button= '%u' ",
(uint32)itr->second.action, (uint32)itr->second.type, (uint32)itr->second.misc, GetGUIDLow(), (uint32)itr->first );
CharacterDatabase.PExecute("UPDATE character_action SET action = '%u', type = '%u' WHERE guid= '%u' AND button= '%u' ",
(uint32)itr->second.GetAction(), (uint32)itr->second.GetType(), GetGUIDLow(), (uint32)itr->first );
itr->second.uState = ACTIONBUTTON_UNCHANGED;
++itr;
break;
@@ -16166,7 +16159,7 @@ void Player::_SaveActions()
default:
++itr;
break;
};
}
}
}
@@ -16982,8 +16975,7 @@ void Player::PetSpellInitialize()
if(itr->second.state == PETSPELL_REMOVED)
continue;
data << uint16(itr->first);
data << uint16(itr->second.active); // pet spell active state isn't boolean
data << uint32(MAKE_UNIT_ACTION_BUTTON(itr->first,itr->second.active));
++addlist;
}
}
@@ -17108,7 +17100,7 @@ void Player::CharmSpellInitialize()
{
for(uint32 i = 0; i < MAX_SPELL_CHARM; ++i)
{
if(charmInfo->GetCharmSpell(i)->spellId)
if(charmInfo->GetCharmSpell(i)->GetAction())
++addlist;
}
}
@@ -17133,11 +17125,8 @@ void Player::CharmSpellInitialize()
for(uint32 i = 0; i < MAX_SPELL_CHARM; ++i)
{
CharmSpellEntry *cspell = charmInfo->GetCharmSpell(i);
if(cspell->spellId)
{
data << uint16(cspell->spellId);
data << uint16(cspell->active);
}
if(cspell->GetAction())
data << uint32(cspell->packedData);
}
}
+40 -13
View File
@@ -134,17 +134,6 @@ enum ActionButtonUpdateState
ACTIONBUTTON_DELETED = 3
};
struct ActionButton
{
ActionButton() : action(0), type(0), misc(0), uState( ACTIONBUTTON_NEW ) {}
ActionButton(uint16 _action, uint8 _type, uint8 _misc) : action(_action), type(_type), misc(_misc), uState( ACTIONBUTTON_NEW ) {}
uint16 action;
uint8 type;
uint8 misc;
ActionButtonUpdateState uState;
};
enum ActionButtonType
{
ACTION_BUTTON_SPELL = 0,
@@ -154,6 +143,32 @@ enum ActionButtonType
ACTION_BUTTON_ITEM = 128
};
#define ACTION_BUTTON_ACTION(X) (uint32(X) & 0x00FFFFFF)
#define ACTION_BUTTON_TYPE(X) ((uint32(X) & 0xFF000000) >> 24)
#define MAX_ACTION_BUTTON_ACTION_VALUE (0x00FFFFFF+1)
struct ActionButton
{
ActionButton() : packedData(0), uState( ACTIONBUTTON_NEW ) {}
uint32 packedData;
ActionButtonUpdateState uState;
// helpers
ActionButtonType GetType() const { return ActionButtonType(ACTION_BUTTON_TYPE(packedData)); }
uint32 GetAction() const { return ACTION_BUTTON_ACTION(packedData); }
void SetActionAndType(uint32 action, ActionButtonType type)
{
uint32 newData = action | (uint32(type) << 24);
if (newData != packedData)
{
packedData = newData;
if (uState != ACTIONBUTTON_NEW)
uState = ACTIONBUTTON_CHANGED;
}
}
};
#define MAX_ACTION_BUTTONS 132 //checked in 2.3.0
typedef std::map<uint8,ActionButton> ActionButtonList;
@@ -191,6 +206,18 @@ struct PlayerLevelInfo
typedef std::list<uint32> PlayerCreateInfoSpells;
struct PlayerCreateInfoAction
{
PlayerCreateInfoAction() : button(0), type(0), action(0) {}
PlayerCreateInfoAction(uint8 _button, uint32 _action, uint8 _type) : button(_button), type(_type), action(_action) {}
uint8 button;
uint8 type;
uint32 action;
};
typedef std::list<PlayerCreateInfoAction> PlayerCreateInfoActions;
struct PlayerInfo
{
// existence checked by displayId != 0 // existence checked by displayId != 0
@@ -207,7 +234,7 @@ struct PlayerInfo
uint16 displayId_f;
PlayerCreateInfoItems item;
PlayerCreateInfoSpells spell;
std::list<uint16> action[4];
PlayerCreateInfoActions action;
PlayerLevelInfo* levelInfo; //[level-1] 0..MaxPlayerLevel-1
};
@@ -1462,7 +1489,7 @@ class TRINITY_DLL_SPEC Player : public Unit
m_cinematic = cine;
}
bool addActionButton(uint8 button, uint16 action, uint8 type, uint8 misc);
ActionButton* addActionButton(uint8 button, uint32 action, uint8 type);
void removeActionButton(uint8 button);
void SendInitialActionButtons() const;
+5 -5
View File
@@ -1093,7 +1093,7 @@ void SpellMgr::LoadSpellAffects()
bar.step();
uint16 entry = fields[0].GetUInt16();
uint32 entry = fields[0].GetUInt32();
uint8 effectId = fields[1].GetUInt8();
SpellEntry const* spellInfo = sSpellStore.LookupEntry(entry);
@@ -1413,7 +1413,7 @@ void SpellMgr::LoadSpellElixirs()
bar.step();
uint16 entry = fields[0].GetUInt16();
uint32 entry = fields[0].GetUInt32();
uint8 mask = fields[1].GetUInt8();
SpellEntry const* spellInfo = sSpellStore.LookupEntry(entry);
@@ -1928,10 +1928,10 @@ void SpellMgr::LoadSpellPetAuras()
bar.step();
uint16 spell = fields[0].GetUInt16();
uint32 spell = fields[0].GetUInt32();
uint8 eff = fields[1].GetUInt8();
uint16 pet = fields[2].GetUInt16();
uint16 aura = fields[3].GetUInt16();
uint32 pet = fields[2].GetUInt32();
uint32 aura = fields[3].GetUInt32();
SpellPetAuraMap::iterator itr = mSpellPetAuraMap.find((spell<<8) + eff);
if(itr != mSpellPetAuraMap.end())
+8 -8
View File
@@ -552,20 +552,20 @@ class PetAura
auras.clear();
}
PetAura(uint16 petEntry, uint16 aura, bool _removeOnChangePet, int _damage) :
PetAura(uint32 petEntry, uint32 aura, bool _removeOnChangePet, int _damage) :
removeOnChangePet(_removeOnChangePet), damage(_damage)
{
auras[petEntry] = aura;
}
uint16 GetAura(uint16 petEntry) const
uint32 GetAura(uint32 petEntry) const
{
std::map<uint16, uint16>::const_iterator itr = auras.find(petEntry);
std::map<uint32, uint32>::const_iterator itr = auras.find(petEntry);
if(itr != auras.end())
return itr->second;
else
{
std::map<uint16, uint16>::const_iterator itr2 = auras.find(0);
std::map<uint32, uint32>::const_iterator itr2 = auras.find(0);
if(itr2 != auras.end())
return itr2->second;
else
@@ -573,7 +573,7 @@ class PetAura
}
}
void AddAura(uint16 petEntry, uint16 aura)
void AddAura(uint32 petEntry, uint32 aura)
{
auras[petEntry] = aura;
}
@@ -589,7 +589,7 @@ class PetAura
}
private:
std::map<uint16, uint16> auras;
std::map<uint32, uint32> auras;
bool removeOnChangePet;
int32 damage;
};
@@ -726,7 +726,7 @@ class SpellMgr
// Accessors (const or static functions)
public:
// Spell affects
flag96 const*GetSpellAffect(uint16 spellId, uint8 effectId) const
flag96 const*GetSpellAffect(uint32 spellId, uint8 effectId) const
{
SpellAffectMap::const_iterator itr = mSpellAffectMap.find((spellId<<8) + effectId);
if( itr != mSpellAffectMap.end( ) )
@@ -965,7 +965,7 @@ class SpellMgr
return mSkillLineAbilityMap.upper_bound(spell_id);
}
PetAura const* GetPetAura(uint16 spell_id, uint8 eff)
PetAura const* GetPetAura(uint32 spell_id, uint8 eff)
{
SpellPetAuraMap::const_iterator itr = mSpellPetAuraMap.find((spell_id<<8) + eff);
if(itr != mSpellPetAuraMap.end())
+27 -31
View File
@@ -12193,11 +12193,9 @@ void Unit::DeleteCharmInfo()
CharmInfo::CharmInfo(Unit* unit)
: m_unit(unit), m_CommandState(COMMAND_FOLLOW), m_petnumber(0), m_barInit(false)
{
for(uint8 i =0; i<MAX_SPELL_CHARM; ++i)
{
m_charmspells[i].spellId = 0;
m_charmspells[i].active = ACT_DISABLED;
}
for(uint8 i = 0; i < MAX_SPELL_CHARM; ++i)
m_charmspells[i].SetActionAndType(0,ACT_DISABLED);
if(m_unit->GetTypeId() == TYPEID_UNIT)
{
m_oldReactState = ((Creature*)m_unit)->GetReactState();
@@ -12274,18 +12272,21 @@ void CharmInfo::InitCharmCreateSpells()
if(spellInfo && spellInfo->Attributes & SPELL_ATTR_CASTABLE_WHILE_DEAD)
spellId = 0;
m_charmspells[x].spellId = spellId;
if(!spellId)
{
m_charmspells[x].SetActionAndType(spellId,ACT_DISABLED);
continue;
}
if (IsPassiveSpell(spellId))
{
m_unit->CastSpell(m_unit, spellId, true);
m_charmspells[x].active = ACT_PASSIVE;
m_charmspells[x].SetActionAndType(spellId,ACT_PASSIVE);
}
else
{
m_charmspells[x].SetActionAndType(spellId,ACT_DISABLED);
ActiveStates newstate;
if(spellInfo)
{
@@ -12320,11 +12321,11 @@ bool CharmInfo::AddSpellToActionBar(uint32 spell_id, ActiveStates newstate)
// new spell rank can be already listed
for(uint8 i = 0; i < MAX_UNIT_ACTION_BAR_INDEX; ++i)
{
if (PetActionBar[i].SpellOrAction && PetActionBar[i].IsActionBarForSpell())
if (uint32 action = PetActionBar[i].GetAction())
{
if (spellmgr.GetFirstSpellInChain(PetActionBar[i].SpellOrAction) == first_id)
if (PetActionBar[i].IsActionBarForSpell() && spellmgr.GetFirstSpellInChain(action) == first_id)
{
PetActionBar[i].SpellOrAction = spell_id;
PetActionBar[i].SetAction(spell_id);
return true;
}
}
@@ -12333,7 +12334,7 @@ bool CharmInfo::AddSpellToActionBar(uint32 spell_id, ActiveStates newstate)
// or use empty slot in other case
for(uint8 i = 0; i < MAX_UNIT_ACTION_BAR_INDEX; ++i)
{
if (!PetActionBar[i].SpellOrAction && PetActionBar[i].IsActionBarForSpell())
if (!PetActionBar[i].GetAction() && PetActionBar[i].IsActionBarForSpell())
{
SetActionBar(i,spell_id,newstate == ACT_DECIDE ? IsAutocastableSpell(spell_id) ? ACT_DISABLED : ACT_PASSIVE : newstate);
return true;
@@ -12348,9 +12349,9 @@ bool CharmInfo::RemoveSpellFromActionBar(uint32 spell_id)
for(uint8 i = 0; i < MAX_UNIT_ACTION_BAR_INDEX; ++i)
{
if (PetActionBar[i].SpellOrAction && PetActionBar[i].IsActionBarForSpell())
if (uint32 action = PetActionBar[i].GetAction())
{
if (spellmgr.GetFirstSpellInChain(PetActionBar[i].SpellOrAction) == first_id)
if (PetActionBar[i].IsActionBarForSpell() && spellmgr.GetFirstSpellInChain(action) == first_id)
{
SetActionBar(i,0,ACT_PASSIVE);
return true;
@@ -12367,12 +12368,8 @@ void CharmInfo::ToggleCreatureAutocast(uint32 spellid, bool apply)
return;
for(uint32 x = 0; x < MAX_SPELL_CHARM; ++x)
{
if(spellid == m_charmspells[x].spellId)
{
m_charmspells[x].active = apply ? ACT_ENABLED : ACT_DISABLED;
}
}
if(spellid == m_charmspells[x].GetAction())
m_charmspells[x].SetType(apply ? ACT_ENABLED : ACT_DISABLED);
}
void CharmInfo::SetPetNumber(uint32 petnumber, bool statwindow)
@@ -12398,17 +12395,19 @@ void CharmInfo::LoadPetActionBar(const std::string& data )
for(iter = tokens.begin(), index = ACTION_BAR_INDEX_PET_SPELL_START; index < ACTION_BAR_INDEX_PET_SPELL_END; ++iter, ++index )
{
// use unsigned cast to avoid sign negative format use at long-> ActiveStates (int) conversion
PetActionBar[index].Type = atol((*iter).c_str());
uint8 type = atol((*iter).c_str());
++iter;
PetActionBar[index].SpellOrAction = atol((*iter).c_str());
uint32 action = atol((*iter).c_str());
PetActionBar[index].SetActionAndType(action,ActiveStates(type));
// check correctness
if(PetActionBar[index].IsActionBarForSpell())
{
if(!sSpellStore.LookupEntry(PetActionBar[index].SpellOrAction))
if(!sSpellStore.LookupEntry(PetActionBar[index].GetAction()))
SetActionBar(index,0,ACT_PASSIVE);
else if(!IsAutocastableSpell(PetActionBar[index].SpellOrAction))
SetActionBar(index,PetActionBar[index].SpellOrAction,ACT_PASSIVE);
else if(!IsAutocastableSpell(PetActionBar[index].GetAction()))
SetActionBar(index,PetActionBar[index].GetAction(),ACT_PASSIVE);
}
}
}
@@ -12416,19 +12415,16 @@ void CharmInfo::LoadPetActionBar(const std::string& data )
void CharmInfo::BuildActionBar( WorldPacket* data )
{
for(uint32 i = 0; i < MAX_UNIT_ACTION_BAR_INDEX; ++i)
{
*data << uint16(PetActionBar[i].SpellOrAction);
*data << uint16(PetActionBar[i].Type);
}
*data << uint32(PetActionBar[i].packedData);
}
void CharmInfo::SetSpellAutocast( uint32 spell_id, bool state )
{
for(uint8 i = 0; i < MAX_UNIT_ACTION_BAR_INDEX; ++i)
{
if(spell_id == PetActionBar[i].SpellOrAction && PetActionBar[i].IsActionBarForSpell())
if(spell_id == PetActionBar[i].GetAction() && PetActionBar[i].IsActionBarForSpell())
{
PetActionBar[i].Type = state ? ACT_ENABLED : ACT_DISABLED;
PetActionBar[i].SetType(state ? ACT_ENABLED : ACT_DISABLED);
break;
}
}
+33 -16
View File
@@ -856,12 +856,12 @@ enum CurrentSpellTypes
enum ActiveStates
{
ACT_PASSIVE = 0x0100, // 0x0100 - passive
ACT_DISABLED = 0x8100, // 0x8000 - castable
ACT_ENABLED = 0xC100, // 0x4000 | 0x8000 - auto cast + castable
ACT_COMMAND = 0x0700, // 0x0100 | 0x0200 | 0x0400
ACT_REACTION = 0x0600, // 0x0200 | 0x0400
ACT_DECIDE = 0x0001 // what is it?
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
@@ -879,24 +879,40 @@ 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 MAX_UNIT_ACTION_BUTTON_ACTION_VALUE (0x00FFFFFF+1)
#define MAKE_UNIT_ACTION_BUTTON(A,T) (uint32(A) | (uint32(T) << 24))
struct UnitActionBarEntry
{
UnitActionBarEntry() : SpellOrAction(0), Type(ACT_DISABLED) {}
UnitActionBarEntry() : packedData(uint32(ACT_DISABLED) << 24) {}
uint16 SpellOrAction;
uint16 Type;
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;
}
};
struct CharmSpellEntry
{
uint16 spellId;
uint16 active;
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;
@@ -909,6 +925,8 @@ enum CharmType
CHARM_TYPE_CONVERT,
};
typedef UnitActionBarEntry CharmSpellEntry;
enum ActionBarIndex
{
ACTION_BAR_INDEX_START = 0,
@@ -947,8 +965,7 @@ struct CharmInfo
void SetSpellAutocast(uint32 spell_id, bool state);
void SetActionBar(uint8 index, uint32 spellOrAction,ActiveStates type)
{
PetActionBar[index].Type = type;
PetActionBar[index].SpellOrAction = spellOrAction;
PetActionBar[index].SetActionAndType(spellOrAction,type);
}
UnitActionBarEntry const* GetActionBarEntry(uint8 index) const { return &(PetActionBar[index]); }