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:
KimLS
2015-03-02 00:44:28 -08:00
parent 14b5a8d817
commit abc5ddc5f8
13 changed files with 177 additions and 160 deletions
+9 -9
View File
@@ -23,19 +23,19 @@
namespace EQEmu
{
template <typename T>
T Clamp(const T& value, const T& lower, const T& upper) {
return std::max(lower, std::min(value, upper));
template <typename T, typename U, typename V>
T Clamp(const T& value, const U& lower, const V& upper) {
return std::max(static_cast<T>(lower), std::min(value, static_cast<T>(upper)));
}
template <typename T>
T ClampLower(const T& value, const T& lower) {
return std::max(lower, value);
template <typename T, typename U>
T ClampLower(const T& value, const U& lower) {
return std::max(static_cast<T>(lower), value);
}
template <typename T>
T ClampUpper(const T& value, const T& upper) {
return std::min(value, upper);
template <typename T, typename U>
T ClampUpper(const T& value, const U& upper) {
return std::min(value, static_cast<T>(upper));
}
template <typename T, typename U, typename V>
+65 -8
View File
@@ -136,6 +136,18 @@ EQEmu::Inventory::~Inventory() {
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) {
auto iter = impl_->containers_.find(slot.Type());
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) {
printf("%s -> %s (%i)\n", src.IsCursor() ? "Cursor" : src.ToString().c_str(), dest.IsCursor() ? "Cursor" : dest.ToString().c_str(), charges);
if(src == dest) {
return true;
}
if(dest.IsDelete()) {
//return Delete(src);
return false;
return _destroy(src);
}
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_dest = Get(dest);
if(dest.IsEquipment() && !CanEquip(i_dest, dest)) {
if(!i_src) {
return false;
}
if(!i_src) {
if(dest.IsEquipment() && !CanEquip(i_src, dest)) {
return false;
}
@@ -234,8 +243,56 @@ bool EQEmu::Inventory::Swap(const InventorySlot &src, const InventorySlot &dest,
}
if(i_src->IsStackable()) {
//charges == 0 -> Move entire stack from src to dest
//charges > 0 -> Move charges number of charges from src to dest (may require creating a new item
//move # charges from src to dest
//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 {
return _swap(src, dest);
}
+4
View File
@@ -126,6 +126,10 @@ namespace EQEmu
Inventory(int race, int class_, int deity);
~Inventory();
void SetRace(int race);
void SetClass(int class_);
void SetDeity(int deity);
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);
+1 -1
View File
@@ -993,7 +993,7 @@ int InventoryOld::GetSlotByItemInst(ItemInst *inst) {
return INVALID_INDEX;
}
uint8 Inventory::FindBrightestLightType()
uint8 InventoryOld::FindBrightestLightType()
{
uint8 brightest_light_type = 0;
+40 -22
View File
@@ -20,6 +20,12 @@
#include "data_verification.h"
#include "item_container.h"
uint32 ItemInstanceSerial = 1;
uint32 EQEmu::GetNextItemInstanceSerial() {
ItemInstanceSerial++;
return ItemInstanceSerial;
}
struct EQEmu::ItemInstance::impl {
const ItemData *base_item_;
ItemData *modified_item_;
@@ -39,24 +45,6 @@ struct EQEmu::ItemInstance::impl {
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) {
impl_ = new impl;
impl_->base_item_ = idata;
@@ -97,6 +85,39 @@ EQEmu::ItemInstance::~ItemInstance() {
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() {
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) {
if(!inst || !inst->GetItem()) {
return false;
}
if(!impl_->base_item_) {
return false;
}
@@ -342,3 +359,4 @@ bool EQEmu::ItemInstance::IsNoDrop() const {
EQEmu::ItemContainer *EQEmu::ItemInstance::GetContainer() {
return &(impl_->contents_);
}
+4 -1
View File
@@ -24,11 +24,12 @@
namespace EQEmu
{
uint32 GetNextItemInstanceSerial();
class ItemContainer;
class ItemInstance
{
public:
ItemInstance();
ItemInstance(const ItemData* idata);
ItemInstance(const ItemData* idata, const int16 charges);
~ItemInstance();
@@ -37,6 +38,8 @@ namespace EQEmu
const ItemData *GetBaseItem();
const ItemData *GetBaseItem() const;
std::shared_ptr<ItemInstance> Split(int charges);
//Container
std::shared_ptr<ItemInstance> Get(const int index);
bool Put(const int index, std::shared_ptr<ItemInstance> inst);
+1 -1
View File
@@ -162,7 +162,7 @@ void EQEmu::MemoryBuffer::Resize(size_t sz) {
if(sz > capacity_) {
size_t new_size = sz + 32;
uchar *temp = new uchar[new_size];
memcpy(temp, buffer_, new_size);
memcpy(temp, buffer_, capacity_);
delete[] buffer_;
buffer_ = temp;
+1 -1
View File
@@ -121,4 +121,4 @@ namespace EQEmu
} // EQEmu
#endif
#endif
+2 -9
View File
@@ -15,14 +15,6 @@
#include "shareddb.h"
#include "string_util.h"
uint32 ItemInstanceSerial = 1;
static inline uint32 GetNextItemInstanceSerial() {
ItemInstanceSerial++;
return ItemInstanceSerial;
}
SharedDatabase::SharedDatabase()
: 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)
@@ -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));
inst->SetSerialNumber(GetNextItemInstanceSerial());
inst->SetSerialNumber(EQEmu::GetNextItemInstanceSerial());
//Set Tracking here
return inst;
}