diff --git a/src/game/Pet.cpp b/src/game/Pet.cpp index 1a9af6755..063a00d8c 100644 --- a/src/game/Pet.cpp +++ b/src/game/Pet.cpp @@ -414,8 +414,7 @@ void Pet::SavePetToDB(PetSaveMode mode) << curmana << ", " << GetPower(POWER_HAPPINESS) << ", '"; - // save only spell slots from action bar - for(uint32 i = ACTION_BAR_INDEX_PET_SPELL_START; i < ACTION_BAR_INDEX_PET_SPELL_END; ++i) + for(uint32 i = ACTION_BAR_INDEX_START; i < ACTION_BAR_INDEX_END; ++i) { ss << uint32(m_charmInfo->GetActionBarEntry(i)->GetType()) << " " << uint32(m_charmInfo->GetActionBarEntry(i)->GetAction()) << " "; diff --git a/src/game/PetHandler.cpp b/src/game/PetHandler.cpp index 57b048964..a58f7e5bf 100644 --- a/src/game/PetHandler.cpp +++ b/src/game/PetHandler.cpp @@ -324,23 +324,59 @@ void WorldSession::HandlePetSetAction( WorldPacket & recv_data ) } count = (recv_data.size() == 24) ? 2 : 1; + + uint32 position[2]; + uint32 data[2]; + bool move_command = false; + for(uint8 i = 0; i < count; ++i) { - uint32 position; - uint32 data; + recv_data >> position[i]; + recv_data >> data[i]; - 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)); + uint8 act_state = UNIT_ACTION_BUTTON_TYPE(data[i]); //ignore invalid position - if(position >= MAX_UNIT_ACTION_BAR_INDEX) + if(position[i] >= MAX_UNIT_ACTION_BAR_INDEX) return; + // in the normal case, command and reaction buttons can only be moved, not removed + // at moving count ==2, at removing count == 1 + // ignore attempt to remove command|reaction buttons (not possible at normal case) + if (act_state == ACT_COMMAND || act_state == ACT_REACTION) + { + if (count == 1) + return; + + move_command = true; + } + } + + // check swap + if (move_command) + { + uint8 act_state_0 = UNIT_ACTION_BUTTON_TYPE(data[0]); + uint32 spell_id_0 = UNIT_ACTION_BUTTON_ACTION(data[0]); + UnitActionBarEntry const* actionEntry_1 = charmInfo->GetActionBarEntry(position[1]); + if (!actionEntry_1 || spell_id_0 != actionEntry_1->GetAction() || + act_state_0 != actionEntry_1->GetType()) + return; + + uint8 act_state_1 = UNIT_ACTION_BUTTON_TYPE(data[1]); + uint32 spell_id_1 = UNIT_ACTION_BUTTON_ACTION(data[1]); + UnitActionBarEntry const* actionEntry_0 = charmInfo->GetActionBarEntry(position[0]); + if (!actionEntry_0 || spell_id_1 != actionEntry_0->GetAction() || + act_state_1 != actionEntry_0->GetType()) + return; + } + + for(uint8 i = 0; i < count; ++i) + { + uint32 spell_id = UNIT_ACTION_BUTTON_ACTION(data[i]); + uint8 act_state = UNIT_ACTION_BUTTON_TYPE(data[i]); + + sLog.outDetail( "Player %s has changed pet spell action. Position: %u, Spell: %u, State: 0x%X", _player->GetName(), position[i], spell_id, uint32(act_state)); + //if it's act for spell (en/disable/cast) and there is a spell given (0 = remove spell) which pet doesn't know, don't add if(!((act_state == ACT_ENABLED || act_state == ACT_DISABLED || act_state == ACT_PASSIVE) && spell_id && !pet->HasSpell(spell_id))) { @@ -361,7 +397,7 @@ void WorldSession::HandlePetSetAction( WorldPacket & recv_data ) ((Pet*)pet)->ToggleAutocast(spell_id, false); } - charmInfo->SetActionBar(position,spell_id,ActiveStates(act_state)); + charmInfo->SetActionBar(position[i],spell_id,ActiveStates(act_state)); } } } diff --git a/src/game/Unit.cpp b/src/game/Unit.cpp index b3535372f..b0daacc54 100644 --- a/src/game/Unit.cpp +++ b/src/game/Unit.cpp @@ -11658,12 +11658,12 @@ void CharmInfo::LoadPetActionBar(const std::string& data ) Tokens tokens = StrSplit(data, " "); - if (tokens.size() != (ACTION_BAR_INDEX_PET_SPELL_END-ACTION_BAR_INDEX_PET_SPELL_START)*2) + if (tokens.size() != (ACTION_BAR_INDEX_END-ACTION_BAR_INDEX_START)*2) return; // non critical, will reset to default int index; Tokens::iterator iter; - for(iter = tokens.begin(), index = ACTION_BAR_INDEX_PET_SPELL_START; index < ACTION_BAR_INDEX_PET_SPELL_END; ++iter, ++index ) + for(iter = tokens.begin(), index = ACTION_BAR_INDEX_START; index < ACTION_BAR_INDEX_END; ++iter, ++index ) { // use unsigned cast to avoid sign negative format use at long-> ActiveStates (int) conversion uint8 type = atol((*iter).c_str()); diff --git a/src/shared/revision_nr.h b/src/shared/revision_nr.h index 9d4bfcc3a..641e1f5b1 100644 --- a/src/shared/revision_nr.h +++ b/src/shared/revision_nr.h @@ -1,4 +1,4 @@ #ifndef __REVISION_NR_H__ #define __REVISION_NR_H__ - #define REVISION_NR "8986" + #define REVISION_NR "8987" #endif // __REVISION_NR_H__