mirror of
https://github.com/EQEmu/Server.git
synced 2025-12-22 11:11:30 +00:00
Early stages of swapping requirements in, should check for basic validity and equipable status
This commit is contained in:
parent
568938d003
commit
18b4d068ea
@ -38,8 +38,8 @@ T ClampUpper(const T& value, const T& upper) {
|
|||||||
return std::min(value, upper);
|
return std::min(value, upper);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T>
|
template <typename T, typename U, typename V>
|
||||||
bool ValueWithin(const T& value, const T& lower, const T& upper) {
|
bool ValueWithin(const T& value, const U& lower, const V& upper) {
|
||||||
return value >= lower && value <= upper;
|
return value >= lower && value <= upper;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -19,8 +19,82 @@
|
|||||||
#include "inventory.h"
|
#include "inventory.h"
|
||||||
#include "data_verification.h"
|
#include "data_verification.h"
|
||||||
#include "item_container_personal_serialization.h"
|
#include "item_container_personal_serialization.h"
|
||||||
|
#include "string_util.h"
|
||||||
#include <map>
|
#include <map>
|
||||||
|
|
||||||
|
bool EQEmu::InventorySlot::IsValid() const {
|
||||||
|
if(type_ == InvTypePersonal && EQEmu::ValueWithin(slot_, PersonalSlotCharm, PersonalSlotCursor)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(type_ == InvTypeBank && EQEmu::ValueWithin(slot_, 0, 23)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(type_ == InvTypeSharedBank && EQEmu::ValueWithin(slot_, 0, 1)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(type_ == InvTypeTribute && EQEmu::ValueWithin(slot_, 0, 4)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(type_ == InvTypeTrade && EQEmu::ValueWithin(slot_, 0, 7)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(type_ == InvTypeWorld && EQEmu::ValueWithin(slot_, 0, 255)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool EQEmu::InventorySlot::IsBank() const {
|
||||||
|
if(type_ == InvTypeBank && EQEmu::ValueWithin(slot_, 0, 23)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(type_ == InvTypeSharedBank && EQEmu::ValueWithin(slot_, 0, 1)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool EQEmu::InventorySlot::IsCursor() const {
|
||||||
|
if(type_ == InvTypePersonal && slot_ == PersonalSlotCursor) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(type_ == InvTypeCursorBuffer) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool EQEmu::InventorySlot::IsEquipment() const {
|
||||||
|
if(type_ == InvTypePersonal && EQEmu::ValueWithin(slot_, PersonalSlotCharm, PersonalSlotAmmo)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool EQEmu::InventorySlot::IsGeneral() const {
|
||||||
|
if(type_ == InvTypePersonal && EQEmu::ValueWithin(slot_, PersonalSlotGeneral1, PersonalSlotGeneral10)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
const std::string EQEmu::InventorySlot::ToString() const {
|
||||||
|
return StringFormat("(%i, %i, %i, %i)", type_, slot_, bag_index_, aug_index_);
|
||||||
|
}
|
||||||
|
|
||||||
struct EQEmu::Inventory::impl
|
struct EQEmu::Inventory::impl
|
||||||
{
|
{
|
||||||
std::map<int, ItemContainer> containers_;
|
std::map<int, ItemContainer> containers_;
|
||||||
@ -35,15 +109,15 @@ EQEmu::Inventory::~Inventory() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
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()) {
|
||||||
auto item = iter->second.Get(slot.slot_);
|
auto item = iter->second.Get(slot.Slot());
|
||||||
if(item) {
|
if(item) {
|
||||||
if(slot.bag_index_ > -1) {
|
if(slot.BagIndex() > -1) {
|
||||||
auto sub_item = item->Get(slot.bag_index_);
|
auto sub_item = item->Get(slot.BagIndex());
|
||||||
if(sub_item) {
|
if(sub_item) {
|
||||||
if(slot.aug_index_ > -1) {
|
if(slot.AugIndex() > -1) {
|
||||||
return sub_item->Get(slot.aug_index_);
|
return sub_item->Get(slot.AugIndex());
|
||||||
} else {
|
} else {
|
||||||
return sub_item;
|
return sub_item;
|
||||||
}
|
}
|
||||||
@ -58,42 +132,42 @@ std::shared_ptr<EQEmu::ItemInstance> EQEmu::Inventory::Get(const InventorySlot &
|
|||||||
}
|
}
|
||||||
|
|
||||||
bool EQEmu::Inventory::Put(const InventorySlot &slot, std::shared_ptr<ItemInstance> inst) {
|
bool EQEmu::Inventory::Put(const InventorySlot &slot, std::shared_ptr<ItemInstance> inst) {
|
||||||
if(impl_->containers_.count(slot.type_) == 0) {
|
if(impl_->containers_.count(slot.Type()) == 0) {
|
||||||
if(slot.type_ == 0) {
|
if(slot.Type() == 0) {
|
||||||
impl_->containers_.insert(std::pair<int, ItemContainer>(slot.type_, ItemContainer(new ItemContainerPersonalSerialization())));
|
impl_->containers_.insert(std::pair<int, ItemContainer>(slot.Type(), ItemContainer(new ItemContainerPersonalSerialization())));
|
||||||
} else {
|
} else {
|
||||||
impl_->containers_.insert(std::pair<int, ItemContainer>(slot.type_, ItemContainer()));
|
impl_->containers_.insert(std::pair<int, ItemContainer>(slot.Type(), ItemContainer()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//Verify item can be put into the slot requested
|
//Verify item can be put into the slot requested
|
||||||
|
|
||||||
auto &container = impl_->containers_[slot.type_];
|
auto &container = impl_->containers_[slot.Type()];
|
||||||
if(slot.bag_index_ > -1) {
|
if(slot.BagIndex() > -1) {
|
||||||
auto item = container.Get(slot.slot_);
|
auto item = container.Get(slot.Slot());
|
||||||
if(!item)
|
if(!item)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
if(slot.aug_index_ > -1) {
|
if(slot.AugIndex() > -1) {
|
||||||
auto bag_item = item->Get(slot.bag_index_);
|
auto bag_item = item->Get(slot.BagIndex());
|
||||||
if(!bag_item) {
|
if(!bag_item) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
return bag_item->Put(slot.aug_index_, inst);
|
return bag_item->Put(slot.AugIndex(), inst);
|
||||||
} else {
|
} else {
|
||||||
return item->Put(slot.bag_index_, inst);
|
return item->Put(slot.BagIndex(), inst);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if(slot.aug_index_ > -1) {
|
if(slot.AugIndex() > -1) {
|
||||||
auto item = container.Get(slot.slot_);
|
auto item = container.Get(slot.Slot());
|
||||||
if(!item)
|
if(!item)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
return item->Put(slot.aug_index_, inst);
|
return item->Put(slot.AugIndex(), inst);
|
||||||
}
|
}
|
||||||
|
|
||||||
return container.Put(slot.slot_, inst);
|
return container.Put(slot.Slot(), inst);
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
@ -104,10 +178,10 @@ bool EQEmu::Inventory::Swap(const InventorySlot &src, const InventorySlot &dest,
|
|||||||
}
|
}
|
||||||
|
|
||||||
int EQEmu::Inventory::CalcMaterialFromSlot(const InventorySlot &slot) {
|
int EQEmu::Inventory::CalcMaterialFromSlot(const InventorySlot &slot) {
|
||||||
if(slot.type_ != 0)
|
if(slot.Type() != 0)
|
||||||
return _MaterialInvalid;
|
return _MaterialInvalid;
|
||||||
|
|
||||||
switch(slot.slot_) {
|
switch(slot.Slot()) {
|
||||||
case PersonalSlotHead:
|
case PersonalSlotHead:
|
||||||
return MaterialHead;
|
return MaterialHead;
|
||||||
case PersonalSlotChest:
|
case PersonalSlotChest:
|
||||||
|
|||||||
@ -20,24 +20,10 @@
|
|||||||
#define COMMON_INVENTORY_H
|
#define COMMON_INVENTORY_H
|
||||||
|
|
||||||
#include "item_container.h"
|
#include "item_container.h"
|
||||||
|
#include <string>
|
||||||
|
|
||||||
namespace EQEmu
|
namespace EQEmu
|
||||||
{
|
{
|
||||||
struct InventorySlot
|
|
||||||
{
|
|
||||||
InventorySlot(int type, int slot)
|
|
||||||
: type_(type), slot_(slot), bag_index_(-1), aug_index_(-1) { }
|
|
||||||
InventorySlot(int type, int slot, int bag_index)
|
|
||||||
: type_(type), slot_(slot), bag_index_(bag_index), aug_index_(-1) { }
|
|
||||||
InventorySlot(int type, int slot, int bag_index, int aug_index)
|
|
||||||
: type_(type), slot_(slot), bag_index_(bag_index), aug_index_(aug_index) { }
|
|
||||||
|
|
||||||
int type_;
|
|
||||||
int slot_;
|
|
||||||
int bag_index_;
|
|
||||||
int aug_index_;
|
|
||||||
};
|
|
||||||
|
|
||||||
enum InventoryType : int
|
enum InventoryType : int
|
||||||
{
|
{
|
||||||
InvTypePersonal = 0,
|
InvTypePersonal = 0,
|
||||||
@ -89,6 +75,48 @@ namespace EQEmu
|
|||||||
PersonalSlotCursor
|
PersonalSlotCursor
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class InventorySlot
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
InventorySlot() : type_(-1), slot_(-1), bag_index_(-1), aug_index_(-1) { }
|
||||||
|
InventorySlot(int type, int slot)
|
||||||
|
: type_(type), slot_(slot), bag_index_(-1), aug_index_(-1) { }
|
||||||
|
InventorySlot(int type, int slot, int bag_index)
|
||||||
|
: type_(type), slot_(slot), bag_index_(bag_index), aug_index_(-1) { }
|
||||||
|
InventorySlot(int type, int slot, int bag_index, int aug_index)
|
||||||
|
: type_(type), slot_(slot), bag_index_(bag_index), aug_index_(aug_index) { }
|
||||||
|
|
||||||
|
bool IsValid() const;
|
||||||
|
bool IsBank() const;
|
||||||
|
bool IsCursor() const;
|
||||||
|
bool IsEquipment() const;
|
||||||
|
bool IsGeneral() const;
|
||||||
|
|
||||||
|
const std::string ToString() const;
|
||||||
|
|
||||||
|
inline int Type() { return type_; }
|
||||||
|
inline int Type() const { return type_; }
|
||||||
|
inline int Slot() { return slot_; }
|
||||||
|
inline int Slot() const { return slot_; }
|
||||||
|
inline int BagIndex() { return bag_index_; }
|
||||||
|
inline int BagIndex() const { return bag_index_; }
|
||||||
|
inline int AugIndex() { return aug_index_; }
|
||||||
|
inline int AugIndex() const { return aug_index_; }
|
||||||
|
|
||||||
|
private:
|
||||||
|
int type_;
|
||||||
|
int slot_;
|
||||||
|
int bag_index_;
|
||||||
|
int aug_index_;
|
||||||
|
};
|
||||||
|
|
||||||
|
inline bool operator==(const InventorySlot &lhs, const InventorySlot &rhs) {
|
||||||
|
return lhs.Type() == rhs.Type() &&
|
||||||
|
lhs.Slot() == rhs.Slot() &&
|
||||||
|
lhs.BagIndex() == rhs.BagIndex() &&
|
||||||
|
lhs.AugIndex() == rhs.AugIndex(); }
|
||||||
|
inline bool operator!=(const InventorySlot &lhs, const InventorySlot &rhs) { return !(lhs == rhs); }
|
||||||
|
|
||||||
class Inventory
|
class Inventory
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
|||||||
@ -124,14 +124,14 @@ bool EQEmu::ItemInstance::Put(const int index, std::shared_ptr<ItemInstance> ins
|
|||||||
|
|
||||||
auto *item = impl_->base_item_;
|
auto *item = impl_->base_item_;
|
||||||
if(item->ItemClass == ItemClassContainer) { // Bag
|
if(item->ItemClass == ItemClassContainer) { // Bag
|
||||||
if(!EQEmu::ValueWithin(index, 0, (int)item->BagSlots)) {
|
if(!EQEmu::ValueWithin(index, 0, item->BagSlots)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
return impl_->contents_.Put(index, inst);
|
return impl_->contents_.Put(index, inst);
|
||||||
}
|
}
|
||||||
else if(item->ItemClass == ItemClassCommon) { // Augment
|
else if(item->ItemClass == ItemClassCommon) { // Augment
|
||||||
if(!EQEmu::ValueWithin(index, 0, (int)EmuConstants::ITEM_COMMON_SIZE)) {
|
if(!EQEmu::ValueWithin(index, 0, EmuConstants::ITEM_COMMON_SIZE)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -2167,7 +2167,7 @@ void Client::AddMoneyToPP(uint64 copper, bool updateclient){
|
|||||||
Log.Out(Logs::General, Logs::None, "Client::AddMoneyToPP() %s should have: plat:%i gold:%i silver:%i copper:%i", GetName(), m_pp.platinum, m_pp.gold, m_pp.silver, m_pp.copper);
|
Log.Out(Logs::General, Logs::None, "Client::AddMoneyToPP() %s should have: plat:%i gold:%i silver:%i copper:%i", GetName(), m_pp.platinum, m_pp.gold, m_pp.silver, m_pp.copper);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Client::EVENT_ITEM_ScriptStopReturn(){
|
void Client::ItemScriptStopReturn(){
|
||||||
/* Set a timestamp in an entity variable for plugin check_handin.pl in return_items
|
/* Set a timestamp in an entity variable for plugin check_handin.pl in return_items
|
||||||
This will stopgap players from items being returned if global_npc.pl has a catch all return_items
|
This will stopgap players from items being returned if global_npc.pl has a catch all return_items
|
||||||
*/
|
*/
|
||||||
@ -2175,11 +2175,11 @@ void Client::EVENT_ITEM_ScriptStopReturn(){
|
|||||||
char buffer[50];
|
char buffer[50];
|
||||||
gettimeofday(&read_time, 0);
|
gettimeofday(&read_time, 0);
|
||||||
sprintf(buffer, "%li.%li \n", read_time.tv_sec, read_time.tv_usec);
|
sprintf(buffer, "%li.%li \n", read_time.tv_sec, read_time.tv_usec);
|
||||||
this->SetEntityVariable("Stop_Return", buffer);
|
SetEntityVariable("Stop_Return", buffer);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Client::AddMoneyToPP(uint32 copper, uint32 silver, uint32 gold, uint32 platinum, bool updateclient){
|
void Client::AddMoneyToPP(uint32 copper, uint32 silver, uint32 gold, uint32 platinum, bool updateclient){
|
||||||
this->EVENT_ITEM_ScriptStopReturn();
|
ItemScriptStopReturn();
|
||||||
|
|
||||||
int32 new_value = m_pp.platinum + platinum;
|
int32 new_value = m_pp.platinum + platinum;
|
||||||
if(new_value >= 0 && new_value > m_pp.platinum)
|
if(new_value >= 0 && new_value > m_pp.platinum)
|
||||||
|
|||||||
@ -800,7 +800,7 @@ public:
|
|||||||
int32 acmod();
|
int32 acmod();
|
||||||
|
|
||||||
// Item methods
|
// Item methods
|
||||||
void EVENT_ITEM_ScriptStopReturn();
|
void ItemScriptStopReturn();
|
||||||
uint32 NukeItem(uint32 itemnum, uint8 where_to_check =
|
uint32 NukeItem(uint32 itemnum, uint8 where_to_check =
|
||||||
(invWhereWorn | invWherePersonal | invWhereBank | invWhereSharedBank | invWhereTrading | invWhereCursor));
|
(invWhereWorn | invWherePersonal | invWhereBank | invWhereSharedBank | invWhereTrading | invWhereCursor));
|
||||||
void SetTint(int16 slot_id, uint32 color);
|
void SetTint(int16 slot_id, uint32 color);
|
||||||
@ -823,6 +823,10 @@ public:
|
|||||||
void IncStats(uint8 type,int16 increase_val);
|
void IncStats(uint8 type,int16 increase_val);
|
||||||
void DropItem(int16 slot_id);
|
void DropItem(int16 slot_id);
|
||||||
|
|
||||||
|
//New Inventory
|
||||||
|
bool SwapItem(const EQEmu::InventorySlot &src, const EQEmu::InventorySlot &dest, int number_in_stack);
|
||||||
|
bool CanEquipItem(std::shared_ptr<EQEmu::ItemInstance> inst, const EQEmu::InventorySlot &slot);
|
||||||
|
|
||||||
//
|
//
|
||||||
// class Client::TextLink
|
// class Client::TextLink
|
||||||
//
|
//
|
||||||
|
|||||||
@ -9593,70 +9593,11 @@ void Client::Handle_OP_MoveItem(const EQApplicationPacket *app)
|
|||||||
}
|
}
|
||||||
|
|
||||||
MoveItem_Struct* mi = (MoveItem_Struct*)app->pBuffer;
|
MoveItem_Struct* mi = (MoveItem_Struct*)app->pBuffer;
|
||||||
auto res = m_inventory.Swap(EQEmu::InventorySlot(mi->from_type, mi->from_slot, mi->from_bag_slot, mi->from_aug_slot),
|
EQEmu::InventorySlot src(mi->from_type, mi->from_slot, mi->from_bag_slot, mi->from_aug_slot);
|
||||||
EQEmu::InventorySlot(mi->to_type, mi->to_slot, mi->to_bag_slot, mi->to_aug_slot),
|
EQEmu::InventorySlot dest(mi->to_type, mi->to_slot, mi->to_bag_slot, mi->to_aug_slot);
|
||||||
mi->number_in_stack);
|
if(!SwapItem(src, dest, mi->number_in_stack)) {
|
||||||
|
//Send Resync Here
|
||||||
//printf("%i %i %i %i --> %i %i %i %i (%u)\n",
|
}
|
||||||
// mi->from_type, mi->from_slot, mi->from_bag_slot, mi->from_aug_slot,
|
|
||||||
// mi->to_type, mi->to_slot, mi->to_bag_slot, mi->to_aug_slot,
|
|
||||||
// mi->number_in_stack);
|
|
||||||
|
|
||||||
//if (spellend_timer.Enabled() && casting_spell_id && !IsBardSong(casting_spell_id))
|
|
||||||
//{
|
|
||||||
// if (mi->from_slot != mi->to_slot && (mi->from_slot <= EmuConstants::GENERAL_END || mi->from_slot > 39) && IsValidSlot(mi->from_slot) && IsValidSlot(mi->to_slot))
|
|
||||||
// {
|
|
||||||
// char *detect = nullptr;
|
|
||||||
// const ItemInst *itm_from = GetInv().GetItem(mi->from_slot);
|
|
||||||
// const ItemInst *itm_to = GetInv().GetItem(mi->to_slot);
|
|
||||||
// MakeAnyLenString(&detect, "Player issued a move item from %u(item id %u) to %u(item id %u) while casting %u.",
|
|
||||||
// mi->from_slot,
|
|
||||||
// itm_from ? itm_from->GetID() : 0,
|
|
||||||
// mi->to_slot,
|
|
||||||
// itm_to ? itm_to->GetID() : 0,
|
|
||||||
// casting_spell_id);
|
|
||||||
// database.SetMQDetectionFlag(AccountName(), GetName(), detect, zone->GetShortName());
|
|
||||||
// safe_delete_array(detect);
|
|
||||||
// Kick(); // Kick client to prevent client and server from getting out-of-sync inventory slots
|
|
||||||
// return;
|
|
||||||
// }
|
|
||||||
//}
|
|
||||||
//
|
|
||||||
//// Illegal bagslot usage checks. Currently, user only receives a message if this check is triggered.
|
|
||||||
//bool mi_hack = false;
|
|
||||||
//
|
|
||||||
//if (mi->from_slot >= EmuConstants::GENERAL_BAGS_BEGIN && mi->from_slot <= EmuConstants::CURSOR_BAG_END) {
|
|
||||||
// if (mi->from_slot >= EmuConstants::CURSOR_BAG_BEGIN) { mi_hack = true; }
|
|
||||||
// else {
|
|
||||||
// int16 from_parent = m_inv.CalcSlotId(mi->from_slot);
|
|
||||||
// if (!m_inv[from_parent]) { mi_hack = true; }
|
|
||||||
// else if (!m_inv[from_parent]->IsType(ItemClassContainer)) { mi_hack = true; }
|
|
||||||
// else if (m_inv.CalcBagIdx(mi->from_slot) >= m_inv[from_parent]->GetItem()->BagSlots) { mi_hack = true; }
|
|
||||||
// }
|
|
||||||
//}
|
|
||||||
//
|
|
||||||
//if (mi->to_slot >= EmuConstants::GENERAL_BAGS_BEGIN && mi->to_slot <= EmuConstants::CURSOR_BAG_END) {
|
|
||||||
// if (mi->to_slot >= EmuConstants::CURSOR_BAG_BEGIN) { mi_hack = true; }
|
|
||||||
// else {
|
|
||||||
// int16 to_parent = m_inv.CalcSlotId(mi->to_slot);
|
|
||||||
// if (!m_inv[to_parent]) { mi_hack = true; }
|
|
||||||
// else if (!m_inv[to_parent]->IsType(ItemClassContainer)) { mi_hack = true; }
|
|
||||||
// else if (m_inv.CalcBagIdx(mi->to_slot) >= m_inv[to_parent]->GetItem()->BagSlots) { mi_hack = true; }
|
|
||||||
// }
|
|
||||||
//}
|
|
||||||
//
|
|
||||||
//if (mi_hack) { Message(15, "Caution: Illegal use of inaccessible bag slots!"); }
|
|
||||||
//
|
|
||||||
//if (!SwapItem(mi) && IsValidSlot(mi->from_slot) && IsValidSlot(mi->to_slot)) {
|
|
||||||
// SwapItemResync(mi);
|
|
||||||
//
|
|
||||||
// bool error = false;
|
|
||||||
// InterrogateInventory(this, false, true, false, error, false);
|
|
||||||
// if (error)
|
|
||||||
// InterrogateInventory(this, true, false, true, error);
|
|
||||||
//}
|
|
||||||
//
|
|
||||||
//return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Client::Handle_OP_OpenContainer(const EQApplicationPacket *app)
|
void Client::Handle_OP_OpenContainer(const EQApplicationPacket *app)
|
||||||
|
|||||||
@ -61,7 +61,7 @@ static uint32 MaxBankedRaidLeadershipPoints(int Level)
|
|||||||
|
|
||||||
void Client::AddEXP(uint32 in_add_exp, uint8 conlevel, bool resexp) {
|
void Client::AddEXP(uint32 in_add_exp, uint8 conlevel, bool resexp) {
|
||||||
|
|
||||||
this->EVENT_ITEM_ScriptStopReturn();
|
ItemScriptStopReturn();
|
||||||
|
|
||||||
uint32 add_exp = in_add_exp;
|
uint32 add_exp = in_add_exp;
|
||||||
|
|
||||||
|
|||||||
@ -18,8 +18,8 @@
|
|||||||
|
|
||||||
#include "../common/global_define.h"
|
#include "../common/global_define.h"
|
||||||
#include "../common/eqemu_logsys.h"
|
#include "../common/eqemu_logsys.h"
|
||||||
|
|
||||||
#include "../common/string_util.h"
|
#include "../common/string_util.h"
|
||||||
|
#include "../common/data_verification.h"
|
||||||
#include "quest_parser_collection.h"
|
#include "quest_parser_collection.h"
|
||||||
#include "worldserver.h"
|
#include "worldserver.h"
|
||||||
#include "zonedb.h"
|
#include "zonedb.h"
|
||||||
@ -191,7 +191,7 @@ bool Client::CheckLoreConflict(const ItemData* item)
|
|||||||
}
|
}
|
||||||
|
|
||||||
bool Client::SummonItem(uint32 item_id, int16 charges, uint32 aug1, uint32 aug2, uint32 aug3, uint32 aug4, uint32 aug5, uint32 aug6, bool attuned, uint16 to_slot, uint32 ornament_icon, uint32 ornament_idfile, uint32 ornament_hero_model) {
|
bool Client::SummonItem(uint32 item_id, int16 charges, uint32 aug1, uint32 aug2, uint32 aug3, uint32 aug4, uint32 aug5, uint32 aug6, bool attuned, uint16 to_slot, uint32 ornament_icon, uint32 ornament_idfile, uint32 ornament_hero_model) {
|
||||||
this->EVENT_ITEM_ScriptStopReturn();
|
ItemScriptStopReturn();
|
||||||
|
|
||||||
// TODO: update calling methods and script apis to handle a failure return
|
// TODO: update calling methods and script apis to handle a failure return
|
||||||
|
|
||||||
@ -3092,3 +3092,74 @@ std::string InventoryOld::GetCustomItemData(int16 slot_id, std::string identifie
|
|||||||
}
|
}
|
||||||
return "";
|
return "";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//New Inventory
|
||||||
|
bool Client::SwapItem(const EQEmu::InventorySlot &src, const EQEmu::InventorySlot &dest, int number_in_stack) {
|
||||||
|
|
||||||
|
if (spellend_timer.Enabled() && casting_spell_id && !IsBardSong(casting_spell_id))
|
||||||
|
{
|
||||||
|
if(src != dest && !src.IsCursor() && src.IsValid() && dest.IsValid()) {
|
||||||
|
auto i_src = m_inventory.Get(src);
|
||||||
|
auto i_dest = m_inventory.Get(dest);
|
||||||
|
std::string detect = StringFormat("Player issued a move item from %s (item id %u) to %s (item id %u) while casting %u.",
|
||||||
|
src.ToString().c_str(),
|
||||||
|
i_src ? i_src->GetItem()->ID : 0,
|
||||||
|
dest.ToString().c_str(),
|
||||||
|
i_dest ? i_dest->GetItem()->ID : 0,
|
||||||
|
casting_spell_id);
|
||||||
|
database.SetMQDetectionFlag(AccountName(), GetName(), detect.c_str(), zone->GetShortName());
|
||||||
|
Kick();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
auto i_src = m_inventory.Get(src);
|
||||||
|
auto i_dest = m_inventory.Get(dest);
|
||||||
|
|
||||||
|
if(dest.IsEquipment() && !CanEquipItem(i_dest, dest)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
printf("Equip check passes %s -> %s\n", src.ToString().c_str(), dest.ToString().c_str());
|
||||||
|
|
||||||
|
bool res = m_inventory.Swap(src, dest, number_in_stack);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Client::CanEquipItem(std::shared_ptr<EQEmu::ItemInstance> inst, const EQEmu::InventorySlot &slot) {
|
||||||
|
if(!inst) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(slot.Type() != 0) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(!EQEmu::ValueWithin(slot.Slot(), EQEmu::PersonalSlotCharm, EQEmu::PersonalSlotAmmo)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto item = inst->GetItem();
|
||||||
|
//check slot
|
||||||
|
|
||||||
|
int use_slot = -1;
|
||||||
|
if(slot.Slot() == EQEmu::PersonalSlotPowerSource) {
|
||||||
|
use_slot = EQEmu::PersonalSlotAmmo;
|
||||||
|
}
|
||||||
|
else if(slot.Slot() == EQEmu::PersonalSlotAmmo) {
|
||||||
|
use_slot = EQEmu::PersonalSlotPowerSource;
|
||||||
|
} else {
|
||||||
|
use_slot = slot.Slot();
|
||||||
|
}
|
||||||
|
|
||||||
|
if(!(item->Slots & (1 << use_slot))) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(!item->IsEquipable(GetBaseRace(), GetBaseClass())) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|||||||
@ -923,7 +923,7 @@ void Client::FinishTrade(Mob* tradingWith, bool finalizer, void* event_entry, st
|
|||||||
if(!tradingWith->IsMoving())
|
if(!tradingWith->IsMoving())
|
||||||
tradingWith->FaceTarget(this);
|
tradingWith->FaceTarget(this);
|
||||||
|
|
||||||
this->EVENT_ITEM_ScriptStopReturn();
|
ItemScriptStopReturn();
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user