mirror of
https://github.com/EQEmu/Server.git
synced 2025-12-23 03:51:30 +00:00
Basic item summoning, fix for saving not working 100 pct, deletion works, cursor queue should work too.
This commit is contained in:
parent
316aa5ef73
commit
dda8ae4803
@ -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_) {
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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;
|
||||
|
||||
@ -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
|
||||
|
||||
|
||||
@ -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();
|
||||
}
|
||||
|
||||
@ -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;
|
||||
|
||||
|
||||
@ -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;
|
||||
}
|
||||
|
||||
@ -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;
|
||||
}
|
||||
|
||||
@ -72,6 +72,8 @@ struct InternalSerializedItem_Struct {
|
||||
struct SerializedItemInstance_Struct {
|
||||
int32 container_id;
|
||||
int32 slot_id;
|
||||
int32 bag_id;
|
||||
int32 aug_id;
|
||||
void *inst;
|
||||
};
|
||||
|
||||
|
||||
@ -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)
|
||||
|
||||
@ -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]; }
|
||||
|
||||
@ -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 */
|
||||
|
||||
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -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;
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user