From 04f08d26a72ab29b11fc2aaef65bc54078cc2086 Mon Sep 17 00:00:00 2001 From: MrSmite Date: Fri, 14 Dec 2012 00:46:36 -0500 Subject: Implements saving of loot (items / money) contained inside lootable inventory items. * Unlooted items / money persist across player sessions * Loot inside items is tied to the item rather than the player so if trading partially looted items becomes possible, this implementation will still work * New tables added: characters_database.sql (first time users) characters_create_item_loot.sql (existing users) Implementation Can be tested with: Watertight Trunk [21113] Bulging Sack of Gems [25422] Fat Sack of Coins [11937] Closes #2048 --- src/server/shared/Database/Implementation/CharacterDatabase.cpp | 9 +++++++++ src/server/shared/Database/Implementation/CharacterDatabase.h | 8 ++++++++ 2 files changed, 17 insertions(+) (limited to 'src/server/shared/Database/Implementation') diff --git a/src/server/shared/Database/Implementation/CharacterDatabase.cpp b/src/server/shared/Database/Implementation/CharacterDatabase.cpp index 33f0cab5170..3ef94f3aafd 100644 --- a/src/server/shared/Database/Implementation/CharacterDatabase.cpp +++ b/src/server/shared/Database/Implementation/CharacterDatabase.cpp @@ -540,6 +540,15 @@ void CharacterDatabaseConnection::DoPrepareStatements() PREPARE_STATEMENT(CHAR_DEL_CHAR_ACTION_EXCEPT_SPEC, "DELETE FROM character_action WHERE spec<>? AND guid = ?", CONNECTION_ASYNC); PREPARE_STATEMENT(CHAR_SEL_CHAR_PET_BY_ENTRY_AND_SLOT, "SELECT id, entry, owner, modelid, level, exp, Reactstate, slot, name, renamed, curhealth, curmana, curhappiness, abdata, savetime, CreatedBySpell, PetType FROM character_pet WHERE owner = ? AND slot = ?", CONNECTION_SYNCH); + // Items that hold loot or money + PREPARE_STATEMENT(CHAR_SEL_ITEMCONTAINER_ITEMS, "SELECT item_id, item_count, follow_rules, ffa, blocked, counted, under_threshold, needs_quest, rnd_prop, rnd_suffix FROM item_loot_items WHERE container_id = ?", CONNECTION_SYNCH); + PREPARE_STATEMENT(CHAR_DEL_ITEMCONTAINER_ITEMS, "DELETE FROM item_loot_items WHERE container_id = ?", CONNECTION_ASYNC); + PREPARE_STATEMENT(CHAR_DEL_ITEMCONTAINER_ITEM, "DELETE FROM item_loot_items WHERE container_id = ? AND item_id = ?", CONNECTION_ASYNC); + PREPARE_STATEMENT(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_prop, rnd_suffix) VALUES (?,?,?,?,?,?,?,?,?,?,?)", CONNECTION_ASYNC); + PREPARE_STATEMENT(CHAR_SEL_ITEMCONTAINER_MONEY, "SELECT money FROM item_loot_money WHERE container_id = ?", CONNECTION_SYNCH); + PREPARE_STATEMENT(CHAR_DEL_ITEMCONTAINER_MONEY, "DELETE FROM item_loot_money WHERE container_id = ?", CONNECTION_ASYNC); + PREPARE_STATEMENT(CHAR_INS_ITEMCONTAINER_MONEY," INSERT INTO item_loot_money (container_id, money) VALUES (?,?)", CONNECTION_ASYNC); + // Calendar PREPARE_STATEMENT(CHAR_REP_CALENDAR_EVENT, "REPLACE INTO calendar_events (id, creator, title, description, type, dungeon, eventtime, flags, time2) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)", CONNECTION_ASYNC); PREPARE_STATEMENT(CHAR_DEL_CALENDAR_EVENT, "DELETE FROM calendar_events WHERE id = ?", CONNECTION_ASYNC); diff --git a/src/server/shared/Database/Implementation/CharacterDatabase.h b/src/server/shared/Database/Implementation/CharacterDatabase.h index 181161978df..d2e69fb0d17 100644 --- a/src/server/shared/Database/Implementation/CharacterDatabase.h +++ b/src/server/shared/Database/Implementation/CharacterDatabase.h @@ -505,6 +505,14 @@ enum CharacterDatabaseStatements CHAR_REP_CALENDAR_INVITE, CHAR_DEL_CALENDAR_INVITE, + CHAR_SEL_ITEMCONTAINER_ITEMS, + CHAR_DEL_ITEMCONTAINER_ITEMS, + CHAR_DEL_ITEMCONTAINER_ITEM, + CHAR_INS_ITEMCONTAINER_ITEMS, + CHAR_SEL_ITEMCONTAINER_MONEY, + CHAR_DEL_ITEMCONTAINER_MONEY, + CHAR_INS_ITEMCONTAINER_MONEY, + MAX_CHARACTERDATABASE_STATEMENTS }; -- cgit v1.2.3 From 63ea4b1056dd6fc8b25f580331307d14bdcc26d2 Mon Sep 17 00:00:00 2001 From: Vincent_Michael Date: Fri, 21 Dec 2012 22:22:36 +0100 Subject: Core: Fix some codestyle in 957571e18c4d6e5874ce1052ae49e4d0d21018be --- src/server/game/Entities/Item/Item.cpp | 15 +++++++-------- src/server/game/Entities/Item/Item.h | 2 +- src/server/game/Handlers/LootHandler.cpp | 2 ++ src/server/game/Loot/LootMgr.h | 2 +- .../shared/Database/Implementation/CharacterDatabase.cpp | 4 ++-- 5 files changed, 13 insertions(+), 12 deletions(-) (limited to 'src/server/shared/Database/Implementation') diff --git a/src/server/game/Entities/Item/Item.cpp b/src/server/game/Entities/Item/Item.cpp index 5303fb8dc38..dd54a3d39db 100644 --- a/src/server/game/Entities/Item/Item.cpp +++ b/src/server/game/Entities/Item/Item.cpp @@ -1210,7 +1210,6 @@ bool Item::CheckSoulboundTradeExpire() void Item::ItemContainerSaveLootToDB() { // Saves the money and item loot associated with an openable item to the DB - if (loot.isLooted()) // no money and no loot return; @@ -1235,7 +1234,7 @@ void Item::ItemContainerSaveLootToDB() // Save items if (!loot.isLooted()) { - + PreparedStatement* stmt_items = CharacterDatabase.GetPreparedStatement(CHAR_DEL_ITEMCONTAINER_ITEMS); stmt_items->setUInt32(0, container_id); trans->Append(stmt_items); @@ -1272,7 +1271,6 @@ void Item::ItemContainerSaveLootToDB() bool Item::ItemContainerLoadLootFromDB() { // Loads the money and item loot associated with an openable item from the DB - // Default. If there are no records for this item then it will be rolled for in Player::SendLoot() m_lootGenerated = false; @@ -1335,18 +1333,19 @@ bool Item::ItemContainerLoadLootFromDB() // Finally add the LootItem to the container loot.items.push_back(loot_item); - + // Increment unlooted count loot.unlootedCount++; - } while (item_result->NextRow()); + } + while (item_result->NextRow()); } } - // Mark the item if it has loot so it won't be generated again on open - m_lootGenerated = !loot.isLooted(); + // Mark the item if it has loot so it won't be generated again on open + m_lootGenerated = !loot.isLooted(); - return m_lootGenerated; + return m_lootGenerated; } void Item::ItemContainerDeleteLootItemsFromDB() diff --git a/src/server/game/Entities/Item/Item.h b/src/server/game/Entities/Item/Item.h index 2e1956250f3..ffe31ed765e 100644 --- a/src/server/game/Entities/Item/Item.h +++ b/src/server/game/Entities/Item/Item.h @@ -231,7 +231,7 @@ class Item : public Object static void DeleteFromDB(SQLTransaction& trans, uint32 itemGuid); virtual void DeleteFromDB(SQLTransaction& trans); static void DeleteFromInventoryDB(SQLTransaction& trans, uint32 itemGuid); - + // Lootable items and their contents void ItemContainerSaveLootToDB(); bool ItemContainerLoadLootFromDB(); diff --git a/src/server/game/Handlers/LootHandler.cpp b/src/server/game/Handlers/LootHandler.cpp index b15636e75d2..92ba5237c68 100644 --- a/src/server/game/Handlers/LootHandler.cpp +++ b/src/server/game/Handlers/LootHandler.cpp @@ -393,8 +393,10 @@ void WorldSession::DoLootRelease(uint64 lguid) player->DestroyItemCount(pItem, count, true); } else + { if (pItem->loot.isLooted()) // Only delete item if no loot or money (unlooted loot is saved to db) player->DestroyItem(pItem->GetBagSlot(), pItem->GetSlot(), true); + } return; // item can be looted only single player } else diff --git a/src/server/game/Loot/LootMgr.h b/src/server/game/Loot/LootMgr.h index cfa5d370e3b..89425e1ee66 100644 --- a/src/server/game/Loot/LootMgr.h +++ b/src/server/game/Loot/LootMgr.h @@ -290,7 +290,7 @@ struct Loot uint8 unlootedCount; uint64 roundRobinPlayer; // GUID of the player having the Round-Robin ownership for the loot. If 0, round robin owner has released. LootType loot_type; // required for achievement system - + // GUIDLow of container that holds this loot (item_instance.entry) // Only set for inventory items that can be right-click looted uint32 containerID; diff --git a/src/server/shared/Database/Implementation/CharacterDatabase.cpp b/src/server/shared/Database/Implementation/CharacterDatabase.cpp index 3ef94f3aafd..b36513ba3bb 100644 --- a/src/server/shared/Database/Implementation/CharacterDatabase.cpp +++ b/src/server/shared/Database/Implementation/CharacterDatabase.cpp @@ -544,10 +544,10 @@ void CharacterDatabaseConnection::DoPrepareStatements() PREPARE_STATEMENT(CHAR_SEL_ITEMCONTAINER_ITEMS, "SELECT item_id, item_count, follow_rules, ffa, blocked, counted, under_threshold, needs_quest, rnd_prop, rnd_suffix FROM item_loot_items WHERE container_id = ?", CONNECTION_SYNCH); PREPARE_STATEMENT(CHAR_DEL_ITEMCONTAINER_ITEMS, "DELETE FROM item_loot_items WHERE container_id = ?", CONNECTION_ASYNC); PREPARE_STATEMENT(CHAR_DEL_ITEMCONTAINER_ITEM, "DELETE FROM item_loot_items WHERE container_id = ? AND item_id = ?", CONNECTION_ASYNC); - PREPARE_STATEMENT(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_prop, rnd_suffix) VALUES (?,?,?,?,?,?,?,?,?,?,?)", CONNECTION_ASYNC); + PREPARE_STATEMENT(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_prop, rnd_suffix) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)", CONNECTION_ASYNC); PREPARE_STATEMENT(CHAR_SEL_ITEMCONTAINER_MONEY, "SELECT money FROM item_loot_money WHERE container_id = ?", CONNECTION_SYNCH); PREPARE_STATEMENT(CHAR_DEL_ITEMCONTAINER_MONEY, "DELETE FROM item_loot_money WHERE container_id = ?", CONNECTION_ASYNC); - PREPARE_STATEMENT(CHAR_INS_ITEMCONTAINER_MONEY," INSERT INTO item_loot_money (container_id, money) VALUES (?,?)", CONNECTION_ASYNC); + PREPARE_STATEMENT(CHAR_INS_ITEMCONTAINER_MONEY, "INSERT INTO item_loot_money (container_id, money) VALUES (?, ?)", CONNECTION_ASYNC); // Calendar PREPARE_STATEMENT(CHAR_REP_CALENDAR_EVENT, "REPLACE INTO calendar_events (id, creator, title, description, type, dungeon, eventtime, flags, time2) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)", CONNECTION_ASYNC); -- cgit v1.2.3