mirror of
https://github.com/EQEmu/Server.git
synced 2026-03-07 03:02:35 +00:00
Inventory Swap implemented and passes tests, though still want to verify it a bit more also does not yet save but that's next. Fixed a crash in memory buffer too.
This commit is contained in:
parent
14b5a8d817
commit
abc5ddc5f8
@ -23,19 +23,19 @@
|
|||||||
namespace EQEmu
|
namespace EQEmu
|
||||||
{
|
{
|
||||||
|
|
||||||
template <typename T>
|
template <typename T, typename U, typename V>
|
||||||
T Clamp(const T& value, const T& lower, const T& upper) {
|
T Clamp(const T& value, const U& lower, const V& upper) {
|
||||||
return std::max(lower, std::min(value, upper));
|
return std::max(static_cast<T>(lower), std::min(value, static_cast<T>(upper)));
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T>
|
template <typename T, typename U>
|
||||||
T ClampLower(const T& value, const T& lower) {
|
T ClampLower(const T& value, const U& lower) {
|
||||||
return std::max(lower, value);
|
return std::max(static_cast<T>(lower), value);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T>
|
template <typename T, typename U>
|
||||||
T ClampUpper(const T& value, const T& upper) {
|
T ClampUpper(const T& value, const U& upper) {
|
||||||
return std::min(value, upper);
|
return std::min(value, static_cast<T>(upper));
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T, typename U, typename V>
|
template <typename T, typename U, typename V>
|
||||||
|
|||||||
@ -136,6 +136,18 @@ EQEmu::Inventory::~Inventory() {
|
|||||||
delete impl_;
|
delete impl_;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void EQEmu::Inventory::SetRace(int race) {
|
||||||
|
impl_->race_ = race;
|
||||||
|
}
|
||||||
|
|
||||||
|
void EQEmu::Inventory::SetClass(int class_) {
|
||||||
|
impl_->class_ = class_;
|
||||||
|
}
|
||||||
|
|
||||||
|
void EQEmu::Inventory::SetDeity(int deity) {
|
||||||
|
impl_->deity_ = deity;
|
||||||
|
}
|
||||||
|
|
||||||
std::shared_ptr<EQEmu::ItemInstance> EQEmu::Inventory::Get(const InventorySlot &slot) {
|
std::shared_ptr<EQEmu::ItemInstance> EQEmu::Inventory::Get(const InventorySlot &slot) {
|
||||||
auto iter = impl_->containers_.find(slot.Type());
|
auto iter = impl_->containers_.find(slot.Type());
|
||||||
if(iter != impl_->containers_.end()) {
|
if(iter != impl_->containers_.end()) {
|
||||||
@ -202,15 +214,12 @@ bool EQEmu::Inventory::Put(const InventorySlot &slot, std::shared_ptr<ItemInstan
|
|||||||
}
|
}
|
||||||
|
|
||||||
bool EQEmu::Inventory::Swap(const InventorySlot &src, const InventorySlot &dest, int charges) {
|
bool EQEmu::Inventory::Swap(const InventorySlot &src, const InventorySlot &dest, int charges) {
|
||||||
printf("%s -> %s (%i)\n", src.IsCursor() ? "Cursor" : src.ToString().c_str(), dest.IsCursor() ? "Cursor" : dest.ToString().c_str(), charges);
|
|
||||||
|
|
||||||
if(src == dest) {
|
if(src == dest) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(dest.IsDelete()) {
|
if(dest.IsDelete()) {
|
||||||
//return Delete(src);
|
return _destroy(src);
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if(!src.IsValid() || !dest.IsValid()) {
|
if(!src.IsValid() || !dest.IsValid()) {
|
||||||
@ -220,11 +229,11 @@ bool EQEmu::Inventory::Swap(const InventorySlot &src, const InventorySlot &dest,
|
|||||||
auto i_src = Get(src);
|
auto i_src = Get(src);
|
||||||
auto i_dest = Get(dest);
|
auto i_dest = Get(dest);
|
||||||
|
|
||||||
if(dest.IsEquipment() && !CanEquip(i_dest, dest)) {
|
if(!i_src) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(!i_src) {
|
if(dest.IsEquipment() && !CanEquip(i_src, dest)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -234,8 +243,56 @@ bool EQEmu::Inventory::Swap(const InventorySlot &src, const InventorySlot &dest,
|
|||||||
}
|
}
|
||||||
|
|
||||||
if(i_src->IsStackable()) {
|
if(i_src->IsStackable()) {
|
||||||
//charges == 0 -> Move entire stack from src to dest
|
//move # charges from src to dest
|
||||||
//charges > 0 -> Move charges number of charges from src to dest (may require creating a new item
|
|
||||||
|
//0 means *all* the charges
|
||||||
|
if(charges == 0) {
|
||||||
|
charges = i_src->GetCharges();
|
||||||
|
}
|
||||||
|
|
||||||
|
//src needs to have that many charges
|
||||||
|
if(i_src->GetCharges() < charges) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
//if dest exists it needs to not only be the same item id but also be able to hold enough charges
|
||||||
|
if(i_dest) {
|
||||||
|
uint32 src_id = i_src->GetBaseItem()->ID;
|
||||||
|
uint32 dest_id = i_dest->GetBaseItem()->ID;
|
||||||
|
if(src_id != dest_id) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
int charges_avail = i_dest->GetBaseItem()->StackSize - i_dest->GetCharges();
|
||||||
|
if(charges_avail < charges) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(i_src->GetCharges() == charges) {
|
||||||
|
if(!_destroy(src)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
i_src->SetCharges(i_src->GetCharges() - charges);
|
||||||
|
}
|
||||||
|
|
||||||
|
i_dest->SetCharges(i_dest->GetCharges() + charges);
|
||||||
|
return true;
|
||||||
|
} else {
|
||||||
|
//if dest does not exist and src charges > # charges then we need to create a new item with # charges in dest
|
||||||
|
//if dest does not exist and src charges == # charges then we need to swap src to dest
|
||||||
|
if(i_src->GetCharges() > charges) {
|
||||||
|
auto split = i_src->Split(charges);
|
||||||
|
if(!split) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
Put(dest, split);
|
||||||
|
return true;
|
||||||
|
} else {
|
||||||
|
return _swap(src, dest);
|
||||||
|
}
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
return _swap(src, dest);
|
return _swap(src, dest);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -126,6 +126,10 @@ namespace EQEmu
|
|||||||
Inventory(int race, int class_, int deity);
|
Inventory(int race, int class_, int deity);
|
||||||
~Inventory();
|
~Inventory();
|
||||||
|
|
||||||
|
void SetRace(int race);
|
||||||
|
void SetClass(int class_);
|
||||||
|
void SetDeity(int deity);
|
||||||
|
|
||||||
std::shared_ptr<ItemInstance> Get(const InventorySlot &slot);
|
std::shared_ptr<ItemInstance> Get(const InventorySlot &slot);
|
||||||
bool Put(const InventorySlot &slot, std::shared_ptr<ItemInstance> inst);
|
bool Put(const InventorySlot &slot, std::shared_ptr<ItemInstance> inst);
|
||||||
bool Swap(const InventorySlot &src, const InventorySlot &dest, int charges);
|
bool Swap(const InventorySlot &src, const InventorySlot &dest, int charges);
|
||||||
|
|||||||
@ -993,7 +993,7 @@ int InventoryOld::GetSlotByItemInst(ItemInst *inst) {
|
|||||||
return INVALID_INDEX;
|
return INVALID_INDEX;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint8 Inventory::FindBrightestLightType()
|
uint8 InventoryOld::FindBrightestLightType()
|
||||||
{
|
{
|
||||||
uint8 brightest_light_type = 0;
|
uint8 brightest_light_type = 0;
|
||||||
|
|
||||||
|
|||||||
@ -20,6 +20,12 @@
|
|||||||
#include "data_verification.h"
|
#include "data_verification.h"
|
||||||
#include "item_container.h"
|
#include "item_container.h"
|
||||||
|
|
||||||
|
uint32 ItemInstanceSerial = 1;
|
||||||
|
uint32 EQEmu::GetNextItemInstanceSerial() {
|
||||||
|
ItemInstanceSerial++;
|
||||||
|
return ItemInstanceSerial;
|
||||||
|
}
|
||||||
|
|
||||||
struct EQEmu::ItemInstance::impl {
|
struct EQEmu::ItemInstance::impl {
|
||||||
const ItemData *base_item_;
|
const ItemData *base_item_;
|
||||||
ItemData *modified_item_;
|
ItemData *modified_item_;
|
||||||
@ -39,24 +45,6 @@ struct EQEmu::ItemInstance::impl {
|
|||||||
ItemContainer contents_;
|
ItemContainer contents_;
|
||||||
};
|
};
|
||||||
|
|
||||||
EQEmu::ItemInstance::ItemInstance() {
|
|
||||||
impl_ = new impl;
|
|
||||||
impl_->base_item_ = nullptr;
|
|
||||||
impl_->modified_item_ = nullptr;
|
|
||||||
impl_->charges_ = -1;
|
|
||||||
impl_->color_ = 0;
|
|
||||||
impl_->attuned_ = false;
|
|
||||||
impl_->ornament_idfile_ = 0;
|
|
||||||
impl_->ornament_icon_ = 0;
|
|
||||||
impl_->ornament_hero_model_ = 0;
|
|
||||||
impl_->serial_id_ = 0;
|
|
||||||
impl_->recast_timestamp_ = 0;
|
|
||||||
impl_->merchant_slot_ = 0;
|
|
||||||
impl_->merchant_count_ = 0;
|
|
||||||
impl_->price_ = 0;
|
|
||||||
memset(impl_->tracking_id_, 0, 17);
|
|
||||||
}
|
|
||||||
|
|
||||||
EQEmu::ItemInstance::ItemInstance(const ItemData* idata) {
|
EQEmu::ItemInstance::ItemInstance(const ItemData* idata) {
|
||||||
impl_ = new impl;
|
impl_ = new impl;
|
||||||
impl_->base_item_ = idata;
|
impl_->base_item_ = idata;
|
||||||
@ -97,6 +85,39 @@ EQEmu::ItemInstance::~ItemInstance() {
|
|||||||
delete impl_;
|
delete impl_;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
std::shared_ptr<EQEmu::ItemInstance> EQEmu::ItemInstance::Split(int charges) {
|
||||||
|
if(!IsStackable()) {
|
||||||
|
//Can't split non stackable items!
|
||||||
|
return std::shared_ptr<EQEmu::ItemInstance>(nullptr);
|
||||||
|
}
|
||||||
|
|
||||||
|
if(charges >= GetCharges()) {
|
||||||
|
return std::shared_ptr<EQEmu::ItemInstance>(nullptr);
|
||||||
|
}
|
||||||
|
|
||||||
|
if(impl_->contents_.Size() > 0) {
|
||||||
|
return std::shared_ptr<EQEmu::ItemInstance>(nullptr);
|
||||||
|
}
|
||||||
|
|
||||||
|
std::shared_ptr<EQEmu::ItemInstance> split = std::shared_ptr<EQEmu::ItemInstance>(new EQEmu::ItemInstance(impl_->base_item_, charges));
|
||||||
|
split->SetSerialNumber(EQEmu::GetNextItemInstanceSerial());
|
||||||
|
//Set Tracking here
|
||||||
|
split->impl_->attuned_ = impl_->attuned_;
|
||||||
|
split->impl_->custom_data_ = impl_->custom_data_;
|
||||||
|
split->impl_->recast_timestamp_ = impl_->recast_timestamp_;
|
||||||
|
split->impl_->price_ = impl_->price_;
|
||||||
|
split->impl_->color_ = impl_->color_;
|
||||||
|
split->impl_->merchant_count_ = impl_->merchant_count_;
|
||||||
|
split->impl_->merchant_slot_ = impl_->merchant_slot_;
|
||||||
|
split->impl_->ornament_hero_model_ = impl_->ornament_hero_model_;
|
||||||
|
split->impl_->ornament_icon_ = impl_->ornament_icon_;
|
||||||
|
split->impl_->ornament_idfile_ = impl_->ornament_idfile_;
|
||||||
|
|
||||||
|
SetCharges(GetCharges() - charges);
|
||||||
|
return split;
|
||||||
|
}
|
||||||
|
|
||||||
const ItemData *EQEmu::ItemInstance::GetItem() {
|
const ItemData *EQEmu::ItemInstance::GetItem() {
|
||||||
return impl_->modified_item_ ? impl_->modified_item_ : impl_->base_item_;
|
return impl_->modified_item_ ? impl_->modified_item_ : impl_->base_item_;
|
||||||
}
|
}
|
||||||
@ -118,10 +139,6 @@ std::shared_ptr<EQEmu::ItemInstance> EQEmu::ItemInstance::Get(const int index) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
bool EQEmu::ItemInstance::Put(const int index, std::shared_ptr<ItemInstance> inst) {
|
bool EQEmu::ItemInstance::Put(const int index, std::shared_ptr<ItemInstance> inst) {
|
||||||
if(!inst || !inst->GetItem()) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(!impl_->base_item_) {
|
if(!impl_->base_item_) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -342,3 +359,4 @@ bool EQEmu::ItemInstance::IsNoDrop() const {
|
|||||||
EQEmu::ItemContainer *EQEmu::ItemInstance::GetContainer() {
|
EQEmu::ItemContainer *EQEmu::ItemInstance::GetContainer() {
|
||||||
return &(impl_->contents_);
|
return &(impl_->contents_);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -24,11 +24,12 @@
|
|||||||
|
|
||||||
namespace EQEmu
|
namespace EQEmu
|
||||||
{
|
{
|
||||||
|
uint32 GetNextItemInstanceSerial();
|
||||||
|
|
||||||
class ItemContainer;
|
class ItemContainer;
|
||||||
class ItemInstance
|
class ItemInstance
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
ItemInstance();
|
|
||||||
ItemInstance(const ItemData* idata);
|
ItemInstance(const ItemData* idata);
|
||||||
ItemInstance(const ItemData* idata, const int16 charges);
|
ItemInstance(const ItemData* idata, const int16 charges);
|
||||||
~ItemInstance();
|
~ItemInstance();
|
||||||
@ -37,6 +38,8 @@ namespace EQEmu
|
|||||||
const ItemData *GetBaseItem();
|
const ItemData *GetBaseItem();
|
||||||
const ItemData *GetBaseItem() const;
|
const ItemData *GetBaseItem() const;
|
||||||
|
|
||||||
|
std::shared_ptr<ItemInstance> Split(int charges);
|
||||||
|
|
||||||
//Container
|
//Container
|
||||||
std::shared_ptr<ItemInstance> Get(const int index);
|
std::shared_ptr<ItemInstance> Get(const int index);
|
||||||
bool Put(const int index, std::shared_ptr<ItemInstance> inst);
|
bool Put(const int index, std::shared_ptr<ItemInstance> inst);
|
||||||
|
|||||||
@ -162,7 +162,7 @@ void EQEmu::MemoryBuffer::Resize(size_t sz) {
|
|||||||
if(sz > capacity_) {
|
if(sz > capacity_) {
|
||||||
size_t new_size = sz + 32;
|
size_t new_size = sz + 32;
|
||||||
uchar *temp = new uchar[new_size];
|
uchar *temp = new uchar[new_size];
|
||||||
memcpy(temp, buffer_, new_size);
|
memcpy(temp, buffer_, capacity_);
|
||||||
delete[] buffer_;
|
delete[] buffer_;
|
||||||
buffer_ = temp;
|
buffer_ = temp;
|
||||||
|
|
||||||
|
|||||||
@ -15,14 +15,6 @@
|
|||||||
#include "shareddb.h"
|
#include "shareddb.h"
|
||||||
#include "string_util.h"
|
#include "string_util.h"
|
||||||
|
|
||||||
uint32 ItemInstanceSerial = 1;
|
|
||||||
static inline uint32 GetNextItemInstanceSerial() {
|
|
||||||
ItemInstanceSerial++;
|
|
||||||
return ItemInstanceSerial;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
SharedDatabase::SharedDatabase()
|
SharedDatabase::SharedDatabase()
|
||||||
: Database(), skill_caps_mmf(nullptr), items_mmf(nullptr), items_hash(nullptr), faction_mmf(nullptr), faction_hash(nullptr),
|
: Database(), skill_caps_mmf(nullptr), items_mmf(nullptr), items_hash(nullptr), faction_mmf(nullptr), faction_hash(nullptr),
|
||||||
loot_table_mmf(nullptr), loot_table_hash(nullptr), loot_drop_mmf(nullptr), loot_drop_hash(nullptr), base_data_mmf(nullptr)
|
loot_table_mmf(nullptr), loot_table_hash(nullptr), loot_drop_mmf(nullptr), loot_drop_hash(nullptr), base_data_mmf(nullptr)
|
||||||
@ -1273,7 +1265,8 @@ std::shared_ptr<EQEmu::ItemInstance> SharedDatabase::CreateItem(uint32 item_id,
|
|||||||
}
|
}
|
||||||
|
|
||||||
std::shared_ptr<EQEmu::ItemInstance> inst = std::shared_ptr<EQEmu::ItemInstance>(new EQEmu::ItemInstance(item, charges));
|
std::shared_ptr<EQEmu::ItemInstance> inst = std::shared_ptr<EQEmu::ItemInstance>(new EQEmu::ItemInstance(item, charges));
|
||||||
inst->SetSerialNumber(GetNextItemInstanceSerial());
|
inst->SetSerialNumber(EQEmu::GetNextItemInstanceSerial());
|
||||||
|
//Set Tracking here
|
||||||
return inst;
|
return inst;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -38,6 +38,8 @@ public:
|
|||||||
TEST_ADD(InventoryTest::InventorySwapCursorToGeneral2);
|
TEST_ADD(InventoryTest::InventorySwapCursorToGeneral2);
|
||||||
TEST_ADD(InventoryTest::InventorySplitStackToCursor);
|
TEST_ADD(InventoryTest::InventorySplitStackToCursor);
|
||||||
TEST_ADD(InventoryTest::InventoryStackCombine);
|
TEST_ADD(InventoryTest::InventoryStackCombine);
|
||||||
|
TEST_ADD(InventoryTest::InventorySplitStackToCursor2);
|
||||||
|
TEST_ADD(InventoryTest::InventoryStackCombine2);
|
||||||
}
|
}
|
||||||
|
|
||||||
~InventoryTest() {
|
~InventoryTest() {
|
||||||
@ -135,7 +137,7 @@ private:
|
|||||||
stackable.SkillModType = -1;
|
stackable.SkillModType = -1;
|
||||||
stackable.Click.Effect = -1;
|
stackable.Click.Effect = -1;
|
||||||
stackable.Weight = 5;
|
stackable.Weight = 5;
|
||||||
stackable.StackSize = 100;
|
stackable.StackSize = 105;
|
||||||
stackable.Stackable = 1;
|
stackable.Stackable = 1;
|
||||||
stackable.Size = 1;
|
stackable.Size = 1;
|
||||||
stackable.Proc.Effect = -1;
|
stackable.Proc.Effect = -1;
|
||||||
@ -261,13 +263,13 @@ private:
|
|||||||
}
|
}
|
||||||
|
|
||||||
void InventorySplitStackToCursor() {
|
void InventorySplitStackToCursor() {
|
||||||
auto swap_result = inv.Swap(EQEmu::InventorySlot(EQEmu::InvTypePersonal, EQEmu::PersonalSlotGeneral1, 7),
|
auto swap_result = inv.Swap(EQEmu::InventorySlot(EQEmu::InvTypePersonal, EQEmu::PersonalSlotGeneral2, 7),
|
||||||
EQEmu::InventorySlot(EQEmu::InvTypePersonal, EQEmu::PersonalSlotCursor), 10);
|
EQEmu::InventorySlot(EQEmu::InvTypePersonal, EQEmu::PersonalSlotCursor), 10);
|
||||||
|
|
||||||
TEST_ASSERT(swap_result == true);
|
TEST_ASSERT(swap_result == true);
|
||||||
|
|
||||||
auto m_stackable_cursor = inv.Get(EQEmu::InventorySlot(EQEmu::InvTypePersonal, EQEmu::PersonalSlotCursor));
|
auto m_stackable_cursor = inv.Get(EQEmu::InventorySlot(EQEmu::InvTypePersonal, EQEmu::PersonalSlotCursor));
|
||||||
auto m_stackable = inv.Get(EQEmu::InventorySlot(EQEmu::InvTypePersonal, EQEmu::PersonalSlotGeneral1, 7));
|
auto m_stackable = inv.Get(EQEmu::InventorySlot(EQEmu::InvTypePersonal, EQEmu::PersonalSlotGeneral2, 7));
|
||||||
|
|
||||||
TEST_ASSERT(m_stackable_cursor);
|
TEST_ASSERT(m_stackable_cursor);
|
||||||
TEST_ASSERT(m_stackable);
|
TEST_ASSERT(m_stackable);
|
||||||
@ -278,12 +280,12 @@ private:
|
|||||||
|
|
||||||
void InventoryStackCombine() {
|
void InventoryStackCombine() {
|
||||||
auto swap_result = inv.Swap(EQEmu::InventorySlot(EQEmu::InvTypePersonal, EQEmu::PersonalSlotCursor),
|
auto swap_result = inv.Swap(EQEmu::InventorySlot(EQEmu::InvTypePersonal, EQEmu::PersonalSlotCursor),
|
||||||
EQEmu::InventorySlot(EQEmu::InvTypePersonal, EQEmu::PersonalSlotGeneral1, 7), 0);
|
EQEmu::InventorySlot(EQEmu::InvTypePersonal, EQEmu::PersonalSlotGeneral2, 7), 0);
|
||||||
|
|
||||||
TEST_ASSERT(swap_result == true);
|
TEST_ASSERT(swap_result == true);
|
||||||
|
|
||||||
auto m_cursor = inv.Get(EQEmu::InventorySlot(EQEmu::InvTypePersonal, EQEmu::PersonalSlotCursor));
|
auto m_cursor = inv.Get(EQEmu::InventorySlot(EQEmu::InvTypePersonal, EQEmu::PersonalSlotCursor));
|
||||||
auto m_stackable = inv.Get(EQEmu::InventorySlot(EQEmu::InvTypePersonal, EQEmu::PersonalSlotGeneral1, 7));
|
auto m_stackable = inv.Get(EQEmu::InventorySlot(EQEmu::InvTypePersonal, EQEmu::PersonalSlotGeneral2, 7));
|
||||||
|
|
||||||
TEST_ASSERT(!m_cursor);
|
TEST_ASSERT(!m_cursor);
|
||||||
TEST_ASSERT(m_stackable);
|
TEST_ASSERT(m_stackable);
|
||||||
@ -291,6 +293,40 @@ private:
|
|||||||
TEST_ASSERT(m_stackable->GetCharges() == 100);
|
TEST_ASSERT(m_stackable->GetCharges() == 100);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void InventorySplitStackToCursor2() {
|
||||||
|
std::shared_ptr<EQEmu::ItemInstance> m_stackable_i(new EQEmu::ItemInstance(&stackable, 10));
|
||||||
|
inv.Put(EQEmu::InventorySlot(EQEmu::InvTypePersonal, EQEmu::PersonalSlotGeneral2, 8), m_stackable_i);
|
||||||
|
|
||||||
|
auto swap_result = inv.Swap(EQEmu::InventorySlot(EQEmu::InvTypePersonal, EQEmu::PersonalSlotGeneral2, 8),
|
||||||
|
EQEmu::InventorySlot(EQEmu::InvTypePersonal, EQEmu::PersonalSlotCursor), 0);
|
||||||
|
|
||||||
|
TEST_ASSERT(swap_result == true);
|
||||||
|
|
||||||
|
auto m_stackable_cursor = inv.Get(EQEmu::InventorySlot(EQEmu::InvTypePersonal, EQEmu::PersonalSlotCursor));
|
||||||
|
auto m_stackable = inv.Get(EQEmu::InventorySlot(EQEmu::InvTypePersonal, EQEmu::PersonalSlotGeneral2, 8));
|
||||||
|
|
||||||
|
TEST_ASSERT(m_stackable_cursor);
|
||||||
|
TEST_ASSERT(!m_stackable);
|
||||||
|
|
||||||
|
TEST_ASSERT(m_stackable_cursor->GetCharges() == 10);
|
||||||
|
}
|
||||||
|
|
||||||
|
void InventoryStackCombine2() {
|
||||||
|
auto swap_result = inv.Swap(EQEmu::InventorySlot(EQEmu::InvTypePersonal, EQEmu::PersonalSlotCursor),
|
||||||
|
EQEmu::InventorySlot(EQEmu::InvTypePersonal, EQEmu::PersonalSlotGeneral2, 7), 5);
|
||||||
|
|
||||||
|
TEST_ASSERT(swap_result == true);
|
||||||
|
|
||||||
|
auto m_cursor = inv.Get(EQEmu::InventorySlot(EQEmu::InvTypePersonal, EQEmu::PersonalSlotCursor));
|
||||||
|
auto m_stackable = inv.Get(EQEmu::InventorySlot(EQEmu::InvTypePersonal, EQEmu::PersonalSlotGeneral2, 7));
|
||||||
|
|
||||||
|
TEST_ASSERT(m_cursor);
|
||||||
|
TEST_ASSERT(m_stackable);
|
||||||
|
|
||||||
|
TEST_ASSERT(m_stackable->GetCharges() == 105);
|
||||||
|
TEST_ASSERT(m_cursor->GetCharges() == 5);
|
||||||
|
}
|
||||||
|
|
||||||
EQEmu::Inventory inv;
|
EQEmu::Inventory inv;
|
||||||
ItemData container;
|
ItemData container;
|
||||||
ItemData armor;
|
ItemData armor;
|
||||||
|
|||||||
@ -1271,7 +1271,6 @@ void Client::Handle_Connect_OP_ZoneEntry(const EQApplicationPacket *app)
|
|||||||
m_pp.platinum_shared = database.GetSharedPlatinum(this->AccountID());
|
m_pp.platinum_shared = database.GetSharedPlatinum(this->AccountID());
|
||||||
|
|
||||||
database.ClearOldRecastTimestamps(cid); /* Clear out our old recast timestamps to keep the DB clean */
|
database.ClearOldRecastTimestamps(cid); /* Clear out our old recast timestamps to keep the DB clean */
|
||||||
loaditems = database.GetInventory(cid, &m_inventory); /* Load Character Inventory */
|
|
||||||
database.LoadCharacterBandolier(cid, &m_pp); /* Load Character Bandolier */
|
database.LoadCharacterBandolier(cid, &m_pp); /* Load Character Bandolier */
|
||||||
database.LoadCharacterBindPoint(cid, &m_pp); /* Load Character Bind */
|
database.LoadCharacterBindPoint(cid, &m_pp); /* Load Character Bind */
|
||||||
database.LoadCharacterMaterialColor(cid, &m_pp); /* Load Character Material */
|
database.LoadCharacterMaterialColor(cid, &m_pp); /* Load Character Material */
|
||||||
@ -1287,6 +1286,11 @@ void Client::Handle_Connect_OP_ZoneEntry(const EQApplicationPacket *app)
|
|||||||
database.LoadCharacterLeadershipAA(cid, &m_pp); /* Load Character Leadership AA's */
|
database.LoadCharacterLeadershipAA(cid, &m_pp); /* Load Character Leadership AA's */
|
||||||
database.LoadCharacterTribute(cid, &m_pp); /* Load CharacterTribute */
|
database.LoadCharacterTribute(cid, &m_pp); /* Load CharacterTribute */
|
||||||
|
|
||||||
|
m_inventory.SetRace(GetBaseRace());
|
||||||
|
m_inventory.SetClass(GetBaseClass());
|
||||||
|
m_inventory.SetDeity(GetDeity());
|
||||||
|
loaditems = database.GetInventory(cid, &m_inventory); /* Load Character Inventory */
|
||||||
|
|
||||||
/* Load AdventureStats */
|
/* Load AdventureStats */
|
||||||
AdventureStats_Struct as;
|
AdventureStats_Struct as;
|
||||||
if(database.GetAdventureStats(cid, &as))
|
if(database.GetAdventureStats(cid, &as))
|
||||||
|
|||||||
@ -824,106 +824,6 @@ void Client::BulkSendInventoryItems() {
|
|||||||
EQApplicationPacket outapp(OP_CharInventory, items.Size());
|
EQApplicationPacket outapp(OP_CharInventory, items.Size());
|
||||||
memcpy(outapp.pBuffer, items, items.Size());
|
memcpy(outapp.pBuffer, items, items.Size());
|
||||||
QueuePacket(&outapp);
|
QueuePacket(&outapp);
|
||||||
|
|
||||||
|
|
||||||
//int16 slot_id = 0;
|
|
||||||
//
|
|
||||||
//// LINKDEAD TRADE ITEMS
|
|
||||||
//// Move trade slot items back into normal inventory..need them there now for the proceeding validity checks -U
|
|
||||||
//for(slot_id = EmuConstants::TRADE_BEGIN; slot_id <= EmuConstants::TRADE_END; slot_id++) {
|
|
||||||
// ItemInst* inst = m_inv.PopItem(slot_id);
|
|
||||||
// if(inst) {
|
|
||||||
// bool is_arrow = (inst->GetItem()->ItemType == ItemTypeArrow) ? true : false;
|
|
||||||
// int16 free_slot_id = m_inv.FindFreeSlot(inst->IsType(ItemClassContainer), true, inst->GetItem()->Size, is_arrow);
|
|
||||||
// Log.Out(Logs::Detail, Logs::Inventory, "Incomplete Trade Transaction: Moving %s from slot %i to %i", inst->GetItem()->Name, slot_id, free_slot_id);
|
|
||||||
// PutItemInInventory(free_slot_id, *inst, false);
|
|
||||||
// database.SaveInventory(character_id, nullptr, slot_id);
|
|
||||||
// safe_delete(inst);
|
|
||||||
// }
|
|
||||||
//}
|
|
||||||
//
|
|
||||||
//bool deletenorent = database.NoRentExpired(GetName());
|
|
||||||
//if(deletenorent){ RemoveNoRent(false); } //client was offline for more than 30 minutes, delete no rent items
|
|
||||||
//
|
|
||||||
//RemoveDuplicateLore(false);
|
|
||||||
//MoveSlotNotAllowed(false);
|
|
||||||
//
|
|
||||||
//// The previous three method calls took care of moving/removing expired/illegal item placements -U
|
|
||||||
//
|
|
||||||
////TODO: this function is just retarded... it re-allocates the buffer for every
|
|
||||||
////new item. It should be changed to loop through once, gather the
|
|
||||||
////lengths, and item packet pointers into an array (fixed length), and
|
|
||||||
////then loop again to build the packet.
|
|
||||||
////EQApplicationPacket *packets[50];
|
|
||||||
////unsigned long buflen = 0;
|
|
||||||
////unsigned long pos = 0;
|
|
||||||
////memset(packets, 0, sizeof(packets));
|
|
||||||
////foreach item in the invendor sections
|
|
||||||
//// packets[pos++] = ReturnItemPacket(...)
|
|
||||||
//// buflen += temp->size
|
|
||||||
////...
|
|
||||||
////allocat the buffer
|
|
||||||
////for r from 0 to pos
|
|
||||||
//// put pos[r]->pBuffer into the buffer
|
|
||||||
////for r from 0 to pos
|
|
||||||
//// safe_delete(pos[r]);
|
|
||||||
//
|
|
||||||
//uint32 size = 0;
|
|
||||||
//uint16 i = 0;
|
|
||||||
//std::map<uint16, std::string> ser_items;
|
|
||||||
//std::map<uint16, std::string>::iterator itr;
|
|
||||||
//
|
|
||||||
////Inventory items
|
|
||||||
//for(slot_id = MAIN_BEGIN; slot_id < EmuConstants::MAP_POSSESSIONS_SIZE; slot_id++) {
|
|
||||||
// const ItemInst* inst = m_inv[slot_id];
|
|
||||||
// if(inst) {
|
|
||||||
// std::string packet = inst->Serialize(slot_id);
|
|
||||||
// ser_items[i++] = packet;
|
|
||||||
// size += packet.length();
|
|
||||||
// }
|
|
||||||
//}
|
|
||||||
//
|
|
||||||
//// Power Source
|
|
||||||
//if(GetClientVersion() >= ClientVersion::SoF) {
|
|
||||||
// const ItemInst* inst = m_inv[MainPowerSource];
|
|
||||||
// if(inst) {
|
|
||||||
// std::string packet = inst->Serialize(MainPowerSource);
|
|
||||||
// ser_items[i++] = packet;
|
|
||||||
// size += packet.length();
|
|
||||||
// }
|
|
||||||
//}
|
|
||||||
//
|
|
||||||
//// Bank items
|
|
||||||
//for(slot_id = EmuConstants::BANK_BEGIN; slot_id <= EmuConstants::BANK_END; slot_id++) {
|
|
||||||
// const ItemInst* inst = m_inv[slot_id];
|
|
||||||
// if(inst) {
|
|
||||||
// std::string packet = inst->Serialize(slot_id);
|
|
||||||
// ser_items[i++] = packet;
|
|
||||||
// size += packet.length();
|
|
||||||
// }
|
|
||||||
//}
|
|
||||||
//
|
|
||||||
//// Shared Bank items
|
|
||||||
//for(slot_id = EmuConstants::SHARED_BANK_BEGIN; slot_id <= EmuConstants::SHARED_BANK_END; slot_id++) {
|
|
||||||
// const ItemInst* inst = m_inv[slot_id];
|
|
||||||
// if(inst) {
|
|
||||||
// std::string packet = inst->Serialize(slot_id);
|
|
||||||
// ser_items[i++] = packet;
|
|
||||||
// size += packet.length();
|
|
||||||
// }
|
|
||||||
//}
|
|
||||||
//
|
|
||||||
//EQApplicationPacket* outapp = new EQApplicationPacket(OP_CharInventory, size);
|
|
||||||
//uchar* ptr = outapp->pBuffer;
|
|
||||||
//for(itr = ser_items.begin(); itr != ser_items.end(); ++itr){
|
|
||||||
// int length = itr->second.length();
|
|
||||||
// if(length > 5) {
|
|
||||||
// memcpy(ptr, itr->second.c_str(), length);
|
|
||||||
// ptr += length;
|
|
||||||
// }
|
|
||||||
//}
|
|
||||||
//QueuePacket(outapp);
|
|
||||||
//safe_delete(outapp);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Client::BulkSendMerchantInventory(int merchant_id, int npcid) {
|
void Client::BulkSendMerchantInventory(int merchant_id, int npcid) {
|
||||||
|
|||||||
@ -3133,12 +3133,14 @@ bool Client::SwapItem(const EQEmu::InventorySlot &src, const EQEmu::InventorySlo
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Message(0, "%s -> %s (%i)\n", src.IsCursor() ? "Cursor" : src.ToString().c_str(), dest.IsCursor() ? "Cursor" : dest.ToString().c_str(), number_in_stack);
|
||||||
|
|
||||||
bool res = m_inventory.Swap(src, dest, number_in_stack);
|
bool res = m_inventory.Swap(src, dest, number_in_stack);
|
||||||
|
|
||||||
if(res) {
|
if(res) {
|
||||||
printf("Swap success\n");
|
Message(0, "Swap success\n");
|
||||||
} else {
|
} else {
|
||||||
printf("Swap failure!\n");
|
Message(0, "Swap failure!\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
if(auto_attack && res && recalc_weapon_speed) {
|
if(auto_attack && res && recalc_weapon_speed) {
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user