diff options
-rw-r--r-- | sql/base/characters_database.sql | 4 | ||||
-rw-r--r-- | sql/updates/characters/master/2022_03_11_00_characters_2021_07_18_00_characters.sql | 2 | ||||
-rw-r--r-- | src/server/database/Database/Implementation/CharacterDatabase.cpp | 6 | ||||
-rw-r--r-- | src/server/game/Entities/Player/Player.cpp | 2 | ||||
-rw-r--r-- | src/server/game/Loot/Loot.cpp | 1 | ||||
-rw-r--r-- | src/server/game/Loot/Loot.h | 7 | ||||
-rw-r--r-- | src/server/game/Loot/LootItemStorage.cpp | 47 | ||||
-rw-r--r-- | src/server/game/Loot/LootItemStorage.h | 4 |
8 files changed, 41 insertions, 32 deletions
diff --git a/sql/base/characters_database.sql b/sql/base/characters_database.sql index 8600cf4905b..314b30994dd 100644 --- a/sql/base/characters_database.sql +++ b/sql/base/characters_database.sql @@ -2979,6 +2979,7 @@ CREATE TABLE `item_loot_items` ( `container_id` bigint unsigned NOT NULL DEFAULT '0' COMMENT 'guid of container (item_instance.guid)', `item_id` int unsigned NOT NULL DEFAULT '0' COMMENT 'loot item entry (item_instance.itemEntry)', `item_count` int NOT NULL DEFAULT '0' COMMENT 'stack size', + `item_index` int(10) unsigned NOT NULL DEFAULT '0', `follow_rules` tinyint(1) NOT NULL DEFAULT '0' COMMENT 'follow loot rules', `ffa` tinyint(1) NOT NULL DEFAULT '0' COMMENT 'free-for-all', `blocked` tinyint(1) NOT NULL DEFAULT '0', @@ -3665,7 +3666,8 @@ INSERT INTO `updates` VALUES ('2022_01_31_01_characters.sql','E0A1FA670F4621AEB594D7ACBA4921CB298F54FF','ARCHIVED','2022-01-31 20:47:59',0), ('2022_01_31_02_characters.sql','6E3A3F02276287DD540BC4C17E246DFB850260D8','ARCHIVED','2022-01-31 21:43:38',0), ('2022_02_28_00_characters_2020_09_27_00_characters.sql','2292A1ED0E7F46DEC41384F75FA6D9461464EEB8','ARCHIVED','2022-02-28 12:43:58',0), -('2022_03_06_00_characters.sql','474AAF9D03E6A56017899C968DC9875368301934','ARCHIVED','2022-03-06 15:12:24',0); +('2022_03_06_00_characters.sql','474AAF9D03E6A56017899C968DC9875368301934','ARCHIVED','2022-03-06 15:12:24',0), +('2022_03_11_00_characters_2021_07_18_00_characters.sql','0BA579ED21F4E75AC2B4797421B5029568B3F6E2','RELEASED','2022-03-11 18:56:07',0); /*!40000 ALTER TABLE `updates` ENABLE KEYS */; UNLOCK TABLES; diff --git a/sql/updates/characters/master/2022_03_11_00_characters_2021_07_18_00_characters.sql b/sql/updates/characters/master/2022_03_11_00_characters_2021_07_18_00_characters.sql new file mode 100644 index 00000000000..e3ad3e1131b --- /dev/null +++ b/sql/updates/characters/master/2022_03_11_00_characters_2021_07_18_00_characters.sql @@ -0,0 +1,2 @@ +-- +ALTER TABLE `item_loot_items` ADD COLUMN `item_index` int(10) unsigned NOT NULL DEFAULT '0' AFTER `item_count`; diff --git a/src/server/database/Database/Implementation/CharacterDatabase.cpp b/src/server/database/Database/Implementation/CharacterDatabase.cpp index 675036a5500..f86f58462f2 100644 --- a/src/server/database/Database/Implementation/CharacterDatabase.cpp +++ b/src/server/database/Database/Implementation/CharacterDatabase.cpp @@ -689,10 +689,10 @@ void CharacterDatabaseConnection::DoPrepareStatements() PrepareStatement(CHAR_DEL_CHAR_CUF_PROFILES, "DELETE FROM character_cuf_profiles WHERE guid = ?", CONNECTION_ASYNC); // Items that hold loot or money - PrepareStatement(CHAR_SEL_ITEMCONTAINER_ITEMS, "SELECT container_id, item_id, item_count, follow_rules, ffa, blocked, counted, under_threshold, needs_quest, rnd_bonus, context, bonus_list_ids FROM item_loot_items", CONNECTION_SYNCH); + PrepareStatement(CHAR_SEL_ITEMCONTAINER_ITEMS, "SELECT container_id, item_id, item_count, item_index, follow_rules, ffa, blocked, counted, under_threshold, needs_quest, rnd_bonus, context, bonus_list_ids FROM item_loot_items", CONNECTION_SYNCH); PrepareStatement(CHAR_DEL_ITEMCONTAINER_ITEMS, "DELETE FROM item_loot_items WHERE container_id = ?", CONNECTION_ASYNC); - PrepareStatement(CHAR_DEL_ITEMCONTAINER_ITEM, "DELETE FROM item_loot_items WHERE container_id = ? AND item_id = ? AND item_count = ?", CONNECTION_ASYNC); - PrepareStatement(CHAR_INS_ITEMCONTAINER_ITEMS, "INSERT INTO item_loot_items (container_id, item_id, item_count, follow_rules, ffa, blocked, counted, under_threshold, needs_quest, rnd_bonus, context, bonus_list_ids) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)", CONNECTION_ASYNC); + PrepareStatement(CHAR_DEL_ITEMCONTAINER_ITEM, "DELETE FROM item_loot_items WHERE container_id = ? AND item_id = ? AND item_count = ? AND item_index = ?", CONNECTION_ASYNC); + PrepareStatement(CHAR_INS_ITEMCONTAINER_ITEMS, "INSERT INTO item_loot_items (container_id, item_id, item_count, item_index, follow_rules, ffa, blocked, counted, under_threshold, needs_quest, rnd_bonus, context, bonus_list_ids) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)", CONNECTION_ASYNC); PrepareStatement(CHAR_SEL_ITEMCONTAINER_MONEY, "SELECT container_id, money FROM item_loot_money", CONNECTION_SYNCH); PrepareStatement(CHAR_DEL_ITEMCONTAINER_MONEY, "DELETE FROM item_loot_money WHERE container_id = ?", CONNECTION_ASYNC); PrepareStatement(CHAR_INS_ITEMCONTAINER_MONEY, "INSERT INTO item_loot_money (container_id, money) VALUES (?, ?)", CONNECTION_ASYNC); diff --git a/src/server/game/Entities/Player/Player.cpp b/src/server/game/Entities/Player/Player.cpp index 7af4a73643d..188294332ac 100644 --- a/src/server/game/Entities/Player/Player.cpp +++ b/src/server/game/Entities/Player/Player.cpp @@ -26610,7 +26610,7 @@ void Player::StoreLootItem(uint8 lootSlot, Loot* loot, AELootResult* aeResult/* // LootItem is being removed (looted) from the container, delete it from the DB. if (!loot->containerID.IsEmpty()) - sLootItemStorage->RemoveStoredLootItemForContainer(loot->containerID.GetCounter(), item->itemid, item->count); + sLootItemStorage->RemoveStoredLootItemForContainer(loot->containerID.GetCounter(), item->itemid, item->count, item->itemIndex); } else SendEquipError(msg, nullptr, nullptr, item->itemid); diff --git a/src/server/game/Loot/Loot.cpp b/src/server/game/Loot/Loot.cpp index 4853ef765f6..4ec7b9b484e 100644 --- a/src/server/game/Loot/Loot.cpp +++ b/src/server/game/Loot/Loot.cpp @@ -304,6 +304,7 @@ void Loot::AddItem(LootStoreItem const& item) LootItem generatedLoot(item); generatedLoot.context = _itemContext; generatedLoot.count = std::min(count, proto->GetMaxStackSize()); + generatedLoot.itemIndex = lootItems.size(); if (_itemContext != ItemContext::NONE) { std::set<uint32> bonusListIDs = sDB2Manager.GetDefaultItemBonusTree(generatedLoot.itemid, _itemContext); diff --git a/src/server/game/Loot/Loot.h b/src/server/game/Loot/Loot.h index f58b3e7de0d..a1bd2d26a6c 100644 --- a/src/server/game/Loot/Loot.h +++ b/src/server/game/Loot/Loot.h @@ -134,12 +134,13 @@ enum LootSlotType struct TC_GAME_API LootItem { uint32 itemid; + uint32 itemIndex; ItemRandomBonusListId randomBonusListId; std::vector<int32> BonusListIDs; ItemContext context; - ConditionContainer conditions; // additional loot condition + ConditionContainer conditions; // additional loot condition GuidSet allowedGUIDs; - ObjectGuid rollWinnerGUID; // Stores the guid of person who won loot, if his bags are full only he can see the item in loot list! + ObjectGuid rollWinnerGUID; // Stores the guid of person who won loot, if his bags are full only he can see the item in loot list! uint8 count : 8; bool is_looted : 1; bool is_blocked : 1; @@ -154,7 +155,7 @@ struct TC_GAME_API LootItem explicit LootItem(LootStoreItem const& li); // Empty constructor for creating an empty LootItem to be filled in with DB data - LootItem() : itemid(0), randomBonusListId(0), context(ItemContext::NONE), count(0), is_looted(false), is_blocked(false), + LootItem() : itemid(0), itemIndex(0), randomBonusListId(0), context(ItemContext::NONE), count(0), is_looted(false), is_blocked(false), freeforall(false), is_underthreshold(false), is_counted(false), needs_quest(false), follow_loot_rules(false) { }; // Basic checks for player/item compatibility - if false no chance to see the item in the loot diff --git a/src/server/game/Loot/LootItemStorage.cpp b/src/server/game/Loot/LootItemStorage.cpp index f4ada654012..7153f1179f8 100644 --- a/src/server/game/Loot/LootItemStorage.cpp +++ b/src/server/game/Loot/LootItemStorage.cpp @@ -80,15 +80,16 @@ void LootItemStorage::LoadStorageFromDB() LootItem lootItem; lootItem.itemid = fields[1].GetUInt32(); lootItem.count = fields[2].GetUInt32(); - lootItem.follow_loot_rules = fields[3].GetBool(); - lootItem.freeforall = fields[4].GetBool(); - lootItem.is_blocked = fields[5].GetBool(); - lootItem.is_counted = fields[6].GetBool(); - lootItem.is_underthreshold = fields[7].GetBool(); - lootItem.needs_quest = fields[8].GetBool(); - lootItem.randomBonusListId = fields[9].GetUInt32(); - lootItem.context = ItemContext(fields[10].GetUInt8()); - for (std::string_view bonusList : Trinity::Tokenize(fields[11].GetStringView(), ' ', false)) + lootItem.itemIndex = fields[3].GetUInt32(); + lootItem.follow_loot_rules = fields[4].GetBool(); + lootItem.freeforall = fields[5].GetBool(); + lootItem.is_blocked = fields[6].GetBool(); + lootItem.is_counted = fields[7].GetBool(); + lootItem.is_underthreshold = fields[8].GetBool(); + lootItem.needs_quest = fields[9].GetBool(); + lootItem.randomBonusListId = fields[10].GetUInt32(); + lootItem.context = ItemContext(fields[11].GetUInt8()); + for (std::string_view bonusList : Trinity::Tokenize(fields[12].GetStringView(), ' ', false)) if (Optional<int32> bonusListID = Trinity::StringTo<int32>(bonusList)) lootItem.BonusListIDs.push_back(*bonusListID); @@ -221,7 +222,7 @@ void LootItemStorage::RemoveStoredLootForContainer(uint64 containerId) CharacterDatabase.CommitTransaction(trans); } -void LootItemStorage::RemoveStoredLootItemForContainer(uint64 containerId, uint32 itemId, uint32 count) +void LootItemStorage::RemoveStoredLootItemForContainer(uint64 containerId, uint32 itemId, uint32 count, uint32 itemIndex) { // write std::unique_lock<std::shared_mutex> lock(*GetLock()); @@ -230,7 +231,7 @@ void LootItemStorage::RemoveStoredLootItemForContainer(uint64 containerId, uint3 if (itr == _lootItemStore.end()) return; - itr->second.RemoveItem(itemId, count); + itr->second.RemoveItem(itemId, count, itemIndex); } void LootItemStorage::AddNewStoredLoot(Loot* loot, Player* player) @@ -296,22 +297,23 @@ void StoredLootContainer::AddLootItem(LootItem const& lootItem, CharacterDatabas CharacterDatabasePreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_INS_ITEMCONTAINER_ITEMS); - // container_id, item_id, item_count, follow_rules, ffa, blocked, counted, under_threshold, needs_quest, rnd_prop, rnd_suffix + // container_id, item_id, item_count, item_index, follow_rules, ffa, blocked, counted, under_threshold, needs_quest, rnd_prop, rnd_suffix stmt->setUInt64(0, _containerId); stmt->setUInt32(1, lootItem.itemid); stmt->setUInt32(2, lootItem.count); - stmt->setBool(3, lootItem.follow_loot_rules); - stmt->setBool(4, lootItem.freeforall); - stmt->setBool(5, lootItem.is_blocked); - stmt->setBool(6, lootItem.is_counted); - stmt->setBool(7, lootItem.is_underthreshold); - stmt->setBool(8, lootItem.needs_quest); - stmt->setInt32(9, lootItem.randomBonusListId); - stmt->setUInt8(10, AsUnderlyingType(lootItem.context)); + stmt->setUInt32(3, lootItem.itemIndex); + stmt->setBool(4, lootItem.follow_loot_rules); + stmt->setBool(5, lootItem.freeforall); + stmt->setBool(6, lootItem.is_blocked); + stmt->setBool(7, lootItem.is_counted); + stmt->setBool(8, lootItem.is_underthreshold); + stmt->setBool(9, lootItem.needs_quest); + stmt->setInt32(10, lootItem.randomBonusListId); + stmt->setUInt8(11, AsUnderlyingType(lootItem.context)); std::ostringstream bonusListIDs; for (int32 bonusListID : lootItem.BonusListIDs) bonusListIDs << bonusListID << ' '; - stmt->setString(11, bonusListIDs.str()); + stmt->setString(12, bonusListIDs.str()); trans->Append(stmt); } @@ -340,7 +342,7 @@ void StoredLootContainer::RemoveMoney() CharacterDatabase.Execute(stmt); } -void StoredLootContainer::RemoveItem(uint32 itemId, uint32 count) +void StoredLootContainer::RemoveItem(uint32 itemId, uint32 count, uint32 itemIndex) { auto bounds = _lootItems.equal_range(itemId); for (auto itr = bounds.first; itr != bounds.second; ++itr) @@ -357,5 +359,6 @@ void StoredLootContainer::RemoveItem(uint32 itemId, uint32 count) stmt->setUInt64(0, _containerId); stmt->setUInt32(1, itemId); stmt->setUInt32(2, count); + stmt->setUInt32(3, itemIndex); CharacterDatabase.Execute(stmt); } diff --git a/src/server/game/Loot/LootItemStorage.h b/src/server/game/Loot/LootItemStorage.h index 700ebb1048a..16ae71e415f 100644 --- a/src/server/game/Loot/LootItemStorage.h +++ b/src/server/game/Loot/LootItemStorage.h @@ -60,7 +60,7 @@ class StoredLootContainer void AddMoney(uint32 money, CharacterDatabaseTransaction trans); void RemoveMoney(); - void RemoveItem(uint32 itemId, uint32 count); + void RemoveItem(uint32 itemId, uint32 count, uint32 itemIndex); uint32 GetContainer() const { return _containerId; } uint32 GetMoney() const { return _money; } @@ -82,7 +82,7 @@ class LootItemStorage bool LoadStoredLoot(Item* item, Player* player); void RemoveStoredMoneyForContainer(uint64 containerId); void RemoveStoredLootForContainer(uint64 containerId); - void RemoveStoredLootItemForContainer(uint64 containerId, uint32 itemId, uint32 count); + void RemoveStoredLootItemForContainer(uint64 containerId, uint32 itemId, uint32 count, uint32 itemIndex); void AddNewStoredLoot(Loot* loot, Player* player); private: |