Core/Loot: implement Loot Item Storage

Port From (https://github.com/TrinityCore/TrinityCore/commit/090fd8304a7a6e2f7c233ac39c94ccc67cc816f8)
This commit is contained in:
hondacrx
2020-05-12 17:11:14 -04:00
parent 9f235e1659
commit 1315f2c7f5
11 changed files with 403 additions and 247 deletions
+2 -184
View File
@@ -366,7 +366,7 @@ namespace Game.Entities
// Delete the items if this is a container
if (!loot.IsLooted())
ItemContainerDeleteLootMoneyAndLootItemsFromDB();
Global.LootItemStorage.RemoveStoredLootForContainer(GetGUID().GetCounter());
Dispose();
return;
@@ -662,7 +662,7 @@ namespace Game.Entities
// Delete the items if this is a container
if (!loot.IsLooted())
ItemContainerDeleteLootMoneyAndLootItemsFromDB();
Global.LootItemStorage.RemoveStoredLootForContainer(GetGUID().GetCounter());
}
public static void DeleteFromInventoryDB(SQLTransaction trans, ulong itemGuid)
@@ -1744,188 +1744,6 @@ namespace Game.Entities
return proto.GetSellPrice();
}
public void ItemContainerSaveLootToDB()
{
// Saves the money and item loot associated with an openable item to the DB
if (loot.IsLooted()) // no money and no loot
return;
SQLTransaction trans = new SQLTransaction();
loot.containerID = GetGUID(); // Save this for when a LootItem is removed
// Save money
if (loot.gold > 0)
{
PreparedStatement stmt_money = DB.Characters.GetPreparedStatement(CharStatements.DEL_ITEMCONTAINER_MONEY);
stmt_money.AddValue(0, loot.containerID.GetCounter());
trans.Append(stmt_money);
stmt_money = DB.Characters.GetPreparedStatement(CharStatements.INS_ITEMCONTAINER_MONEY);
stmt_money.AddValue(0, loot.containerID.GetCounter());
stmt_money.AddValue(1, loot.gold);
trans.Append(stmt_money);
}
// Save items
if (!loot.IsLooted())
{
PreparedStatement stmt_items = DB.Characters.GetPreparedStatement(CharStatements.DEL_ITEMCONTAINER_ITEMS);
stmt_items.AddValue(0, loot.containerID.GetCounter());
trans.Append(stmt_items);
// Now insert the items
foreach (var _li in loot.items)
{
// When an item is looted, it doesn't get removed from the items collection
// but we don't want to resave it.
if (!_li.canSave)
continue;
Player guid = GetOwner();
if (!_li.AllowedForPlayer(guid))
continue;
stmt_items = DB.Characters.GetPreparedStatement(CharStatements.INS_ITEMCONTAINER_ITEMS);
// container_id, item_id, item_count, follow_rules, ffa, blocked, counted, under_threshold, needs_quest, rnd_prop, context, bonus_list_ids
stmt_items.AddValue(0, loot.containerID.GetCounter());
stmt_items.AddValue(1, _li.itemid);
stmt_items.AddValue(2, _li.count);
stmt_items.AddValue(3, _li.follow_loot_rules);
stmt_items.AddValue(4, _li.freeforall);
stmt_items.AddValue(5, _li.is_blocked);
stmt_items.AddValue(6, _li.is_counted);
stmt_items.AddValue(7, _li.is_underthreshold);
stmt_items.AddValue(8, _li.needs_quest);
stmt_items.AddValue(9, _li.randomBonusListId);
stmt_items.AddValue(10, _li.context);
string bonusListIDs = "";
foreach (int bonusListID in _li.BonusListIDs)
bonusListIDs += bonusListID + ' ';
stmt_items.AddValue(11, bonusListIDs);
trans.Append(stmt_items);
}
}
DB.Characters.CommitTransaction(trans);
}
public bool 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;
// Save this for later use
loot.containerID = GetGUID();
// First, see if there was any money loot. This gets added directly to the container.
PreparedStatement stmt = DB.Characters.GetPreparedStatement(CharStatements.SEL_ITEMCONTAINER_MONEY);
stmt.AddValue(0, loot.containerID.GetCounter());
SQLResult money_result = DB.Characters.Query(stmt);
if (!money_result.IsEmpty())
{
loot.gold = money_result.Read<uint>(0);
}
// Next, load any items that were saved
stmt = DB.Characters.GetPreparedStatement(CharStatements.SEL_ITEMCONTAINER_ITEMS);
stmt.AddValue(0, loot.containerID.GetCounter());
SQLResult item_result = DB.Characters.Query(stmt);
if (!item_result.IsEmpty())
{
// Get a LootTemplate for the container item. This is where
// the saved loot was originally rolled from, we will copy conditions from it
LootTemplate lt = LootStorage.Items.GetLootFor(GetEntry());
if (lt != null)
{
do
{
// Create an empty LootItem
LootItem loot_item = new LootItem();
// item_id, itm_count, follow_rules, ffa, blocked, counted, under_threshold, needs_quest, rnd_prop, context, bonus_list_ids
loot_item.itemid = item_result.Read<uint>(0);
loot_item.count = item_result.Read<byte>(1);
loot_item.follow_loot_rules = item_result.Read<bool>(2);
loot_item.freeforall = item_result.Read<bool>(3);
loot_item.is_blocked = item_result.Read<bool>(4);
loot_item.is_counted = item_result.Read<bool>(5);
loot_item.canSave = true;
loot_item.is_underthreshold = item_result.Read<bool>(6);
loot_item.needs_quest = item_result.Read<bool>(7);
loot_item.randomBonusListId = item_result.Read<uint>(8);
loot_item.context = (ItemContext)item_result.Read<byte>(9);
StringArray bonusLists = new StringArray(item_result.Read<string>(10), ' ');
if (!bonusLists.IsEmpty())
{
foreach (string line in bonusLists)
{
if (uint.TryParse(line, out uint id))
loot_item.BonusListIDs.Add(id);
}
}
// Copy the extra loot conditions from the item in the loot template
lt.CopyConditions(loot_item);
// If container item is in a bag, add that player as an allowed looter
if (GetBagSlot() != 0)
loot_item.AddAllowedLooter(GetOwner());
// Finally add the LootItem to the container
loot.items.Add(loot_item);
// Increment unlooted count
loot.unlootedCount++;
}
while (item_result.NextRow());
}
}
// Mark the item if it has loot so it won't be generated again on open
m_lootGenerated = !loot.IsLooted();
return m_lootGenerated;
}
void ItemContainerDeleteLootItemsFromDB()
{
// Deletes items associated with an openable item from the DB
PreparedStatement stmt = DB.Characters.GetPreparedStatement(CharStatements.DEL_ITEMCONTAINER_ITEMS);
stmt.AddValue(0, GetGUID().GetCounter());
DB.Characters.Execute(stmt);
}
void ItemContainerDeleteLootItemFromDB(uint itemID)
{
// Deletes a single item associated with an openable item from the DB
PreparedStatement stmt = DB.Characters.GetPreparedStatement(CharStatements.DEL_ITEMCONTAINER_ITEM);
stmt.AddValue(0, GetGUID().GetCounter());
stmt.AddValue(1, itemID);
DB.Characters.Execute(stmt);
}
void ItemContainerDeleteLootMoneyFromDB()
{
// Deletes the money loot associated with an openable item from the DB
PreparedStatement stmt = DB.Characters.GetPreparedStatement(CharStatements.DEL_ITEMCONTAINER_MONEY);
stmt.AddValue(0, GetGUID().GetCounter());
DB.Characters.Execute(stmt);
}
public void ItemContainerDeleteLootMoneyAndLootItemsFromDB()
{
// Deletes money and items associated with an openable item from the DB
ItemContainerDeleteLootMoneyFromDB();
ItemContainerDeleteLootItemsFromDB();
}
public uint GetItemLevel(Player owner)
{
ItemTemplate itemTemplate = GetTemplate();