mirror of
https://github.com/EQEmu/Server.git
synced 2026-01-04 15:43:52 +00:00
Saving and loading of guids for items, still needs a lot of work, esp with corpses. No auditing yet
This commit is contained in:
parent
593127fb7e
commit
d6bdaa5c6e
@ -24,16 +24,16 @@
|
||||
#include "rulesys.h"
|
||||
#include "shareddb.h"
|
||||
#include "strings.h"
|
||||
|
||||
#include "util/uuid.h"
|
||||
//#include "../common/light_source.h"
|
||||
|
||||
#include <limits.h>
|
||||
|
||||
//#include <iostream>
|
||||
|
||||
int32 NextItemInstSerialNumber = 1;
|
||||
uint32 NextItemInstSerialNumber = 1;
|
||||
|
||||
static inline int32 GetNextItemInstSerialNumber() {
|
||||
static inline uint32 GetNextItemInstSerialNumber() {
|
||||
|
||||
// The Bazaar relies on each item a client has up for Trade having a unique
|
||||
// identifier. This 'SerialNumber' is sent in Serialized item packets and
|
||||
@ -45,7 +45,7 @@ static inline int32 GetNextItemInstSerialNumber() {
|
||||
// NextItemInstSerialNumber is the next one to hand out.
|
||||
//
|
||||
// It is very unlikely to reach 2,147,483,647. Maybe we should call abort(), rather than wrapping back to 1.
|
||||
if(NextItemInstSerialNumber >= INT_MAX)
|
||||
if(NextItemInstSerialNumber >= UINT_MAX)
|
||||
NextItemInstSerialNumber = 1;
|
||||
else
|
||||
NextItemInstSerialNumber++;
|
||||
@ -56,13 +56,21 @@ static inline int32 GetNextItemInstSerialNumber() {
|
||||
//
|
||||
// class EQ::ItemInstance
|
||||
//
|
||||
EQ::ItemInstance::ItemInstance(const ItemData* item, int16 charges) {
|
||||
EQ::ItemInstance::ItemInstance(const ItemData* item, const std::string& guid, int16 charges) {
|
||||
m_use_type = ItemInstNormal;
|
||||
if(item) {
|
||||
m_item = new ItemData(*item);
|
||||
} else {
|
||||
m_item = nullptr;
|
||||
}
|
||||
|
||||
if (guid.empty()) {
|
||||
m_guid = EQ::Util::UUID::Generate().ToString();
|
||||
}
|
||||
else {
|
||||
m_guid = guid;
|
||||
}
|
||||
|
||||
m_charges = charges;
|
||||
m_price = 0;
|
||||
m_attuned = false;
|
||||
@ -72,7 +80,7 @@ EQ::ItemInstance::ItemInstance(const ItemData* item, int16 charges) {
|
||||
else
|
||||
m_color = 0;
|
||||
m_merchantcount = 1;
|
||||
m_SerialNumber = GetNextItemInstSerialNumber();
|
||||
m_serial_number = GetNextItemInstSerialNumber();
|
||||
|
||||
m_exp = 0;
|
||||
m_evolveLvl = 0;
|
||||
@ -85,9 +93,10 @@ EQ::ItemInstance::ItemInstance(const ItemData* item, int16 charges) {
|
||||
m_ornament_hero_model = 0;
|
||||
m_recast_timestamp = 0;
|
||||
m_new_id_file = 0;
|
||||
m_currentslot = 0;
|
||||
}
|
||||
|
||||
EQ::ItemInstance::ItemInstance(SharedDatabase *db, uint32 item_id, int16 charges) {
|
||||
EQ::ItemInstance::ItemInstance(SharedDatabase *db, uint32 item_id, const std::string& guid, int16 charges) {
|
||||
m_use_type = ItemInstNormal;
|
||||
m_item = db->GetItem(item_id);
|
||||
if(m_item) {
|
||||
@ -97,6 +106,13 @@ EQ::ItemInstance::ItemInstance(SharedDatabase *db, uint32 item_id, int16 charges
|
||||
m_item = nullptr;
|
||||
}
|
||||
|
||||
if (guid.empty()) {
|
||||
m_guid = EQ::Util::UUID::Generate().ToString();
|
||||
}
|
||||
else {
|
||||
m_guid = guid;
|
||||
}
|
||||
|
||||
m_charges = charges;
|
||||
m_price = 0;
|
||||
m_merchantslot = 0;
|
||||
@ -106,7 +122,7 @@ EQ::ItemInstance::ItemInstance(SharedDatabase *db, uint32 item_id, int16 charges
|
||||
else
|
||||
m_color = 0;
|
||||
m_merchantcount = 1;
|
||||
m_SerialNumber = GetNextItemInstSerialNumber();
|
||||
m_serial_number = GetNextItemInstSerialNumber();
|
||||
|
||||
m_exp = 0;
|
||||
m_evolveLvl = 0;
|
||||
@ -119,17 +135,20 @@ EQ::ItemInstance::ItemInstance(SharedDatabase *db, uint32 item_id, int16 charges
|
||||
m_ornament_hero_model = 0;
|
||||
m_recast_timestamp = 0;
|
||||
m_new_id_file = 0;
|
||||
m_currentslot = 0;
|
||||
}
|
||||
|
||||
EQ::ItemInstance::ItemInstance(ItemInstTypes use_type) {
|
||||
m_use_type = use_type;
|
||||
|
||||
m_guid = EQ::Util::UUID::Generate().ToString();
|
||||
m_item = nullptr;
|
||||
m_charges = 0;
|
||||
m_price = 0;
|
||||
m_attuned = false;
|
||||
m_merchantslot = 0;
|
||||
m_color = 0;
|
||||
|
||||
m_serial_number = 0;
|
||||
m_exp = 0;
|
||||
m_evolveLvl = 0;
|
||||
m_activated = false;
|
||||
@ -141,6 +160,8 @@ EQ::ItemInstance::ItemInstance(ItemInstTypes use_type) {
|
||||
m_ornament_hero_model = 0;
|
||||
m_recast_timestamp = 0;
|
||||
m_new_id_file = 0;
|
||||
m_currentslot = 0;
|
||||
m_merchantcount = 0;
|
||||
}
|
||||
|
||||
// Make a copy of an EQ::ItemInstance object
|
||||
@ -152,6 +173,7 @@ EQ::ItemInstance::ItemInstance(const ItemInstance& copy)
|
||||
else
|
||||
m_item = nullptr;
|
||||
|
||||
m_guid = copy.m_guid;
|
||||
m_charges=copy.m_charges;
|
||||
m_price=copy.m_price;
|
||||
m_color=copy.m_color;
|
||||
@ -176,7 +198,7 @@ EQ::ItemInstance::ItemInstance(const ItemInstance& copy)
|
||||
for (iter = copy.m_custom_data.begin(); iter != copy.m_custom_data.end(); ++iter) {
|
||||
m_custom_data[iter->first] = iter->second;
|
||||
}
|
||||
m_SerialNumber = copy.m_SerialNumber;
|
||||
m_serial_number = copy.m_serial_number;
|
||||
m_custom_data = copy.m_custom_data;
|
||||
m_timers = copy.m_timers;
|
||||
|
||||
|
||||
@ -69,9 +69,9 @@ namespace EQ
|
||||
/////////////////////////
|
||||
|
||||
// Constructors/Destructor
|
||||
ItemInstance(const ItemData* item = nullptr, int16 charges = 0);
|
||||
ItemInstance(const ItemData* item, const std::string& guid, int16 charges);
|
||||
|
||||
ItemInstance(SharedDatabase *db, uint32 item_id, int16 charges = 0);
|
||||
ItemInstance(SharedDatabase *db, uint32 item_id, const std::string &guid, int16 charges);
|
||||
|
||||
ItemInstance(ItemInstTypes use_type);
|
||||
|
||||
@ -79,6 +79,8 @@ namespace EQ
|
||||
|
||||
~ItemInstance();
|
||||
|
||||
inline std::string GetGuid() const { return m_guid; }
|
||||
|
||||
// Query item type
|
||||
bool IsType(item::ItemClass item_class) const;
|
||||
|
||||
@ -225,11 +227,8 @@ namespace EQ
|
||||
std::string Serialize(int16 slot_id) const { InternalSerializedItem_Struct s; s.slot_id = slot_id; s.inst = (const void*)this; std::string ser; ser.assign((char*)&s, sizeof(InternalSerializedItem_Struct)); return ser; }
|
||||
void Serialize(OutBuffer& ob, int16 slot_id) const { InternalSerializedItem_Struct isi; isi.slot_id = slot_id; isi.inst = (const void*)this; ob.write((const char*)&isi, sizeof(isi)); }
|
||||
|
||||
inline int32 GetSerialNumber() const { return m_SerialNumber; }
|
||||
inline void SetSerialNumber(int32 id) { m_SerialNumber = id; }
|
||||
|
||||
inline std::string GetGUID() const { return m_guid; }
|
||||
inline void SetGUID(const std::string &guid) { m_guid = guid; }
|
||||
inline int32 GetSerialNumber() const { return m_serial_number; }
|
||||
inline void SetSerialNumber(int32 id) { m_serial_number = id; }
|
||||
|
||||
std::map<std::string, ::Timer>& GetTimers() { return m_timers; }
|
||||
void SetTimer(std::string name, uint32 time);
|
||||
@ -306,6 +305,7 @@ namespace EQ
|
||||
|
||||
void _PutItem(uint8 index, ItemInstance* inst) { m_contents[index] = inst; }
|
||||
|
||||
std::string m_guid;
|
||||
ItemInstTypes m_use_type; // Usage type for item
|
||||
const ItemData* m_item; // Ptr to item data
|
||||
int16 m_charges; // # of charges for chargeable items
|
||||
@ -315,8 +315,7 @@ namespace EQ
|
||||
int16 m_currentslot;
|
||||
bool m_attuned;
|
||||
int32 m_merchantcount; //number avaliable on the merchant, -1=unlimited
|
||||
int32 m_SerialNumber; // Unique identifier for this instance of an item. Needed for Bazaar.
|
||||
std::string m_guid;
|
||||
uint32 m_serial_number; // Unique identifier for this instance of an item. Needed for Bazaar.
|
||||
uint32 m_exp;
|
||||
int8 m_evolveLvl;
|
||||
bool m_activated;
|
||||
|
||||
@ -295,11 +295,11 @@ bool SharedDatabase::UpdateInventorySlot(uint32 char_id, const EQ::ItemInstance*
|
||||
|
||||
// Update/Insert item
|
||||
const std::string query = StringFormat("REPLACE INTO inventory "
|
||||
"(charid, slotid, itemid, charges, instnodrop, custom_data, color, "
|
||||
"(guid, charid, slotid, itemid, charges, instnodrop, custom_data, color, "
|
||||
"augslot1, augslot2, augslot3, augslot4, augslot5, augslot6, ornamenticon, ornamentidfile, ornament_hero_model) "
|
||||
"VALUES( %lu, %lu, %lu, %lu, %lu, '%s', %lu, "
|
||||
"VALUES( '%s', %lu, %lu, %lu, %lu, %lu, '%s', %lu, "
|
||||
"%lu, %lu, %lu, %lu, %lu, %lu, %lu, %lu, %lu)",
|
||||
static_cast<unsigned long>(char_id), static_cast<unsigned long>(slot_id), static_cast<unsigned long>(inst->GetItem()->ID),
|
||||
inst->GetGuid().c_str(), static_cast<unsigned long>(char_id), static_cast<unsigned long>(slot_id), static_cast<unsigned long>(inst->GetItem()->ID),
|
||||
static_cast<unsigned long>(charges), static_cast<unsigned long>(inst->IsAttuned() ? 1 : 0),
|
||||
inst->GetCustomDataString().c_str(), static_cast<unsigned long>(inst->GetColor()),
|
||||
static_cast<unsigned long>(augslot[0]), static_cast<unsigned long>(augslot[1]), static_cast<unsigned long>(augslot[2]),
|
||||
@ -343,11 +343,11 @@ bool SharedDatabase::UpdateSharedBankSlot(uint32 char_id, const EQ::ItemInstance
|
||||
charges = 0x7FFF;
|
||||
|
||||
const std::string query = StringFormat("REPLACE INTO sharedbank "
|
||||
"(acctid, slotid, itemid, charges, custom_data, "
|
||||
"(guid, acctid, slotid, itemid, charges, custom_data, "
|
||||
"augslot1, augslot2, augslot3, augslot4, augslot5, augslot6) "
|
||||
"VALUES( %lu, %lu, %lu, %lu, '%s', "
|
||||
"VALUES( '%s', %lu, %lu, %lu, %lu, '%s', "
|
||||
"%lu, %lu, %lu, %lu, %lu, %lu)",
|
||||
static_cast<unsigned long>(account_id), static_cast<unsigned long>(slot_id), static_cast<unsigned long>(inst->GetItem()->ID),
|
||||
inst->GetGuid().c_str(), static_cast<unsigned long>(account_id), static_cast<unsigned long>(slot_id), static_cast<unsigned long>(inst->GetItem()->ID),
|
||||
static_cast<unsigned long>(charges), inst->GetCustomDataString().c_str(), static_cast<unsigned long>(augslot[0]),
|
||||
static_cast<unsigned long>(augslot[1]), static_cast<unsigned long>(augslot[2]), static_cast<unsigned long>(augslot[3]), static_cast<unsigned long>(augslot[4]),
|
||||
static_cast<unsigned long>(augslot[5]));
|
||||
@ -481,7 +481,7 @@ bool SharedDatabase::SetStartingItems(PlayerProfile_Struct* pp, EQ::InventoryPro
|
||||
if(!myitem)
|
||||
continue;
|
||||
|
||||
const EQ::ItemInstance* myinst = CreateBaseItem(myitem, charges);
|
||||
const EQ::ItemInstance* myinst = CreateBaseItem(myitem, "", charges);
|
||||
|
||||
if(slot < 0)
|
||||
slot = inv->FindFreeSlot(0, 0);
|
||||
@ -502,14 +502,14 @@ bool SharedDatabase::GetSharedBank(uint32 id, EQ::InventoryProfile *inv, bool is
|
||||
if (is_charid)
|
||||
query = StringFormat("SELECT sb.slotid, sb.itemid, sb.charges, "
|
||||
"sb.augslot1, sb.augslot2, sb.augslot3, "
|
||||
"sb.augslot4, sb.augslot5, sb.augslot6, sb.custom_data "
|
||||
"sb.augslot4, sb.augslot5, sb.augslot6, sb.custom_data, sb.guid "
|
||||
"FROM sharedbank sb INNER JOIN character_data ch "
|
||||
"ON ch.account_id=sb.acctid WHERE ch.id = %i ORDER BY sb.slotid",
|
||||
id);
|
||||
else
|
||||
query = StringFormat("SELECT slotid, itemid, charges, "
|
||||
"augslot1, augslot2, augslot3, "
|
||||
"augslot4, augslot5, augslot6, custom_data "
|
||||
"augslot4, augslot5, augslot6, custom_data, guid "
|
||||
"FROM sharedbank WHERE acctid=%i ORDER BY slotid",
|
||||
id);
|
||||
auto results = QueryDatabase(query);
|
||||
@ -538,7 +538,9 @@ bool SharedDatabase::GetSharedBank(uint32 id, EQ::InventoryProfile *inv, bool is
|
||||
continue;
|
||||
}
|
||||
|
||||
EQ::ItemInstance *inst = CreateBaseItem(item, charges);
|
||||
std::string guid = row[10];
|
||||
|
||||
EQ::ItemInstance *inst = CreateBaseItem(item, guid, charges);
|
||||
if (inst && item->IsClassCommon()) {
|
||||
for (int i = EQ::invaug::SOCKET_BEGIN; i <= EQ::invaug::SOCKET_END; i++) {
|
||||
if (aug[i])
|
||||
@ -598,7 +600,7 @@ bool SharedDatabase::GetInventory(uint32 char_id, EQ::InventoryProfile *inv)
|
||||
// Retrieve character inventory
|
||||
const std::string query =
|
||||
StringFormat("SELECT slotid, itemid, charges, color, augslot1, augslot2, augslot3, augslot4, augslot5, "
|
||||
"augslot6, instnodrop, custom_data, ornamenticon, ornamentidfile, ornament_hero_model FROM "
|
||||
"augslot6, instnodrop, custom_data, ornamenticon, ornamentidfile, ornament_hero_model, guid FROM "
|
||||
"inventory WHERE charid = %i ORDER BY slotid",
|
||||
char_id);
|
||||
auto results = QueryDatabase(query);
|
||||
@ -672,7 +674,8 @@ bool SharedDatabase::GetInventory(uint32 char_id, EQ::InventoryProfile *inv)
|
||||
continue;
|
||||
}
|
||||
|
||||
EQ::ItemInstance *inst = CreateBaseItem(item, charges);
|
||||
std::string guid = row[15];
|
||||
EQ::ItemInstance *inst = CreateBaseItem(item, guid, charges);
|
||||
|
||||
if (inst == nullptr)
|
||||
continue;
|
||||
@ -781,7 +784,7 @@ bool SharedDatabase::GetInventory(uint32 account_id, char *name, EQ::InventoryPr
|
||||
const std::string query =
|
||||
StringFormat("SELECT slotid, itemid, charges, color, augslot1, "
|
||||
"augslot2, augslot3, augslot4, augslot5, augslot6, instnodrop, custom_data, ornamenticon, "
|
||||
"ornamentidfile, ornament_hero_model "
|
||||
"ornamentidfile, ornament_hero_model, guid "
|
||||
"FROM inventory INNER JOIN character_data ch "
|
||||
"ON ch.id = charid WHERE ch.name = '%s' AND ch.account_id = %i ORDER BY slotid",
|
||||
name, account_id);
|
||||
@ -816,7 +819,9 @@ bool SharedDatabase::GetInventory(uint32 account_id, char *name, EQ::InventoryPr
|
||||
if (!item)
|
||||
continue;
|
||||
|
||||
EQ::ItemInstance *inst = CreateBaseItem(item, charges);
|
||||
std::string guid = row[15];
|
||||
|
||||
EQ::ItemInstance *inst = CreateBaseItem(item, guid, charges);
|
||||
|
||||
if (inst == nullptr)
|
||||
continue;
|
||||
@ -1550,7 +1555,7 @@ EQ::ItemInstance* SharedDatabase::CreateItem(
|
||||
|
||||
const EQ::ItemData* item = GetItem(item_id);
|
||||
if (item) {
|
||||
inst = CreateBaseItem(item, charges);
|
||||
inst = CreateBaseItem(item, "", charges);
|
||||
|
||||
if (!inst) {
|
||||
LogError("Error: valid item data returned a null reference for EQ::ItemInstance creation in SharedDatabase::CreateItem()");
|
||||
@ -1585,7 +1590,7 @@ EQ::ItemInstance* SharedDatabase::CreateItem(
|
||||
) {
|
||||
EQ::ItemInstance* inst = nullptr;
|
||||
if (item) {
|
||||
inst = CreateBaseItem(item, charges);
|
||||
inst = CreateBaseItem(item, "", charges);
|
||||
|
||||
if (!inst) {
|
||||
LogError("Error: valid item data returned a null reference for EQ::ItemInstance creation in SharedDatabase::CreateItem()");
|
||||
@ -1605,7 +1610,7 @@ EQ::ItemInstance* SharedDatabase::CreateItem(
|
||||
return inst;
|
||||
}
|
||||
|
||||
EQ::ItemInstance* SharedDatabase::CreateBaseItem(const EQ::ItemData* item, int16 charges) {
|
||||
EQ::ItemInstance* SharedDatabase::CreateBaseItem(const EQ::ItemData* item, const std::string& guid, int16 charges) {
|
||||
EQ::ItemInstance* inst = nullptr;
|
||||
if (item) {
|
||||
// if maxcharges is -1 that means it is an unlimited use item.
|
||||
@ -1616,7 +1621,7 @@ EQ::ItemInstance* SharedDatabase::CreateBaseItem(const EQ::ItemData* item, int16
|
||||
if(charges <= 0 && item->Stackable)
|
||||
charges = 1;
|
||||
|
||||
inst = new EQ::ItemInstance(item, charges);
|
||||
inst = new EQ::ItemInstance(item, guid, charges);
|
||||
|
||||
if (inst == nullptr) {
|
||||
LogError("Error: valid item data returned a null reference for EQ::ItemInstance creation in SharedDatabase::CreateBaseItem()");
|
||||
|
||||
@ -139,7 +139,7 @@ public:
|
||||
uint32 aug6 = 0,
|
||||
bool attuned = 0
|
||||
);
|
||||
EQ::ItemInstance *CreateBaseItem(const EQ::ItemData *item, int16 charges = 0);
|
||||
EQ::ItemInstance *CreateBaseItem(const EQ::ItemData *item, const std::string &guid, int16 charges);
|
||||
|
||||
void GetItemsCount(int32 &item_count, uint32 &max_id);
|
||||
void LoadItems(void *data, uint32 size, int32 items, uint32 max_item_id);
|
||||
|
||||
@ -876,7 +876,8 @@ bool WorldDatabase::GetCharSelInventory(uint32 account_id, char *name, EQ::Inven
|
||||
" custom_data,"
|
||||
" ornamenticon,"
|
||||
" ornamentidfile,"
|
||||
" ornament_hero_model "
|
||||
" ornament_hero_model, ",
|
||||
" guid "
|
||||
"FROM"
|
||||
" inventory "
|
||||
"INNER JOIN"
|
||||
@ -932,12 +933,13 @@ bool WorldDatabase::GetCharSelInventory(uint32 account_id, char *name, EQ::Inven
|
||||
uint32 ornament_icon = (uint32)Strings::ToUnsignedInt(row[12]);
|
||||
uint32 ornament_idfile = (uint32)Strings::ToUnsignedInt(row[13]);
|
||||
uint32 ornament_hero_model = (uint32)Strings::ToUnsignedInt(row[14]);
|
||||
std::string guid = row[15];
|
||||
|
||||
const EQ::ItemData *item = content_db.GetItem(item_id);
|
||||
if (!item)
|
||||
continue;
|
||||
|
||||
EQ::ItemInstance *inst = content_db.CreateBaseItem(item, charges);
|
||||
EQ::ItemInstance *inst = content_db.CreateBaseItem(item, guid, charges);
|
||||
|
||||
if (inst == nullptr)
|
||||
continue;
|
||||
|
||||
@ -2218,7 +2218,7 @@ bool NPC::Attack(Mob* other, int Hand, bool bRiposte, bool IsStrikethrough, bool
|
||||
|
||||
//do attack animation regardless of whether or not we can hit below
|
||||
int16 charges = 0;
|
||||
EQ::ItemInstance weapon_inst(weapon, charges);
|
||||
EQ::ItemInstance weapon_inst(weapon, "", charges);
|
||||
my_hit.skill = AttackAnimation(Hand, &weapon_inst, my_hit.skill);
|
||||
|
||||
//basically "if not immune" then do the attack
|
||||
|
||||
@ -4743,7 +4743,7 @@ uint16 EntityList::CreateGroundObject(uint32 itemid, const glm::vec4& position,
|
||||
if (!is)
|
||||
return 0;
|
||||
|
||||
auto i = new EQ::ItemInstance(is, is->MaxCharges);
|
||||
auto i = new EQ::ItemInstance(is, "", is->MaxCharges);
|
||||
if (!i)
|
||||
return 0;
|
||||
|
||||
|
||||
@ -2901,7 +2901,7 @@ void Client::DisenchantSummonedBags(bool client_update)
|
||||
if (!new_id) { continue; }
|
||||
auto new_item = database.GetItem(new_id);
|
||||
if (!new_item) { continue; }
|
||||
auto new_inst = database.CreateBaseItem(new_item);
|
||||
auto new_inst = database.CreateBaseItem(new_item, "", 0);
|
||||
if (!new_inst) { continue; }
|
||||
|
||||
if (CopyBagContents(new_inst, inst)) {
|
||||
@ -2925,7 +2925,7 @@ void Client::DisenchantSummonedBags(bool client_update)
|
||||
if (!new_id) { continue; }
|
||||
auto new_item = database.GetItem(new_id);
|
||||
if (!new_item) { continue; }
|
||||
auto new_inst = database.CreateBaseItem(new_item);
|
||||
auto new_inst = database.CreateBaseItem(new_item, "", 0);
|
||||
if (!new_inst) { continue; }
|
||||
|
||||
if (CopyBagContents(new_inst, inst)) {
|
||||
@ -2946,7 +2946,7 @@ void Client::DisenchantSummonedBags(bool client_update)
|
||||
if (!new_id) { continue; }
|
||||
auto new_item = database.GetItem(new_id);
|
||||
if (!new_item) { continue; }
|
||||
auto new_inst = database.CreateBaseItem(new_item);
|
||||
auto new_inst = database.CreateBaseItem(new_item, "", 0);
|
||||
if (!new_inst) { continue; }
|
||||
|
||||
if (CopyBagContents(new_inst, inst)) {
|
||||
@ -2967,7 +2967,7 @@ void Client::DisenchantSummonedBags(bool client_update)
|
||||
if (!new_id) { break; }
|
||||
auto new_item = database.GetItem(new_id);
|
||||
if (!new_item) { break; }
|
||||
auto new_inst = database.CreateBaseItem(new_item);
|
||||
auto new_inst = database.CreateBaseItem(new_item, "", 0);
|
||||
if (!new_inst) { break; }
|
||||
|
||||
if (CopyBagContents(new_inst, inst)) {
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user