Basic item summoning, fix for saving not working 100 pct, deletion works, cursor queue should work too.

This commit is contained in:
KimLS 2015-03-05 18:03:37 -08:00
parent 316aa5ef73
commit dda8ae4803
14 changed files with 459 additions and 108 deletions

View File

@ -22,6 +22,7 @@
#include "data_verification.h"
#include "string_util.h"
#include <map>
#include <queue>
bool EQEmu::InventorySlot::IsValid() const {
if(type_ == InvTypePersonal && EQEmu::ValueWithin(slot_, PersonalSlotCharm, PersonalSlotCursor)) {
@ -225,7 +226,28 @@ bool EQEmu::Inventory::Swap(const InventorySlot &src, const InventorySlot &dest,
return true;
}
if(!src.IsValid() || !dest.IsValid()) {
if(!src.IsValid()) {
return false;
}
if(src.Type() == InvTypeCursorBuffer || dest.Type() == InvTypeCursorBuffer) {
return true;
}
if(dest.IsDelete()) {
impl_->data_model_->Begin();
bool v = _destroy(src);
if(v) {
impl_->data_model_->Commit();
}
else {
impl_->data_model_->Rollback();
}
return v;
}
if(!dest.IsValid()) {
return false;
}
@ -252,17 +274,6 @@ bool EQEmu::Inventory::Swap(const InventorySlot &src, const InventorySlot &dest,
}
impl_->data_model_->Begin();
if(dest.IsDelete()) {
bool v = _destroy(src);
if(v) {
impl_->data_model_->Commit();
} else {
impl_->data_model_->Rollback();
}
return v;
}
if(i_src->IsStackable()) {
//move # charges from src to dest
@ -356,6 +367,109 @@ bool EQEmu::Inventory::Swap(const InventorySlot &src, const InventorySlot &dest,
return true;
}
bool EQEmu::Inventory::Summon(const InventorySlot &slot, std::shared_ptr<ItemInstance> inst) {
if(!inst)
return false;
if(CheckLoreConflict(inst->GetBaseItem())) {
return false;
}
auto cur = Get(slot);
if(cur) {
if(slot.IsCursor()) {
PushToCursorBuffer(inst);
}
return false;
}
impl_->data_model_->Begin();
bool v = Put(slot, inst);
if(v) {
impl_->data_model_->Insert(slot, inst);
impl_->data_model_->Commit();
} else {
impl_->data_model_->Rollback();
}
return v;
}
bool EQEmu::Inventory::PushToCursorBuffer(std::shared_ptr<ItemInstance> inst) {
if(impl_->containers_.count(InvTypeCursorBuffer) == 0) {
impl_->containers_.insert(std::pair<int, ItemContainer>(InvTypeCursorBuffer, ItemContainer()));
}
int32 top = 0;
auto &container = impl_->containers_[InvTypeCursorBuffer];
auto iter = container.Begin();
while(iter != container.End()) {
top = iter->first;
++iter;
}
InventorySlot slot(InvTypeCursorBuffer, top + 1);
impl_->data_model_->Begin();
bool v = Put(slot, inst);
if(v) {
impl_->data_model_->Insert(slot, inst);
impl_->data_model_->Commit();
}
else {
impl_->data_model_->Rollback();
}
return v;
}
bool EQEmu::Inventory::PopFromCursorBuffer() {
InventorySlot cursor(InvTypePersonal, PersonalSlotCursor);
auto inst = Get(cursor);
if(inst) {
return false;
}
if(impl_->containers_.count(InvTypeCursorBuffer) == 0) {
return false;
}
int32 top = 0;
auto &container = impl_->containers_[InvTypeCursorBuffer];
auto iter = container.Begin();
while(iter != container.End()) {
top = iter->first;
++iter;
}
InventorySlot slot(InvTypeCursorBuffer, top);
inst = Get(slot);
if(inst) {
impl_->data_model_->Begin();
bool v = _destroy(slot);
impl_->data_model_->Delete(slot);
if(!v) {
impl_->data_model_->Rollback();
return false;
}
v = Put(cursor, inst);
impl_->data_model_->Insert(cursor, inst);
if(!v) {
impl_->data_model_->Rollback();
return false;
}
impl_->data_model_->Commit();
return true;
}
return false;
}
int EQEmu::Inventory::CalcMaterialFromSlot(const InventorySlot &slot) {
if(slot.Type() != 0)
return _MaterialInvalid;
@ -441,17 +555,59 @@ bool EQEmu::Inventory::CanEquip(std::shared_ptr<EQEmu::ItemInstance> inst, const
return false;
}
//todo: check deity
if(!item->IsEquipable(impl_->race_, impl_->class_)) {
return false;
}
//Checking augments
auto iter = inst->GetContainer()->Begin();
auto end = inst->GetContainer()->End();
while(iter != end) {
if(!CanEquip(iter->second, InventorySlot(slot.Type(), slot.Slot(), slot.BagIndex(), iter->first))) {
return false;
}
++iter;
}
return true;
}
bool EQEmu::Inventory::CheckLoreConflict(const ItemData *item) {
if(!item)
return false;
if(!item->LoreFlag)
return false;
if(item->LoreGroup == 0)
return false;
if(item->LoreGroup == 0xFFFFFFFF) {
//look everywhere except shared bank
for(auto &container : impl_->containers_) {
if(container.first != InvTypeSharedBank && container.second.HasItem(item->ID)) {
return true;
}
}
}
else {
//look everywhere except shared bank
for(auto &container : impl_->containers_) {
if(container.first != InvTypeSharedBank && container.second.HasItemByLoreGroup(item->LoreGroup)) {
return true;
}
}
}
return false;
}
bool EQEmu::Inventory::Serialize(MemoryBuffer &buf) {
buf.SetWritePosition(0);
buf.SetReadPosition(0);
buf.Resize(0);
buf.Write<int32>(105);
bool value = false;
for(auto &iter : impl_->containers_) {

View File

@ -135,11 +135,15 @@ namespace EQEmu
std::shared_ptr<ItemInstance> Get(const InventorySlot &slot);
bool Put(const InventorySlot &slot, std::shared_ptr<ItemInstance> inst);
bool Swap(const InventorySlot &src, const InventorySlot &dest, int charges);
bool Summon(const InventorySlot &slot, std::shared_ptr<ItemInstance> inst);
bool PushToCursorBuffer(std::shared_ptr<ItemInstance> inst);
bool PopFromCursorBuffer();
//utility
static int CalcMaterialFromSlot(const InventorySlot &slot);
static InventorySlot CalcSlotFromMaterial(int material);
bool CanEquip(std::shared_ptr<EQEmu::ItemInstance> inst, const EQEmu::InventorySlot &slot);
bool CheckLoreConflict(const ItemData *item);
bool Serialize(MemoryBuffer &buf);
//testing

View File

@ -153,9 +153,23 @@ void EQEmu::InventoryDatabaseDataModel::Insert(const InventorySlot &slot, std::s
DataEvent evt;
evt.evt = DB_Insert;
evt.inst = iter->second;
evt.slot = InventorySlot(slot.Type(), slot.Slot(), -1, iter->first);
evt.slot = InventorySlot(slot.Type(), slot.Slot(), iter->first, -1);
impl_->events_.push_back(evt);
//do augments here
if(evt.inst->GetBaseItem()->ItemClass == ItemClassCommon) {
auto inst_container = evt.inst->GetContainer();
auto inst_iter = inst_container->Begin();
while(inst_iter != inst_container->End()) {
DataEvent evt;
evt.evt = DB_Insert;
evt.inst = inst_iter->second;
evt.slot = InventorySlot(slot.Type(), slot.Slot(), iter->first, inst_iter->first);
impl_->events_.push_back(evt);
++inst_iter;
}
}
++iter;
}
}
@ -166,14 +180,15 @@ void EQEmu::InventoryDatabaseDataModel::Insert(const InventorySlot &slot, std::s
DataEvent evt;
evt.evt = DB_Insert;
evt.inst = iter->second;
evt.slot = InventorySlot(slot.Type(), slot.Slot(), iter->first);
evt.slot = InventorySlot(slot.Type(), slot.Slot(), -1, iter->first);
impl_->events_.push_back(evt);
++iter;
}
}
}
else if(inst->GetBaseItem()->ItemClass == ItemClassCommon) {
else if(slot.AugIndex() < 0 && inst->GetBaseItem()->ItemClass == ItemClassCommon) {
//bag item that can have augs
//if common put all augment contents in
auto container = inst->GetContainer();
auto iter = container->Begin();
@ -181,7 +196,7 @@ void EQEmu::InventoryDatabaseDataModel::Insert(const InventorySlot &slot, std::s
DataEvent evt;
evt.evt = DB_Insert;
evt.inst = iter->second;
evt.slot = InventorySlot(slot.Type(), slot.Slot(), iter->first, slot.BagIndex());
evt.slot = InventorySlot(slot.Type(), slot.Slot(), slot.BagIndex(), iter->first);
impl_->events_.push_back(evt);
++iter;

View File

@ -29,11 +29,11 @@ namespace EQEmu
InventoryNullDataModel() { }
virtual ~InventoryNullDataModel() { }
virtual void Begin() { printf("NDM: Begin\n"); }
virtual bool Commit() { printf("NDM: Commit\n"); return true; }
virtual void Rollback() { printf("NDM: Rollback\n"); }
virtual void Insert(const InventorySlot &slot, std::shared_ptr<ItemInstance> inst) { printf("NDM: Insert %s %s\n", slot.ToString().c_str(), inst ? inst->GetBaseItem()->Name : "Null" ); }
virtual void Delete(const InventorySlot &slot) { printf("NDM: Delete %s\n", slot.ToString().c_str()); }
virtual void Begin() { }
virtual bool Commit() { return true; }
virtual void Rollback() { }
virtual void Insert(const InventorySlot &slot, std::shared_ptr<ItemInstance> inst) { }
virtual void Delete(const InventorySlot &slot) { }
};
} // EQEmu

View File

@ -65,6 +65,29 @@ bool EQEmu::ItemContainer::Put(const int slot_id, std::shared_ptr<ItemInstance>
return false;
}
bool EQEmu::ItemContainer::HasItem(uint32 item_id) {
for(auto &item : impl_->items_) {
if(item.second->GetBaseItem()->ID == item_id) {
return true;
}
}
return false;
}
bool EQEmu::ItemContainer::HasItemByLoreGroup(uint32 loregroup) {
if(loregroup == 0xFFFFFFFF)
return false;
for(auto &item : impl_->items_) {
if(item.second->GetBaseItem()->LoreGroup == loregroup) {
return true;
}
}
return false;
}
uint32 EQEmu::ItemContainer::Size() {
return (uint32)impl_->items_.size();
}

View File

@ -42,6 +42,11 @@ namespace EQEmu
std::shared_ptr<ItemInstance> Get(const int slot_id);
bool Put(const int slot_id, std::shared_ptr<ItemInstance> inst);
bool Delete(const int slot_id);
//Utility
bool HasItem(uint32 item_id);
bool HasItemByLoreGroup(uint32 loregroup);
uint32 Size();
uint32 Size() const;

View File

@ -9,6 +9,8 @@ bool EQEmu::ItemContainerDefaultSerialization::Serialize(MemoryBuffer &buf, cons
for(auto &iter : items) {
buf.Write<int32>(container_number);
buf.Write<int32>(iter.first);
buf.Write<int32>(-1);
buf.Write<int32>(-1);
buf.Write<void*>(iter.second.get());
ret = true;
}

View File

@ -10,6 +10,8 @@ bool EQEmu::ItemContainerPersonalSerialization::Serialize(MemoryBuffer &buf, con
if(iter.first < 33) {
buf.Write<int32>(container_number);
buf.Write<int32>(iter.first);
buf.Write<int32>(-1);
buf.Write<int32>(-1);
buf.Write<void*>(iter.second.get());
ret = true;
}

View File

@ -72,6 +72,8 @@ struct InternalSerializedItem_Struct {
struct SerializedItemInstance_Struct {
int32 container_id;
int32 slot_id;
int32 bag_id;
int32 aug_id;
void *inst;
};

View File

@ -602,18 +602,18 @@ namespace RoF2
EQApplicationPacket *in = *p;
*p = nullptr;
size_t entry_size = sizeof(int32) * 2 + sizeof(void*);
size_t entries = in->size / entry_size;
size_t entry_size = sizeof(SerializedItemInstance_Struct);
size_t entries = (in->size - sizeof(int32)) / entry_size;
if(entries == 0 || in->size % entry_size != 0) {
if(entries == 0 || (in->size - sizeof(int32)) % entry_size != 0) {
Log.Out(Logs::General, Logs::Netcode, "[STRUCTS] Wrong size on outbound %s: Got %d, expected multiple of %d",
opcodes->EmuToName(in->GetOpcode()), in->size, entry_size);
opcodes->EmuToName(in->GetOpcode()), (in->size - sizeof(int32)), entry_size);
delete in;
return;
}
unsigned char *__emu_buffer = in->pBuffer;
SerializedItemInstance_Struct *sis = (SerializedItemInstance_Struct*)__emu_buffer;
SerializedItemInstance_Struct *sis = (SerializedItemInstance_Struct*)(__emu_buffer + sizeof(int32));
EQEmu::MemoryBuffer packet_data;
packet_data.Write<uint32>(entries);
@ -1490,33 +1490,41 @@ namespace RoF2
ENCODE(OP_ItemPacket)
{
delete *p;
EQApplicationPacket *in = *p;
*p = nullptr;
////consume the packet
//EQApplicationPacket *in = *p;
//*p = nullptr;
//
//unsigned char *__emu_buffer = in->pBuffer;
//ItemPacket_Struct *old_item_pkt = (ItemPacket_Struct *)__emu_buffer;
//InternalSerializedItem_Struct *int_struct = (InternalSerializedItem_Struct *)(old_item_pkt->SerializedItem);
//
//uint32 length;
//char *serialized = SerializeItem((ItemInst *)int_struct->inst, int_struct->slot_id, &length, 0, old_item_pkt->PacketType);
//
//if (!serialized) {
// Log.Out(Logs::General, Logs::Netcode, "[STRUCTS] Serialization failed on item slot %d.", int_struct->slot_id);
// delete in;
// return;
//}
//in->size = length + 4;
//in->pBuffer = new unsigned char[in->size];
//ItemPacket_Struct *new_item_pkt = (ItemPacket_Struct *)in->pBuffer;
//new_item_pkt->PacketType = old_item_pkt->PacketType;
//memcpy(new_item_pkt->SerializedItem, serialized, length);
//
//delete[] __emu_buffer;
//safe_delete_array(serialized);
//dest->FastQueuePacket(&in, ack_req);
size_t entry_size = sizeof(SerializedItemInstance_Struct);
size_t entries = (in->size - sizeof(int32)) / entry_size;
if(entries == 0 || entries > 1 || (in->size - sizeof(int32)) % entry_size != 0) {
Log.Out(Logs::General, Logs::Netcode, "[STRUCTS] Wrong size on outbound %s: Got %d, expected multiple of %d",
opcodes->EmuToName(in->GetOpcode()), (in->size - sizeof(int32)), entry_size);
delete in;
return;
}
unsigned char *__emu_buffer = in->pBuffer;
int32 *packet_type = (int32*)(__emu_buffer);
SerializedItemInstance_Struct *sis = (SerializedItemInstance_Struct*)(__emu_buffer + sizeof(int32));
EQEmu::MemoryBuffer packet_data;
packet_data.Write<int32>(*packet_type);
EQEmu::ItemInstance *inst = (EQEmu::ItemInstance*)sis->inst;
if(!inst) {
delete in;
return;
}
SerializeItem(packet_data, inst, sis->container_id, sis->slot_id, sis->bag_id, sis->slot_id);
in->pBuffer = new uchar[packet_data.Size()];
in->size = packet_data.Size();
memcpy(in->pBuffer, packet_data, in->size);
delete[] __emu_buffer;
dest->FastQueuePacket(&in, ack_req);
}
ENCODE(OP_ItemVerifyReply)

View File

@ -818,13 +818,28 @@ public:
void QSSwapItemAuditor(MoveItemOld_Struct* move_in, bool postaction_call = false);
void PutLootInInventory(int16 slot_id, const ItemInst &inst, ServerLootItem_Struct** bag_item_data = 0);
bool AutoPutLootInInventory(ItemInst& inst, bool try_worn = false, bool try_cursor = true, ServerLootItem_Struct** bag_item_data = 0);
bool SummonItem(uint32 item_id, int16 charges = -1, uint32 aug1 = 0, uint32 aug2 = 0, uint32 aug3 = 0, uint32 aug4 = 0, uint32 aug5 = 0, uint32 aug6 = 0, bool attuned = false, uint16 to_slot = MainCursor, uint32 ornament_icon = 0, uint32 ornament_idfile = 0, uint32 ornament_hero_model = 0);
bool SummonItem(uint32 item_id, int16 charges = -1,
uint32 aug1 = 0, uint32 aug2 = 0, uint32 aug3 = 0, uint32 aug4 = 0, uint32 aug5 = 0, uint32 aug6 = 0, bool attuned = false,
uint16 to_slot = MainCursor, uint32 ornament_icon = 0, uint32 ornament_idfile = 0, uint32 ornament_hero_model = 0);
void SetStats(uint8 type,int16 set_val);
void IncStats(uint8 type,int16 increase_val);
void DropItem(int16 slot_id);
//New Inventory
bool SwapItem(const EQEmu::InventorySlot &src, const EQEmu::InventorySlot &dest, int number_in_stack);
bool SummonItem(uint32 item_id,
int16 charges,
const EQEmu::InventorySlot &slot,
uint32 aug1 = 0,
uint32 aug2 = 0,
uint32 aug3 = 0,
uint32 aug4 = 0,
uint32 aug5 = 0,
uint32 aug6 = 0,
bool attuned = false,
uint32 ornament_icon = 0,
uint32 ornament_idfile = 0,
uint32 ornament_hero_model = 0);
//
// class Client::TextLink
@ -881,6 +896,9 @@ public:
bool IsValidSlot(uint32 slot);
bool IsBankSlot(uint32 slot);
//inv2
void SendItemPacket(const EQEmu::InventorySlot &slot, std::shared_ptr<EQEmu::ItemInstance> inst, ItemPacketType packet_type);
inline bool IsTrader() const { return(Trader); }
inline bool IsBuyer() const { return(Buyer); }
eqFilterMode GetFilter(eqFilterType filter_id) const { return ClientFilters[filter_id]; }

View File

@ -1722,14 +1722,11 @@ void Client::Handle_Connect_OP_ZoneEntry(const EQApplicationPacket *app)
*/
if (loaditems) { /* Dont load if a length error occurs */
BulkSendInventoryItems();
// /* Send stuff on the cursor which isnt sent in bulk */
// for (auto iter = m_inv.cursor_cbegin(); iter != m_inv.cursor_cend(); ++iter) {
// /* First item cursor is sent in bulk inventory packet */
// if (iter == m_inv.cursor_cbegin())
// continue;
// const ItemInst *inst = *iter;
// SendItemPacket(MainCursor, inst, ItemPacketSummonItem);
// }
EQEmu::InventorySlot slot(EQEmu::InvTypePersonal, EQEmu::PersonalSlotCursor);
auto cursor = m_inventory.Get(slot);
if(cursor) {
SendItemPacket(slot, cursor, ItemPacketSummonItem);
}
}
/* Task Packets */

View File

@ -5418,24 +5418,25 @@ void command_summonitem(Client *c, const Seperator *sep)
item_status = static_cast<int16>(item->MinStatus);
}
EQEmu::InventorySlot cursor(EQEmu::InvTypePersonal, EQEmu::PersonalSlotCursor);
if (item_status > c->Admin())
c->Message(13, "Error: Insufficient status to summon this item.");
else if (sep->argnum==2 && sep->IsNumber(2))
c->SummonItem(itemid, atoi(sep->arg[2]));
c->SummonItem(itemid, atoi(sep->arg[2]), cursor);
else if (sep->argnum==3)
c->SummonItem(itemid, atoi(sep->arg[2]), atoi(sep->arg[3]));
c->SummonItem(itemid, atoi(sep->arg[2]), cursor, atoi(sep->arg[3]));
else if (sep->argnum==4)
c->SummonItem(itemid, atoi(sep->arg[2]), atoi(sep->arg[3]), atoi(sep->arg[4]));
c->SummonItem(itemid, atoi(sep->arg[2]), cursor, atoi(sep->arg[3]), atoi(sep->arg[4]));
else if (sep->argnum==5)
c->SummonItem(itemid, atoi(sep->arg[2]), atoi(sep->arg[3]), atoi(sep->arg[4]), atoi(sep->arg[5]));
c->SummonItem(itemid, atoi(sep->arg[2]), cursor, atoi(sep->arg[3]), atoi(sep->arg[4]), atoi(sep->arg[5]));
else if (sep->argnum==6)
c->SummonItem(itemid, atoi(sep->arg[2]), atoi(sep->arg[3]), atoi(sep->arg[4]), atoi(sep->arg[5]), atoi(sep->arg[6]));
c->SummonItem(itemid, atoi(sep->arg[2]), cursor, atoi(sep->arg[3]), atoi(sep->arg[4]), atoi(sep->arg[5]), atoi(sep->arg[6]));
else if (sep->argnum==7)
c->SummonItem(itemid, atoi(sep->arg[2]), atoi(sep->arg[3]), atoi(sep->arg[4]), atoi(sep->arg[5]), atoi(sep->arg[6]), atoi(sep->arg[7]));
c->SummonItem(itemid, atoi(sep->arg[2]), cursor, atoi(sep->arg[3]), atoi(sep->arg[4]), atoi(sep->arg[5]), atoi(sep->arg[6]), atoi(sep->arg[7]));
else if (sep->argnum==8)
c->SummonItem(itemid, atoi(sep->arg[2]), atoi(sep->arg[3]), atoi(sep->arg[4]), atoi(sep->arg[5]), atoi(sep->arg[6]), atoi(sep->arg[7]), atoi(sep->arg[8]));
c->SummonItem(itemid, atoi(sep->arg[2]), cursor, atoi(sep->arg[3]), atoi(sep->arg[4]), atoi(sep->arg[5]), atoi(sep->arg[6]), atoi(sep->arg[7]), atoi(sep->arg[8]));
else {
c->SummonItem(itemid);
c->SummonItem(itemid, -1, cursor);
}
}
}

View File

@ -2427,52 +2427,74 @@ uint32 Client::GetEquipmentColor(uint8 material_slot) const
// Send an item packet (including all subitems of the item)
void Client::SendItemPacket(int16 slot_id, const ItemInst* inst, ItemPacketType packet_type)
{
if (!inst)
// if (!inst)
// return;
//
// // Serialize item into |-delimited string
// std::string packet = inst->Serialize(slot_id);
//
// EmuOpcode opcode = OP_Unknown;
// EQApplicationPacket* outapp = nullptr;
// ItemPacket_Struct* itempacket = nullptr;
//
// // Construct packet
// opcode = (packet_type==ItemPacketViewLink) ? OP_ItemLinkResponse : OP_ItemPacket;
// outapp = new EQApplicationPacket(opcode, packet.length()+sizeof(ItemPacket_Struct));
// itempacket = (ItemPacket_Struct*)outapp->pBuffer;
// memcpy(itempacket->SerializedItem, packet.c_str(), packet.length());
// itempacket->PacketType = packet_type;
//
//#if EQDEBUG >= 9
// DumpPacket(outapp);
//#endif
// FastQueuePacket(&outapp);
}
void Client::SendItemPacket(const EQEmu::InventorySlot &slot, std::shared_ptr<EQEmu::ItemInstance> inst, ItemPacketType packet_type) {
if(!inst) {
return;
}
// Serialize item into |-delimited string
std::string packet = inst->Serialize(slot_id);
EQEmu::MemoryBuffer item;
EmuOpcode opcode = OP_Unknown;
EQApplicationPacket* outapp = nullptr;
ItemPacket_Struct* itempacket = nullptr;
opcode = (packet_type == ItemPacketViewLink) ? OP_ItemLinkResponse : OP_ItemPacket;
// Construct packet
opcode = (packet_type==ItemPacketViewLink) ? OP_ItemLinkResponse : OP_ItemPacket;
outapp = new EQApplicationPacket(opcode, packet.length()+sizeof(ItemPacket_Struct));
itempacket = (ItemPacket_Struct*)outapp->pBuffer;
memcpy(itempacket->SerializedItem, packet.c_str(), packet.length());
itempacket->PacketType = packet_type;
item.Write<int32>((int32)packet_type);
item.Write<int32>(slot.Type());
item.Write<int32>(slot.Slot());
item.Write<int32>(slot.BagIndex());
item.Write<int32>(slot.AugIndex());
item.Write<void*>(inst.get());
#if EQDEBUG >= 9
DumpPacket(outapp);
#endif
FastQueuePacket(&outapp);
EQApplicationPacket outapp(opcode, item.Size());
memcpy(outapp.pBuffer, item, item.Size());
QueuePacket(&outapp);
}
EQApplicationPacket* Client::ReturnItemPacket(int16 slot_id, const ItemInst* inst, ItemPacketType packet_type)
{
if (!inst)
return nullptr;
// Serialize item into |-delimited string
std::string packet = inst->Serialize(slot_id);
EmuOpcode opcode = OP_Unknown;
EQApplicationPacket* outapp = nullptr;
BulkItemPacket_Struct* itempacket = nullptr;
// Construct packet
opcode = OP_ItemPacket;
outapp = new EQApplicationPacket(opcode, packet.length()+1);
itempacket = (BulkItemPacket_Struct*)outapp->pBuffer;
memcpy(itempacket->SerializedItem, packet.c_str(), packet.length());
#if EQDEBUG >= 9
DumpPacket(outapp);
#endif
return outapp;
return nullptr;
// if (!inst)
// return nullptr;
//
// // Serialize item into |-delimited string
// std::string packet = inst->Serialize(slot_id);
//
// EmuOpcode opcode = OP_Unknown;
// EQApplicationPacket* outapp = nullptr;
// BulkItemPacket_Struct* itempacket = nullptr;
//
// // Construct packet
// opcode = OP_ItemPacket;
// outapp = new EQApplicationPacket(opcode, packet.length()+1);
// itempacket = (BulkItemPacket_Struct*)outapp->pBuffer;
// memcpy(itempacket->SerializedItem, packet.c_str(), packet.length());
//
//#if EQDEBUG >= 9
// DumpPacket(outapp);
//#endif
//
// return outapp;
}
static int16 BandolierSlotToWeaponSlot(int BandolierSlot)
@ -3143,7 +3165,16 @@ bool Client::SwapItem(const EQEmu::InventorySlot &src, const EQEmu::InventorySlo
} else {
Message(0, "Swap failure!\n");
//should kick the player here...
}
EQEmu::InventorySlot cursor(EQEmu::InvTypePersonal, EQEmu::PersonalSlotCursor);
if(!m_inventory.Get(cursor)) {
if(m_inventory.PopFromCursorBuffer()) {
auto c_inst = m_inventory.Get(cursor);
if(c_inst) {
SendItemPacket(EQEmu::InventorySlot(EQEmu::InvTypePersonal, EQEmu::PersonalSlotCursor), c_inst, ItemPacketSummonItem);
}
}
}
if(auto_attack && res && recalc_weapon_speed) {
@ -3157,3 +3188,90 @@ bool Client::SwapItem(const EQEmu::InventorySlot &src, const EQEmu::InventorySlo
return res;
}
bool Client::SummonItem(uint32 item_id,
int16 charges,
const EQEmu::InventorySlot &slot,
uint32 aug1,
uint32 aug2,
uint32 aug3,
uint32 aug4,
uint32 aug5,
uint32 aug6,
bool attuned,
uint32 ornament_icon,
uint32 ornament_idfile,
uint32 ornament_hero_model)
{
std::shared_ptr<EQEmu::ItemInstance> inst = database.CreateItem(item_id, charges);
if(!inst)
return false;
if(inst->GetBaseItem()->ItemClass == ItemClassCommon) {
if(aug1) {
std::shared_ptr<EQEmu::ItemInstance> aug = database.CreateItem(aug1);
if(!aug)
return false;
if(!inst->Put(0, aug)) {
return false;
}
}
if(aug2) {
std::shared_ptr<EQEmu::ItemInstance> aug = database.CreateItem(aug2);
if(!aug)
return false;
if(!inst->Put(1, aug)) {
return false;
}
}
if(aug3) {
std::shared_ptr<EQEmu::ItemInstance> aug = database.CreateItem(aug3);
if(!aug)
return false;
if(!inst->Put(2, aug)) {
return false;
}
}
if(aug4) {
std::shared_ptr<EQEmu::ItemInstance> aug = database.CreateItem(aug4);
if(!aug)
return false;
if(!inst->Put(3, aug)) {
return false;
}
}
if(aug5) {
std::shared_ptr<EQEmu::ItemInstance> aug = database.CreateItem(aug5);
if(!aug)
return false;
if(!inst->Put(4, aug)) {
return false;
}
}
if(aug6) {
std::shared_ptr<EQEmu::ItemInstance> aug = database.CreateItem(aug6);
if(!aug)
return false;
if(!inst->Put(5, aug)) {
return false;
}
}
}
auto res = m_inventory.Summon(slot, inst);
if(res) {
SendItemPacket(slot, inst, ItemPacketSummonItem);
}
return res;
}