From e757ebf6ba441358ec5b53bceef54f35fdfa929e Mon Sep 17 00:00:00 2001 From: NNN666 Date: Fri, 13 Jul 2012 15:16:37 +0200 Subject: [PATCH] Core/Player: Fix issues with 'ignore this slot' option on equipment manager usage --- sql/base/characters_database.sql | 39 ++++++++++--------- ..._00_characters_character_equipmentsets.sql | 22 +++++++++++ src/server/game/Entities/Player/Player.cpp | 13 ++++++- src/server/game/Entities/Player/Player.h | 3 +- src/server/game/Handlers/CharacterHandler.cpp | 12 ++++++ .../Implementation/CharacterDatabase.cpp | 6 +-- 6 files changed, 70 insertions(+), 25 deletions(-) create mode 100644 sql/updates/characters/2012_06_13_00_characters_character_equipmentsets.sql diff --git a/sql/base/characters_database.sql b/sql/base/characters_database.sql index 57e5f6f6ab..b4a3af6e8f 100644 --- a/sql/base/characters_database.sql +++ b/sql/base/characters_database.sql @@ -547,25 +547,26 @@ CREATE TABLE `character_equipmentsets` ( `setindex` tinyint(3) unsigned NOT NULL DEFAULT '0', `name` varchar(31) NOT NULL, `iconname` varchar(100) NOT NULL, - `item0` int(10) unsigned NOT NULL DEFAULT '0', - `item1` int(10) unsigned NOT NULL DEFAULT '0', - `item2` int(10) unsigned NOT NULL DEFAULT '0', - `item3` int(10) unsigned NOT NULL DEFAULT '0', - `item4` int(10) unsigned NOT NULL DEFAULT '0', - `item5` int(10) unsigned NOT NULL DEFAULT '0', - `item6` int(10) unsigned NOT NULL DEFAULT '0', - `item7` int(10) unsigned NOT NULL DEFAULT '0', - `item8` int(10) unsigned NOT NULL DEFAULT '0', - `item9` int(10) unsigned NOT NULL DEFAULT '0', - `item10` int(10) unsigned NOT NULL DEFAULT '0', - `item11` int(10) unsigned NOT NULL DEFAULT '0', - `item12` int(10) unsigned NOT NULL DEFAULT '0', - `item13` int(10) unsigned NOT NULL DEFAULT '0', - `item14` int(10) unsigned NOT NULL DEFAULT '0', - `item15` int(10) unsigned NOT NULL DEFAULT '0', - `item16` int(10) unsigned NOT NULL DEFAULT '0', - `item17` int(10) unsigned NOT NULL DEFAULT '0', - `item18` int(10) unsigned NOT NULL DEFAULT '0', + `ignore_mask` int(11) unsigned NOT NULL DEFAULT '0', + `item0` int(11) unsigned NOT NULL DEFAULT '0', + `item1` int(11) unsigned NOT NULL DEFAULT '0', + `item2` int(11) unsigned NOT NULL DEFAULT '0', + `item3` int(11) unsigned NOT NULL DEFAULT '0', + `item4` int(11) unsigned NOT NULL DEFAULT '0', + `item5` int(11) unsigned NOT NULL DEFAULT '0', + `item6` int(11) unsigned NOT NULL DEFAULT '0', + `item7` int(11) unsigned NOT NULL DEFAULT '0', + `item8` int(11) unsigned NOT NULL DEFAULT '0', + `item9` int(11) unsigned NOT NULL DEFAULT '0', + `item10` int(11) unsigned NOT NULL DEFAULT '0', + `item11` int(11) unsigned NOT NULL DEFAULT '0', + `item12` int(11) unsigned NOT NULL DEFAULT '0', + `item13` int(11) unsigned NOT NULL DEFAULT '0', + `item14` int(11) unsigned NOT NULL DEFAULT '0', + `item15` int(11) unsigned NOT NULL DEFAULT '0', + `item16` int(11) unsigned NOT NULL DEFAULT '0', + `item17` int(11) unsigned NOT NULL DEFAULT '0', + `item18` int(11) unsigned NOT NULL DEFAULT '0', PRIMARY KEY (`setguid`), UNIQUE KEY `idx_set` (`guid`,`setguid`,`setindex`), KEY `Idx_setindex` (`setindex`) diff --git a/sql/updates/characters/2012_06_13_00_characters_character_equipmentsets.sql b/sql/updates/characters/2012_06_13_00_characters_character_equipmentsets.sql new file mode 100644 index 0000000000..ebf12062be --- /dev/null +++ b/sql/updates/characters/2012_06_13_00_characters_character_equipmentsets.sql @@ -0,0 +1,22 @@ +ALTER TABLE `character_equipmentsets` +MODIFY COLUMN `item0` int(11) unsigned NOT NULL DEFAULT 0, +MODIFY COLUMN `item1` int(11) unsigned NOT NULL DEFAULT 0, +MODIFY COLUMN `item2` int(11) unsigned NOT NULL DEFAULT 0, +MODIFY COLUMN `item3` int(11) unsigned NOT NULL DEFAULT 0, +MODIFY COLUMN `item4` int(11) unsigned NOT NULL DEFAULT 0, +MODIFY COLUMN `item5` int(11) unsigned NOT NULL DEFAULT 0, +MODIFY COLUMN `item6` int(11) unsigned NOT NULL DEFAULT 0, +MODIFY COLUMN `item7` int(11) unsigned NOT NULL DEFAULT 0, +MODIFY COLUMN `item8` int(11) unsigned NOT NULL DEFAULT 0, +MODIFY COLUMN `item9` int(11) unsigned NOT NULL DEFAULT 0, +MODIFY COLUMN `item10` int(11) unsigned NOT NULL DEFAULT 0, +MODIFY COLUMN `item11` int(11) unsigned NOT NULL DEFAULT 0, +MODIFY COLUMN `item12` int(11) unsigned NOT NULL DEFAULT 0, +MODIFY COLUMN `item13` int(11) unsigned NOT NULL DEFAULT 0, +MODIFY COLUMN `item14` int(11) unsigned NOT NULL DEFAULT 0, +MODIFY COLUMN `item15` int(11) unsigned NOT NULL DEFAULT 0, +MODIFY COLUMN `item16` int(11) unsigned NOT NULL DEFAULT 0, +MODIFY COLUMN `item17` int(11) unsigned NOT NULL DEFAULT 0, +MODIFY COLUMN `item18` int(11) unsigned NOT NULL DEFAULT 0; + +ALTER TABLE `character_equipmentsets` ADD COLUMN `ignore_mask` int(11) unsigned NOT NULL DEFAULT 0 AFTER `iconname`; diff --git a/src/server/game/Entities/Player/Player.cpp b/src/server/game/Entities/Player/Player.cpp index c38ceb6f57..e24882e145 100755 --- a/src/server/game/Entities/Player/Player.cpp +++ b/src/server/game/Entities/Player/Player.cpp @@ -16677,10 +16677,11 @@ void Player::_LoadEquipmentSets(PreparedQueryResult result) uint8 index = fields[1].GetUInt8(); eqSet.Name = fields[2].GetString(); eqSet.IconName = fields[3].GetString(); + eqSet.IgnoreMask = fields[4].GetUInt32(); eqSet.state = EQUIPMENT_SET_UNCHANGED; for (uint32 i = 0; i < EQUIPMENT_SLOT_END; ++i) - eqSet.Items[i] = fields[4+i].GetUInt32(); + eqSet.Items[i] = fields[5+i].GetUInt32(); m_EquipmentSets[index] = eqSet; @@ -24822,7 +24823,13 @@ void Player::SendEquipmentSetList() data << itr->second.Name; data << itr->second.IconName; for (uint32 i = 0; i < EQUIPMENT_SLOT_END; ++i) - data.appendPackGUID(MAKE_NEW_GUID(itr->second.Items[i], 0, HIGHGUID_ITEM)); + { + // ignored slots stored in IgnoreMask, client wants "1" as raw GUID, so no HIGHGUID_ITEM + if (itr->second.IgnoreMask & (1 << i)) + data.appendPackGUID(MAKE_NEW_GUID(uint64(1))); + else + data.appendPackGUID(MAKE_NEW_GUID(itr->second.Items[i], 0, HIGHGUID_ITEM)); + } ++count; // client have limit but it checked at loading and set } @@ -24888,6 +24895,7 @@ void Player::_SaveEquipmentSets(SQLTransaction& trans) stmt = CharacterDatabase.GetPreparedStatement(CHAR_UPD_EQUIP_SET); stmt->setString(j++, eqset.Name.c_str()); stmt->setString(j++, eqset.IconName.c_str()); + stmt->setUInt32(j++, eqset.IgnoreMask); for (uint8 i=0; isetUInt32(j++, eqset.Items[i]); stmt->setUInt32(j++, GetGUIDLow()); @@ -24904,6 +24912,7 @@ void Player::_SaveEquipmentSets(SQLTransaction& trans) stmt->setUInt32(j++, index); stmt->setString(j++, eqset.Name.c_str()); stmt->setString(j++, eqset.IconName.c_str()); + stmt->setUInt32(j++, eqset.IgnoreMask); for (uint8 i=0; isetUInt32(j++, eqset.Items[i]); trans->Append(stmt); diff --git a/src/server/game/Entities/Player/Player.h b/src/server/game/Entities/Player/Player.h index b0cbb5c792..b1e4e81900 100755 --- a/src/server/game/Entities/Player/Player.h +++ b/src/server/game/Entities/Player/Player.h @@ -640,7 +640,7 @@ enum EquipmentSetUpdateState struct EquipmentSet { - EquipmentSet() : Guid(0), state(EQUIPMENT_SET_NEW) + EquipmentSet() : Guid(0), IgnoreMask(0), state(EQUIPMENT_SET_NEW) { for (uint8 i = 0; i < EQUIPMENT_SLOT_END; ++i) Items[i] = 0; @@ -649,6 +649,7 @@ struct EquipmentSet uint64 Guid; std::string Name; std::string IconName; + uint32 IgnoreMask; uint32 Items[EQUIPMENT_SLOT_END]; EquipmentSetUpdateState state; }; diff --git a/src/server/game/Handlers/CharacterHandler.cpp b/src/server/game/Handlers/CharacterHandler.cpp index 2d70efd330..29ee2b5cb4 100644 --- a/src/server/game/Handlers/CharacterHandler.cpp +++ b/src/server/game/Handlers/CharacterHandler.cpp @@ -1514,6 +1514,14 @@ void WorldSession::HandleEquipmentSetSave(WorldPacket &recv_data) uint64 itemGuid; recv_data.readPackGUID(itemGuid); + // equipment manager sends "1" (as raw GUID) for slots set to "ignore" (don't touch slot at equip set) + if (itemGuid == 1) + { + // ignored slots saved as bit mask because we have no free special values for Items[i] + eqSet.IgnoreMask |= 1 << i; + continue; + } + Item* item = _player->GetItemByPos(INVENTORY_SLOT_BAG_0, i); if (!item && itemGuid) // cheating check 1 @@ -1555,6 +1563,10 @@ void WorldSession::HandleEquipmentSetUse(WorldPacket &recv_data) sLog->outDebug(LOG_FILTER_PLAYER_ITEMS, "Item " UI64FMTD ": srcbag %u, srcslot %u", itemGuid, srcbag, srcslot); + // check if item slot is set to "ignored" (raw value == 1), must not be unequipped then + if (itemGuid == 1) + continue; + Item* item = _player->GetItemByGuid(itemGuid); uint16 dstpos = i | (INVENTORY_SLOT_BAG_0 << 8); diff --git a/src/server/shared/Database/Implementation/CharacterDatabase.cpp b/src/server/shared/Database/Implementation/CharacterDatabase.cpp index 89cc6ab25e..3bb6783f8c 100644 --- a/src/server/shared/Database/Implementation/CharacterDatabase.cpp +++ b/src/server/shared/Database/Implementation/CharacterDatabase.cpp @@ -94,7 +94,7 @@ void CharacterDatabaseConnection::DoPrepareStatements() PREPARE_STATEMENT(CHAR_SEL_GUILD_MEMBER, "SELECT guildid, rank FROM guild_member WHERE guid = ?", CONNECTION_BOTH) PREPARE_STATEMENT(CHAR_SEL_CHARACTER_ACHIEVEMENTS, "SELECT achievement, date FROM character_achievement WHERE guid = ?", CONNECTION_ASYNC) PREPARE_STATEMENT(CHAR_SEL_CHARACTER_CRITERIAPROGRESS, "SELECT criteria, counter, date FROM character_achievement_progress WHERE guid = ?", CONNECTION_ASYNC) - PREPARE_STATEMENT(CHAR_SEL_CHARACTER_EQUIPMENTSETS, "SELECT setguid, setindex, name, iconname, item0, item1, item2, item3, item4, item5, item6, item7, item8, " + PREPARE_STATEMENT(CHAR_SEL_CHARACTER_EQUIPMENTSETS, "SELECT setguid, setindex, name, iconname, ignore_mask, item0, item1, item2, item3, item4, item5, item6, item7, item8, " "item9, item10, item11, item12, item13, item14, item15, item16, item17, item18 FROM character_equipmentsets WHERE guid = ? ORDER BY setindex", CONNECTION_ASYNC) PREPARE_STATEMENT(CHAR_SEL_CHARACTER_BGDATA, "SELECT instanceId, team, joinX, joinY, joinZ, joinO, joinMapId, taxiStart, taxiEnd, mountSpell FROM character_battleground_data WHERE guid = ?", CONNECTION_ASYNC) PREPARE_STATEMENT(CHAR_SEL_CHARACTER_GLYPHS, "SELECT spec, glyph1, glyph2, glyph3, glyph4, glyph5, glyph6 FROM character_glyphs WHERE guid = ?", CONNECTION_ASYNC) @@ -235,8 +235,8 @@ void CharacterDatabaseConnection::DoPrepareStatements() PREPARE_STATEMENT(CHAR_DEL_OLD_CHANNELS, "DELETE FROM channels WHERE ownership = 1 AND lastUsed + ? < UNIX_TIMESTAMP()", CONNECTION_ASYNC) // Equipmentsets - PREPARE_STATEMENT(CHAR_UPD_EQUIP_SET, "UPDATE character_equipmentsets SET name=?, iconname=?, item0=?, item1=?, item2=?, item3=?, item4=?, item5=?, item6=?, item7=?, item8=?, item9=?, item10=?, item11=?, item12=?, item13=?, item14=?, item15=?, item16=?, item17=?, item18=? WHERE guid=? AND setguid=? AND setindex=?", CONNECTION_ASYNC) - PREPARE_STATEMENT(CHAR_INS_EQUIP_SET, "INSERT INTO character_equipmentsets (guid, setguid, setindex, name, iconname, item0, item1, item2, item3, item4, item5, item6, item7, item8, item9, item10, item11, item12, item13, item14, item15, item16, item17, item18) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)", CONNECTION_ASYNC) + PREPARE_STATEMENT(CHAR_UPD_EQUIP_SET, "UPDATE character_equipmentsets SET name=?, iconname=?, ignore_mask=?, item0=?, item1=?, item2=?, item3=?, item4=?, item5=?, item6=?, item7=?, item8=?, item9=?, item10=?, item11=?, item12=?, item13=?, item14=?, item15=?, item16=?, item17=?, item18=? WHERE guid=? AND setguid=? AND setindex=?", CONNECTION_ASYNC) + PREPARE_STATEMENT(CHAR_INS_EQUIP_SET, "INSERT INTO character_equipmentsets (guid, setguid, setindex, name, iconname, ignore_mask, item0, item1, item2, item3, item4, item5, item6, item7, item8, item9, item10, item11, item12, item13, item14, item15, item16, item17, item18) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)", CONNECTION_ASYNC) PREPARE_STATEMENT(CHAR_DEL_EQUIP_SET, "DELETE FROM character_equipmentsets WHERE setguid=?", CONNECTION_ASYNC) // Auras