mirror of
https://github.com/EQEmu/Server.git
synced 2026-09-01 07:26:36 +00:00
More work on swapping, almost there just need to write code for stack split/move/combining
This commit is contained in:
+97
-2
@@ -51,6 +51,10 @@ bool EQEmu::InventorySlot::IsValid() const {
|
||||
return false;
|
||||
}
|
||||
|
||||
bool EQEmu::InventorySlot::IsDelete() const {
|
||||
return type_ == -1 && slot_ == -1 && bag_index_ == -1 && aug_index_ == -1;
|
||||
}
|
||||
|
||||
bool EQEmu::InventorySlot::IsBank() const {
|
||||
if(type_ == InvTypeBank && EQEmu::ValueWithin(slot_, 0, 23)) {
|
||||
return true;
|
||||
@@ -91,6 +95,24 @@ bool EQEmu::InventorySlot::IsGeneral() const {
|
||||
return false;
|
||||
}
|
||||
|
||||
bool EQEmu::InventorySlot::IsWeapon() const {
|
||||
if(type_ == InvTypePersonal &&
|
||||
(EQEmu::ValueWithin(slot_, PersonalSlotPrimary, PersonalSlotSecondary) || slot_ == PersonalSlotRange))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool EQEmu::InventorySlot::IsTrade() const {
|
||||
if(type_ == InvTypeTrade) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
const std::string EQEmu::InventorySlot::ToString() const {
|
||||
return StringFormat("(%i, %i, %i, %i)", type_, slot_, bag_index_, aug_index_);
|
||||
}
|
||||
@@ -100,12 +122,14 @@ struct EQEmu::Inventory::impl
|
||||
std::map<int, ItemContainer> containers_;
|
||||
int race_;
|
||||
int class_;
|
||||
int deity_;
|
||||
};
|
||||
|
||||
EQEmu::Inventory::Inventory(int race, int class_) {
|
||||
EQEmu::Inventory::Inventory(int race, int class_, int deity) {
|
||||
impl_ = new impl;
|
||||
impl_->race_ = race;
|
||||
impl_->class_ = class_;
|
||||
impl_->deity_ = deity;
|
||||
}
|
||||
|
||||
EQEmu::Inventory::~Inventory() {
|
||||
@@ -178,7 +202,45 @@ bool EQEmu::Inventory::Put(const InventorySlot &slot, std::shared_ptr<ItemInstan
|
||||
}
|
||||
|
||||
bool EQEmu::Inventory::Swap(const InventorySlot &src, const InventorySlot &dest, int charges) {
|
||||
return false;
|
||||
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;
|
||||
}
|
||||
|
||||
if(!src.IsValid() || !dest.IsValid()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
auto i_src = Get(src);
|
||||
auto i_dest = Get(dest);
|
||||
|
||||
if(dest.IsEquipment() && !CanEquip(i_dest, dest)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if(!i_src) {
|
||||
return false;
|
||||
}
|
||||
|
||||
//Check this -> trade no drop
|
||||
if(dest.IsTrade() && i_src->IsNoDrop()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
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
|
||||
} else {
|
||||
return _swap(src, dest);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
int EQEmu::Inventory::CalcMaterialFromSlot(const InventorySlot &slot) {
|
||||
@@ -288,3 +350,36 @@ bool EQEmu::Inventory::Serialize(MemoryBuffer &buf) {
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
bool EQEmu::Inventory::_swap(const InventorySlot &src, const InventorySlot &dest) {
|
||||
auto src_i = Get(src);
|
||||
auto dest_i = Get(dest);
|
||||
|
||||
if(src_i) {
|
||||
if(!_destroy(src)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if(dest_i) {
|
||||
if(!_destroy(dest)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if(!Put(src, dest_i)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if(src_i) {
|
||||
if(!Put(dest, src_i)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool EQEmu::Inventory::_destroy(const InventorySlot &slot) {
|
||||
return Put(slot, std::shared_ptr<EQEmu::ItemInstance>(nullptr));
|
||||
}
|
||||
|
||||
+7
-1
@@ -87,10 +87,13 @@ namespace EQEmu
|
||||
: type_(type), slot_(slot), bag_index_(bag_index), aug_index_(aug_index) { }
|
||||
|
||||
bool IsValid() const;
|
||||
bool IsDelete() const;
|
||||
bool IsBank() const;
|
||||
bool IsCursor() const;
|
||||
bool IsEquipment() const;
|
||||
bool IsGeneral() const;
|
||||
bool IsWeapon() const;
|
||||
bool IsTrade() const;
|
||||
|
||||
const std::string ToString() const;
|
||||
|
||||
@@ -120,7 +123,7 @@ namespace EQEmu
|
||||
class Inventory
|
||||
{
|
||||
public:
|
||||
Inventory(int race, int class_);
|
||||
Inventory(int race, int class_, int deity);
|
||||
~Inventory();
|
||||
|
||||
std::shared_ptr<ItemInstance> Get(const InventorySlot &slot);
|
||||
@@ -133,6 +136,9 @@ namespace EQEmu
|
||||
bool CanEquip(std::shared_ptr<EQEmu::ItemInstance> inst, const EQEmu::InventorySlot &slot);
|
||||
bool Serialize(MemoryBuffer &buf);
|
||||
private:
|
||||
bool _swap(const InventorySlot &src, const InventorySlot &dest);
|
||||
bool _destroy(const InventorySlot &slot);
|
||||
|
||||
struct impl;
|
||||
impl *impl_;
|
||||
};
|
||||
|
||||
@@ -51,13 +51,15 @@ std::shared_ptr<EQEmu::ItemInstance> EQEmu::ItemContainer::Get(const int slot_id
|
||||
}
|
||||
|
||||
bool EQEmu::ItemContainer::Put(const int slot_id, std::shared_ptr<ItemInstance> inst) {
|
||||
if(!inst)
|
||||
return false;
|
||||
|
||||
auto iter = impl_->items_.find(slot_id);
|
||||
if(iter == impl_->items_.end()) {
|
||||
impl_->items_[slot_id] = inst;
|
||||
if(!inst) {
|
||||
impl_->items_.erase(slot_id);
|
||||
return true;
|
||||
} else {
|
||||
auto iter = impl_->items_.find(slot_id);
|
||||
if(iter == impl_->items_.end()) {
|
||||
impl_->items_[slot_id] = inst;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
|
||||
@@ -105,6 +105,10 @@ const ItemData *EQEmu::ItemInstance::GetBaseItem() {
|
||||
return impl_->base_item_;
|
||||
}
|
||||
|
||||
const ItemData *EQEmu::ItemInstance::GetBaseItem() const {
|
||||
return impl_->base_item_;
|
||||
}
|
||||
|
||||
std::shared_ptr<EQEmu::ItemInstance> EQEmu::ItemInstance::Get(const int index) {
|
||||
if(EQEmu::ValueWithin(index, 0, 255)) {
|
||||
return impl_->contents_.Get(index);
|
||||
@@ -139,9 +143,13 @@ bool EQEmu::ItemInstance::Put(const int index, std::shared_ptr<ItemInstance> ins
|
||||
return false;
|
||||
}
|
||||
|
||||
auto *aug_item = inst->GetItem();
|
||||
int aug_type = aug_item->AugType;
|
||||
if(aug_type == -1 || (1 << (item->AugSlotType[index] - 1)) & aug_type) {
|
||||
if(inst) {
|
||||
auto *aug_item = inst->GetItem();
|
||||
int aug_type = aug_item->AugType;
|
||||
if(aug_type == -1 || (1 << (item->AugSlotType[index] - 1)) & aug_type) {
|
||||
return impl_->contents_.Put(index, inst);
|
||||
}
|
||||
} else {
|
||||
return impl_->contents_.Put(index, inst);
|
||||
}
|
||||
|
||||
@@ -323,6 +331,14 @@ bool EQEmu::ItemInstance::IsStackable() const {
|
||||
return impl_->base_item_->Stackable;
|
||||
}
|
||||
|
||||
bool EQEmu::ItemInstance::IsNoDrop() {
|
||||
return GetAttuned() || GetBaseItem()->NoDrop == 0;
|
||||
}
|
||||
|
||||
bool EQEmu::ItemInstance::IsNoDrop() const {
|
||||
return GetAttuned() || GetBaseItem()->NoDrop == 0;
|
||||
}
|
||||
|
||||
EQEmu::ItemContainer *EQEmu::ItemInstance::GetContainer() {
|
||||
return &(impl_->contents_);
|
||||
}
|
||||
|
||||
@@ -35,6 +35,7 @@ namespace EQEmu
|
||||
|
||||
const ItemData *GetItem();
|
||||
const ItemData *GetBaseItem();
|
||||
const ItemData *GetBaseItem() const;
|
||||
|
||||
//Container
|
||||
std::shared_ptr<ItemInstance> Get(const int index);
|
||||
@@ -95,6 +96,9 @@ namespace EQEmu
|
||||
bool IsStackable();
|
||||
bool IsStackable() const;
|
||||
|
||||
bool IsNoDrop();
|
||||
bool IsNoDrop() const;
|
||||
|
||||
//Internal state
|
||||
//Used for low level operations such as encode/decode
|
||||
ItemContainer *GetContainer();
|
||||
|
||||
Reference in New Issue
Block a user