mirror of
https://github.com/EQEmu/Server.git
synced 2026-05-22 20:33:01 +00:00
Compare commits
36 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 46cb96a026 | |||
| bbc3733c3a | |||
| 5995afa1b8 | |||
| ff3cb9fc54 | |||
| 56e7d1b0dc | |||
| 7341ecc185 | |||
| 279ed8d86c | |||
| 21ce5c6daa | |||
| 00af95502e | |||
| dda8ae4803 | |||
| 316aa5ef73 | |||
| 9fcdf5367e | |||
| 972d3d8874 | |||
| abc5ddc5f8 | |||
| 14b5a8d817 | |||
| 20cbe4af44 | |||
| 7870bf103a | |||
| 18b4d068ea | |||
| 568938d003 | |||
| 215861dd86 | |||
| c62cff1ce7 | |||
| 69612b44d4 | |||
| 8bce7893ed | |||
| 4e4168852b | |||
| ca278d029e | |||
| 273574d4db | |||
| c71a5888ff | |||
| b3c53e5907 | |||
| f511862004 | |||
| a90e9cf4c6 | |||
| 2d617f0ea7 | |||
| 551c0ef368 | |||
| a5274b9b6e | |||
| fc2492a859 | |||
| 701e194ece | |||
| b75e6308dd |
+18
-1
@@ -30,9 +30,16 @@ SET(common_sources
|
||||
faction.cpp
|
||||
guild_base.cpp
|
||||
guilds.cpp
|
||||
inventory.cpp
|
||||
inventory_db_data_model.cpp
|
||||
ipc_mutex.cpp
|
||||
item.cpp
|
||||
item_container.cpp
|
||||
item_container_default_serialization.cpp
|
||||
item_container_personal_serialization.cpp
|
||||
item_instance.cpp
|
||||
md5.cpp
|
||||
memory_buffer.cpp
|
||||
memory_mapped_file.cpp
|
||||
misc.cpp
|
||||
misc_functions.cpp
|
||||
@@ -135,15 +142,25 @@ SET(common_headers
|
||||
global_define.h
|
||||
guild_base.h
|
||||
guilds.h
|
||||
inventory.h
|
||||
inventory_data_model.h
|
||||
inventory_db_data_model.h
|
||||
inventory_null_data_model.h
|
||||
ipc_mutex.h
|
||||
item.h
|
||||
item_container.h
|
||||
item_container_default_serialization.h
|
||||
item_container_personal_serialization.h
|
||||
item_container_serialization_strategy.h
|
||||
item_data.h
|
||||
item_fieldlist.h
|
||||
item_struct.h
|
||||
item_instance.h
|
||||
languages.h
|
||||
linked_list.h
|
||||
loottable.h
|
||||
mail_oplist.h
|
||||
md5.h
|
||||
memory_buffer.h
|
||||
memory_mapped_file.h
|
||||
misc.h
|
||||
misc_functions.h
|
||||
|
||||
+11
-11
@@ -23,23 +23,23 @@
|
||||
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>
|
||||
bool ValueWithin(const T& value, const T& lower, const T& upper) {
|
||||
template <typename T, typename U, typename V>
|
||||
bool ValueWithin(const T& value, const U& lower, const V& upper) {
|
||||
return value >= lower && value <= upper;
|
||||
}
|
||||
|
||||
|
||||
+1
-1
@@ -677,7 +677,7 @@ bool Database::SaveCharacterCreate(uint32 character_id, uint32 account_id, Playe
|
||||
}
|
||||
|
||||
/* This only for new Character creation storing */
|
||||
bool Database::StoreCharacter(uint32 account_id, PlayerProfile_Struct* pp, Inventory* inv) {
|
||||
bool Database::StoreCharacter(uint32 account_id, PlayerProfile_Struct* pp, InventoryOld* inv) {
|
||||
uint32 charid = 0;
|
||||
char zone[50];
|
||||
float x, y, z;
|
||||
|
||||
+3
-2
@@ -27,6 +27,7 @@
|
||||
#include "dbcore.h"
|
||||
#include "linked_list.h"
|
||||
#include "eq_packet_structs.h"
|
||||
#include "inventory.h"
|
||||
|
||||
#include <cmath>
|
||||
#include <string>
|
||||
@@ -36,7 +37,7 @@
|
||||
//atoi is not uint32 or uint32 safe!!!!
|
||||
#define atoul(str) strtoul(str, nullptr, 10)
|
||||
|
||||
class Inventory;
|
||||
class InventoryOld;
|
||||
class MySQLRequestResult;
|
||||
class Client;
|
||||
|
||||
@@ -102,7 +103,7 @@ public:
|
||||
bool SaveCharacterCreate(uint32 character_id, uint32 account_id, PlayerProfile_Struct* pp);
|
||||
bool SetHackerFlag(const char* accountname, const char* charactername, const char* hacked);
|
||||
bool SetMQDetectionFlag(const char* accountname, const char* charactername, const char* hacked, const char* zone);
|
||||
bool StoreCharacter(uint32 account_id, PlayerProfile_Struct* pp, Inventory* inv);
|
||||
bool StoreCharacter(uint32 account_id, PlayerProfile_Struct* pp, InventoryOld* inv);
|
||||
bool UpdateName(const char* oldname, const char* newname);
|
||||
|
||||
/* General Information Queries */
|
||||
|
||||
@@ -306,7 +306,7 @@ enum AugmentationRestrictionTypes : uint8 {
|
||||
/*
|
||||
** Container use types
|
||||
**
|
||||
** This correlates to world 'object.type' (object.h/Object.cpp) as well as Item_Struct.BagType
|
||||
** This correlates to world 'object.type' (object.h/Object.cpp) as well as ItemData.BagType
|
||||
**
|
||||
** (ref: database, web forums and eqstr_us.txt)
|
||||
*/
|
||||
|
||||
+29
-10
@@ -25,7 +25,7 @@
|
||||
#include <list>
|
||||
#include <time.h>
|
||||
#include "../common/version.h"
|
||||
//#include "../common/item_struct.h"
|
||||
//#include "../common/item_data.h"
|
||||
|
||||
static const uint32 BUFF_COUNT = 25;
|
||||
static const uint32 MAX_MERC = 100;
|
||||
@@ -126,6 +126,14 @@ struct LDoNTrapTemplate
|
||||
|
||||
// All clients translate the character select information to some degree
|
||||
|
||||
struct Inventory_Slot_Struct
|
||||
{
|
||||
int16 type;
|
||||
int16 slot;
|
||||
int16 bag;
|
||||
int16 aug;
|
||||
};
|
||||
|
||||
struct Color_Struct
|
||||
{
|
||||
union {
|
||||
@@ -1558,7 +1566,7 @@ struct DeleteItem_Struct {
|
||||
/*0012*/
|
||||
};
|
||||
|
||||
struct MoveItem_Struct
|
||||
struct MoveItemOld_Struct
|
||||
{
|
||||
/*0000*/ uint32 from_slot;
|
||||
/*0004*/ uint32 to_slot;
|
||||
@@ -1566,6 +1574,19 @@ struct MoveItem_Struct
|
||||
/*0012*/
|
||||
};
|
||||
|
||||
struct MoveItem_Struct
|
||||
{
|
||||
int16 from_type;
|
||||
int16 from_slot;
|
||||
int16 from_bag_slot;
|
||||
int16 from_aug_slot;
|
||||
int16 to_type;
|
||||
int16 to_slot;
|
||||
int16 to_bag_slot;
|
||||
int16 to_aug_slot;
|
||||
uint32 number_in_stack;
|
||||
};
|
||||
|
||||
// both MoveItem_Struct/DeleteItem_Struct server structures will be changing to a structure-based slot format..this will
|
||||
// be used for handling SoF/SoD/etc... time stamps sent using the MoveItem_Struct format. (nothing will be done with this
|
||||
// info at the moment..but, it is forwarded on to the server for handling/future use)
|
||||
@@ -1957,13 +1978,11 @@ Unknowns:
|
||||
|
||||
|
||||
struct Merchant_Sell_Struct {
|
||||
/*000*/ uint32 npcid; // Merchant NPC's entity id
|
||||
/*004*/ uint32 playerid; // Player's entity id
|
||||
/*008*/ uint32 itemslot;
|
||||
uint32 unknown12;
|
||||
/*016*/ uint8 quantity; // Already sold
|
||||
/*017*/ uint8 Unknown016[3];
|
||||
/*020*/ uint32 price;
|
||||
uint32 npcid;
|
||||
uint32 playerid;
|
||||
uint32 itemslot;
|
||||
int32 quantity;
|
||||
uint32 price;
|
||||
};
|
||||
struct Merchant_Purchase_Struct {
|
||||
/*000*/ uint32 npcid; // Merchant NPC's entity id
|
||||
@@ -2099,7 +2118,7 @@ struct AdventureLeaderboard_Struct
|
||||
/*struct Item_Shop_Struct {
|
||||
uint16 merchantid;
|
||||
uint8 itemtype;
|
||||
Item_Struct item;
|
||||
ItemData item;
|
||||
uint8 iss_unknown001[6];
|
||||
};*/
|
||||
|
||||
|
||||
@@ -0,0 +1,782 @@
|
||||
/* EQEMu: Everquest Server Emulator
|
||||
Copyright (C) 2001-2015 EQEMu Development Team (http://eqemulator.net)
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; version 2 of the License.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY except by those people which sell it, which
|
||||
are required to give you total support for your newly bought product;
|
||||
without even the implied warranty of MERCHANTABILITY or FITNESS FOR
|
||||
A PARTICULAR PURPOSE. See the GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#include "inventory.h"
|
||||
#include "inventory_null_data_model.h"
|
||||
#include "item_container_personal_serialization.h"
|
||||
#include "data_verification.h"
|
||||
#include "string_util.h"
|
||||
#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::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;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
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_);
|
||||
}
|
||||
|
||||
struct EQEmu::Inventory::impl
|
||||
{
|
||||
std::map<int, ItemContainer> containers_;
|
||||
int race_;
|
||||
int class_;
|
||||
int deity_;
|
||||
std::unique_ptr<InventoryDataModel> data_model_;
|
||||
};
|
||||
|
||||
EQEmu::Inventory::Inventory(int race, int class_, int deity) {
|
||||
impl_ = new impl;
|
||||
impl_->race_ = race;
|
||||
impl_->class_ = class_;
|
||||
impl_->deity_ = deity;
|
||||
impl_->data_model_ = std::unique_ptr<InventoryDataModel>(new InventoryNullDataModel());
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
void EQEmu::Inventory::SetDataModel(InventoryDataModel *dm) {
|
||||
impl_->data_model_ = std::unique_ptr<InventoryDataModel>(dm);
|
||||
}
|
||||
|
||||
EQEmu::ItemInstance::pointer EQEmu::Inventory::Get(const InventorySlot &slot) {
|
||||
auto iter = impl_->containers_.find(slot.Type());
|
||||
if(iter != impl_->containers_.end()) {
|
||||
auto item = iter->second.Get(slot.Slot());
|
||||
if(item) {
|
||||
if(slot.BagIndex() > -1) {
|
||||
auto sub_item = item->Get(slot.BagIndex());
|
||||
if(sub_item) {
|
||||
if(slot.AugIndex() > -1) {
|
||||
return sub_item->Get(slot.AugIndex());
|
||||
} else {
|
||||
return sub_item;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
return item;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return ItemInstance::pointer(nullptr);
|
||||
}
|
||||
|
||||
bool EQEmu::Inventory::Put(const InventorySlot &slot, ItemInstance::pointer &inst) {
|
||||
if(impl_->containers_.count(slot.Type()) == 0) {
|
||||
if(slot.Type() == 0) {
|
||||
impl_->containers_.insert(std::pair<int, ItemContainer>(slot.Type(), ItemContainer(new ItemContainerPersonalSerialization())));
|
||||
} else {
|
||||
impl_->containers_.insert(std::pair<int, ItemContainer>(slot.Type(), ItemContainer()));
|
||||
}
|
||||
}
|
||||
|
||||
//Verify item can be put into the slot requested
|
||||
|
||||
auto &container = impl_->containers_[slot.Type()];
|
||||
if(slot.BagIndex() > -1) {
|
||||
auto item = container.Get(slot.Slot());
|
||||
if(!item)
|
||||
return false;
|
||||
|
||||
if(slot.AugIndex() > -1) {
|
||||
auto bag_item = item->Get(slot.BagIndex());
|
||||
if(!bag_item) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return bag_item->Put(slot.AugIndex(), inst);
|
||||
} else {
|
||||
return item->Put(slot.BagIndex(), inst);
|
||||
}
|
||||
} else {
|
||||
if(slot.AugIndex() > -1) {
|
||||
auto item = container.Get(slot.Slot());
|
||||
if(!item)
|
||||
return false;
|
||||
|
||||
return item->Put(slot.AugIndex(), inst);
|
||||
}
|
||||
|
||||
return container.Put(slot.Slot(), inst);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool EQEmu::Inventory::Swap(const InventorySlot &src, const InventorySlot &dest, int charges) {
|
||||
if(src == dest) {
|
||||
return true;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
auto i_src = Get(src);
|
||||
auto i_dest = Get(dest);
|
||||
|
||||
if(!i_src) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if(i_src->GetBaseItem()->ItemClass == ItemClassContainer && dest.BagIndex() > -1) {
|
||||
if(i_src->GetContainer()->Size() > 0) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if(dest.IsEquipment() && !CanEquip(i_src, dest)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
//Check this -> trade no drop
|
||||
if(dest.IsTrade() && i_src->IsNoDrop()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
impl_->data_model_->Begin();
|
||||
if(i_src->IsStackable()) {
|
||||
//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) {
|
||||
impl_->data_model_->Rollback();
|
||||
return false;
|
||||
}
|
||||
|
||||
//if dest exists it needs to not only be the same item id but also be able to hold enough charges to combine
|
||||
//we can also swap if src id != dest id
|
||||
if(i_dest) {
|
||||
uint32 src_id = i_src->GetBaseItem()->ID;
|
||||
uint32 dest_id = i_dest->GetBaseItem()->ID;
|
||||
if(src_id != dest_id) {
|
||||
bool v = _swap(src, dest);
|
||||
if(v) {
|
||||
impl_->data_model_->Commit();
|
||||
}
|
||||
else {
|
||||
impl_->data_model_->Rollback();
|
||||
}
|
||||
|
||||
return v;
|
||||
}
|
||||
|
||||
int charges_avail = i_dest->GetBaseItem()->StackSize - i_dest->GetCharges();
|
||||
if(charges_avail < charges) {
|
||||
impl_->data_model_->Rollback();
|
||||
return false;
|
||||
}
|
||||
|
||||
if(i_src->GetCharges() == charges) {
|
||||
if(!_destroy(src)) {
|
||||
impl_->data_model_->Rollback();
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
i_src->SetCharges(i_src->GetCharges() - charges);
|
||||
impl_->data_model_->Insert(src, i_src);
|
||||
}
|
||||
|
||||
i_dest->SetCharges(i_dest->GetCharges() + charges);
|
||||
impl_->data_model_->Delete(dest);
|
||||
impl_->data_model_->Insert(dest, i_dest);
|
||||
impl_->data_model_->Commit();
|
||||
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) {
|
||||
impl_->data_model_->Rollback();
|
||||
return false;
|
||||
}
|
||||
|
||||
Put(dest, split);
|
||||
impl_->data_model_->Delete(src);
|
||||
impl_->data_model_->Delete(dest);
|
||||
impl_->data_model_->Insert(src, i_src);
|
||||
impl_->data_model_->Insert(dest, split);
|
||||
impl_->data_model_->Commit();
|
||||
return true;
|
||||
} else {
|
||||
bool v = _swap(src, dest);
|
||||
if(v) {
|
||||
impl_->data_model_->Commit();
|
||||
} else {
|
||||
impl_->data_model_->Rollback();
|
||||
}
|
||||
|
||||
return v;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
bool v = _swap(src, dest);
|
||||
if(v) {
|
||||
impl_->data_model_->Commit();
|
||||
}
|
||||
else {
|
||||
impl_->data_model_->Rollback();
|
||||
}
|
||||
|
||||
return v;
|
||||
}
|
||||
|
||||
impl_->data_model_->Commit();
|
||||
return true;
|
||||
}
|
||||
|
||||
bool EQEmu::Inventory::Summon(const InventorySlot &slot, ItemInstance::pointer &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(ItemInstance::pointer &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;
|
||||
}
|
||||
|
||||
EQEmu::InventorySlot EQEmu::Inventory::FindFreeSlot(ItemInstance::pointer &inst, int container_id, int slot_id_start, int slot_id_end) {
|
||||
bool for_bag = inst->GetItem()->ItemClass == ItemClassContainer;
|
||||
int min_size = inst->GetItem()->Size;
|
||||
bool is_arrow = inst->GetItem()->ItemType == ItemTypeArrow;
|
||||
|
||||
//check upper level inventory
|
||||
for(int i = slot_id_start; i <= slot_id_end; ++i) {
|
||||
EQEmu::InventorySlot slot(container_id, i);
|
||||
if(!Get(slot)) {
|
||||
return slot;
|
||||
}
|
||||
}
|
||||
|
||||
//if not for a bag then check inside bags
|
||||
if (!for_bag) {
|
||||
for(int i = slot_id_start; i <= slot_id_end; ++i) {
|
||||
EQEmu::InventorySlot slot(container_id, i);
|
||||
auto inst = Get(slot);
|
||||
|
||||
if(inst && inst->GetBaseItem()->ItemClass == ItemClassContainer && inst->GetBaseItem()->BagSize >= min_size)
|
||||
{
|
||||
if(inst->GetBaseItem()->BagType == BagTypeQuiver && !is_arrow)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
int slots = inst->GetBaseItem()->BagSlots;
|
||||
for(int b_i = 0; b_i < slots; ++b_i) {
|
||||
EQEmu::InventorySlot bag_slot(container_id, i, b_i);
|
||||
|
||||
if(!Get(bag_slot)) {
|
||||
return bag_slot;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return EQEmu::InventorySlot();
|
||||
}
|
||||
|
||||
int EQEmu::Inventory::FindFreeStackSlots(ItemInstance::pointer &inst, int container_id, int slot_id_start, int slot_id_end) {
|
||||
if(!inst->IsStackable()) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
bool is_arrow = inst->GetItem()->ItemType == ItemTypeArrow;
|
||||
int item_id = inst->GetItem()->ID;
|
||||
|
||||
int charges_to_check = inst->GetCharges();
|
||||
int charges = 0;
|
||||
|
||||
auto iter = impl_->containers_.find(container_id);
|
||||
if(iter == impl_->containers_.end()) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
auto &container = iter->second;
|
||||
for(int i = slot_id_start; i <= slot_id_end; ++i) {
|
||||
auto current = container.Get(i);
|
||||
if(!current) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if(current->GetItem()->ID == item_id) {
|
||||
int free_charges = current->GetItem()->StackSize - current->GetCharges();
|
||||
if(free_charges)
|
||||
charges += free_charges;
|
||||
|
||||
if(charges >= charges_to_check) {
|
||||
return charges_to_check;
|
||||
}
|
||||
} else if(current->GetItem()->ItemClass == ItemClassContainer) {
|
||||
int sz = current->GetItem()->BagSlots;
|
||||
for(int i = 0; i < sz; ++i) {
|
||||
auto sub_item = current->Get(i);
|
||||
if(!sub_item) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if(sub_item->GetItem()->ID == item_id) {
|
||||
int free_charges = sub_item->GetItem()->StackSize - sub_item->GetCharges();
|
||||
if(free_charges)
|
||||
charges += free_charges;
|
||||
|
||||
if(charges >= charges_to_check) {
|
||||
return charges_to_check;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(charges >= charges_to_check) {
|
||||
return charges_to_check;
|
||||
}
|
||||
|
||||
return charges;
|
||||
}
|
||||
|
||||
void EQEmu::Inventory::UpdateSlot(const InventorySlot &slot, ItemInstance::pointer &inst) {
|
||||
impl_->data_model_->Begin();
|
||||
|
||||
impl_->data_model_->Delete(slot);
|
||||
if(inst) {
|
||||
impl_->data_model_->Insert(slot, inst);
|
||||
}
|
||||
|
||||
impl_->data_model_->Commit();
|
||||
}
|
||||
|
||||
int EQEmu::Inventory::CalcMaterialFromSlot(const InventorySlot &slot) {
|
||||
if(slot.Type() != 0)
|
||||
return _MaterialInvalid;
|
||||
|
||||
switch(slot.Slot()) {
|
||||
case PersonalSlotHead:
|
||||
return MaterialHead;
|
||||
case PersonalSlotChest:
|
||||
return MaterialChest;
|
||||
case PersonalSlotArms:
|
||||
return MaterialArms;
|
||||
case PersonalSlotWrist1:
|
||||
return MaterialWrist;
|
||||
case PersonalSlotHands:
|
||||
return MaterialHands;
|
||||
case PersonalSlotLegs:
|
||||
return MaterialLegs;
|
||||
case PersonalSlotFeet:
|
||||
return MaterialFeet;
|
||||
case PersonalSlotPrimary:
|
||||
return MaterialPrimary;
|
||||
case PersonalSlotSecondary:
|
||||
return MaterialSecondary;
|
||||
default:
|
||||
return _MaterialInvalid;
|
||||
}
|
||||
}
|
||||
|
||||
EQEmu::InventorySlot EQEmu::Inventory::CalcSlotFromMaterial(int material) {
|
||||
switch(material)
|
||||
{
|
||||
case MaterialHead:
|
||||
return EQEmu::InventorySlot(InvTypePersonal, PersonalSlotHead);
|
||||
case MaterialChest:
|
||||
return EQEmu::InventorySlot(InvTypePersonal, PersonalSlotChest);
|
||||
case MaterialArms:
|
||||
return EQEmu::InventorySlot(InvTypePersonal, PersonalSlotArms);
|
||||
case MaterialWrist:
|
||||
return EQEmu::InventorySlot(InvTypePersonal, PersonalSlotWrist1);
|
||||
case MaterialHands:
|
||||
return EQEmu::InventorySlot(InvTypePersonal, PersonalSlotHands);
|
||||
case MaterialLegs:
|
||||
return EQEmu::InventorySlot(InvTypePersonal, PersonalSlotLegs);
|
||||
case MaterialFeet:
|
||||
return EQEmu::InventorySlot(InvTypePersonal, PersonalSlotFeet);
|
||||
case MaterialPrimary:
|
||||
return EQEmu::InventorySlot(InvTypePersonal, PersonalSlotPrimary);
|
||||
case MaterialSecondary:
|
||||
return EQEmu::InventorySlot(InvTypePersonal, PersonalSlotSecondary);
|
||||
default:
|
||||
return EQEmu::InventorySlot(-1, -1);
|
||||
}
|
||||
}
|
||||
|
||||
bool EQEmu::Inventory::CanEquip(EQEmu::ItemInstance::pointer &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;
|
||||
}
|
||||
|
||||
//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) {
|
||||
EQEmu::ItemInstance::pointer itm = iter->second;
|
||||
if(!CanEquip(itm, 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_) {
|
||||
bool v = iter.second.Serialize(buf, iter.first);
|
||||
if(v && !value) {
|
||||
value = true;
|
||||
}
|
||||
}
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
void EQEmu::Inventory::Interrogate() {
|
||||
printf("Inventory:\n");
|
||||
printf("Class: %u, Race: %u, Deity: %u\n", impl_->class_, impl_->race_, impl_->deity_);
|
||||
for(auto &iter : impl_->containers_) {
|
||||
printf("Container: %u\n", iter.first);
|
||||
iter.second.Interrogate(1);
|
||||
}
|
||||
printf("\n");
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
impl_->data_model_->Insert(src, dest_i);
|
||||
if(!Put(src, dest_i)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if(src_i) {
|
||||
impl_->data_model_->Insert(dest, src_i);
|
||||
if(!Put(dest, src_i)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool EQEmu::Inventory::_destroy(const InventorySlot &slot) {
|
||||
bool v = Put(slot, EQEmu::ItemInstance::pointer(nullptr));
|
||||
impl_->data_model_->Delete(slot);
|
||||
return v;
|
||||
}
|
||||
@@ -0,0 +1,165 @@
|
||||
/* EQEMu: Everquest Server Emulator
|
||||
Copyright (C) 2001-2015 EQEMu Development Team (http://eqemulator.net)
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; version 2 of the License.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY except by those people which sell it, which
|
||||
are required to give you total support for your newly bought product;
|
||||
without even the implied warranty of MERCHANTABILITY or FITNESS FOR
|
||||
A PARTICULAR PURPOSE. See the GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#ifndef COMMON_INVENTORY_H
|
||||
#define COMMON_INVENTORY_H
|
||||
|
||||
#include "item_container.h"
|
||||
#include <string>
|
||||
|
||||
namespace EQEmu
|
||||
{
|
||||
enum InventoryType : int
|
||||
{
|
||||
InvTypePersonal = 0,
|
||||
InvTypeBank,
|
||||
InvTypeSharedBank,
|
||||
InvTypeTrade,
|
||||
InvTypeWorld,
|
||||
InvTypeCursorBuffer,
|
||||
InvTypeTribute,
|
||||
InvTypeTrophyTribute,
|
||||
InvTypeGuildTribute,
|
||||
InvTypeMerchant
|
||||
};
|
||||
|
||||
enum PersonaInventorySlot : int
|
||||
{
|
||||
PersonalSlotCharm = 0,
|
||||
PersonalSlotEar1,
|
||||
PersonalSlotHead,
|
||||
PersonalSlotFace,
|
||||
PersonalSlotEar2,
|
||||
PersonalSlotNeck,
|
||||
PersonalSlotShoulders,
|
||||
PersonalSlotArms,
|
||||
PersonalSlotBack,
|
||||
PersonalSlotWrist1,
|
||||
PersonalSlotWrist2,
|
||||
PersonalSlotRange,
|
||||
PersonalSlotHands,
|
||||
PersonalSlotPrimary,
|
||||
PersonalSlotSecondary,
|
||||
PersonalSlotFinger1,
|
||||
PersonalSlotFinger2,
|
||||
PersonalSlotChest,
|
||||
PersonalSlotLegs,
|
||||
PersonalSlotFeet,
|
||||
PersonalSlotWaist,
|
||||
PersonalSlotPowerSource,
|
||||
PersonalSlotAmmo,
|
||||
PersonalSlotGeneral1,
|
||||
PersonalSlotGeneral2,
|
||||
PersonalSlotGeneral3,
|
||||
PersonalSlotGeneral4,
|
||||
PersonalSlotGeneral5,
|
||||
PersonalSlotGeneral6,
|
||||
PersonalSlotGeneral7,
|
||||
PersonalSlotGeneral8,
|
||||
PersonalSlotGeneral9,
|
||||
PersonalSlotGeneral10,
|
||||
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 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;
|
||||
|
||||
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 InventoryDataModel;
|
||||
class Inventory
|
||||
{
|
||||
public:
|
||||
Inventory(int race, int class_, int deity);
|
||||
~Inventory();
|
||||
|
||||
void SetRace(int race);
|
||||
void SetClass(int class_);
|
||||
void SetDeity(int deity);
|
||||
void SetDataModel(InventoryDataModel *dm);
|
||||
|
||||
ItemInstance::pointer Get(const InventorySlot &slot);
|
||||
bool Put(const InventorySlot &slot, ItemInstance::pointer &inst);
|
||||
bool Swap(const InventorySlot &src, const InventorySlot &dest, int charges);
|
||||
bool Summon(const InventorySlot &slot, ItemInstance::pointer &inst);
|
||||
bool PushToCursorBuffer(ItemInstance::pointer &inst);
|
||||
bool PopFromCursorBuffer();
|
||||
InventorySlot FindFreeSlot(ItemInstance::pointer &inst, int container_id, int slot_id_start, int slot_id_end);
|
||||
int FindFreeStackSlots(ItemInstance::pointer &inst, int container_id, int slot_id_start, int slot_id_end);
|
||||
void UpdateSlot(const InventorySlot &slot, ItemInstance::pointer &inst);
|
||||
|
||||
//utility
|
||||
static int CalcMaterialFromSlot(const InventorySlot &slot);
|
||||
static InventorySlot CalcSlotFromMaterial(int material);
|
||||
bool CanEquip(EQEmu::ItemInstance::pointer &inst, const EQEmu::InventorySlot &slot);
|
||||
bool CheckLoreConflict(const ItemData *item);
|
||||
bool Serialize(MemoryBuffer &buf);
|
||||
|
||||
//testing
|
||||
void Interrogate();
|
||||
private:
|
||||
bool _swap(const InventorySlot &src, const InventorySlot &dest);
|
||||
bool _destroy(const InventorySlot &slot);
|
||||
|
||||
struct impl;
|
||||
impl *impl_;
|
||||
};
|
||||
|
||||
} // EQEmu
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,40 @@
|
||||
/* EQEMu: Everquest Server Emulator
|
||||
Copyright (C) 2001-2015 EQEMu Development Team (http://eqemulator.net)
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; version 2 of the License.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY except by those people which sell it, which
|
||||
are required to give you total support for your newly bought product;
|
||||
without even the implied warranty of MERCHANTABILITY or FITNESS FOR
|
||||
A PARTICULAR PURPOSE. See the GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#ifndef COMMON_INVENTORY_DATA_MODEL_H
|
||||
#define COMMON_INVENTORY_DATA_MODEL_H
|
||||
|
||||
#include "inventory.h"
|
||||
|
||||
namespace EQEmu
|
||||
{
|
||||
class InventoryDataModel
|
||||
{
|
||||
public:
|
||||
InventoryDataModel() { }
|
||||
virtual ~InventoryDataModel() { }
|
||||
|
||||
virtual void Begin() = 0;
|
||||
virtual bool Commit() = 0;
|
||||
virtual void Rollback() = 0;
|
||||
virtual void Insert(const InventorySlot &slot, ItemInstance::pointer &inst) = 0;
|
||||
virtual void Delete(const InventorySlot &slot) = 0;
|
||||
};
|
||||
} // EQEmu
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,212 @@
|
||||
#include "inventory_db_data_model.h"
|
||||
#include "shareddb.h"
|
||||
#include "string_util.h"
|
||||
#include <list>
|
||||
#include <string>
|
||||
|
||||
enum DataEventTypes
|
||||
{
|
||||
DB_Insert,
|
||||
DB_Delete
|
||||
};
|
||||
|
||||
struct DataEvent
|
||||
{
|
||||
DataEventTypes evt;
|
||||
EQEmu::InventorySlot slot;
|
||||
EQEmu::ItemInstance::pointer inst;
|
||||
};
|
||||
|
||||
struct EQEmu::InventoryDatabaseDataModel::impl {
|
||||
SharedDatabase *db_;
|
||||
std::list<DataEvent> events_;
|
||||
uint32 char_id_;
|
||||
};
|
||||
|
||||
EQEmu::InventoryDatabaseDataModel::InventoryDatabaseDataModel(SharedDatabase *db, uint32 char_id) {
|
||||
impl_ = new impl;
|
||||
impl_->db_ = db;
|
||||
impl_->char_id_ = char_id;
|
||||
}
|
||||
|
||||
EQEmu::InventoryDatabaseDataModel::~InventoryDatabaseDataModel() {
|
||||
delete impl_;
|
||||
}
|
||||
|
||||
void EQEmu::InventoryDatabaseDataModel::Begin() {
|
||||
impl_->db_->TransactionBegin();
|
||||
impl_->events_.clear();
|
||||
}
|
||||
|
||||
bool EQEmu::InventoryDatabaseDataModel::Commit() {
|
||||
std::string base_insert = "INSERT INTO character_inventory(id, type, slot, bag_index, aug_index, "
|
||||
"item_id, charges, color, attuned, custom_data, ornament_icon, ornament_idfile, ornament_hero_model"
|
||||
", tracking_id) VALUES";
|
||||
|
||||
std::string current_insert = base_insert;
|
||||
bool insert = false;
|
||||
for(auto iter : impl_->events_) {
|
||||
if(iter.evt == DB_Delete) {
|
||||
if(insert) {
|
||||
insert = false;
|
||||
|
||||
//commit the current_insert
|
||||
auto res = impl_->db_->QueryDatabase(current_insert);
|
||||
if(!res.Success()) {
|
||||
Rollback();
|
||||
return false;
|
||||
}
|
||||
|
||||
current_insert = base_insert;
|
||||
}
|
||||
|
||||
std::string current_delete;
|
||||
if(iter.slot.BagIndex() > -1) {
|
||||
if(iter.slot.AugIndex() > -1) {
|
||||
current_delete = StringFormat("DELETE FROM character_inventory WHERE id=%u AND type=%u AND slot=%u AND bag_index=%u AND aug_index=%u",
|
||||
impl_->char_id_, iter.slot.Type(), iter.slot.Slot(), iter.slot.BagIndex(), iter.slot.AugIndex());
|
||||
}
|
||||
else {
|
||||
current_delete = StringFormat("DELETE FROM character_inventory WHERE id=%u AND type=%u AND slot=%u AND bag_index=%u",
|
||||
impl_->char_id_, iter.slot.Type(), iter.slot.Slot(), iter.slot.BagIndex());
|
||||
}
|
||||
}
|
||||
else if(iter.slot.AugIndex() > -1) {
|
||||
current_delete = StringFormat("DELETE FROM character_inventory WHERE id=%u AND type=%u AND slot=%u AND aug_index=%u",
|
||||
impl_->char_id_, iter.slot.Type(), iter.slot.Slot(), iter.slot.AugIndex());
|
||||
}
|
||||
else {
|
||||
current_delete = StringFormat("DELETE FROM character_inventory WHERE id=%u AND type=%u AND slot=%u",
|
||||
impl_->char_id_, iter.slot.Type(), iter.slot.Slot());
|
||||
}
|
||||
|
||||
auto res = impl_->db_->QueryDatabase(current_delete);
|
||||
if(!res.Success()) {
|
||||
Rollback();
|
||||
return false;
|
||||
}
|
||||
|
||||
} else {
|
||||
//insert
|
||||
if(!insert) {
|
||||
insert = true;
|
||||
} else {
|
||||
current_insert += ",";
|
||||
}
|
||||
|
||||
current_insert += StringFormat("(%u, %i, %i, %i, %i, %u, %i, %u, %u, '%s', %u, %u, %u, %llu)",
|
||||
impl_->char_id_,
|
||||
iter.slot.Type(),
|
||||
iter.slot.Slot(),
|
||||
iter.slot.BagIndex(),
|
||||
iter.slot.AugIndex(),
|
||||
iter.inst->GetBaseItem()->ID,
|
||||
iter.inst->GetCharges(),
|
||||
iter.inst->GetColor(),
|
||||
iter.inst->GetAttuned(),
|
||||
EscapeString(iter.inst->GetCustomData()).c_str(),
|
||||
iter.inst->GetOrnamentIcon(),
|
||||
iter.inst->GetOrnamentIDFile(),
|
||||
iter.inst->GetOrnamentHeroModel(),
|
||||
iter.inst->GetTrackingID());
|
||||
}
|
||||
}
|
||||
|
||||
if(insert) {
|
||||
insert = false;
|
||||
|
||||
//commit the current_insert
|
||||
auto res = impl_->db_->QueryDatabase(current_insert);
|
||||
if(!res.Success()) {
|
||||
Rollback();
|
||||
return false;
|
||||
}
|
||||
|
||||
current_insert = base_insert;
|
||||
}
|
||||
|
||||
impl_->db_->TransactionCommit();
|
||||
impl_->events_.clear();
|
||||
return true;
|
||||
}
|
||||
|
||||
void EQEmu::InventoryDatabaseDataModel::Rollback() {
|
||||
impl_->db_->TransactionRollback();
|
||||
impl_->events_.clear();
|
||||
}
|
||||
|
||||
void EQEmu::InventoryDatabaseDataModel::Insert(const InventorySlot &slot, ItemInstance::pointer &inst) {
|
||||
DataEvent evt;
|
||||
evt.evt = DB_Insert;
|
||||
evt.inst = inst;
|
||||
evt.slot = slot;
|
||||
impl_->events_.push_back(evt);
|
||||
|
||||
//insert current item
|
||||
if(slot.BagIndex() < 0 && slot.AugIndex() < 0) {
|
||||
//if bag put all bag contents in
|
||||
//if common put all augment contents in
|
||||
if(inst->GetBaseItem()->ItemClass == ItemClassContainer) {
|
||||
auto container = inst->GetContainer();
|
||||
auto iter = container->Begin();
|
||||
while(iter != container->End()) {
|
||||
DataEvent evt;
|
||||
evt.evt = DB_Insert;
|
||||
evt.inst = iter->second;
|
||||
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;
|
||||
}
|
||||
}
|
||||
else if(inst->GetBaseItem()->ItemClass == ItemClassCommon) {
|
||||
auto container = inst->GetContainer();
|
||||
auto iter = container->Begin();
|
||||
while(iter != container->End()) {
|
||||
DataEvent evt;
|
||||
evt.evt = DB_Insert;
|
||||
evt.inst = iter->second;
|
||||
evt.slot = InventorySlot(slot.Type(), slot.Slot(), -1, iter->first);
|
||||
impl_->events_.push_back(evt);
|
||||
|
||||
++iter;
|
||||
}
|
||||
}
|
||||
}
|
||||
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();
|
||||
while(iter != container->End()) {
|
||||
DataEvent evt;
|
||||
evt.evt = DB_Insert;
|
||||
evt.inst = iter->second;
|
||||
evt.slot = InventorySlot(slot.Type(), slot.Slot(), slot.BagIndex(), iter->first);
|
||||
impl_->events_.push_back(evt);
|
||||
|
||||
++iter;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void EQEmu::InventoryDatabaseDataModel::Delete(const InventorySlot &slot) {
|
||||
DataEvent evt;
|
||||
evt.evt = DB_Delete;
|
||||
evt.slot = slot;
|
||||
impl_->events_.push_back(evt);
|
||||
}
|
||||
@@ -0,0 +1,45 @@
|
||||
/* EQEMu: Everquest Server Emulator
|
||||
Copyright (C) 2001-2015 EQEMu Development Team (http://eqemulator.net)
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; version 2 of the License.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY except by those people which sell it, which
|
||||
are required to give you total support for your newly bought product;
|
||||
without even the implied warranty of MERCHANTABILITY or FITNESS FOR
|
||||
A PARTICULAR PURPOSE. See the GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#ifndef COMMON_INVENTORY_DB_DATA_MODEL_H
|
||||
#define COMMON_INVENTORY_DB_DATA_MODEL_H
|
||||
|
||||
#include "inventory_data_model.h"
|
||||
|
||||
class SharedDatabase;
|
||||
|
||||
namespace EQEmu
|
||||
{
|
||||
class InventoryDatabaseDataModel : public InventoryDataModel
|
||||
{
|
||||
public:
|
||||
InventoryDatabaseDataModel(SharedDatabase *db, uint32 char_id);
|
||||
virtual ~InventoryDatabaseDataModel();
|
||||
|
||||
virtual void Begin();
|
||||
virtual bool Commit();
|
||||
virtual void Rollback();
|
||||
virtual void Insert(const InventorySlot &slot, ItemInstance::pointer &inst);
|
||||
virtual void Delete(const InventorySlot &slot);
|
||||
private:
|
||||
struct impl;
|
||||
impl *impl_;
|
||||
};
|
||||
} // EQEmu
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,40 @@
|
||||
/* EQEMu: Everquest Server Emulator
|
||||
Copyright (C) 2001-2015 EQEMu Development Team (http://eqemulator.net)
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; version 2 of the License.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY except by those people which sell it, which
|
||||
are required to give you total support for your newly bought product;
|
||||
without even the implied warranty of MERCHANTABILITY or FITNESS FOR
|
||||
A PARTICULAR PURPOSE. See the GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#ifndef COMMON_INVENTORY_NULL_DATA_MODEL_H
|
||||
#define COMMON_INVENTORY_NULL_DATA_MODEL_H
|
||||
|
||||
#include "inventory_data_model.h"
|
||||
|
||||
namespace EQEmu
|
||||
{
|
||||
class InventoryNullDataModel : public InventoryDataModel
|
||||
{
|
||||
public:
|
||||
InventoryNullDataModel() { }
|
||||
virtual ~InventoryNullDataModel() { }
|
||||
|
||||
virtual void Begin() { }
|
||||
virtual bool Commit() { return true; }
|
||||
virtual void Rollback() { }
|
||||
virtual void Insert(const InventorySlot &slot, ItemInstance::pointer &inst) { }
|
||||
virtual void Delete(const InventorySlot &slot) { }
|
||||
};
|
||||
} // EQEmu
|
||||
|
||||
#endif
|
||||
+95
-95
@@ -105,9 +105,9 @@ ItemInst* ItemInstQueue::peek_front() const
|
||||
|
||||
|
||||
//
|
||||
// class Inventory
|
||||
// class InventoryOld
|
||||
//
|
||||
Inventory::~Inventory()
|
||||
InventoryOld::~InventoryOld()
|
||||
{
|
||||
for (auto iter = m_worn.begin(); iter != m_worn.end(); ++iter) {
|
||||
safe_delete(iter->second);
|
||||
@@ -135,7 +135,7 @@ Inventory::~Inventory()
|
||||
m_trade.clear();
|
||||
}
|
||||
|
||||
void Inventory::CleanDirty() {
|
||||
void InventoryOld::CleanDirty() {
|
||||
auto iter = dirty_inst.begin();
|
||||
while (iter != dirty_inst.end()) {
|
||||
delete (*iter);
|
||||
@@ -144,14 +144,14 @@ void Inventory::CleanDirty() {
|
||||
dirty_inst.clear();
|
||||
}
|
||||
|
||||
void Inventory::MarkDirty(ItemInst *inst) {
|
||||
void InventoryOld::MarkDirty(ItemInst *inst) {
|
||||
if (inst) {
|
||||
dirty_inst.push_back(inst);
|
||||
}
|
||||
}
|
||||
|
||||
// Retrieve item at specified slot; returns false if item not found
|
||||
ItemInst* Inventory::GetItem(int16 slot_id) const
|
||||
ItemInst* InventoryOld::GetItem(int16 slot_id) const
|
||||
{
|
||||
ItemInst* result = nullptr;
|
||||
|
||||
@@ -186,37 +186,37 @@ ItemInst* Inventory::GetItem(int16 slot_id) const
|
||||
// Inner bag slots
|
||||
else if (slot_id >= EmuConstants::TRADE_BAGS_BEGIN && slot_id <= EmuConstants::TRADE_BAGS_END) {
|
||||
// Trade bag slots
|
||||
ItemInst* inst = _GetItem(m_trade, Inventory::CalcSlotId(slot_id));
|
||||
ItemInst* inst = _GetItem(m_trade, InventoryOld::CalcSlotId(slot_id));
|
||||
if (inst && inst->IsType(ItemClassContainer)) {
|
||||
result = inst->GetItem(Inventory::CalcBagIdx(slot_id));
|
||||
result = inst->GetItem(InventoryOld::CalcBagIdx(slot_id));
|
||||
}
|
||||
}
|
||||
else if (slot_id >= EmuConstants::SHARED_BANK_BAGS_BEGIN && slot_id <= EmuConstants::SHARED_BANK_BAGS_END) {
|
||||
// Shared Bank bag slots
|
||||
ItemInst* inst = _GetItem(m_shbank, Inventory::CalcSlotId(slot_id));
|
||||
ItemInst* inst = _GetItem(m_shbank, InventoryOld::CalcSlotId(slot_id));
|
||||
if (inst && inst->IsType(ItemClassContainer)) {
|
||||
result = inst->GetItem(Inventory::CalcBagIdx(slot_id));
|
||||
result = inst->GetItem(InventoryOld::CalcBagIdx(slot_id));
|
||||
}
|
||||
}
|
||||
else if (slot_id >= EmuConstants::BANK_BAGS_BEGIN && slot_id <= EmuConstants::BANK_BAGS_END) {
|
||||
// Bank bag slots
|
||||
ItemInst* inst = _GetItem(m_bank, Inventory::CalcSlotId(slot_id));
|
||||
ItemInst* inst = _GetItem(m_bank, InventoryOld::CalcSlotId(slot_id));
|
||||
if (inst && inst->IsType(ItemClassContainer)) {
|
||||
result = inst->GetItem(Inventory::CalcBagIdx(slot_id));
|
||||
result = inst->GetItem(InventoryOld::CalcBagIdx(slot_id));
|
||||
}
|
||||
}
|
||||
else if (slot_id >= EmuConstants::CURSOR_BAG_BEGIN && slot_id <= EmuConstants::CURSOR_BAG_END) {
|
||||
// Cursor bag slots
|
||||
ItemInst* inst = m_cursor.peek_front();
|
||||
if (inst && inst->IsType(ItemClassContainer)) {
|
||||
result = inst->GetItem(Inventory::CalcBagIdx(slot_id));
|
||||
result = inst->GetItem(InventoryOld::CalcBagIdx(slot_id));
|
||||
}
|
||||
}
|
||||
else if (slot_id >= EmuConstants::GENERAL_BAGS_BEGIN && slot_id <= EmuConstants::GENERAL_BAGS_END) {
|
||||
// Personal inventory bag slots
|
||||
ItemInst* inst = _GetItem(m_inv, Inventory::CalcSlotId(slot_id));
|
||||
ItemInst* inst = _GetItem(m_inv, InventoryOld::CalcSlotId(slot_id));
|
||||
if (inst && inst->IsType(ItemClassContainer)) {
|
||||
result = inst->GetItem(Inventory::CalcBagIdx(slot_id));
|
||||
result = inst->GetItem(InventoryOld::CalcBagIdx(slot_id));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -224,13 +224,13 @@ ItemInst* Inventory::GetItem(int16 slot_id) const
|
||||
}
|
||||
|
||||
// Retrieve item at specified position within bag
|
||||
ItemInst* Inventory::GetItem(int16 slot_id, uint8 bagidx) const
|
||||
ItemInst* InventoryOld::GetItem(int16 slot_id, uint8 bagidx) const
|
||||
{
|
||||
return GetItem(Inventory::CalcSlotId(slot_id, bagidx));
|
||||
return GetItem(InventoryOld::CalcSlotId(slot_id, bagidx));
|
||||
}
|
||||
|
||||
// Put an item snto specified slot
|
||||
int16 Inventory::PutItem(int16 slot_id, const ItemInst& inst)
|
||||
int16 InventoryOld::PutItem(int16 slot_id, const ItemInst& inst)
|
||||
{
|
||||
// Clean up item already in slot (if exists)
|
||||
DeleteItem(slot_id);
|
||||
@@ -245,19 +245,19 @@ int16 Inventory::PutItem(int16 slot_id, const ItemInst& inst)
|
||||
return _PutItem(slot_id, inst.Clone());
|
||||
}
|
||||
|
||||
int16 Inventory::PushCursor(const ItemInst& inst)
|
||||
int16 InventoryOld::PushCursor(const ItemInst& inst)
|
||||
{
|
||||
m_cursor.push(inst.Clone());
|
||||
return MainCursor;
|
||||
}
|
||||
|
||||
ItemInst* Inventory::GetCursorItem()
|
||||
ItemInst* InventoryOld::GetCursorItem()
|
||||
{
|
||||
return m_cursor.peek_front();
|
||||
}
|
||||
|
||||
// Swap items in inventory
|
||||
bool Inventory::SwapItem(int16 slot_a, int16 slot_b)
|
||||
bool InventoryOld::SwapItem(int16 slot_a, int16 slot_b)
|
||||
{
|
||||
// Temp holding areas for a and b
|
||||
ItemInst* inst_a = GetItem(slot_a);
|
||||
@@ -273,7 +273,7 @@ bool Inventory::SwapItem(int16 slot_a, int16 slot_b)
|
||||
}
|
||||
|
||||
// Remove item from inventory (with memory delete)
|
||||
bool Inventory::DeleteItem(int16 slot_id, uint8 quantity)
|
||||
bool InventoryOld::DeleteItem(int16 slot_id, uint8 quantity)
|
||||
{
|
||||
// Pop item out of inventory map (or queue)
|
||||
ItemInst* item_to_delete = PopItem(slot_id);
|
||||
@@ -293,7 +293,7 @@ bool Inventory::DeleteItem(int16 slot_id, uint8 quantity)
|
||||
((item_to_delete->GetItem()->MaxCharges == 0) || item_to_delete->IsExpendable()))
|
||||
) {
|
||||
// Item can now be destroyed
|
||||
Inventory::MarkDirty(item_to_delete);
|
||||
InventoryOld::MarkDirty(item_to_delete);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -303,19 +303,19 @@ bool Inventory::DeleteItem(int16 slot_id, uint8 quantity)
|
||||
return false;
|
||||
}
|
||||
|
||||
Inventory::MarkDirty(item_to_delete);
|
||||
InventoryOld::MarkDirty(item_to_delete);
|
||||
return true;
|
||||
|
||||
}
|
||||
|
||||
// Checks All items in a bag for No Drop
|
||||
bool Inventory::CheckNoDrop(int16 slot_id) {
|
||||
bool InventoryOld::CheckNoDrop(int16 slot_id) {
|
||||
ItemInst* inst = GetItem(slot_id);
|
||||
if (!inst) return false;
|
||||
if (!inst->GetItem()->NoDrop) return true;
|
||||
if (inst->GetItem()->ItemClass == 1) {
|
||||
for (uint8 i = SUB_BEGIN; i < EmuConstants::ITEM_CONTAINER_SIZE; i++) {
|
||||
ItemInst* bagitem = GetItem(Inventory::CalcSlotId(slot_id, i));
|
||||
ItemInst* bagitem = GetItem(InventoryOld::CalcSlotId(slot_id, i));
|
||||
if (bagitem && !bagitem->GetItem()->NoDrop)
|
||||
return true;
|
||||
}
|
||||
@@ -325,7 +325,7 @@ bool Inventory::CheckNoDrop(int16 slot_id) {
|
||||
|
||||
// Remove item from bucket without memory delete
|
||||
// Returns item pointer if full delete was successful
|
||||
ItemInst* Inventory::PopItem(int16 slot_id)
|
||||
ItemInst* InventoryOld::PopItem(int16 slot_id)
|
||||
{
|
||||
ItemInst* p = nullptr;
|
||||
|
||||
@@ -358,9 +358,9 @@ ItemInst* Inventory::PopItem(int16 slot_id)
|
||||
}
|
||||
else {
|
||||
// Is slot inside bag?
|
||||
ItemInst* baginst = GetItem(Inventory::CalcSlotId(slot_id));
|
||||
ItemInst* baginst = GetItem(InventoryOld::CalcSlotId(slot_id));
|
||||
if (baginst != nullptr && baginst->IsType(ItemClassContainer)) {
|
||||
p = baginst->PopItem(Inventory::CalcBagIdx(slot_id));
|
||||
p = baginst->PopItem(InventoryOld::CalcBagIdx(slot_id));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -368,7 +368,7 @@ ItemInst* Inventory::PopItem(int16 slot_id)
|
||||
return p;
|
||||
}
|
||||
|
||||
bool Inventory::HasSpaceForItem(const Item_Struct *ItemToTry, int16 Quantity) {
|
||||
bool InventoryOld::HasSpaceForItem(const ItemData *ItemToTry, int16 Quantity) {
|
||||
|
||||
if (ItemToTry->Stackable) {
|
||||
|
||||
@@ -388,7 +388,7 @@ bool Inventory::HasSpaceForItem(const Item_Struct *ItemToTry, int16 Quantity) {
|
||||
}
|
||||
if (InvItem && InvItem->IsType(ItemClassContainer)) {
|
||||
|
||||
int16 BaseSlotID = Inventory::CalcSlotId(i, SUB_BEGIN);
|
||||
int16 BaseSlotID = InventoryOld::CalcSlotId(i, SUB_BEGIN);
|
||||
uint8 BagSize = InvItem->GetItem()->BagSlots;
|
||||
for (uint8 BagSlot = SUB_BEGIN; BagSlot < BagSize; BagSlot++) {
|
||||
|
||||
@@ -432,7 +432,7 @@ bool Inventory::HasSpaceForItem(const Item_Struct *ItemToTry, int16 Quantity) {
|
||||
}
|
||||
else if (InvItem->IsType(ItemClassContainer) && CanItemFitInContainer(ItemToTry, InvItem->GetItem())) {
|
||||
|
||||
int16 BaseSlotID = Inventory::CalcSlotId(i, SUB_BEGIN);
|
||||
int16 BaseSlotID = InventoryOld::CalcSlotId(i, SUB_BEGIN);
|
||||
|
||||
uint8 BagSize = InvItem->GetItem()->BagSlots;
|
||||
|
||||
@@ -468,7 +468,7 @@ bool Inventory::HasSpaceForItem(const Item_Struct *ItemToTry, int16 Quantity) {
|
||||
|
||||
//This function has a flaw in that it only returns the last stack that it looked at
|
||||
//when quantity is greater than 1 and not all of quantity can be found in 1 stack.
|
||||
int16 Inventory::HasItem(uint32 item_id, uint8 quantity, uint8 where)
|
||||
int16 InventoryOld::HasItem(uint32 item_id, uint8 quantity, uint8 where)
|
||||
{
|
||||
int16 slot_id = INVALID_INDEX;
|
||||
|
||||
@@ -518,7 +518,7 @@ int16 Inventory::HasItem(uint32 item_id, uint8 quantity, uint8 where)
|
||||
}
|
||||
|
||||
//this function has the same quantity flaw mentioned above in HasItem()
|
||||
int16 Inventory::HasItemByUse(uint8 use, uint8 quantity, uint8 where)
|
||||
int16 InventoryOld::HasItemByUse(uint8 use, uint8 quantity, uint8 where)
|
||||
{
|
||||
int16 slot_id = INVALID_INDEX;
|
||||
|
||||
@@ -564,7 +564,7 @@ int16 Inventory::HasItemByUse(uint8 use, uint8 quantity, uint8 where)
|
||||
return slot_id;
|
||||
}
|
||||
|
||||
int16 Inventory::HasItemByLoreGroup(uint32 loregroup, uint8 where)
|
||||
int16 InventoryOld::HasItemByLoreGroup(uint32 loregroup, uint8 where)
|
||||
{
|
||||
int16 slot_id = INVALID_INDEX;
|
||||
|
||||
@@ -612,7 +612,7 @@ int16 Inventory::HasItemByLoreGroup(uint32 loregroup, uint8 where)
|
||||
|
||||
// Locate an available inventory slot
|
||||
// Returns slot_id when there's one available, else SLOT_INVALID
|
||||
int16 Inventory::FindFreeSlot(bool for_bag, bool try_cursor, uint8 min_size, bool is_arrow)
|
||||
int16 InventoryOld::FindFreeSlot(bool for_bag, bool try_cursor, uint8 min_size, bool is_arrow)
|
||||
{
|
||||
// Check basic inventory
|
||||
for (int16 i = EmuConstants::GENERAL_BEGIN; i <= EmuConstants::GENERAL_END; i++) {
|
||||
@@ -631,7 +631,7 @@ int16 Inventory::FindFreeSlot(bool for_bag, bool try_cursor, uint8 min_size, boo
|
||||
continue;
|
||||
}
|
||||
|
||||
int16 base_slot_id = Inventory::CalcSlotId(i, SUB_BEGIN);
|
||||
int16 base_slot_id = InventoryOld::CalcSlotId(i, SUB_BEGIN);
|
||||
|
||||
uint8 slots = inst->GetItem()->BagSlots;
|
||||
uint8 j;
|
||||
@@ -656,9 +656,9 @@ int16 Inventory::FindFreeSlot(bool for_bag, bool try_cursor, uint8 min_size, boo
|
||||
}
|
||||
|
||||
// This is a mix of HasSpaceForItem and FindFreeSlot..due to existing coding behavior, it was better to add a new helper function...
|
||||
int16 Inventory::FindFreeSlotForTradeItem(const ItemInst* inst) {
|
||||
int16 InventoryOld::FindFreeSlotForTradeItem(const ItemInst* inst) {
|
||||
// Do not arbitrarily use this function..it is designed for use with Client::ResetTrade() and Client::FinishTrade().
|
||||
// If you have a need, use it..but, understand it is not a compatible replacement for Inventory::FindFreeSlot().
|
||||
// If you have a need, use it..but, understand it is not a compatible replacement for InventoryOld::FindFreeSlot().
|
||||
//
|
||||
// I'll probably implement a bitmask in the new inventory system to avoid having to adjust stack bias
|
||||
|
||||
@@ -701,7 +701,7 @@ int16 Inventory::FindFreeSlotForTradeItem(const ItemInst* inst) {
|
||||
continue;
|
||||
|
||||
if ((sub_inst->GetID() == inst->GetID()) && (sub_inst->GetCharges() < sub_inst->GetItem()->StackSize))
|
||||
return Inventory::CalcSlotId(free_slot, free_bag_slot);
|
||||
return InventoryOld::CalcSlotId(free_slot, free_bag_slot);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -717,7 +717,7 @@ int16 Inventory::FindFreeSlotForTradeItem(const ItemInst* inst) {
|
||||
|
||||
for (uint8 free_bag_slot = SUB_BEGIN; (free_bag_slot < main_inst->GetItem()->BagSlots) && (free_bag_slot < EmuConstants::ITEM_CONTAINER_SIZE); ++free_bag_slot) {
|
||||
if (!main_inst->GetItem(free_bag_slot))
|
||||
return Inventory::CalcSlotId(free_slot, free_bag_slot);
|
||||
return InventoryOld::CalcSlotId(free_slot, free_bag_slot);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -732,7 +732,7 @@ int16 Inventory::FindFreeSlotForTradeItem(const ItemInst* inst) {
|
||||
|
||||
for (uint8 free_bag_slot = SUB_BEGIN; (free_bag_slot < main_inst->GetItem()->BagSlots) && (free_bag_slot < EmuConstants::ITEM_CONTAINER_SIZE); ++free_bag_slot) {
|
||||
if (!main_inst->GetItem(free_bag_slot))
|
||||
return Inventory::CalcSlotId(free_slot, free_bag_slot);
|
||||
return InventoryOld::CalcSlotId(free_slot, free_bag_slot);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -754,7 +754,7 @@ int16 Inventory::FindFreeSlotForTradeItem(const ItemInst* inst) {
|
||||
|
||||
for (uint8 free_bag_slot = SUB_BEGIN; (free_bag_slot < main_inst->GetItem()->BagSlots) && (free_bag_slot < EmuConstants::ITEM_CONTAINER_SIZE); ++free_bag_slot) {
|
||||
if (!main_inst->GetItem(free_bag_slot))
|
||||
return Inventory::CalcSlotId(free_slot, free_bag_slot);
|
||||
return InventoryOld::CalcSlotId(free_slot, free_bag_slot);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -764,7 +764,7 @@ int16 Inventory::FindFreeSlotForTradeItem(const ItemInst* inst) {
|
||||
}
|
||||
|
||||
// Opposite of below: Get parent bag slot_id from a slot inside of bag
|
||||
int16 Inventory::CalcSlotId(int16 slot_id) {
|
||||
int16 InventoryOld::CalcSlotId(int16 slot_id) {
|
||||
int16 parent_slot_id = INVALID_INDEX;
|
||||
|
||||
// this is not a bag range... using this risks over-writing existing items
|
||||
@@ -792,8 +792,8 @@ int16 Inventory::CalcSlotId(int16 slot_id) {
|
||||
}
|
||||
|
||||
// Calculate slot_id for an item within a bag
|
||||
int16 Inventory::CalcSlotId(int16 bagslot_id, uint8 bagidx) {
|
||||
if (!Inventory::SupportsContainers(bagslot_id))
|
||||
int16 InventoryOld::CalcSlotId(int16 bagslot_id, uint8 bagidx) {
|
||||
if (!InventoryOld::SupportsContainers(bagslot_id))
|
||||
return INVALID_INDEX;
|
||||
|
||||
int16 slot_id = INVALID_INDEX;
|
||||
@@ -817,7 +817,7 @@ int16 Inventory::CalcSlotId(int16 bagslot_id, uint8 bagidx) {
|
||||
return slot_id;
|
||||
}
|
||||
|
||||
uint8 Inventory::CalcBagIdx(int16 slot_id) {
|
||||
uint8 InventoryOld::CalcBagIdx(int16 slot_id) {
|
||||
uint8 index = 0;
|
||||
|
||||
// this is not a bag range... using this risks over-writing existing items
|
||||
@@ -846,7 +846,7 @@ uint8 Inventory::CalcBagIdx(int16 slot_id) {
|
||||
return index;
|
||||
}
|
||||
|
||||
int16 Inventory::CalcSlotFromMaterial(uint8 material)
|
||||
int16 InventoryOld::CalcSlotFromMaterial(uint8 material)
|
||||
{
|
||||
switch (material)
|
||||
{
|
||||
@@ -873,7 +873,7 @@ int16 Inventory::CalcSlotFromMaterial(uint8 material)
|
||||
}
|
||||
}
|
||||
|
||||
uint8 Inventory::CalcMaterialFromSlot(int16 equipslot)
|
||||
uint8 InventoryOld::CalcMaterialFromSlot(int16 equipslot)
|
||||
{
|
||||
switch (equipslot)
|
||||
{
|
||||
@@ -901,7 +901,7 @@ uint8 Inventory::CalcMaterialFromSlot(int16 equipslot)
|
||||
}
|
||||
}
|
||||
|
||||
bool Inventory::CanItemFitInContainer(const Item_Struct *ItemToTry, const Item_Struct *Container) {
|
||||
bool InventoryOld::CanItemFitInContainer(const ItemData *ItemToTry, const ItemData *Container) {
|
||||
|
||||
if (!ItemToTry || !Container)
|
||||
return false;
|
||||
@@ -918,7 +918,7 @@ bool Inventory::CanItemFitInContainer(const Item_Struct *ItemToTry, const Item_S
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Inventory::SupportsClickCasting(int16 slot_id)
|
||||
bool InventoryOld::SupportsClickCasting(int16 slot_id)
|
||||
{
|
||||
// there are a few non-potion items that identify as ItemTypePotion..so, we still need to ubiquitously include the equipment range
|
||||
if ((uint16)slot_id <= EmuConstants::GENERAL_END || slot_id == MainPowerSource)
|
||||
@@ -934,7 +934,7 @@ bool Inventory::SupportsClickCasting(int16 slot_id)
|
||||
return false;
|
||||
}
|
||||
|
||||
bool Inventory::SupportsPotionBeltCasting(int16 slot_id)
|
||||
bool InventoryOld::SupportsPotionBeltCasting(int16 slot_id)
|
||||
{
|
||||
if ((uint16)slot_id <= EmuConstants::GENERAL_END || slot_id == MainPowerSource || (slot_id >= EmuConstants::GENERAL_BAGS_BEGIN && slot_id <= EmuConstants::GENERAL_BAGS_END))
|
||||
return true;
|
||||
@@ -943,7 +943,7 @@ bool Inventory::SupportsPotionBeltCasting(int16 slot_id)
|
||||
}
|
||||
|
||||
// Test whether a given slot can support a container item
|
||||
bool Inventory::SupportsContainers(int16 slot_id)
|
||||
bool InventoryOld::SupportsContainers(int16 slot_id)
|
||||
{
|
||||
if ((slot_id == MainCursor) ||
|
||||
(slot_id >= EmuConstants::GENERAL_BEGIN && slot_id <= EmuConstants::GENERAL_END) ||
|
||||
@@ -957,7 +957,7 @@ bool Inventory::SupportsContainers(int16 slot_id)
|
||||
return false;
|
||||
}
|
||||
|
||||
int Inventory::GetSlotByItemInst(ItemInst *inst) {
|
||||
int InventoryOld::GetSlotByItemInst(ItemInst *inst) {
|
||||
if (!inst)
|
||||
return INVALID_INDEX;
|
||||
|
||||
@@ -993,7 +993,7 @@ int Inventory::GetSlotByItemInst(ItemInst *inst) {
|
||||
return INVALID_INDEX;
|
||||
}
|
||||
|
||||
uint8 Inventory::FindBrightestLightType()
|
||||
uint8 InventoryOld::FindBrightestLightType()
|
||||
{
|
||||
uint8 brightest_light_type = 0;
|
||||
|
||||
@@ -1032,7 +1032,7 @@ uint8 Inventory::FindBrightestLightType()
|
||||
return brightest_light_type;
|
||||
}
|
||||
|
||||
void Inventory::dumpEntireInventory() {
|
||||
void InventoryOld::dumpEntireInventory() {
|
||||
|
||||
dumpWornItems();
|
||||
dumpInventory();
|
||||
@@ -1042,29 +1042,29 @@ void Inventory::dumpEntireInventory() {
|
||||
std::cout << std::endl;
|
||||
}
|
||||
|
||||
void Inventory::dumpWornItems() {
|
||||
void InventoryOld::dumpWornItems() {
|
||||
std::cout << "Worn items:" << std::endl;
|
||||
dumpItemCollection(m_worn);
|
||||
}
|
||||
|
||||
void Inventory::dumpInventory() {
|
||||
void InventoryOld::dumpInventory() {
|
||||
std::cout << "Inventory items:" << std::endl;
|
||||
dumpItemCollection(m_inv);
|
||||
}
|
||||
|
||||
void Inventory::dumpBankItems() {
|
||||
void InventoryOld::dumpBankItems() {
|
||||
|
||||
std::cout << "Bank items:" << std::endl;
|
||||
dumpItemCollection(m_bank);
|
||||
}
|
||||
|
||||
void Inventory::dumpSharedBankItems() {
|
||||
void InventoryOld::dumpSharedBankItems() {
|
||||
|
||||
std::cout << "Shared Bank items:" << std::endl;
|
||||
dumpItemCollection(m_shbank);
|
||||
}
|
||||
|
||||
int Inventory::GetSlotByItemInstCollection(const std::map<int16, ItemInst*> &collection, ItemInst *inst) {
|
||||
int InventoryOld::GetSlotByItemInstCollection(const std::map<int16, ItemInst*> &collection, ItemInst *inst) {
|
||||
for (auto iter = collection.begin(); iter != collection.end(); ++iter) {
|
||||
ItemInst *t_inst = iter->second;
|
||||
if (t_inst == inst) {
|
||||
@@ -1074,7 +1074,7 @@ int Inventory::GetSlotByItemInstCollection(const std::map<int16, ItemInst*> &col
|
||||
if (t_inst && !t_inst->IsType(ItemClassContainer)) {
|
||||
for (auto b_iter = t_inst->_cbegin(); b_iter != t_inst->_cend(); ++b_iter) {
|
||||
if (b_iter->second == inst) {
|
||||
return Inventory::CalcSlotId(iter->first, b_iter->first);
|
||||
return InventoryOld::CalcSlotId(iter->first, b_iter->first);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1083,7 +1083,7 @@ int Inventory::GetSlotByItemInstCollection(const std::map<int16, ItemInst*> &col
|
||||
return -1;
|
||||
}
|
||||
|
||||
void Inventory::dumpItemCollection(const std::map<int16, ItemInst*> &collection)
|
||||
void InventoryOld::dumpItemCollection(const std::map<int16, ItemInst*> &collection)
|
||||
{
|
||||
for (auto it = collection.cbegin(); it != collection.cend(); ++it) {
|
||||
auto inst = it->second;
|
||||
@@ -1097,7 +1097,7 @@ void Inventory::dumpItemCollection(const std::map<int16, ItemInst*> &collection)
|
||||
}
|
||||
}
|
||||
|
||||
void Inventory::dumpBagContents(ItemInst *inst, std::map<int16, ItemInst*>::const_iterator *it)
|
||||
void InventoryOld::dumpBagContents(ItemInst *inst, std::map<int16, ItemInst*>::const_iterator *it)
|
||||
{
|
||||
if (!inst || !inst->IsType(ItemClassContainer))
|
||||
return;
|
||||
@@ -1108,7 +1108,7 @@ void Inventory::dumpBagContents(ItemInst *inst, std::map<int16, ItemInst*>::cons
|
||||
if (!baginst || !baginst->GetItem())
|
||||
continue;
|
||||
|
||||
std::string subSlot = StringFormat(" Slot %d: %s (%d)", Inventory::CalcSlotId((*it)->first, itb->first),
|
||||
std::string subSlot = StringFormat(" Slot %d: %s (%d)", InventoryOld::CalcSlotId((*it)->first, itb->first),
|
||||
baginst->GetItem()->Name, (baginst->GetCharges() <= 0) ? 1 : baginst->GetCharges());
|
||||
std::cout << subSlot << std::endl;
|
||||
}
|
||||
@@ -1116,7 +1116,7 @@ void Inventory::dumpBagContents(ItemInst *inst, std::map<int16, ItemInst*>::cons
|
||||
}
|
||||
|
||||
// Internal Method: Retrieves item within an inventory bucket
|
||||
ItemInst* Inventory::_GetItem(const std::map<int16, ItemInst*>& bucket, int16 slot_id) const
|
||||
ItemInst* InventoryOld::_GetItem(const std::map<int16, ItemInst*>& bucket, int16 slot_id) const
|
||||
{
|
||||
auto it = bucket.find(slot_id);
|
||||
if (it != bucket.end()) {
|
||||
@@ -1129,7 +1129,7 @@ ItemInst* Inventory::_GetItem(const std::map<int16, ItemInst*>& bucket, int16 sl
|
||||
|
||||
// Internal Method: "put" item into bucket, without regard for what is currently in bucket
|
||||
// Assumes item has already been allocated
|
||||
int16 Inventory::_PutItem(int16 slot_id, ItemInst* inst)
|
||||
int16 InventoryOld::_PutItem(int16 slot_id, ItemInst* inst)
|
||||
{
|
||||
// What happens here when we _PutItem(MainCursor)? Bad things..really bad things...
|
||||
//
|
||||
@@ -1175,25 +1175,25 @@ int16 Inventory::_PutItem(int16 slot_id, ItemInst* inst)
|
||||
}
|
||||
else {
|
||||
// Slot must be within a bag
|
||||
parentSlot = Inventory::CalcSlotId(slot_id);
|
||||
parentSlot = InventoryOld::CalcSlotId(slot_id);
|
||||
ItemInst* baginst = GetItem(parentSlot); // Get parent bag
|
||||
if (baginst && baginst->IsType(ItemClassContainer))
|
||||
{
|
||||
baginst->_PutItem(Inventory::CalcBagIdx(slot_id), inst);
|
||||
baginst->_PutItem(InventoryOld::CalcBagIdx(slot_id), inst);
|
||||
result = slot_id;
|
||||
}
|
||||
}
|
||||
|
||||
if (result == INVALID_INDEX) {
|
||||
Log.Out(Logs::General, Logs::Error, "Inventory::_PutItem: Invalid slot_id specified (%i) with parent slot id (%i)", slot_id, parentSlot);
|
||||
Inventory::MarkDirty(inst); // Slot not found, clean up
|
||||
Log.Out(Logs::General, Logs::Error, "InventoryOld::_PutItem: Invalid slot_id specified (%i) with parent slot id (%i)", slot_id, parentSlot);
|
||||
InventoryOld::MarkDirty(inst); // Slot not found, clean up
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
// Internal Method: Checks an inventory bucket for a particular item
|
||||
int16 Inventory::_HasItem(std::map<int16, ItemInst*>& bucket, uint32 item_id, uint8 quantity)
|
||||
int16 InventoryOld::_HasItem(std::map<int16, ItemInst*>& bucket, uint32 item_id, uint8 quantity)
|
||||
{
|
||||
uint8 quantity_found = 0;
|
||||
|
||||
@@ -1221,7 +1221,7 @@ int16 Inventory::_HasItem(std::map<int16, ItemInst*>& bucket, uint32 item_id, ui
|
||||
if (bag_inst->GetID() == item_id) {
|
||||
quantity_found += (bag_inst->GetCharges() <= 0) ? 1 : bag_inst->GetCharges();
|
||||
if (quantity_found >= quantity)
|
||||
return Inventory::CalcSlotId(iter->first, bag_iter->first);
|
||||
return InventoryOld::CalcSlotId(iter->first, bag_iter->first);
|
||||
}
|
||||
|
||||
for (int index = AUG_BEGIN; index < EmuConstants::ITEM_COMMON_SIZE; ++index) {
|
||||
@@ -1235,7 +1235,7 @@ int16 Inventory::_HasItem(std::map<int16, ItemInst*>& bucket, uint32 item_id, ui
|
||||
}
|
||||
|
||||
// Internal Method: Checks an inventory queue type bucket for a particular item
|
||||
int16 Inventory::_HasItem(ItemInstQueue& iqueue, uint32 item_id, uint8 quantity)
|
||||
int16 InventoryOld::_HasItem(ItemInstQueue& iqueue, uint32 item_id, uint8 quantity)
|
||||
{
|
||||
// The downfall of this (these) queue procedure is that callers presume that when an item is
|
||||
// found, it is presented as being available on the cursor. In cases of a parity check, this
|
||||
@@ -1269,7 +1269,7 @@ int16 Inventory::_HasItem(ItemInstQueue& iqueue, uint32 item_id, uint8 quantity)
|
||||
if (bag_inst->GetID() == item_id) {
|
||||
quantity_found += (bag_inst->GetCharges() <= 0) ? 1 : bag_inst->GetCharges();
|
||||
if (quantity_found >= quantity)
|
||||
return Inventory::CalcSlotId(MainCursor, bag_iter->first);
|
||||
return InventoryOld::CalcSlotId(MainCursor, bag_iter->first);
|
||||
}
|
||||
|
||||
for (int index = AUG_BEGIN; index < EmuConstants::ITEM_COMMON_SIZE; ++index) {
|
||||
@@ -1286,7 +1286,7 @@ int16 Inventory::_HasItem(ItemInstQueue& iqueue, uint32 item_id, uint8 quantity)
|
||||
}
|
||||
|
||||
// Internal Method: Checks an inventory bucket for a particular item
|
||||
int16 Inventory::_HasItemByUse(std::map<int16, ItemInst*>& bucket, uint8 use, uint8 quantity)
|
||||
int16 InventoryOld::_HasItemByUse(std::map<int16, ItemInst*>& bucket, uint8 use, uint8 quantity)
|
||||
{
|
||||
uint8 quantity_found = 0;
|
||||
|
||||
@@ -1309,7 +1309,7 @@ int16 Inventory::_HasItemByUse(std::map<int16, ItemInst*>& bucket, uint8 use, ui
|
||||
if (bag_inst->IsType(ItemClassCommon) && bag_inst->GetItem()->ItemType == use) {
|
||||
quantity_found += (bag_inst->GetCharges() <= 0) ? 1 : bag_inst->GetCharges();
|
||||
if (quantity_found >= quantity)
|
||||
return Inventory::CalcSlotId(iter->first, bag_iter->first);
|
||||
return InventoryOld::CalcSlotId(iter->first, bag_iter->first);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1318,7 +1318,7 @@ int16 Inventory::_HasItemByUse(std::map<int16, ItemInst*>& bucket, uint8 use, ui
|
||||
}
|
||||
|
||||
// Internal Method: Checks an inventory queue type bucket for a particular item
|
||||
int16 Inventory::_HasItemByUse(ItemInstQueue& iqueue, uint8 use, uint8 quantity)
|
||||
int16 InventoryOld::_HasItemByUse(ItemInstQueue& iqueue, uint8 use, uint8 quantity)
|
||||
{
|
||||
uint8 quantity_found = 0;
|
||||
|
||||
@@ -1341,7 +1341,7 @@ int16 Inventory::_HasItemByUse(ItemInstQueue& iqueue, uint8 use, uint8 quantity)
|
||||
if (bag_inst->IsType(ItemClassCommon) && bag_inst->GetItem()->ItemType == use) {
|
||||
quantity_found += (bag_inst->GetCharges() <= 0) ? 1 : bag_inst->GetCharges();
|
||||
if (quantity_found >= quantity)
|
||||
return Inventory::CalcSlotId(MainCursor, bag_iter->first);
|
||||
return InventoryOld::CalcSlotId(MainCursor, bag_iter->first);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1352,7 +1352,7 @@ int16 Inventory::_HasItemByUse(ItemInstQueue& iqueue, uint8 use, uint8 quantity)
|
||||
return INVALID_INDEX;
|
||||
}
|
||||
|
||||
int16 Inventory::_HasItemByLoreGroup(std::map<int16, ItemInst*>& bucket, uint32 loregroup)
|
||||
int16 InventoryOld::_HasItemByLoreGroup(std::map<int16, ItemInst*>& bucket, uint32 loregroup)
|
||||
{
|
||||
for (auto iter = bucket.begin(); iter != bucket.end(); ++iter) {
|
||||
auto inst = iter->second;
|
||||
@@ -1376,7 +1376,7 @@ int16 Inventory::_HasItemByLoreGroup(std::map<int16, ItemInst*>& bucket, uint32
|
||||
if (bag_inst == nullptr) { continue; }
|
||||
|
||||
if (bag_inst->IsType(ItemClassCommon) && bag_inst->GetItem()->LoreGroup == loregroup)
|
||||
return Inventory::CalcSlotId(iter->first, bag_iter->first);
|
||||
return InventoryOld::CalcSlotId(iter->first, bag_iter->first);
|
||||
|
||||
for (int index = AUG_BEGIN; index < EmuConstants::ITEM_COMMON_SIZE; ++index) {
|
||||
auto aug_inst = bag_inst->GetAugment(index);
|
||||
@@ -1392,7 +1392,7 @@ int16 Inventory::_HasItemByLoreGroup(std::map<int16, ItemInst*>& bucket, uint32
|
||||
}
|
||||
|
||||
// Internal Method: Checks an inventory queue type bucket for a particular item
|
||||
int16 Inventory::_HasItemByLoreGroup(ItemInstQueue& iqueue, uint32 loregroup)
|
||||
int16 InventoryOld::_HasItemByLoreGroup(ItemInstQueue& iqueue, uint32 loregroup)
|
||||
{
|
||||
for (auto iter = iqueue.cbegin(); iter != iqueue.cend(); ++iter) {
|
||||
auto inst = *iter;
|
||||
@@ -1416,7 +1416,7 @@ int16 Inventory::_HasItemByLoreGroup(ItemInstQueue& iqueue, uint32 loregroup)
|
||||
if (bag_inst == nullptr) { continue; }
|
||||
|
||||
if (bag_inst->IsType(ItemClassCommon) && bag_inst->GetItem()->LoreGroup == loregroup)
|
||||
return Inventory::CalcSlotId(MainCursor, bag_iter->first);
|
||||
return InventoryOld::CalcSlotId(MainCursor, bag_iter->first);
|
||||
|
||||
for (int index = AUG_BEGIN; index < EmuConstants::ITEM_COMMON_SIZE; ++index) {
|
||||
auto aug_inst = bag_inst->GetAugment(index);
|
||||
@@ -1438,7 +1438,7 @@ int16 Inventory::_HasItemByLoreGroup(ItemInstQueue& iqueue, uint32 loregroup)
|
||||
//
|
||||
// class ItemInst
|
||||
//
|
||||
ItemInst::ItemInst(const Item_Struct* item, int16 charges) {
|
||||
ItemInst::ItemInst(const ItemData* item, int16 charges) {
|
||||
m_use_type = ItemInstNormal;
|
||||
m_item = item;
|
||||
m_charges = charges;
|
||||
@@ -1548,7 +1548,7 @@ ItemInst::ItemInst(const ItemInst& copy)
|
||||
m_evolveLvl = copy.m_evolveLvl;
|
||||
m_activated = copy.m_activated;
|
||||
if (copy.m_scaledItem)
|
||||
m_scaledItem = new Item_Struct(*copy.m_scaledItem);
|
||||
m_scaledItem = new ItemData(*copy.m_scaledItem);
|
||||
else
|
||||
m_scaledItem = nullptr;
|
||||
|
||||
@@ -1767,7 +1767,7 @@ void ItemInst::ClearByFlags(byFlagSetting is_nodrop, byFlagSetting is_norent)
|
||||
continue;
|
||||
}
|
||||
|
||||
const Item_Struct* item = inst->GetItem();
|
||||
const ItemData* item = inst->GetItem();
|
||||
if (item == nullptr) {
|
||||
cur = m_contents.erase(cur);
|
||||
continue;
|
||||
@@ -1908,7 +1908,7 @@ bool ItemInst::UpdateOrnamentationInfo() {
|
||||
int32 ornamentationAugtype = RuleI(Character, OrnamentationAugmentType);
|
||||
if (GetOrnamentationAug(ornamentationAugtype))
|
||||
{
|
||||
const Item_Struct* ornamentItem;
|
||||
const ItemData* ornamentItem;
|
||||
ornamentItem = GetOrnamentationAug(ornamentationAugtype)->GetItem();
|
||||
if (ornamentItem != nullptr)
|
||||
{
|
||||
@@ -1935,7 +1935,7 @@ bool ItemInst::UpdateOrnamentationInfo() {
|
||||
return ornamentSet;
|
||||
}
|
||||
|
||||
bool ItemInst::CanTransform(const Item_Struct *ItemToTry, const Item_Struct *Container, bool AllowAll) {
|
||||
bool ItemInst::CanTransform(const ItemData *ItemToTry, const ItemData *Container, bool AllowAll) {
|
||||
if (!ItemToTry || !Container) return false;
|
||||
|
||||
if (ItemToTry->ItemType == ItemTypeArrow || strnlen(Container->CharmFile, 30) == 0)
|
||||
@@ -2003,7 +2003,7 @@ void ItemInst::PutAugment(SharedDatabase *db, uint8 slot, uint32 item_id)
|
||||
if (item_id == NO_ITEM) { return; }
|
||||
if (db == nullptr) { return; /* TODO: add log message for nullptr */ }
|
||||
|
||||
const ItemInst* aug = db->CreateItem(item_id);
|
||||
const ItemInst* aug = db->CreateItemOld(item_id);
|
||||
if (aug) {
|
||||
PutAugment(slot, *aug);
|
||||
safe_delete(aug);
|
||||
@@ -2069,7 +2069,7 @@ bool ItemInst::IsAmmo() const
|
||||
|
||||
}
|
||||
|
||||
const Item_Struct* ItemInst::GetItem() const
|
||||
const ItemData* ItemInst::GetItem() const
|
||||
{
|
||||
if (!m_item)
|
||||
return nullptr;
|
||||
@@ -2080,7 +2080,7 @@ const Item_Struct* ItemInst::GetItem() const
|
||||
return m_item;
|
||||
}
|
||||
|
||||
const Item_Struct* ItemInst::GetUnscaledItem() const
|
||||
const ItemData* ItemInst::GetUnscaledItem() const
|
||||
{
|
||||
// No operator calls and defaults to nullptr
|
||||
return m_item;
|
||||
@@ -2159,7 +2159,7 @@ ItemInst* ItemInst::Clone() const
|
||||
bool ItemInst::IsSlotAllowed(int16 slot_id) const {
|
||||
// 'SupportsContainers' and 'slot_id > 21' previously saw the reassigned PowerSource slot (9999 to 22) as valid
|
||||
if (!m_item) { return false; }
|
||||
else if (Inventory::SupportsContainers(slot_id)) { return true; }
|
||||
else if (InventoryOld::SupportsContainers(slot_id)) { return true; }
|
||||
else if (m_item->Slots & (1 << slot_id)) { return true; }
|
||||
else if (slot_id == MainPowerSource && (m_item->Slots & (1 << 22))) { return true; } // got lazy... <watch>
|
||||
else if (slot_id != MainPowerSource && slot_id > EmuConstants::EQUIPMENT_END) { return true; }
|
||||
@@ -2188,10 +2188,10 @@ void ItemInst::ScaleItem() {
|
||||
return;
|
||||
|
||||
if (m_scaledItem) {
|
||||
memcpy(m_scaledItem, m_item, sizeof(Item_Struct));
|
||||
memcpy(m_scaledItem, m_item, sizeof(ItemData));
|
||||
}
|
||||
else {
|
||||
m_scaledItem = new Item_Struct(*m_item);
|
||||
m_scaledItem = new ItemData(*m_item);
|
||||
}
|
||||
|
||||
float Mult = (float)(GetExp()) / 10000; // scaling is determined by exp, with 10,000 being full stats
|
||||
@@ -2335,9 +2335,9 @@ EvolveInfo::~EvolveInfo() {
|
||||
|
||||
|
||||
//
|
||||
// struct Item_Struct
|
||||
// struct ItemData
|
||||
//
|
||||
bool Item_Struct::IsEquipable(uint16 Race, uint16 Class_) const
|
||||
bool ItemData::IsEquipable(uint16 Race, uint16 Class_) const
|
||||
{
|
||||
bool IsRace = false;
|
||||
bool IsClass = false;
|
||||
|
||||
+15
-15
@@ -27,7 +27,7 @@ class ItemParse; // Parses item packets
|
||||
class EvolveInfo; // Stores information about an evolving item family
|
||||
|
||||
#include "../common/eq_constants.h"
|
||||
#include "../common/item_struct.h"
|
||||
#include "../common/item_data.h"
|
||||
#include "../common/timer.h"
|
||||
|
||||
#include <list>
|
||||
@@ -104,9 +104,9 @@ protected:
|
||||
};
|
||||
|
||||
// ########################################
|
||||
// Class: Inventory
|
||||
// Class: InventoryOld
|
||||
// Character inventory
|
||||
class Inventory
|
||||
class InventoryOld
|
||||
{
|
||||
friend class ItemInst;
|
||||
public:
|
||||
@@ -114,8 +114,8 @@ public:
|
||||
// Public Methods
|
||||
///////////////////////////////
|
||||
|
||||
Inventory() { m_version = ClientVersion::Unknown; m_versionset = false; }
|
||||
~Inventory();
|
||||
InventoryOld() { m_version = ClientVersion::Unknown; m_versionset = false; }
|
||||
~InventoryOld();
|
||||
|
||||
// Inventory v2 creep
|
||||
bool SetInventoryVersion(ClientVersion version) {
|
||||
@@ -168,7 +168,7 @@ public:
|
||||
ItemInst* PopItem(int16 slot_id);
|
||||
|
||||
// Check whether there is space for the specified number of the specified item.
|
||||
bool HasSpaceForItem(const Item_Struct *ItemToTry, int16 Quantity);
|
||||
bool HasSpaceForItem(const ItemData *ItemToTry, int16 Quantity);
|
||||
|
||||
// Check whether item exists in inventory
|
||||
// where argument specifies OR'd list of invWhere constants to look
|
||||
@@ -193,7 +193,7 @@ public:
|
||||
static int16 CalcSlotFromMaterial(uint8 material);
|
||||
static uint8 CalcMaterialFromSlot(int16 equipslot);
|
||||
|
||||
static bool CanItemFitInContainer(const Item_Struct *ItemToTry, const Item_Struct *Container);
|
||||
static bool CanItemFitInContainer(const ItemData *ItemToTry, const ItemData *Container);
|
||||
|
||||
// Test for valid inventory casting slot
|
||||
bool SupportsClickCasting(int16 slot_id);
|
||||
@@ -270,7 +270,7 @@ public:
|
||||
/////////////////////////
|
||||
|
||||
// Constructors/Destructor
|
||||
ItemInst(const Item_Struct* item = nullptr, int16 charges = 0);
|
||||
ItemInst(const ItemData* item = nullptr, int16 charges = 0);
|
||||
|
||||
ItemInst(SharedDatabase *db, uint32 item_id, int16 charges = 0);
|
||||
|
||||
@@ -331,7 +331,7 @@ public:
|
||||
bool IsAugmented();
|
||||
ItemInst* GetOrnamentationAug(int32 ornamentationAugtype) const;
|
||||
bool UpdateOrnamentationInfo();
|
||||
static bool CanTransform(const Item_Struct *ItemToTry, const Item_Struct *Container, bool AllowAll = false);
|
||||
static bool CanTransform(const ItemData *ItemToTry, const ItemData *Container, bool AllowAll = false);
|
||||
|
||||
// Has attack/delay?
|
||||
bool IsWeapon() const;
|
||||
@@ -340,8 +340,8 @@ public:
|
||||
// Accessors
|
||||
const uint32 GetID() const { return ((m_item) ? m_item->ID : NO_ITEM); }
|
||||
const uint32 GetItemScriptID() const { return ((m_item) ? m_item->ScriptFileID : NO_ITEM); }
|
||||
const Item_Struct* GetItem() const;
|
||||
const Item_Struct* GetUnscaledItem() const;
|
||||
const ItemData* GetItem() const;
|
||||
const ItemData* GetUnscaledItem() const;
|
||||
|
||||
int16 GetCharges() const { return m_charges; }
|
||||
void SetCharges(int16 charges) { m_charges = charges; }
|
||||
@@ -376,7 +376,7 @@ public:
|
||||
// Allows treatment of this object as though it were a pointer to m_item
|
||||
operator bool() const { return (m_item != nullptr); }
|
||||
|
||||
// Compare inner Item_Struct of two ItemInst objects
|
||||
// Compare inner ItemData of two ItemInst objects
|
||||
bool operator==(const ItemInst& right) const { return (this->m_item == right.m_item); }
|
||||
bool operator!=(const ItemInst& right) const { return (this->m_item != right.m_item); }
|
||||
|
||||
@@ -425,13 +425,13 @@ protected:
|
||||
std::map<uint8, ItemInst*>::const_iterator _cbegin() { return m_contents.cbegin(); }
|
||||
std::map<uint8, ItemInst*>::const_iterator _cend() { return m_contents.cend(); }
|
||||
|
||||
friend class Inventory;
|
||||
friend class InventoryOld;
|
||||
|
||||
|
||||
void _PutItem(uint8 index, ItemInst* inst) { m_contents[index] = inst; }
|
||||
|
||||
ItemInstTypes m_use_type; // Usage type for item
|
||||
const Item_Struct* m_item; // Ptr to item data
|
||||
const ItemData* m_item; // Ptr to item data
|
||||
int16 m_charges; // # of charges for chargeable items
|
||||
uint32 m_price; // Bazaar /trader price
|
||||
uint32 m_color;
|
||||
@@ -443,7 +443,7 @@ protected:
|
||||
uint32 m_exp;
|
||||
int8 m_evolveLvl;
|
||||
bool m_activated;
|
||||
Item_Struct* m_scaledItem;
|
||||
ItemData* m_scaledItem;
|
||||
EvolveInfo* m_evolveInfo;
|
||||
bool m_scaling;
|
||||
uint32 m_ornamenticon;
|
||||
|
||||
@@ -0,0 +1,135 @@
|
||||
#include "item_container.h"
|
||||
#include "item_container_default_serialization.h"
|
||||
#include <utility>
|
||||
|
||||
struct EQEmu::ItemContainer::impl
|
||||
{
|
||||
std::map<int, ItemInstance::pointer> items_;
|
||||
ItemContainerSerializationStrategy *serialize_strat_;
|
||||
};
|
||||
|
||||
EQEmu::ItemContainer::ItemContainer()
|
||||
{
|
||||
impl_ = new impl();
|
||||
impl_->serialize_strat_ = new ItemContainerDefaultSerialization();
|
||||
}
|
||||
|
||||
EQEmu::ItemContainer::ItemContainer(ItemContainerSerializationStrategy *strategy) {
|
||||
impl_ = new impl();
|
||||
impl_->serialize_strat_ = strategy;
|
||||
}
|
||||
|
||||
EQEmu::ItemContainer::~ItemContainer()
|
||||
{
|
||||
if(impl_) {
|
||||
delete impl_->serialize_strat_;
|
||||
delete impl_;
|
||||
}
|
||||
}
|
||||
|
||||
EQEmu::ItemContainer::ItemContainer(ItemContainer &&other) {
|
||||
impl_ = other.impl_;
|
||||
other.impl_ = nullptr;
|
||||
}
|
||||
|
||||
EQEmu::ItemContainer& EQEmu::ItemContainer::operator=(ItemContainer &&other) {
|
||||
if(this == &other)
|
||||
return *this;
|
||||
|
||||
impl_ = other.impl_;
|
||||
other.impl_ = nullptr;
|
||||
return *this;
|
||||
}
|
||||
|
||||
EQEmu::ItemInstance::pointer EQEmu::ItemContainer::Get(const int slot_id) {
|
||||
auto iter = impl_->items_.find(slot_id);
|
||||
if(iter != impl_->items_.end()) {
|
||||
return iter->second;
|
||||
}
|
||||
|
||||
return EQEmu::ItemInstance::pointer(nullptr);
|
||||
}
|
||||
|
||||
bool EQEmu::ItemContainer::Put(const int slot_id, ItemInstance::pointer &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;
|
||||
}
|
||||
|
||||
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();
|
||||
}
|
||||
|
||||
uint32 EQEmu::ItemContainer::Size() const {
|
||||
return (uint32)impl_->items_.size();
|
||||
}
|
||||
|
||||
bool EQEmu::ItemContainer::Delete(const int slot_id) {
|
||||
auto iter = impl_->items_.find(slot_id);
|
||||
if(iter == impl_->items_.end()) {
|
||||
return false;
|
||||
} else {
|
||||
impl_->items_.erase(iter);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
bool EQEmu::ItemContainer::Serialize(MemoryBuffer &buf, int container_number) {
|
||||
if(impl_->serialize_strat_) {
|
||||
return impl_->serialize_strat_->Serialize(buf, container_number, impl_->items_);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
EQEmu::ItemContainer::ItemContainerIter EQEmu::ItemContainer::Begin() {
|
||||
return impl_->items_.begin();
|
||||
}
|
||||
|
||||
EQEmu::ItemContainer::ItemContainerIter EQEmu::ItemContainer::End() {
|
||||
return impl_->items_.end();
|
||||
}
|
||||
|
||||
void EQEmu::ItemContainer::Interrogate(int level) {
|
||||
char buffer[16] = { 0 };
|
||||
for(int i = 0; i < level; ++i) {
|
||||
buffer[i] = '\t';
|
||||
}
|
||||
|
||||
for(auto &iter : impl_->items_) {
|
||||
printf("%s%u: (%u)%s (%u)\n", buffer, iter.first, iter.second->GetBaseItem()->ID, iter.second->GetBaseItem()->Name, iter.second->GetCharges());
|
||||
iter.second->Interrogate(level + 1);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,70 @@
|
||||
/* EQEMu: Everquest Server Emulator
|
||||
Copyright (C) 2001-2015 EQEMu Development Team (http://eqemulator.net)
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; version 2 of the License.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY except by those people which sell it, which
|
||||
are required to give you total support for your newly bought product;
|
||||
without even the implied warranty of MERCHANTABILITY or FITNESS FOR
|
||||
A PARTICULAR PURPOSE. See the GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#ifndef COMMON_ITEM_CONTAINER_H
|
||||
#define COMMON_ITEM_CONTAINER_H
|
||||
|
||||
#include "item_instance.h"
|
||||
#include "item_container_serialization_strategy.h"
|
||||
#include "memory_buffer.h"
|
||||
#include <memory>
|
||||
#include <map>
|
||||
|
||||
namespace EQEmu
|
||||
{
|
||||
class ItemContainerSerializationStrategy;
|
||||
class ItemContainer
|
||||
{
|
||||
public:
|
||||
typedef std::map<int, ItemInstance::pointer>::const_iterator ItemContainerIter;
|
||||
|
||||
ItemContainer();
|
||||
ItemContainer(ItemContainerSerializationStrategy *strategy);
|
||||
~ItemContainer();
|
||||
ItemContainer(ItemContainer &&other);
|
||||
ItemContainer& operator=(ItemContainer &&other);
|
||||
|
||||
ItemInstance::pointer Get(const int slot_id);
|
||||
bool Put(const int slot_id, ItemInstance::pointer &inst);
|
||||
bool Delete(const int slot_id);
|
||||
|
||||
//Utility
|
||||
bool HasItem(uint32 item_id);
|
||||
bool HasItemByLoreGroup(uint32 loregroup);
|
||||
|
||||
uint32 Size();
|
||||
uint32 Size() const;
|
||||
|
||||
//Low level interface for encode/decode
|
||||
bool Serialize(MemoryBuffer &buf, int container_number);
|
||||
ItemContainerIter Begin();
|
||||
ItemContainerIter End();
|
||||
|
||||
//testing
|
||||
void Interrogate(int level);
|
||||
protected:
|
||||
struct impl;
|
||||
impl *impl_;
|
||||
|
||||
private:
|
||||
ItemContainer(const ItemContainer &other);
|
||||
ItemContainer& operator=(const ItemContainer &other);
|
||||
};
|
||||
} // EQEmu
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,19 @@
|
||||
#include "item_container_default_serialization.h"
|
||||
|
||||
bool EQEmu::ItemContainerDefaultSerialization::Serialize(MemoryBuffer &buf, const int container_number, const std::map<int, ItemInstance::pointer>& items) {
|
||||
if(items.size() == 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
bool ret = false;
|
||||
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;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
@@ -0,0 +1,35 @@
|
||||
/* EQEMu: Everquest Server Emulator
|
||||
Copyright (C) 2001-2015 EQEMu Development Team (http://eqemulator.net)
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; version 2 of the License.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY except by those people which sell it, which
|
||||
are required to give you total support for your newly bought product;
|
||||
without even the implied warranty of MERCHANTABILITY or FITNESS FOR
|
||||
A PARTICULAR PURPOSE. See the GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#ifndef COMMON_ITEM_CONTAINER_DEFAULT_SERIALIZATION_H
|
||||
#define COMMON_ITEM_CONTAINER_DEFAULT_SERIALIZATION_H
|
||||
|
||||
#include "item_container_serialization_strategy.h"
|
||||
|
||||
namespace EQEmu
|
||||
{
|
||||
class ItemContainerDefaultSerialization : public ItemContainerSerializationStrategy
|
||||
{
|
||||
public:
|
||||
ItemContainerDefaultSerialization() { }
|
||||
virtual ~ItemContainerDefaultSerialization() { }
|
||||
virtual bool Serialize(MemoryBuffer &buf, const int container_number, const std::map<int, ItemInstance::pointer>& items);
|
||||
};
|
||||
} // EQEmu
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,21 @@
|
||||
#include "item_container_personal_serialization.h"
|
||||
|
||||
bool EQEmu::ItemContainerPersonalSerialization::Serialize(MemoryBuffer &buf, const int container_number, const std::map<int, ItemInstance::pointer>& items) {
|
||||
if(items.size() == 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
bool ret = false;
|
||||
for(auto &iter : items) {
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
@@ -0,0 +1,35 @@
|
||||
/* EQEMu: Everquest Server Emulator
|
||||
Copyright (C) 2001-2015 EQEMu Development Team (http://eqemulator.net)
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; version 2 of the License.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY except by those people which sell it, which
|
||||
are required to give you total support for your newly bought product;
|
||||
without even the implied warranty of MERCHANTABILITY or FITNESS FOR
|
||||
A PARTICULAR PURPOSE. See the GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#ifndef COMMON_ITEM_CONTAINER_PERSONAL_SERIALIZATION_H
|
||||
#define COMMON_ITEM_CONTAINER_PERSONAL_SERIALIZATION_H
|
||||
|
||||
#include "item_container_serialization_strategy.h"
|
||||
|
||||
namespace EQEmu
|
||||
{
|
||||
class ItemContainerPersonalSerialization : public ItemContainerSerializationStrategy
|
||||
{
|
||||
public:
|
||||
ItemContainerPersonalSerialization() { }
|
||||
virtual ~ItemContainerPersonalSerialization() { }
|
||||
virtual bool Serialize(MemoryBuffer &buf, const int container_number, const std::map<int, ItemInstance::pointer>& items);
|
||||
};
|
||||
} // EQEmu
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,37 @@
|
||||
/* EQEMu: Everquest Server Emulator
|
||||
Copyright (C) 2001-2015 EQEMu Development Team (http://eqemulator.net)
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; version 2 of the License.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY except by those people which sell it, which
|
||||
are required to give you total support for your newly bought product;
|
||||
without even the implied warranty of MERCHANTABILITY or FITNESS FOR
|
||||
A PARTICULAR PURPOSE. See the GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#ifndef COMMON_ITEM_CONTAINER_SERIALIZATION_STRATEGY_H
|
||||
#define COMMON_ITEM_CONTAINER_SERIALIZATION_STRATEGY_H
|
||||
|
||||
#include "item_container.h"
|
||||
#include "memory_buffer.h"
|
||||
#include <map>
|
||||
|
||||
namespace EQEmu
|
||||
{
|
||||
class ItemContainerSerializationStrategy
|
||||
{
|
||||
public:
|
||||
ItemContainerSerializationStrategy() { }
|
||||
virtual ~ItemContainerSerializationStrategy() { }
|
||||
virtual bool Serialize(MemoryBuffer &buf, const int container_number, const std::map<int, ItemInstance::pointer>& items) = 0;
|
||||
};
|
||||
} // EQEmu
|
||||
|
||||
#endif
|
||||
@@ -16,8 +16,8 @@
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 04111-1307 USA
|
||||
*/
|
||||
|
||||
#ifndef ITEM_STRUCT_H
|
||||
#define ITEM_STRUCT_H
|
||||
#ifndef COMMON_ITEM_DATA_H
|
||||
#define COMMON_ITEM_DATA_H
|
||||
|
||||
/*
|
||||
* Note: (Doodman)
|
||||
@@ -35,7 +35,7 @@
|
||||
*
|
||||
* Note #3: (Doodman)
|
||||
* Please take care when adding new found data fields to add them
|
||||
* to the appropriate structure. Item_Struct has elements that are
|
||||
* to the appropriate structure. ItemData has elements that are
|
||||
* global to all types of items only.
|
||||
*
|
||||
* Note #4: (Doodman)
|
||||
@@ -46,7 +46,7 @@
|
||||
#include "eq_dictionary.h"
|
||||
|
||||
/*
|
||||
** Child struct of Item_Struct:
|
||||
** Child struct of ItemData:
|
||||
** Effect data: Click, Proc, Focus, Worn, Scroll
|
||||
**
|
||||
*/
|
||||
@@ -69,10 +69,18 @@ struct InternalSerializedItem_Struct {
|
||||
const void * inst;
|
||||
};
|
||||
|
||||
struct SerializedItemInstance_Struct {
|
||||
int32 container_id;
|
||||
int32 slot_id;
|
||||
int32 bag_id;
|
||||
int32 aug_id;
|
||||
void *inst;
|
||||
};
|
||||
|
||||
// use EmuConstants::ITEM_COMMON_SIZE
|
||||
//#define MAX_AUGMENT_SLOTS 5
|
||||
|
||||
struct Item_Struct {
|
||||
struct ItemData {
|
||||
bool IsEquipable(uint16 Race, uint16 Class) const;
|
||||
// Non packet based fields
|
||||
uint8 MinStatus;
|
||||
@@ -99,17 +107,10 @@ struct Item_Struct {
|
||||
uint32 Favor; // Individual favor
|
||||
uint32 GuildFavor; // Guild favor
|
||||
uint32 PointType;
|
||||
|
||||
//uint32 Unk117;
|
||||
//uint32 Unk118;
|
||||
//uint32 Unk121;
|
||||
//uint32 Unk124;
|
||||
|
||||
uint8 BagType; // 0:Small Bag, 1:Large Bag, 2:Quiver, 3:Belt Pouch ... there are 50 types
|
||||
uint8 BagSlots; // Number of slots: can only be 2, 4, 6, 8, or 10
|
||||
uint8 BagSlots; // Number of slots
|
||||
uint8 BagSize; // 0:TINY, 1:SMALL, 2:MEDIUM, 3:LARGE, 4:GIANT
|
||||
uint8 BagWR; // 0->100
|
||||
|
||||
bool BenefitFlag;
|
||||
bool Tradeskills; // Is this a tradeskill item?
|
||||
int8 CR; // Save vs Cold
|
||||
@@ -128,7 +129,6 @@ struct Item_Struct {
|
||||
int32 Mana; // Mana
|
||||
int32 AC; // AC
|
||||
uint32 Deity; // Bitmask of Deities that can equip this item
|
||||
//uint32 Unk033
|
||||
int32 SkillModValue; // % Mod to skill specified in SkillModType
|
||||
uint32 SkillModType; // Type of skill for SkillModValue to apply to
|
||||
uint32 BaneDmgRace; // Bane Damage Race
|
||||
@@ -150,13 +150,11 @@ struct Item_Struct {
|
||||
uint32 Color; // RR GG BB 00 <-- as it appears in pc
|
||||
uint32 Classes; // Bitfield of classes that can equip item (1 << class#)
|
||||
uint32 Races; // Bitfield of races that can equip item (1 << race#)
|
||||
//uint32 Unk054;
|
||||
int16 MaxCharges; // Maximum charges items can hold: -1 if not a chargeable item
|
||||
uint8 ItemType; // Item Type/Skill (itemClass* from above)
|
||||
uint8 Material; // Item material type
|
||||
uint32 HerosForgeModel;// Hero's Forge Armor Model Type (2-13?)
|
||||
float SellRate; // Sell rate
|
||||
//uint32 Unk059;
|
||||
union {
|
||||
uint32 Fulfilment; // Food fulfilment (How long it lasts)
|
||||
int16 CastTime; // Cast Time for clicky effects, in milliseconds
|
||||
@@ -211,7 +209,6 @@ struct Item_Struct {
|
||||
int16 StackSize;
|
||||
uint8 PotionBeltSlots;
|
||||
ItemEffect_Struct Click, Proc, Worn, Focus, Scroll, Bard;
|
||||
|
||||
uint8 Book; // 0=Not book, 1=Book
|
||||
uint32 BookType;
|
||||
char Filename[33]; // Filename for book data
|
||||
@@ -240,11 +237,11 @@ struct Item_Struct {
|
||||
uint32 ScriptFileID;
|
||||
uint16 ExpendableArrow;
|
||||
uint32 Clairvoyance;
|
||||
char ClickName[65];
|
||||
char ProcName[65];
|
||||
char WornName[65];
|
||||
char FocusName[65];
|
||||
char ScrollName[65];
|
||||
char ClickName[65];
|
||||
char ProcName[65];
|
||||
char WornName[65];
|
||||
char FocusName[65];
|
||||
char ScrollName[65];
|
||||
|
||||
};
|
||||
|
||||
@@ -0,0 +1,389 @@
|
||||
/* EQEMu: Everquest Server Emulator
|
||||
Copyright (C) 2001-2015 EQEMu Development Team (http://eqemulator.net)
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; version 2 of the License.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY except by those people which sell it, which
|
||||
are required to give you total support for your newly bought product;
|
||||
without even the implied warranty of MERCHANTABILITY or FITNESS FOR
|
||||
A PARTICULAR PURPOSE. See the GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#include "item_instance.h"
|
||||
#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_;
|
||||
int16 charges_;
|
||||
uint32 color_;
|
||||
bool attuned_;
|
||||
std::string custom_data_;
|
||||
uint32 ornament_idfile_;
|
||||
uint32 ornament_icon_;
|
||||
uint32 ornament_hero_model_;
|
||||
char tracking_id_[17];
|
||||
uint32 serial_id_;
|
||||
uint32 recast_timestamp_;
|
||||
uint32 merchant_slot_;
|
||||
uint32 merchant_count_;
|
||||
uint32 price_;
|
||||
ItemContainer contents_;
|
||||
};
|
||||
|
||||
EQEmu::ItemInstance::ItemInstance(const ItemData* idata) {
|
||||
impl_ = new impl;
|
||||
impl_->base_item_ = idata;
|
||||
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, int16 charges) {
|
||||
impl_ = new impl;
|
||||
impl_->base_item_ = idata;
|
||||
impl_->modified_item_ = nullptr;
|
||||
impl_->charges_ = charges;
|
||||
impl_->color_ = 0;
|
||||
impl_->attuned_ = false;
|
||||
impl_->ornament_idfile_ = 0;
|
||||
impl_->ornament_icon_ = 0;
|
||||
impl_->ornament_hero_model_ = 0;
|
||||
impl_->recast_timestamp_ = 0;
|
||||
impl_->serial_id_ = 0;
|
||||
impl_->merchant_slot_ = 0;
|
||||
impl_->merchant_count_ = 0;
|
||||
impl_->price_ = 0;
|
||||
memset(impl_->tracking_id_, 0, 17);
|
||||
}
|
||||
|
||||
EQEmu::ItemInstance::~ItemInstance() {
|
||||
delete impl_;
|
||||
}
|
||||
|
||||
|
||||
EQEmu::ItemInstance::pointer EQEmu::ItemInstance::Split(int charges) {
|
||||
if(!IsStackable()) {
|
||||
//Can't split non stackable items!
|
||||
return pointer(nullptr);
|
||||
}
|
||||
|
||||
if(charges >= GetCharges()) {
|
||||
return pointer(nullptr);
|
||||
}
|
||||
|
||||
if(impl_->contents_.Size() > 0) {
|
||||
return pointer(nullptr);
|
||||
}
|
||||
|
||||
pointer split = pointer(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_;
|
||||
}
|
||||
|
||||
const ItemData *EQEmu::ItemInstance::GetBaseItem() {
|
||||
return impl_->base_item_;
|
||||
}
|
||||
|
||||
const ItemData *EQEmu::ItemInstance::GetBaseItem() const {
|
||||
return impl_->base_item_;
|
||||
}
|
||||
|
||||
EQEmu::ItemInstance::pointer EQEmu::ItemInstance::Get(const int index) {
|
||||
if(EQEmu::ValueWithin(index, 0, 255)) {
|
||||
return impl_->contents_.Get(index);
|
||||
}
|
||||
|
||||
return pointer(nullptr);
|
||||
}
|
||||
|
||||
bool EQEmu::ItemInstance::Put(const int index, pointer &inst) {
|
||||
if(!impl_->base_item_) {
|
||||
return false;
|
||||
}
|
||||
|
||||
auto item = impl_->base_item_;
|
||||
if(item->ItemClass == ItemClassContainer) { // Bag
|
||||
if(!EQEmu::ValueWithin(index, 0, item->BagSlots)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return impl_->contents_.Put(index, inst);
|
||||
}
|
||||
else if(item->ItemClass == ItemClassCommon) { // Augment
|
||||
if(!EQEmu::ValueWithin(index, 0, EmuConstants::ITEM_COMMON_SIZE)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if(!item->AugSlotVisible[index]) {
|
||||
return false;
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
int16 EQEmu::ItemInstance::GetCharges() {
|
||||
return impl_->charges_;
|
||||
}
|
||||
|
||||
int16 EQEmu::ItemInstance::GetCharges() const {
|
||||
return impl_->charges_;
|
||||
}
|
||||
|
||||
void EQEmu::ItemInstance::SetCharges(const int16 charges) {
|
||||
impl_->charges_ = charges;
|
||||
}
|
||||
|
||||
uint32 EQEmu::ItemInstance::GetColor() {
|
||||
return impl_->color_;
|
||||
}
|
||||
|
||||
uint32 EQEmu::ItemInstance::GetColor() const {
|
||||
return impl_->color_;
|
||||
}
|
||||
|
||||
void EQEmu::ItemInstance::SetColor(const uint32 color) {
|
||||
impl_->color_ = color;
|
||||
}
|
||||
|
||||
bool EQEmu::ItemInstance::GetAttuned() {
|
||||
return impl_->attuned_;
|
||||
}
|
||||
|
||||
bool EQEmu::ItemInstance::GetAttuned() const {
|
||||
return impl_->attuned_;
|
||||
}
|
||||
|
||||
void EQEmu::ItemInstance::SetAttuned(const bool attuned) {
|
||||
impl_->attuned_ = attuned;
|
||||
}
|
||||
|
||||
std::string EQEmu::ItemInstance::GetCustomData() {
|
||||
return impl_->custom_data_;
|
||||
}
|
||||
|
||||
std::string EQEmu::ItemInstance::GetCustomData() const {
|
||||
return impl_->custom_data_;
|
||||
}
|
||||
|
||||
void EQEmu::ItemInstance::SetCustomData(const std::string &custom_data) {
|
||||
//We need to actually set the custom data stuff based on this string
|
||||
impl_->custom_data_ = custom_data;
|
||||
}
|
||||
|
||||
uint32 EQEmu::ItemInstance::GetOrnamentIDFile() {
|
||||
return impl_->ornament_idfile_;
|
||||
}
|
||||
|
||||
uint32 EQEmu::ItemInstance::GetOrnamentIDFile() const {
|
||||
return impl_->ornament_idfile_;
|
||||
}
|
||||
|
||||
void EQEmu::ItemInstance::SetOrnamentIDFile(const uint32 ornament_idfile) {
|
||||
impl_->ornament_idfile_ = ornament_idfile;
|
||||
}
|
||||
|
||||
uint32 EQEmu::ItemInstance::GetOrnamentIcon() {
|
||||
return impl_->ornament_icon_;
|
||||
}
|
||||
|
||||
uint32 EQEmu::ItemInstance::GetOrnamentIcon() const {
|
||||
return impl_->ornament_icon_;
|
||||
}
|
||||
|
||||
void EQEmu::ItemInstance::SetOrnamentIcon(const uint32 ornament_icon) {
|
||||
impl_->ornament_icon_ = ornament_icon;
|
||||
}
|
||||
|
||||
uint32 EQEmu::ItemInstance::GetOrnamentHeroModel() {
|
||||
return impl_->ornament_hero_model_;
|
||||
}
|
||||
|
||||
uint32 EQEmu::ItemInstance::GetOrnamentHeroModel() const {
|
||||
return impl_->ornament_hero_model_;
|
||||
}
|
||||
|
||||
uint32 EQEmu::ItemInstance::GetOrnamentHeroModel(int material_slot) {
|
||||
uint32 hero_model = 0;
|
||||
if(impl_->ornament_hero_model_ > 0)
|
||||
{
|
||||
hero_model = impl_->ornament_hero_model_;
|
||||
if(material_slot >= 0)
|
||||
{
|
||||
hero_model = (impl_->ornament_hero_model_ * 100) + material_slot;
|
||||
}
|
||||
}
|
||||
return hero_model;
|
||||
}
|
||||
|
||||
uint32 EQEmu::ItemInstance::GetOrnamentHeroModel(int material_slot) const {
|
||||
uint32 hero_model = 0;
|
||||
if(impl_->ornament_hero_model_ > 0)
|
||||
{
|
||||
hero_model = impl_->ornament_hero_model_;
|
||||
if(material_slot >= 0)
|
||||
{
|
||||
hero_model = (impl_->ornament_hero_model_ * 100) + material_slot;
|
||||
}
|
||||
}
|
||||
return hero_model;
|
||||
}
|
||||
|
||||
void EQEmu::ItemInstance::SetOrnamentHeroModel(const uint32 ornament_hero_model) {
|
||||
impl_->ornament_hero_model_ = ornament_hero_model;
|
||||
}
|
||||
|
||||
const char* EQEmu::ItemInstance::GetTrackingID() {
|
||||
return impl_->tracking_id_;
|
||||
}
|
||||
|
||||
const char* EQEmu::ItemInstance::GetTrackingID() const {
|
||||
return impl_->tracking_id_;
|
||||
}
|
||||
|
||||
void EQEmu::ItemInstance::SetTrackingID(const char *tracking_id) {
|
||||
size_t len = strlen(tracking_id);
|
||||
if(len > 16) {
|
||||
return;
|
||||
}
|
||||
|
||||
strncpy(impl_->tracking_id_, tracking_id, 16);
|
||||
}
|
||||
|
||||
uint32 EQEmu::ItemInstance::GetRecastTimestamp() {
|
||||
return impl_->recast_timestamp_;
|
||||
}
|
||||
|
||||
uint32 EQEmu::ItemInstance::GetRecastTimestamp() const {
|
||||
return impl_->recast_timestamp_;
|
||||
}
|
||||
|
||||
void EQEmu::ItemInstance::SetRecastTimestamp(const uint32 recast_timestamp) {
|
||||
impl_->recast_timestamp_ = recast_timestamp;
|
||||
}
|
||||
|
||||
uint32 EQEmu::ItemInstance::GetMerchantSlot() {
|
||||
return impl_->merchant_slot_;
|
||||
}
|
||||
|
||||
uint32 EQEmu::ItemInstance::GetMerchantSlot() const {
|
||||
return impl_->merchant_slot_;
|
||||
}
|
||||
|
||||
void EQEmu::ItemInstance::SetMerchantSlot(uint32 slot) {
|
||||
impl_->merchant_slot_ = slot;
|
||||
}
|
||||
|
||||
uint32 EQEmu::ItemInstance::GetMerchantCount() {
|
||||
return impl_->merchant_count_;
|
||||
}
|
||||
|
||||
uint32 EQEmu::ItemInstance::GetMerchantCount() const {
|
||||
return impl_->merchant_count_;
|
||||
}
|
||||
|
||||
void EQEmu::ItemInstance::SetMerchantCount(const uint32 cnt) {
|
||||
impl_->merchant_count_ = cnt;
|
||||
}
|
||||
|
||||
uint32 EQEmu::ItemInstance::GetPrice() {
|
||||
return impl_->price_;
|
||||
}
|
||||
|
||||
uint32 EQEmu::ItemInstance::GetPrice() const {
|
||||
return impl_->price_;
|
||||
}
|
||||
|
||||
void EQEmu::ItemInstance::SetPrice(const uint32 p) {
|
||||
impl_->price_ = p;
|
||||
}
|
||||
|
||||
uint32 EQEmu::ItemInstance::GetSerialNumber() {
|
||||
return impl_->serial_id_;
|
||||
}
|
||||
|
||||
uint32 EQEmu::ItemInstance::GetSerialNumber() const {
|
||||
return impl_->serial_id_;
|
||||
}
|
||||
|
||||
void EQEmu::ItemInstance::SetSerialNumber(const uint32 sn) {
|
||||
impl_->serial_id_ = sn;
|
||||
}
|
||||
|
||||
bool EQEmu::ItemInstance::IsStackable() {
|
||||
return impl_->base_item_->Stackable;
|
||||
}
|
||||
|
||||
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_);
|
||||
}
|
||||
|
||||
void EQEmu::ItemInstance::Interrogate(int level) {
|
||||
impl_->contents_.Interrogate(level);
|
||||
}
|
||||
@@ -0,0 +1,126 @@
|
||||
/* EQEMu: Everquest Server Emulator
|
||||
Copyright (C) 2001-2015 EQEMu Development Team (http://eqemulator.net)
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; version 2 of the License.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY except by those people which sell it, which
|
||||
are required to give you total support for your newly bought product;
|
||||
without even the implied warranty of MERCHANTABILITY or FITNESS FOR
|
||||
A PARTICULAR PURPOSE. See the GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#ifndef COMMON_ITEM_INSTANCE_H
|
||||
#define COMMON_ITEM_INSTANCE_H
|
||||
|
||||
#include "item_data.h"
|
||||
#include <memory>
|
||||
|
||||
namespace EQEmu
|
||||
{
|
||||
uint32 GetNextItemInstanceSerial();
|
||||
|
||||
class ItemContainer;
|
||||
class ItemInstance
|
||||
{
|
||||
public:
|
||||
typedef std::shared_ptr<ItemInstance> pointer;
|
||||
ItemInstance(const ItemData* idata);
|
||||
ItemInstance(const ItemData* idata, const int16 charges);
|
||||
~ItemInstance();
|
||||
|
||||
const ItemData *GetItem();
|
||||
const ItemData *GetBaseItem();
|
||||
const ItemData *GetBaseItem() const;
|
||||
|
||||
pointer Split(int charges);
|
||||
|
||||
//Container
|
||||
pointer Get(const int index);
|
||||
bool Put(const int index, pointer &inst);
|
||||
|
||||
//Persistent State
|
||||
int16 GetCharges();
|
||||
int16 GetCharges() const;
|
||||
void SetCharges(const int16 charges);
|
||||
|
||||
uint32 GetColor();
|
||||
uint32 GetColor() const;
|
||||
void SetColor(const uint32 color);
|
||||
|
||||
bool GetAttuned();
|
||||
bool GetAttuned() const;
|
||||
void SetAttuned(const bool attuned);
|
||||
|
||||
std::string GetCustomData();
|
||||
std::string GetCustomData() const;
|
||||
void SetCustomData(const std::string &custom_data);
|
||||
|
||||
uint32 GetOrnamentIDFile();
|
||||
uint32 GetOrnamentIDFile() const;
|
||||
void SetOrnamentIDFile(const uint32 ornament_idfile);
|
||||
|
||||
uint32 GetOrnamentIcon();
|
||||
uint32 GetOrnamentIcon() const;
|
||||
void SetOrnamentIcon(const uint32 ornament_icon);
|
||||
|
||||
uint32 GetOrnamentHeroModel();
|
||||
uint32 GetOrnamentHeroModel() const;
|
||||
uint32 GetOrnamentHeroModel(int material_slot);
|
||||
uint32 GetOrnamentHeroModel(int material_slot) const;
|
||||
void SetOrnamentHeroModel(const uint32 ornament_hero_model);
|
||||
|
||||
const char* GetTrackingID();
|
||||
const char* GetTrackingID() const;
|
||||
void SetTrackingID(const char *tracking_id);
|
||||
|
||||
uint32 GetRecastTimestamp();
|
||||
uint32 GetRecastTimestamp() const;
|
||||
void SetRecastTimestamp(const uint32 recast_timestamp);
|
||||
|
||||
//Merchant
|
||||
uint32 GetMerchantSlot();
|
||||
uint32 GetMerchantSlot() const;
|
||||
void SetMerchantSlot(const uint32 slot);
|
||||
|
||||
uint32 GetMerchantCount();
|
||||
uint32 GetMerchantCount() const;
|
||||
void SetMerchantCount(const uint32 cnt);
|
||||
|
||||
uint32 GetPrice();
|
||||
uint32 GetPrice() const;
|
||||
void SetPrice(const uint32 p);
|
||||
|
||||
//Serial Number
|
||||
uint32 GetSerialNumber();
|
||||
uint32 GetSerialNumber() const;
|
||||
void SetSerialNumber(uint32 sn);
|
||||
|
||||
//Basic Stats
|
||||
bool IsStackable();
|
||||
bool IsStackable() const;
|
||||
|
||||
bool IsNoDrop();
|
||||
bool IsNoDrop() const;
|
||||
|
||||
void CheckStackRemaining(pointer &insert, int &charges);
|
||||
|
||||
//Internal state
|
||||
//Used for low level operations such as encode/decode
|
||||
ItemContainer *GetContainer();
|
||||
|
||||
void Interrogate(int level);
|
||||
private:
|
||||
struct impl;
|
||||
impl *impl_;
|
||||
};
|
||||
|
||||
} // EQEmu
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,212 @@
|
||||
#include "memory_buffer.h"
|
||||
|
||||
EQEmu::MemoryBuffer::MemoryBuffer() {
|
||||
buffer_ = nullptr;
|
||||
size_ = 0;
|
||||
capacity_ = 0;
|
||||
read_pos_ = 0;
|
||||
write_pos_ = 0;
|
||||
}
|
||||
|
||||
EQEmu::MemoryBuffer::MemoryBuffer(size_t sz) {
|
||||
buffer_ = nullptr;
|
||||
size_ = 0;
|
||||
capacity_ = 0;
|
||||
read_pos_ = 0;
|
||||
write_pos_ = 0;
|
||||
Resize(sz);
|
||||
}
|
||||
|
||||
EQEmu::MemoryBuffer::MemoryBuffer(const MemoryBuffer &other) {
|
||||
if(other.capacity_) {
|
||||
buffer_ = new uchar[other.capacity_];
|
||||
memcpy(buffer_, other.buffer_, other.capacity_);
|
||||
} else {
|
||||
buffer_ = nullptr;
|
||||
}
|
||||
|
||||
size_ = other.size_;
|
||||
capacity_ = other.capacity_;
|
||||
write_pos_ = other.write_pos_;
|
||||
read_pos_ = other.read_pos_;
|
||||
}
|
||||
|
||||
EQEmu::MemoryBuffer::MemoryBuffer(MemoryBuffer &&other) {
|
||||
uchar *tbuf = other.buffer_;
|
||||
size_t tsz = other.size_;
|
||||
size_t tcapacity = other.capacity_;
|
||||
size_t twrite_pos = other.write_pos_;
|
||||
size_t tread_pos = other.read_pos_;
|
||||
|
||||
other.buffer_ = nullptr;
|
||||
other.size_ = 0;
|
||||
other.capacity_ = 0;
|
||||
other.read_pos_ = 0;
|
||||
other.write_pos_ = 0;
|
||||
|
||||
buffer_ = tbuf;
|
||||
size_ = tsz;
|
||||
capacity_ = tcapacity;
|
||||
write_pos_ = twrite_pos;
|
||||
read_pos_ = tread_pos;
|
||||
}
|
||||
|
||||
EQEmu::MemoryBuffer& EQEmu::MemoryBuffer::operator=(const MemoryBuffer &other) {
|
||||
if(this == &other) {
|
||||
return *this;
|
||||
}
|
||||
|
||||
if(buffer_) {
|
||||
delete[] buffer_;
|
||||
}
|
||||
|
||||
if(other.capacity_) {
|
||||
buffer_ = new uchar[other.capacity_];
|
||||
memcpy(buffer_, other.buffer_, other.capacity_);
|
||||
}
|
||||
else {
|
||||
buffer_ = nullptr;
|
||||
}
|
||||
|
||||
size_ = other.size_;
|
||||
capacity_ = other.capacity_;
|
||||
write_pos_ = other.write_pos_;
|
||||
read_pos_ = other.read_pos_;
|
||||
return *this;
|
||||
}
|
||||
|
||||
EQEmu::MemoryBuffer& EQEmu::MemoryBuffer::operator=(MemoryBuffer &&other) {
|
||||
uchar *tbuf = other.buffer_;
|
||||
size_t tsz = other.size_;
|
||||
size_t tcapacity = other.capacity_;
|
||||
size_t twrite_pos = other.write_pos_;
|
||||
size_t tread_pos = other.read_pos_;
|
||||
|
||||
other.buffer_ = nullptr;
|
||||
other.size_ = 0;
|
||||
other.capacity_ = 0;
|
||||
other.read_pos_ = 0;
|
||||
other.write_pos_ = 0;
|
||||
|
||||
buffer_ = tbuf;
|
||||
size_ = tsz;
|
||||
capacity_ = tcapacity;
|
||||
write_pos_ = twrite_pos;
|
||||
read_pos_ = tread_pos;
|
||||
return *this;
|
||||
}
|
||||
|
||||
EQEmu::MemoryBuffer& EQEmu::MemoryBuffer::operator+=(const MemoryBuffer &rhs) {
|
||||
if(!rhs.buffer_) {
|
||||
return *this;
|
||||
}
|
||||
|
||||
if(buffer_) {
|
||||
size_t old_size = size_;
|
||||
Resize(size_ + rhs.size_);
|
||||
memcpy(&buffer_[old_size], rhs.buffer_, rhs.size_);
|
||||
} else {
|
||||
buffer_ = new uchar[rhs.capacity_];
|
||||
memcpy(buffer_, rhs.buffer_, rhs.capacity_);
|
||||
size_ = rhs.size_;
|
||||
capacity_ = rhs.capacity_;
|
||||
}
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
EQEmu::MemoryBuffer::~MemoryBuffer() { Clear(); }
|
||||
|
||||
uchar& EQEmu::MemoryBuffer::operator[](size_t pos) {
|
||||
return buffer_[pos];
|
||||
}
|
||||
|
||||
const uchar& EQEmu::MemoryBuffer::operator[](size_t pos) const {
|
||||
return buffer_[pos];
|
||||
}
|
||||
|
||||
bool EQEmu::MemoryBuffer::Empty() {
|
||||
return size_ == 0;
|
||||
}
|
||||
|
||||
bool EQEmu::MemoryBuffer::Empty() const {
|
||||
return size_ == 0;
|
||||
}
|
||||
|
||||
size_t EQEmu::MemoryBuffer::Size() {
|
||||
return size_;
|
||||
}
|
||||
|
||||
size_t EQEmu::MemoryBuffer::Size() const {
|
||||
return size_;
|
||||
}
|
||||
|
||||
size_t EQEmu::MemoryBuffer::Capacity() {
|
||||
return capacity_;
|
||||
}
|
||||
|
||||
size_t EQEmu::MemoryBuffer::Capacity() const {
|
||||
return capacity_;
|
||||
}
|
||||
|
||||
void EQEmu::MemoryBuffer::Resize(size_t sz) {
|
||||
if(!buffer_) {
|
||||
size_t new_size = sz + 64;
|
||||
buffer_ = new uchar[new_size];
|
||||
capacity_ = new_size;
|
||||
size_ = sz;
|
||||
memset(buffer_, 0, capacity_);
|
||||
return;
|
||||
}
|
||||
|
||||
if(sz > capacity_) {
|
||||
size_t new_size = sz + 32;
|
||||
uchar *temp = new uchar[new_size];
|
||||
memcpy(temp, buffer_, capacity_);
|
||||
delete[] buffer_;
|
||||
buffer_ = temp;
|
||||
|
||||
capacity_ = new_size;
|
||||
size_ = sz;
|
||||
}
|
||||
else {
|
||||
size_ = sz;
|
||||
}
|
||||
}
|
||||
|
||||
void EQEmu::MemoryBuffer::Clear() {
|
||||
if(buffer_) {
|
||||
delete[] buffer_;
|
||||
buffer_ = nullptr;
|
||||
}
|
||||
|
||||
size_ = 0;
|
||||
capacity_ = 0;
|
||||
write_pos_ = 0;
|
||||
read_pos_ = 0;
|
||||
}
|
||||
|
||||
void EQEmu::MemoryBuffer::Zero() {
|
||||
if(buffer_) {
|
||||
memset(buffer_, 0, capacity_);
|
||||
}
|
||||
}
|
||||
|
||||
void EQEmu::MemoryBuffer::Write(const char *val, size_t len) {
|
||||
size_t size_needed = write_pos_ + len;
|
||||
Resize(size_needed);
|
||||
|
||||
memcpy(&buffer_[write_pos_], val, len);
|
||||
write_pos_ += len;
|
||||
}
|
||||
|
||||
void EQEmu::MemoryBuffer::Read(uchar *buf, size_t len) {
|
||||
memcpy(buf, &buffer_[read_pos_], len);
|
||||
read_pos_ += len;
|
||||
}
|
||||
|
||||
void EQEmu::MemoryBuffer::Read(char *str) {
|
||||
size_t len = strlen((const char*)&buffer_[read_pos_]);
|
||||
memcpy(str, &buffer_[read_pos_], len);
|
||||
read_pos_ += len;
|
||||
}
|
||||
@@ -0,0 +1,124 @@
|
||||
/* EQEMu: Everquest Server Emulator
|
||||
Copyright (C) 2001-2015 EQEMu Development Team (http://eqemulator.net)
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; version 2 of the License.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY except by those people which sell it, which
|
||||
are required to give you total support for your newly bought product;
|
||||
without even the implied warranty of MERCHANTABILITY or FITNESS FOR
|
||||
A PARTICULAR PURPOSE. See the GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#ifndef COMMON_MEMORY_BUFFER_H
|
||||
#define COMMON_MEMORY_BUFFER_H
|
||||
|
||||
#include "types.h"
|
||||
#include <type_traits>
|
||||
#include <string.h>
|
||||
#include <string>
|
||||
|
||||
namespace EQEmu
|
||||
{
|
||||
class MemoryBuffer
|
||||
{
|
||||
public:
|
||||
MemoryBuffer();
|
||||
MemoryBuffer(size_t sz);
|
||||
MemoryBuffer(const MemoryBuffer &other);
|
||||
MemoryBuffer(MemoryBuffer &&other);
|
||||
MemoryBuffer& operator=(const MemoryBuffer &other);
|
||||
MemoryBuffer& operator=(MemoryBuffer &&other);
|
||||
MemoryBuffer& operator+=(const MemoryBuffer &rhs);
|
||||
friend MemoryBuffer operator+(MemoryBuffer lhs, const MemoryBuffer& rhs) { return lhs += rhs; }
|
||||
~MemoryBuffer();
|
||||
|
||||
uchar& operator[](size_t pos);
|
||||
const uchar& operator[](size_t pos) const;
|
||||
|
||||
template<typename T>
|
||||
operator T*() {
|
||||
return reinterpret_cast<T*>(buffer_);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
operator T*() const {
|
||||
return reinterpret_cast<T*>(buffer_);
|
||||
}
|
||||
|
||||
operator bool() { return buffer_ != nullptr; }
|
||||
operator bool() const { return buffer_ != nullptr; }
|
||||
|
||||
bool Empty();
|
||||
bool Empty() const;
|
||||
size_t Size();
|
||||
size_t Size() const;
|
||||
size_t Capacity();
|
||||
size_t Capacity() const;
|
||||
|
||||
void Resize(size_t sz);
|
||||
void Clear();
|
||||
void Zero();
|
||||
|
||||
template<typename T>
|
||||
void Write(T val) {
|
||||
static_assert(std::is_pod<T>::value, "MemoryBuffer::Write<T>(T val) only works on pod and string types.");
|
||||
Write((const char*)&val, sizeof(T));
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
T Read() {
|
||||
static_assert(std::is_pod<T>::value, "MemoryBuffer::Read<T>() only works on pod and string types.");
|
||||
T temp;
|
||||
Read((uchar*)&temp, sizeof(T));
|
||||
return temp;
|
||||
}
|
||||
|
||||
void Write(const std::string &val) {
|
||||
Write(val.c_str(), val.length());
|
||||
Write((uint8)0);
|
||||
}
|
||||
|
||||
void Write(const char *val) {
|
||||
size_t len = strlen(val);
|
||||
Write(val, len);
|
||||
Write((uint8)0);
|
||||
}
|
||||
|
||||
std::string ReadString() {
|
||||
std::string ret;
|
||||
size_t len = strlen((const char*)&buffer_[read_pos_]);
|
||||
ret.resize(len);
|
||||
memcpy(&ret[0], &buffer_[read_pos_], len);
|
||||
read_pos_ += len + 1;
|
||||
return ret;
|
||||
}
|
||||
|
||||
void Write(const char *val, size_t len);
|
||||
void Read(uchar *buf, size_t len);
|
||||
void Read(char *str);
|
||||
|
||||
inline size_t GetWritePosition() { return write_pos_; }
|
||||
inline void SetWritePosition(size_t wp) { write_pos_ = wp; }
|
||||
inline void WriteSkipBytes(size_t skip) { write_pos_ += skip; }
|
||||
inline size_t GetReadPosition() { return read_pos_; }
|
||||
inline void SetReadPosition(size_t wp) { read_pos_ = wp; }
|
||||
inline void ReadSkipBytes(size_t skip) { read_pos_ += skip; }
|
||||
|
||||
private:
|
||||
uchar *buffer_;
|
||||
size_t size_;
|
||||
size_t capacity_;
|
||||
size_t write_pos_;
|
||||
size_t read_pos_;
|
||||
};
|
||||
|
||||
} // EQEmu
|
||||
|
||||
#endif
|
||||
+10
-10
@@ -10,19 +10,19 @@
|
||||
#include "rof2.h"
|
||||
|
||||
void RegisterAllPatches(EQStreamIdentifier &into) {
|
||||
Titanium::Register(into);
|
||||
SoF::Register(into);
|
||||
SoD::Register(into);
|
||||
UF::Register(into);
|
||||
RoF::Register(into);
|
||||
//Titanium::Register(into);
|
||||
//SoF::Register(into);
|
||||
//SoD::Register(into);
|
||||
//UF::Register(into);
|
||||
//RoF::Register(into);
|
||||
RoF2::Register(into);
|
||||
}
|
||||
|
||||
void ReloadAllPatches() {
|
||||
Titanium::Reload();
|
||||
SoF::Reload();
|
||||
SoD::Reload();
|
||||
UF::Reload();
|
||||
RoF::Reload();
|
||||
//Titanium::Reload();
|
||||
//SoF::Reload();
|
||||
//SoD::Reload();
|
||||
//UF::Reload();
|
||||
//RoF::Reload();
|
||||
RoF2::Reload();
|
||||
}
|
||||
|
||||
+90
-89
@@ -532,71 +532,72 @@ namespace RoF
|
||||
{
|
||||
//consume the packet
|
||||
EQApplicationPacket *in = *p;
|
||||
delete in;
|
||||
|
||||
*p = nullptr;
|
||||
|
||||
if (in->size == 0) {
|
||||
|
||||
in->size = 4;
|
||||
in->pBuffer = new uchar[in->size];
|
||||
|
||||
*((uint32 *)in->pBuffer) = 0;
|
||||
|
||||
dest->FastQueuePacket(&in, ack_req);
|
||||
return;
|
||||
}
|
||||
|
||||
//store away the emu struct
|
||||
unsigned char *__emu_buffer = in->pBuffer;
|
||||
|
||||
int ItemCount = in->size / sizeof(InternalSerializedItem_Struct);
|
||||
|
||||
if (ItemCount == 0 || (in->size % sizeof(InternalSerializedItem_Struct)) != 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(InternalSerializedItem_Struct));
|
||||
|
||||
delete in;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
InternalSerializedItem_Struct *eq = (InternalSerializedItem_Struct *)in->pBuffer;
|
||||
|
||||
in->pBuffer = new uchar[4];
|
||||
*(uint32 *)in->pBuffer = ItemCount;
|
||||
in->size = 4;
|
||||
|
||||
for (int r = 0; r < ItemCount; r++, eq++) {
|
||||
|
||||
uint32 Length = 0;
|
||||
|
||||
char* Serialized = SerializeItem((const ItemInst*)eq->inst, eq->slot_id, &Length, 0);
|
||||
|
||||
if (Serialized) {
|
||||
|
||||
uchar *OldBuffer = in->pBuffer;
|
||||
in->pBuffer = new uchar[in->size + Length];
|
||||
memcpy(in->pBuffer, OldBuffer, in->size);
|
||||
|
||||
safe_delete_array(OldBuffer);
|
||||
|
||||
memcpy(in->pBuffer + in->size, Serialized, Length);
|
||||
in->size += Length;
|
||||
|
||||
safe_delete_array(Serialized);
|
||||
}
|
||||
else {
|
||||
Log.Out(Logs::General, Logs::Netcode, "[ERROR] Serialization failed on item slot %d during OP_CharInventory. Item skipped.", eq->slot_id);
|
||||
}
|
||||
}
|
||||
|
||||
delete[] __emu_buffer;
|
||||
|
||||
//Log.LogDebugType(Logs::General, Logs::Netcode, "[ERROR] Sending inventory to client");
|
||||
//Log.Hex(Logs::Netcode, in->pBuffer, in->size);
|
||||
|
||||
dest->FastQueuePacket(&in, ack_req);
|
||||
//*p = nullptr;
|
||||
//
|
||||
//if (in->size == 0) {
|
||||
//
|
||||
// in->size = 4;
|
||||
// in->pBuffer = new uchar[in->size];
|
||||
//
|
||||
// *((uint32 *)in->pBuffer) = 0;
|
||||
//
|
||||
// dest->FastQueuePacket(&in, ack_req);
|
||||
// return;
|
||||
//}
|
||||
//
|
||||
////store away the emu struct
|
||||
//unsigned char *__emu_buffer = in->pBuffer;
|
||||
//
|
||||
//int ItemCount = in->size / sizeof(InternalSerializedItem_Struct);
|
||||
//
|
||||
//if (ItemCount == 0 || (in->size % sizeof(InternalSerializedItem_Struct)) != 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(InternalSerializedItem_Struct));
|
||||
//
|
||||
// delete in;
|
||||
//
|
||||
// return;
|
||||
//}
|
||||
//
|
||||
//InternalSerializedItem_Struct *eq = (InternalSerializedItem_Struct *)in->pBuffer;
|
||||
//
|
||||
//in->pBuffer = new uchar[4];
|
||||
//*(uint32 *)in->pBuffer = ItemCount;
|
||||
//in->size = 4;
|
||||
//
|
||||
//for (int r = 0; r < ItemCount; r++, eq++) {
|
||||
//
|
||||
// uint32 Length = 0;
|
||||
//
|
||||
// char* Serialized = SerializeItem((const ItemInst*)eq->inst, eq->slot_id, &Length, 0);
|
||||
//
|
||||
// if (Serialized) {
|
||||
//
|
||||
// uchar *OldBuffer = in->pBuffer;
|
||||
// in->pBuffer = new uchar[in->size + Length];
|
||||
// memcpy(in->pBuffer, OldBuffer, in->size);
|
||||
//
|
||||
// safe_delete_array(OldBuffer);
|
||||
//
|
||||
// memcpy(in->pBuffer + in->size, Serialized, Length);
|
||||
// in->size += Length;
|
||||
//
|
||||
// safe_delete_array(Serialized);
|
||||
// }
|
||||
// else {
|
||||
// Log.Out(Logs::General, Logs::Netcode, "[ERROR] Serialization failed on item slot %d during OP_CharInventory. Item skipped.", eq->slot_id);
|
||||
// }
|
||||
//}
|
||||
//
|
||||
//delete[] __emu_buffer;
|
||||
//
|
||||
////Log.LogDebugType(Logs::General, Logs::Netcode, "[ERROR] Sending inventory to client");
|
||||
////Log.Hex(Logs::Netcode, in->pBuffer, in->size);
|
||||
//
|
||||
//dest->FastQueuePacket(&in, ack_req);
|
||||
}
|
||||
|
||||
ENCODE(OP_ClickObjectAction)
|
||||
@@ -1708,14 +1709,14 @@ namespace RoF
|
||||
|
||||
ENCODE(OP_MoveItem)
|
||||
{
|
||||
ENCODE_LENGTH_EXACT(MoveItem_Struct);
|
||||
SETUP_DIRECT_ENCODE(MoveItem_Struct, structs::MoveItem_Struct);
|
||||
|
||||
eq->from_slot = ServerToRoFSlot(emu->from_slot);
|
||||
eq->to_slot = ServerToRoFSlot(emu->to_slot);
|
||||
OUT(number_in_stack);
|
||||
|
||||
FINISH_ENCODE();
|
||||
//ENCODE_LENGTH_EXACT(MoveItem_Struct);
|
||||
//SETUP_DIRECT_ENCODE(MoveItem_Struct, structs::MoveItem_Struct);
|
||||
//
|
||||
//eq->from_slot = ServerToRoFSlot(emu->from_slot);
|
||||
//eq->to_slot = ServerToRoFSlot(emu->to_slot);
|
||||
//OUT(number_in_stack);
|
||||
//
|
||||
//FINISH_ENCODE();
|
||||
}
|
||||
|
||||
ENCODE(OP_NewSpawn) { ENCODE_FORWARD(OP_ZoneSpawns); }
|
||||
@@ -3065,13 +3066,13 @@ namespace RoF
|
||||
{
|
||||
ENCODE_LENGTH_EXACT(Merchant_Sell_Struct);
|
||||
SETUP_DIRECT_ENCODE(Merchant_Sell_Struct, structs::Merchant_Sell_Struct);
|
||||
|
||||
|
||||
OUT(npcid);
|
||||
OUT(playerid);
|
||||
OUT(itemslot);
|
||||
OUT(quantity);
|
||||
OUT(price);
|
||||
|
||||
|
||||
FINISH_ENCODE();
|
||||
}
|
||||
|
||||
@@ -4703,16 +4704,16 @@ namespace RoF
|
||||
|
||||
DECODE(OP_MoveItem)
|
||||
{
|
||||
DECODE_LENGTH_EXACT(structs::MoveItem_Struct);
|
||||
SETUP_DIRECT_DECODE(MoveItem_Struct, structs::MoveItem_Struct);
|
||||
|
||||
//Log.LogDebugType(Logs::General, Logs::Netcode, "[ERROR] Moved item from %u to %u", eq->from_slot.MainSlot, eq->to_slot.MainSlot);
|
||||
Log.Out(Logs::General, Logs::Netcode, "[RoF] MoveItem SlotType from %i to %i, MainSlot from %i to %i, SubSlot from %i to %i, AugSlot from %i to %i, Unknown01 from %i to %i, Number %u", eq->from_slot.SlotType, eq->to_slot.SlotType, eq->from_slot.MainSlot, eq->to_slot.MainSlot, eq->from_slot.SubSlot, eq->to_slot.SubSlot, eq->from_slot.AugSlot, eq->to_slot.AugSlot, eq->from_slot.Unknown01, eq->to_slot.Unknown01, eq->number_in_stack);
|
||||
emu->from_slot = RoFToServerSlot(eq->from_slot);
|
||||
emu->to_slot = RoFToServerSlot(eq->to_slot);
|
||||
IN(number_in_stack);
|
||||
|
||||
FINISH_DIRECT_DECODE();
|
||||
//DECODE_LENGTH_EXACT(structs::MoveItem_Struct);
|
||||
//SETUP_DIRECT_DECODE(MoveItem_Struct, structs::MoveItem_Struct);
|
||||
//
|
||||
////Log.LogDebugType(Logs::General, Logs::Netcode, "[ERROR] Moved item from %u to %u", eq->from_slot.MainSlot, eq->to_slot.MainSlot);
|
||||
//Log.Out(Logs::General, Logs::Netcode, "[RoF] MoveItem SlotType from %i to %i, MainSlot from %i to %i, SubSlot from %i to %i, AugSlot from %i to %i, Unknown01 from %i to %i, Number %u", eq->from_slot.SlotType, eq->to_slot.SlotType, eq->from_slot.MainSlot, eq->to_slot.MainSlot, eq->from_slot.SubSlot, eq->to_slot.SubSlot, eq->from_slot.AugSlot, eq->to_slot.AugSlot, eq->from_slot.Unknown01, eq->to_slot.Unknown01, eq->number_in_stack);
|
||||
//emu->from_slot = RoFToServerSlot(eq->from_slot);
|
||||
//emu->to_slot = RoFToServerSlot(eq->to_slot);
|
||||
//IN(number_in_stack);
|
||||
//
|
||||
//FINISH_DIRECT_DECODE();
|
||||
}
|
||||
|
||||
DECODE(OP_PetCommands)
|
||||
@@ -4840,13 +4841,13 @@ namespace RoF
|
||||
{
|
||||
DECODE_LENGTH_EXACT(structs::Merchant_Sell_Struct);
|
||||
SETUP_DIRECT_DECODE(Merchant_Sell_Struct, structs::Merchant_Sell_Struct);
|
||||
|
||||
|
||||
IN(npcid);
|
||||
IN(playerid);
|
||||
IN(itemslot);
|
||||
IN(quantity);
|
||||
IN(price);
|
||||
|
||||
|
||||
FINISH_DIRECT_DECODE();
|
||||
}
|
||||
|
||||
@@ -5043,7 +5044,7 @@ namespace RoF
|
||||
|
||||
std::stringstream ss(std::stringstream::in | std::stringstream::out | std::stringstream::binary);
|
||||
|
||||
const Item_Struct *item = inst->GetUnscaledItem();
|
||||
const ItemData *item = inst->GetUnscaledItem();
|
||||
//Log.LogDebugType(Logs::General, Logs::Netcode, "[ERROR] Serialize called for: %s", item->Name);
|
||||
|
||||
RoF::structs::ItemSerializationHeader hdr;
|
||||
@@ -5102,7 +5103,7 @@ namespace RoF
|
||||
ss.write(tmp, strlen(tmp));
|
||||
ss.write((const char*)&null_term, sizeof(uint8));
|
||||
ornaIcon = inst->GetOrnamentationIcon();
|
||||
heroModel = inst->GetOrnamentHeroModel(Inventory::CalcMaterialFromSlot(slot_id_in));
|
||||
heroModel = inst->GetOrnamentHeroModel(InventoryOld::CalcMaterialFromSlot(slot_id_in));
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -5545,7 +5546,7 @@ namespace RoF
|
||||
|
||||
/*
|
||||
// TEST CODE: <watch>
|
||||
SubSlotNumber = Inventory::CalcSlotID(slot_id_in, x);
|
||||
SubSlotNumber = InventoryOld::CalcSlotID(slot_id_in, x);
|
||||
*/
|
||||
|
||||
SubSerializations[x] = SerializeItem(subitem, SubSlotNumber, &SubLengths[x], depth + 1);
|
||||
|
||||
+177
-244
@@ -12,6 +12,8 @@
|
||||
#include "../item.h"
|
||||
#include "rof2_structs.h"
|
||||
#include "../rulesys.h"
|
||||
#include "../memory_buffer.h"
|
||||
#include "../inventory.h"
|
||||
|
||||
#include <iostream>
|
||||
#include <sstream>
|
||||
@@ -24,7 +26,7 @@ namespace RoF2
|
||||
static OpcodeManager *opcodes = nullptr;
|
||||
static Strategy struct_strategy;
|
||||
|
||||
char* SerializeItem(const ItemInst *inst, int16 slot_id, uint32 *length, uint8 depth, ItemPacketType packet_type);
|
||||
void SerializeItem(EQEmu::MemoryBuffer &packet_data, EQEmu::ItemInstance *inst, int container_id, int slot_id, int bag_id, int aug_id);
|
||||
|
||||
// server to client inventory location converters
|
||||
static inline structs::ItemSlotStruct ServerToRoF2Slot(uint32 serverSlot, ItemPacketType PacketType = ItemPacketInvalid);
|
||||
@@ -603,70 +605,39 @@ namespace RoF2
|
||||
{
|
||||
//consume the packet
|
||||
EQApplicationPacket *in = *p;
|
||||
|
||||
*p = nullptr;
|
||||
|
||||
if (in->size == 0) {
|
||||
|
||||
in->size = 4;
|
||||
in->pBuffer = new uchar[in->size];
|
||||
|
||||
*((uint32 *)in->pBuffer) = 0;
|
||||
|
||||
dest->FastQueuePacket(&in, ack_req);
|
||||
return;
|
||||
}
|
||||
|
||||
//store away the emu struct
|
||||
unsigned char *__emu_buffer = in->pBuffer;
|
||||
|
||||
int ItemCount = in->size / sizeof(InternalSerializedItem_Struct);
|
||||
|
||||
if (ItemCount == 0 || (in->size % sizeof(InternalSerializedItem_Struct)) != 0) {
|
||||
size_t entry_size = sizeof(SerializedItemInstance_Struct);
|
||||
size_t entries = (in->size - sizeof(int32)) / entry_size;
|
||||
|
||||
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, sizeof(InternalSerializedItem_Struct));
|
||||
|
||||
opcodes->EmuToName(in->GetOpcode()), (in->size - sizeof(int32)), entry_size);
|
||||
delete in;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
InternalSerializedItem_Struct *eq = (InternalSerializedItem_Struct *)in->pBuffer;
|
||||
unsigned char *__emu_buffer = in->pBuffer;
|
||||
SerializedItemInstance_Struct *sis = (SerializedItemInstance_Struct*)(__emu_buffer + sizeof(int32));
|
||||
EQEmu::MemoryBuffer packet_data;
|
||||
packet_data.Write<uint32>(entries);
|
||||
|
||||
for(size_t i = 0; i < entries; ++i) {
|
||||
EQEmu::ItemInstance *inst = (EQEmu::ItemInstance*)sis[i].inst;
|
||||
|
||||
in->pBuffer = new uchar[4];
|
||||
*(uint32 *)in->pBuffer = ItemCount;
|
||||
in->size = 4;
|
||||
|
||||
for (int r = 0; r < ItemCount; r++, eq++) {
|
||||
|
||||
uint32 Length = 0;
|
||||
|
||||
char* Serialized = SerializeItem((const ItemInst*)eq->inst, eq->slot_id, &Length, 0, ItemPacketCharInventory);
|
||||
|
||||
if (Serialized) {
|
||||
|
||||
uchar *OldBuffer = in->pBuffer;
|
||||
in->pBuffer = new uchar[in->size + Length];
|
||||
memcpy(in->pBuffer, OldBuffer, in->size);
|
||||
|
||||
safe_delete_array(OldBuffer);
|
||||
|
||||
memcpy(in->pBuffer + in->size, Serialized, Length);
|
||||
in->size += Length;
|
||||
|
||||
safe_delete_array(Serialized);
|
||||
}
|
||||
else {
|
||||
Log.Out(Logs::General, Logs::Netcode, "[ERROR] Serialization failed on item slot %d during OP_CharInventory. Item skipped.", eq->slot_id);
|
||||
if(!inst) {
|
||||
continue;
|
||||
}
|
||||
|
||||
SerializeItem(packet_data, inst, sis[i].container_id, sis[i].slot_id, -1, -1);
|
||||
}
|
||||
|
||||
in->pBuffer = new uchar[packet_data.Size()];
|
||||
in->size = packet_data.Size();
|
||||
memcpy(in->pBuffer, packet_data, in->size);
|
||||
|
||||
|
||||
delete[] __emu_buffer;
|
||||
|
||||
//Log.LogDebugType(Logs::General, Logs::Netcode, "[ERROR] Sending inventory to client");
|
||||
//Log.Hex(Logs::Netcode, in->pBuffer, in->size);
|
||||
|
||||
dest->FastQueuePacket(&in, ack_req);
|
||||
}
|
||||
|
||||
@@ -1526,30 +1497,40 @@ namespace RoF2
|
||||
|
||||
ENCODE(OP_ItemPacket)
|
||||
{
|
||||
//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);
|
||||
size_t entry_size = sizeof(SerializedItemInstance_Struct);
|
||||
size_t entries = (in->size - sizeof(int32)) / entry_size;
|
||||
|
||||
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);
|
||||
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;
|
||||
}
|
||||
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);
|
||||
|
||||
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;
|
||||
safe_delete_array(serialized);
|
||||
dest->FastQueuePacket(&in, ack_req);
|
||||
}
|
||||
|
||||
@@ -1782,9 +1763,15 @@ namespace RoF2
|
||||
ENCODE_LENGTH_EXACT(MoveItem_Struct);
|
||||
SETUP_DIRECT_ENCODE(MoveItem_Struct, structs::MoveItem_Struct);
|
||||
|
||||
eq->from_slot = ServerToRoF2Slot(emu->from_slot);
|
||||
eq->to_slot = ServerToRoF2Slot(emu->to_slot);
|
||||
OUT(number_in_stack);
|
||||
eq->from_slot.SlotType = emu->from_type;
|
||||
eq->from_slot.MainSlot = emu->from_slot;
|
||||
eq->from_slot.SubSlot = emu->from_bag_slot;
|
||||
eq->from_slot.AugSlot = emu->from_aug_slot;
|
||||
eq->to_slot.SlotType = emu->to_type;
|
||||
eq->to_slot.MainSlot = emu->to_slot;
|
||||
eq->to_slot.SubSlot = emu->to_bag_slot;
|
||||
eq->to_slot.AugSlot = emu->to_aug_slot;
|
||||
eq->number_in_stack = emu->number_in_stack;
|
||||
|
||||
FINISH_ENCODE();
|
||||
}
|
||||
@@ -4854,11 +4841,16 @@ namespace RoF2
|
||||
DECODE_LENGTH_EXACT(structs::MoveItem_Struct);
|
||||
SETUP_DIRECT_DECODE(MoveItem_Struct, structs::MoveItem_Struct);
|
||||
|
||||
Log.Out(Logs::General, Logs::Netcode, "[RoF2] MoveItem SlotType from %i to %i, MainSlot from %i to %i, SubSlot from %i to %i, AugSlot from %i to %i, Unknown01 from %i to %i, Number %u", eq->from_slot.SlotType, eq->to_slot.SlotType, eq->from_slot.MainSlot, eq->to_slot.MainSlot, eq->from_slot.SubSlot, eq->to_slot.SubSlot, eq->from_slot.AugSlot, eq->to_slot.AugSlot, eq->from_slot.Unknown01, eq->to_slot.Unknown01, eq->number_in_stack);
|
||||
emu->from_slot = RoF2ToServerSlot(eq->from_slot);
|
||||
emu->to_slot = RoF2ToServerSlot(eq->to_slot);
|
||||
IN(number_in_stack);
|
||||
|
||||
emu->from_type = eq->from_slot.SlotType;
|
||||
emu->from_slot = eq->from_slot.MainSlot;
|
||||
emu->from_bag_slot = eq->from_slot.SubSlot;
|
||||
emu->from_aug_slot = eq->from_slot.AugSlot;
|
||||
emu->to_type = eq->to_slot.SlotType;
|
||||
emu->to_slot = eq->to_slot.MainSlot;
|
||||
emu->to_bag_slot = eq->to_slot.SubSlot;
|
||||
emu->to_aug_slot = eq->to_slot.AugSlot;
|
||||
emu->number_in_stack = eq->number_in_stack;
|
||||
|
||||
FINISH_DIRECT_DECODE();
|
||||
}
|
||||
|
||||
@@ -5233,51 +5225,43 @@ namespace RoF2
|
||||
return NextItemInstSerialNumber;
|
||||
}
|
||||
|
||||
char* SerializeItem(const ItemInst *inst, int16 slot_id_in, uint32 *length, uint8 depth, ItemPacketType packet_type)
|
||||
{
|
||||
int ornamentationAugtype = RuleI(Character, OrnamentationAugmentType);
|
||||
void SerializeItem(EQEmu::MemoryBuffer &packet_data, EQEmu::ItemInstance *inst, int container_id, int slot_id, int bag_id, int aug_id) {
|
||||
int ornamentation_augtype = RuleI(Character, OrnamentationAugmentType);
|
||||
uint8 null_term = 0;
|
||||
bool stackable = inst->IsStackable();
|
||||
uint32 merchant_slot = inst->GetMerchantSlot();
|
||||
uint32 charges = inst->GetCharges();
|
||||
if (!stackable && charges > 254)
|
||||
charges = 0xFFFFFFFF;
|
||||
|
||||
std::stringstream ss(std::stringstream::in | std::stringstream::out | std::stringstream::binary);
|
||||
|
||||
const Item_Struct *item = inst->GetUnscaledItem();
|
||||
//Log.LogDebugType(Logs::General, Logs::Netcode, "[ERROR] Serialize called for: %s", item->Name);
|
||||
|
||||
const ItemData *item = inst->GetBaseItem();
|
||||
RoF2::structs::ItemSerializationHeader hdr;
|
||||
|
||||
//sprintf(hdr.unknown000, "06e0002Y1W00");
|
||||
|
||||
snprintf(hdr.unknown000, sizeof(hdr.unknown000), "%016d", item->ID);
|
||||
snprintf(hdr.tracking_id, sizeof(hdr.tracking_id), "%016d", inst->GetSerialNumber());
|
||||
|
||||
hdr.stacksize = stackable ? charges : 1;
|
||||
hdr.unknown004 = 0;
|
||||
|
||||
structs::ItemSlotStruct slot_id = ServerToRoF2Slot(slot_id_in, packet_type);
|
||||
hdr.slot_type = (merchant_slot == 0) ? container_id : 9; // 9 is merchant 20 is reclaim items?
|
||||
hdr.main_slot = (merchant_slot == 0) ? slot_id : merchant_slot;
|
||||
hdr.sub_slot = (merchant_slot == 0) ? bag_id : 0xffff;
|
||||
hdr.aug_slot = (merchant_slot == 0) ? aug_id : 0xffff;
|
||||
|
||||
hdr.slot_type = (merchant_slot == 0) ? slot_id.SlotType : 9; // 9 is merchant 20 is reclaim items?
|
||||
hdr.main_slot = (merchant_slot == 0) ? slot_id.MainSlot : merchant_slot;
|
||||
hdr.sub_slot = (merchant_slot == 0) ? slot_id.SubSlot : 0xffff;
|
||||
hdr.aug_slot = (merchant_slot == 0) ? slot_id.AugSlot : 0xffff;
|
||||
hdr.price = inst->GetPrice();
|
||||
hdr.merchant_slot = (merchant_slot == 0) ? 1 : inst->GetMerchantCount();
|
||||
hdr.scaled_value = inst->IsScaling() ? inst->GetExp() / 100 : 0;
|
||||
//hdr.scaled_value = inst->IsScaling() ? inst->GetExp() / 100 : 0;
|
||||
hdr.scaled_value = 0;
|
||||
|
||||
hdr.instance_id = (merchant_slot == 0) ? inst->GetSerialNumber() : merchant_slot;
|
||||
hdr.unknown028 = 0;
|
||||
hdr.last_cast_time = inst->GetRecastTimestamp();
|
||||
hdr.charges = (stackable ? (item->MaxCharges ? 1 : 0) : charges);
|
||||
hdr.inst_nodrop = inst->IsAttuned() ? 1 : 0;
|
||||
hdr.inst_nodrop = inst->GetAttuned() ? 1 : 0;
|
||||
hdr.unknown044 = 0;
|
||||
hdr.unknown048 = 0;
|
||||
hdr.unknown052 = 0;
|
||||
hdr.isEvolving = item->EvolvingLevel > 0 ? 1 : 0;
|
||||
ss.write((const char*)&hdr, sizeof(RoF2::structs::ItemSerializationHeader));
|
||||
packet_data.Write((const char*)&hdr, sizeof(RoF2::structs::ItemSerializationHeader));
|
||||
|
||||
if (item->EvolvingLevel > 0) {
|
||||
if(item->EvolvingLevel > 0) {
|
||||
RoF2::structs::EvolvingItem evotop;
|
||||
evotop.unknown001 = 0;
|
||||
evotop.unknown002 = 0;
|
||||
@@ -5287,74 +5271,75 @@ namespace RoF2
|
||||
evotop.progress = 95.512;
|
||||
evotop.Activated = 1;
|
||||
evotop.evomaxlevel = 7;
|
||||
ss.write((const char*)&evotop, sizeof(RoF2::structs::EvolvingItem));
|
||||
packet_data.Write((const char*)&evotop, sizeof(RoF2::structs::EvolvingItem));
|
||||
}
|
||||
//ORNAMENT IDFILE / ICON
|
||||
uint32 ornaIcon = 0;
|
||||
uint32 heroModel = 0;
|
||||
|
||||
if (inst->GetOrnamentationIDFile() && inst->GetOrnamentationIcon())
|
||||
uint32 orn_icon = 0;
|
||||
uint32 hero_model = 0;
|
||||
|
||||
if(inst->GetOrnamentIDFile() && inst->GetOrnamentIcon())
|
||||
{
|
||||
char tmp[30]; memset(tmp, 0x0, 30); sprintf(tmp, "IT%d", inst->GetOrnamentationIDFile());
|
||||
char tmp[30] = { 0 };
|
||||
sprintf(tmp, "IT%d", inst->GetOrnamentIDFile());
|
||||
//Mainhand
|
||||
ss.write(tmp, strlen(tmp));
|
||||
ss.write((const char*)&null_term, sizeof(uint8));
|
||||
packet_data.Write(tmp, strlen(tmp));
|
||||
packet_data.Write((const char*)&null_term, sizeof(uint8));
|
||||
//Offhand
|
||||
ss.write(tmp, strlen(tmp));
|
||||
ss.write((const char*)&null_term, sizeof(uint8));
|
||||
ornaIcon = inst->GetOrnamentationIcon();
|
||||
heroModel = inst->GetOrnamentHeroModel(Inventory::CalcMaterialFromSlot(slot_id_in));
|
||||
packet_data.Write(tmp, strlen(tmp));
|
||||
packet_data.Write((const char*)&null_term, sizeof(uint8));
|
||||
orn_icon = inst->GetOrnamentIcon();
|
||||
hero_model = inst->GetOrnamentHeroModel(EQEmu::Inventory::CalcMaterialFromSlot(EQEmu::InventorySlot(container_id, slot_id)));
|
||||
}
|
||||
else
|
||||
{
|
||||
ss.write((const char*)&null_term, sizeof(uint8)); // no main hand Ornamentation
|
||||
ss.write((const char*)&null_term, sizeof(uint8)); // no off hand Ornamentation
|
||||
packet_data.Write((const char*)&null_term, sizeof(uint8)); // no main hand Ornamentation
|
||||
packet_data.Write((const char*)&null_term, sizeof(uint8)); // no off hand Ornamentation
|
||||
}
|
||||
|
||||
RoF2::structs::ItemSerializationHeaderFinish hdrf;
|
||||
hdrf.ornamentIcon = ornaIcon;
|
||||
hdrf.ornamentIcon = orn_icon;
|
||||
hdrf.unknowna1 = 0xffffffff;
|
||||
hdrf.ornamentHeroModel = heroModel;
|
||||
hdrf.ornamentHeroModel = hero_model;
|
||||
hdrf.unknown063 = 0;
|
||||
hdrf.Copied = 0;
|
||||
hdrf.unknowna4 = 0xffffffff;
|
||||
hdrf.unknowna5 = 0;
|
||||
hdrf.ItemClass = item->ItemClass;
|
||||
|
||||
ss.write((const char*)&hdrf, sizeof(RoF2::structs::ItemSerializationHeaderFinish));
|
||||
packet_data.Write((const char*)&hdrf, sizeof(RoF2::structs::ItemSerializationHeaderFinish));
|
||||
|
||||
if (strlen(item->Name) > 0)
|
||||
if(strlen(item->Name) > 0)
|
||||
{
|
||||
ss.write(item->Name, strlen(item->Name));
|
||||
ss.write((const char*)&null_term, sizeof(uint8));
|
||||
packet_data.Write(item->Name, strlen(item->Name));
|
||||
packet_data.Write((const char*)&null_term, sizeof(uint8));
|
||||
}
|
||||
else
|
||||
{
|
||||
ss.write((const char*)&null_term, sizeof(uint8));
|
||||
packet_data.Write((const char*)&null_term, sizeof(uint8));
|
||||
}
|
||||
|
||||
if (strlen(item->Lore) > 0)
|
||||
if(strlen(item->Lore) > 0)
|
||||
{
|
||||
ss.write(item->Lore, strlen(item->Lore));
|
||||
ss.write((const char*)&null_term, sizeof(uint8));
|
||||
packet_data.Write(item->Lore, strlen(item->Lore));
|
||||
packet_data.Write((const char*)&null_term, sizeof(uint8));
|
||||
}
|
||||
else
|
||||
{
|
||||
ss.write((const char*)&null_term, sizeof(uint8));
|
||||
packet_data.Write((const char*)&null_term, sizeof(uint8));
|
||||
}
|
||||
|
||||
if (strlen(item->IDFile) > 0)
|
||||
if(strlen(item->IDFile) > 0)
|
||||
{
|
||||
ss.write(item->IDFile, strlen(item->IDFile));
|
||||
ss.write((const char*)&null_term, sizeof(uint8));
|
||||
packet_data.Write(item->IDFile, strlen(item->IDFile));
|
||||
packet_data.Write((const char*)&null_term, sizeof(uint8));
|
||||
}
|
||||
else
|
||||
{
|
||||
ss.write((const char*)&null_term, sizeof(uint8));
|
||||
packet_data.Write((const char*)&null_term, sizeof(uint8));
|
||||
}
|
||||
|
||||
ss.write((const char*)&null_term, sizeof(uint8));
|
||||
//Log.LogDebugType(Logs::General, Logs::Netcode, "[ERROR] ItemBody struct is %i bytes", sizeof(RoF2::structs::ItemBodyStruct));
|
||||
packet_data.Write((const char*)&null_term, sizeof(uint8));
|
||||
|
||||
RoF2::structs::ItemBodyStruct ibs;
|
||||
memset(&ibs, 0, sizeof(RoF2::structs::ItemBodyStruct));
|
||||
|
||||
@@ -5406,10 +5391,10 @@ namespace RoF2
|
||||
ibs.Magic = item->Magic;
|
||||
ibs.CastTime_ = item->CastTime_;
|
||||
ibs.ReqLevel = item->ReqLevel;
|
||||
if (item->ReqLevel > 100)
|
||||
if(item->ReqLevel > 100)
|
||||
ibs.ReqLevel = 100;
|
||||
ibs.RecLevel = item->RecLevel;
|
||||
if (item->RecLevel > 100)
|
||||
if(item->RecLevel > 100)
|
||||
ibs.RecLevel = 100;
|
||||
ibs.RecSkill = item->RecSkill;
|
||||
ibs.BardType = item->BardType;
|
||||
@@ -5448,20 +5433,19 @@ namespace RoF2
|
||||
ibs.FactionAmt4 = item->FactionAmt4;
|
||||
ibs.FactionMod4 = item->FactionMod4;
|
||||
|
||||
ss.write((const char*)&ibs, sizeof(RoF2::structs::ItemBodyStruct));
|
||||
packet_data.Write((const char*)&ibs, sizeof(RoF2::structs::ItemBodyStruct));
|
||||
|
||||
//charm text
|
||||
if (strlen(item->CharmFile) > 0)
|
||||
if(strlen(item->CharmFile) > 0)
|
||||
{
|
||||
ss.write((const char*)item->CharmFile, strlen(item->CharmFile));
|
||||
ss.write((const char*)&null_term, sizeof(uint8));
|
||||
packet_data.Write((const char*)item->CharmFile, strlen(item->CharmFile));
|
||||
packet_data.Write((const char*)&null_term, sizeof(uint8));
|
||||
}
|
||||
else
|
||||
{
|
||||
ss.write((const char*)&null_term, sizeof(uint8));
|
||||
packet_data.Write((const char*)&null_term, sizeof(uint8));
|
||||
}
|
||||
|
||||
//Log.LogDebugType(Logs::General, Logs::Netcode, "[ERROR] ItemBody secondary struct is %i bytes", sizeof(RoF2::structs::ItemSecondaryBodyStruct));
|
||||
RoF2::structs::ItemSecondaryBodyStruct isbs;
|
||||
memset(&isbs, 0, sizeof(RoF2::structs::ItemSecondaryBodyStruct));
|
||||
|
||||
@@ -5469,7 +5453,7 @@ namespace RoF2
|
||||
isbs.augrestrict2 = -1;
|
||||
isbs.augrestrict = item->AugRestrict;
|
||||
|
||||
for (int x = AUG_BEGIN; x < consts::ITEM_COMMON_SIZE; x++)
|
||||
for(int x = AUG_BEGIN; x < consts::ITEM_COMMON_SIZE; x++)
|
||||
{
|
||||
isbs.augslots[x].type = item->AugSlotType[x];
|
||||
isbs.augslots[x].visible = item->AugSlotVisible[x];
|
||||
@@ -5490,19 +5474,18 @@ namespace RoF2
|
||||
isbs.book = item->Book;
|
||||
isbs.booktype = item->BookType;
|
||||
|
||||
ss.write((const char*)&isbs, sizeof(RoF2::structs::ItemSecondaryBodyStruct));
|
||||
packet_data.Write((const char*)&isbs, sizeof(RoF2::structs::ItemSecondaryBodyStruct));
|
||||
|
||||
if (strlen(item->Filename) > 0)
|
||||
if(strlen(item->Filename) > 0)
|
||||
{
|
||||
ss.write((const char*)item->Filename, strlen(item->Filename));
|
||||
ss.write((const char*)&null_term, sizeof(uint8));
|
||||
packet_data.Write((const char*)item->Filename, strlen(item->Filename));
|
||||
packet_data.Write((const char*)&null_term, sizeof(uint8));
|
||||
}
|
||||
else
|
||||
{
|
||||
ss.write((const char*)&null_term, sizeof(uint8));
|
||||
packet_data.Write((const char*)&null_term, sizeof(uint8));
|
||||
}
|
||||
|
||||
//Log.LogDebugType(Logs::General, Logs::Netcode, "[ERROR] ItemBody tertiary struct is %i bytes", sizeof(RoF2::structs::ItemTertiaryBodyStruct));
|
||||
RoF2::structs::ItemTertiaryBodyStruct itbs;
|
||||
memset(&itbs, 0, sizeof(RoF2::structs::ItemTertiaryBodyStruct));
|
||||
|
||||
@@ -5536,12 +5519,11 @@ namespace RoF2
|
||||
itbs.unknown13 = 0;
|
||||
itbs.unknown14 = 0;
|
||||
|
||||
ss.write((const char*)&itbs, sizeof(RoF2::structs::ItemTertiaryBodyStruct));
|
||||
packet_data.Write((const char*)&itbs, sizeof(RoF2::structs::ItemTertiaryBodyStruct));
|
||||
|
||||
// Effect Structures Broken down to allow variable length strings for effect names
|
||||
int32 effect_unknown = 0;
|
||||
|
||||
//Log.LogDebugType(Logs::General, Logs::Netcode, "[ERROR] ItemBody Click effect struct is %i bytes", sizeof(RoF2::structs::ClickEffectStruct));
|
||||
RoF2::structs::ClickEffectStruct ices;
|
||||
memset(&ices, 0, sizeof(RoF2::structs::ClickEffectStruct));
|
||||
|
||||
@@ -5554,21 +5536,20 @@ namespace RoF2
|
||||
ices.recast = item->RecastDelay;
|
||||
ices.recast_type = item->RecastType;
|
||||
|
||||
ss.write((const char*)&ices, sizeof(RoF2::structs::ClickEffectStruct));
|
||||
packet_data.Write((const char*)&ices, sizeof(RoF2::structs::ClickEffectStruct));
|
||||
|
||||
if (strlen(item->ClickName) > 0)
|
||||
if(strlen(item->ClickName) > 0)
|
||||
{
|
||||
ss.write((const char*)item->ClickName, strlen(item->ClickName));
|
||||
ss.write((const char*)&null_term, sizeof(uint8));
|
||||
packet_data.Write((const char*)item->ClickName, strlen(item->ClickName));
|
||||
packet_data.Write((const char*)&null_term, sizeof(uint8));
|
||||
}
|
||||
else
|
||||
{
|
||||
ss.write((const char*)&null_term, sizeof(uint8));
|
||||
packet_data.Write((const char*)&null_term, sizeof(uint8));
|
||||
}
|
||||
|
||||
ss.write((const char*)&effect_unknown, sizeof(int32)); // clickunk7
|
||||
packet_data.Write((const char*)&effect_unknown, sizeof(int32)); // clickunk7
|
||||
|
||||
//Log.LogDebugType(Logs::General, Logs::Netcode, "[ERROR] ItemBody proc effect struct is %i bytes", sizeof(RoF2::structs::ProcEffectStruct));
|
||||
RoF2::structs::ProcEffectStruct ipes;
|
||||
memset(&ipes, 0, sizeof(RoF2::structs::ProcEffectStruct));
|
||||
|
||||
@@ -5578,21 +5559,20 @@ namespace RoF2
|
||||
ipes.level = item->Proc.Level;
|
||||
ipes.procrate = item->ProcRate;
|
||||
|
||||
ss.write((const char*)&ipes, sizeof(RoF2::structs::ProcEffectStruct));
|
||||
packet_data.Write((const char*)&ipes, sizeof(RoF2::structs::ProcEffectStruct));
|
||||
|
||||
if (strlen(item->ProcName) > 0)
|
||||
if(strlen(item->ProcName) > 0)
|
||||
{
|
||||
ss.write((const char*)item->ProcName, strlen(item->ProcName));
|
||||
ss.write((const char*)&null_term, sizeof(uint8));
|
||||
packet_data.Write((const char*)item->ProcName, strlen(item->ProcName));
|
||||
packet_data.Write((const char*)&null_term, sizeof(uint8));
|
||||
}
|
||||
else
|
||||
{
|
||||
ss.write((const char*)&null_term, sizeof(uint8));
|
||||
packet_data.Write((const char*)&null_term, sizeof(uint8));
|
||||
}
|
||||
|
||||
ss.write((const char*)&effect_unknown, sizeof(int32)); // unknown5
|
||||
packet_data.Write((const char*)&effect_unknown, sizeof(int32)); // unknown5
|
||||
|
||||
//Log.LogDebugType(Logs::General, Logs::Netcode, "[ERROR] ItemBody worn effect struct is %i bytes", sizeof(RoF2::structs::WornEffectStruct));
|
||||
RoF2::structs::WornEffectStruct iwes;
|
||||
memset(&iwes, 0, sizeof(RoF2::structs::WornEffectStruct));
|
||||
|
||||
@@ -5601,19 +5581,19 @@ namespace RoF2
|
||||
iwes.type = item->Worn.Type;
|
||||
iwes.level = item->Worn.Level;
|
||||
|
||||
ss.write((const char*)&iwes, sizeof(RoF2::structs::WornEffectStruct));
|
||||
packet_data.Write((const char*)&iwes, sizeof(RoF2::structs::WornEffectStruct));
|
||||
|
||||
if (strlen(item->WornName) > 0)
|
||||
if(strlen(item->WornName) > 0)
|
||||
{
|
||||
ss.write((const char*)item->WornName, strlen(item->WornName));
|
||||
ss.write((const char*)&null_term, sizeof(uint8));
|
||||
packet_data.Write((const char*)item->WornName, strlen(item->WornName));
|
||||
packet_data.Write((const char*)&null_term, sizeof(uint8));
|
||||
}
|
||||
else
|
||||
{
|
||||
ss.write((const char*)&null_term, sizeof(uint8));
|
||||
packet_data.Write((const char*)&null_term, sizeof(uint8));
|
||||
}
|
||||
|
||||
ss.write((const char*)&effect_unknown, sizeof(int32)); // unknown6
|
||||
packet_data.Write((const char*)&effect_unknown, sizeof(int32)); // unknown6
|
||||
|
||||
RoF2::structs::WornEffectStruct ifes;
|
||||
memset(&ifes, 0, sizeof(RoF2::structs::WornEffectStruct));
|
||||
@@ -5623,19 +5603,19 @@ namespace RoF2
|
||||
ifes.type = item->Focus.Type;
|
||||
ifes.level = item->Focus.Level;
|
||||
|
||||
ss.write((const char*)&ifes, sizeof(RoF2::structs::WornEffectStruct));
|
||||
packet_data.Write((const char*)&ifes, sizeof(RoF2::structs::WornEffectStruct));
|
||||
|
||||
if (strlen(item->FocusName) > 0)
|
||||
if(strlen(item->FocusName) > 0)
|
||||
{
|
||||
ss.write((const char*)item->FocusName, strlen(item->FocusName));
|
||||
ss.write((const char*)&null_term, sizeof(uint8));
|
||||
packet_data.Write((const char*)item->FocusName, strlen(item->FocusName));
|
||||
packet_data.Write((const char*)&null_term, sizeof(uint8));
|
||||
}
|
||||
else
|
||||
{
|
||||
ss.write((const char*)&null_term, sizeof(uint8));
|
||||
packet_data.Write((const char*)&null_term, sizeof(uint8));
|
||||
}
|
||||
|
||||
ss.write((const char*)&effect_unknown, sizeof(int32)); // unknown6
|
||||
packet_data.Write((const char*)&effect_unknown, sizeof(int32)); // unknown6
|
||||
|
||||
RoF2::structs::WornEffectStruct ises;
|
||||
memset(&ises, 0, sizeof(RoF2::structs::WornEffectStruct));
|
||||
@@ -5645,19 +5625,19 @@ namespace RoF2
|
||||
ises.type = item->Scroll.Type;
|
||||
ises.level = item->Scroll.Level;
|
||||
|
||||
ss.write((const char*)&ises, sizeof(RoF2::structs::WornEffectStruct));
|
||||
packet_data.Write((const char*)&ises, sizeof(RoF2::structs::WornEffectStruct));
|
||||
|
||||
if (strlen(item->ScrollName) > 0)
|
||||
if(strlen(item->ScrollName) > 0)
|
||||
{
|
||||
ss.write((const char*)item->ScrollName, strlen(item->ScrollName));
|
||||
ss.write((const char*)&null_term, sizeof(uint8));
|
||||
packet_data.Write((const char*)item->ScrollName, strlen(item->ScrollName));
|
||||
packet_data.Write((const char*)&null_term, sizeof(uint8));
|
||||
}
|
||||
else
|
||||
{
|
||||
ss.write((const char*)&null_term, sizeof(uint8));
|
||||
packet_data.Write((const char*)&null_term, sizeof(uint8));
|
||||
}
|
||||
|
||||
ss.write((const char*)&effect_unknown, sizeof(int32)); // unknown6
|
||||
packet_data.Write((const char*)&effect_unknown, sizeof(int32)); // unknown6
|
||||
|
||||
// Bard Effect?
|
||||
RoF2::structs::WornEffectStruct ibes;
|
||||
@@ -5669,21 +5649,13 @@ namespace RoF2
|
||||
ibes.level = item->Bard.Level;
|
||||
//ibes.unknown6 = 0xffffffff;
|
||||
|
||||
ss.write((const char*)&ibes, sizeof(RoF2::structs::WornEffectStruct));
|
||||
packet_data.Write((const char*)&ibes, sizeof(RoF2::structs::WornEffectStruct));
|
||||
|
||||
/*
|
||||
if(strlen(item->BardName) > 0)
|
||||
{
|
||||
ss.write((const char*)item->BardName, strlen(item->BardName));
|
||||
ss.write((const char*)&null_term, sizeof(uint8));
|
||||
}
|
||||
else */
|
||||
ss.write((const char*)&null_term, sizeof(uint8));
|
||||
packet_data.Write((const char*)&null_term, sizeof(uint8));
|
||||
|
||||
ss.write((const char*)&effect_unknown, sizeof(int32)); // unknown6
|
||||
packet_data.Write((const char*)&effect_unknown, sizeof(int32)); // unknown6
|
||||
// End of Effects
|
||||
|
||||
//Log.LogDebugType(Logs::General, Logs::Netcode, "[ERROR] ItemBody Quaternary effect struct is %i bytes", sizeof(RoF2::structs::ItemQuaternaryBodyStruct));
|
||||
RoF2::structs::ItemQuaternaryBodyStruct iqbs;
|
||||
memset(&iqbs, 0, sizeof(RoF2::structs::ItemQuaternaryBodyStruct));
|
||||
|
||||
@@ -5727,65 +5699,26 @@ namespace RoF2
|
||||
|
||||
iqbs.unknown39 = 1;
|
||||
|
||||
iqbs.subitem_count = 0;
|
||||
EQEmu::ItemContainer *container = inst->GetContainer();
|
||||
if(container) {
|
||||
iqbs.subitem_count = container->Size();
|
||||
packet_data.Write((const char*)&iqbs, sizeof(RoF2::structs::ItemQuaternaryBodyStruct));
|
||||
|
||||
char *SubSerializations[10]; // <watch>
|
||||
|
||||
uint32 SubLengths[10];
|
||||
|
||||
for (int x = SUB_BEGIN; x < EmuConstants::ITEM_CONTAINER_SIZE; ++x) {
|
||||
|
||||
SubSerializations[x] = nullptr;
|
||||
|
||||
const ItemInst* subitem = ((const ItemInst*)inst)->GetItem(x);
|
||||
|
||||
if (subitem) {
|
||||
|
||||
int SubSlotNumber;
|
||||
|
||||
iqbs.subitem_count++;
|
||||
|
||||
if (slot_id_in >= EmuConstants::GENERAL_BEGIN && slot_id_in <= EmuConstants::GENERAL_END) // (< 30) - no cursor?
|
||||
//SubSlotNumber = (((slot_id_in + 3) * 10) + x + 1);
|
||||
SubSlotNumber = (((slot_id_in + 3) * EmuConstants::ITEM_CONTAINER_SIZE) + x + 1);
|
||||
else if (slot_id_in >= EmuConstants::BANK_BEGIN && slot_id_in <= EmuConstants::BANK_END)
|
||||
//SubSlotNumber = (((slot_id_in - 2000) * 10) + 2030 + x + 1);
|
||||
SubSlotNumber = (((slot_id_in - EmuConstants::BANK_BEGIN) * EmuConstants::ITEM_CONTAINER_SIZE) + EmuConstants::BANK_BAGS_BEGIN + x);
|
||||
else if (slot_id_in >= EmuConstants::SHARED_BANK_BEGIN && slot_id_in <= EmuConstants::SHARED_BANK_END)
|
||||
//SubSlotNumber = (((slot_id_in - 2500) * 10) + 2530 + x + 1);
|
||||
SubSlotNumber = (((slot_id_in - EmuConstants::SHARED_BANK_BEGIN) * EmuConstants::ITEM_CONTAINER_SIZE) + EmuConstants::SHARED_BANK_BAGS_BEGIN + x);
|
||||
else
|
||||
SubSlotNumber = slot_id_in; // ???????
|
||||
|
||||
/*
|
||||
// TEST CODE: <watch>
|
||||
SubSlotNumber = Inventory::CalcSlotID(slot_id_in, x);
|
||||
*/
|
||||
|
||||
SubSerializations[x] = SerializeItem(subitem, SubSlotNumber, &SubLengths[x], depth + 1, packet_type);
|
||||
auto iter = container->Begin();
|
||||
auto end = container->End();
|
||||
while(iter != end) {
|
||||
auto sub_inst = inst->Get(iter->first);
|
||||
if(sub_inst) {
|
||||
uint32 bag_slot = iter->first;
|
||||
packet_data.Write((const char*)&bag_slot, sizeof(uint32));
|
||||
SerializeItem(packet_data, sub_inst.get(), container_id, slot_id, bag_slot, -1);
|
||||
}
|
||||
++iter;
|
||||
}
|
||||
} else {
|
||||
iqbs.subitem_count = 0;
|
||||
packet_data.Write((const char*)&iqbs, sizeof(RoF2::structs::ItemQuaternaryBodyStruct));
|
||||
}
|
||||
|
||||
ss.write((const char*)&iqbs, sizeof(RoF2::structs::ItemQuaternaryBodyStruct));
|
||||
|
||||
for (int x = SUB_BEGIN; x < EmuConstants::ITEM_CONTAINER_SIZE; ++x) {
|
||||
|
||||
if (SubSerializations[x]) {
|
||||
|
||||
ss.write((const char*)&x, sizeof(uint32));
|
||||
|
||||
ss.write(SubSerializations[x], SubLengths[x]);
|
||||
|
||||
safe_delete_array(SubSerializations[x]);
|
||||
}
|
||||
}
|
||||
|
||||
char* item_serial = new char[ss.tellp()];
|
||||
memset(item_serial, 0, ss.tellp());
|
||||
memcpy(item_serial, ss.str().c_str(), ss.tellp());
|
||||
|
||||
*length = ss.tellp();
|
||||
return item_serial;
|
||||
}
|
||||
|
||||
static inline structs::ItemSlotStruct ServerToRoF2Slot(uint32 serverSlot, ItemPacketType PacketType)
|
||||
|
||||
@@ -2310,7 +2310,7 @@ struct AdventureLeaderboard_Struct
|
||||
/*struct Item_Shop_Struct {
|
||||
uint16 merchantid;
|
||||
uint8 itemtype;
|
||||
Item_Struct item;
|
||||
ItemData item;
|
||||
uint8 iss_unknown001[6];
|
||||
};*/
|
||||
|
||||
@@ -4406,7 +4406,7 @@ struct RoF2SlotStruct
|
||||
|
||||
struct ItemSerializationHeader
|
||||
{
|
||||
/*000*/ char unknown000[17]; // New for HoT. Looks like a string.
|
||||
/*000*/ char tracking_id[17]; // New for HoT. Looks like a string.
|
||||
/*017*/ uint32 stacksize;
|
||||
/*021*/ uint32 unknown004;
|
||||
/*025*/ uint8 slot_type; // 0 = normal, 1 = bank, 2 = shared bank, 9 = merchant, 20 = ?
|
||||
|
||||
@@ -2338,7 +2338,7 @@ struct AdventureLeaderboard_Struct
|
||||
/*struct Item_Shop_Struct {
|
||||
uint16 merchantid;
|
||||
uint8 itemtype;
|
||||
Item_Struct item;
|
||||
ItemData item;
|
||||
uint8 iss_unknown001[6];
|
||||
};*/
|
||||
|
||||
|
||||
+85
-84
@@ -336,71 +336,72 @@ namespace SoD
|
||||
{
|
||||
//consume the packet
|
||||
EQApplicationPacket *in = *p;
|
||||
delete in;
|
||||
|
||||
*p = nullptr;
|
||||
|
||||
if (in->size == 0) {
|
||||
|
||||
in->size = 4;
|
||||
|
||||
in->pBuffer = new uchar[in->size];
|
||||
|
||||
*((uint32 *)in->pBuffer) = 0;
|
||||
|
||||
dest->FastQueuePacket(&in, ack_req);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
//store away the emu struct
|
||||
unsigned char *__emu_buffer = in->pBuffer;
|
||||
|
||||
int ItemCount = in->size / sizeof(InternalSerializedItem_Struct);
|
||||
|
||||
if (ItemCount == 0 || (in->size % sizeof(InternalSerializedItem_Struct)) != 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(InternalSerializedItem_Struct));
|
||||
|
||||
delete in;
|
||||
return;
|
||||
}
|
||||
|
||||
InternalSerializedItem_Struct *eq = (InternalSerializedItem_Struct *)in->pBuffer;
|
||||
in->pBuffer = new uchar[4];
|
||||
*(uint32 *)in->pBuffer = ItemCount;
|
||||
in->size = 4;
|
||||
|
||||
for (int r = 0; r < ItemCount; r++, eq++) {
|
||||
|
||||
uint32 Length = 0;
|
||||
char* Serialized = SerializeItem((const ItemInst*)eq->inst, eq->slot_id, &Length, 0);
|
||||
|
||||
if (Serialized) {
|
||||
|
||||
uchar *OldBuffer = in->pBuffer;
|
||||
in->pBuffer = new uchar[in->size + Length];
|
||||
memcpy(in->pBuffer, OldBuffer, in->size);
|
||||
|
||||
safe_delete_array(OldBuffer);
|
||||
|
||||
memcpy(in->pBuffer + in->size, Serialized, Length);
|
||||
in->size += Length;
|
||||
|
||||
safe_delete_array(Serialized);
|
||||
|
||||
}
|
||||
else {
|
||||
Log.Out(Logs::General, Logs::Netcode, "[ERROR] Serialization failed on item slot %d during OP_CharInventory. Item skipped.", eq->slot_id);
|
||||
}
|
||||
}
|
||||
|
||||
delete[] __emu_buffer;
|
||||
|
||||
//Log.LogDebugType(Logs::General, Logs::Netcode, "[ERROR] Sending inventory to client");
|
||||
//Log.Hex(Logs::Netcode, in->pBuffer, in->size);
|
||||
|
||||
dest->FastQueuePacket(&in, ack_req);
|
||||
//*p = nullptr;
|
||||
//
|
||||
//if (in->size == 0) {
|
||||
//
|
||||
// in->size = 4;
|
||||
//
|
||||
// in->pBuffer = new uchar[in->size];
|
||||
//
|
||||
// *((uint32 *)in->pBuffer) = 0;
|
||||
//
|
||||
// dest->FastQueuePacket(&in, ack_req);
|
||||
//
|
||||
// return;
|
||||
//}
|
||||
//
|
||||
////store away the emu struct
|
||||
//unsigned char *__emu_buffer = in->pBuffer;
|
||||
//
|
||||
//int ItemCount = in->size / sizeof(InternalSerializedItem_Struct);
|
||||
//
|
||||
//if (ItemCount == 0 || (in->size % sizeof(InternalSerializedItem_Struct)) != 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(InternalSerializedItem_Struct));
|
||||
//
|
||||
// delete in;
|
||||
// return;
|
||||
//}
|
||||
//
|
||||
//InternalSerializedItem_Struct *eq = (InternalSerializedItem_Struct *)in->pBuffer;
|
||||
//in->pBuffer = new uchar[4];
|
||||
//*(uint32 *)in->pBuffer = ItemCount;
|
||||
//in->size = 4;
|
||||
//
|
||||
//for (int r = 0; r < ItemCount; r++, eq++) {
|
||||
//
|
||||
// uint32 Length = 0;
|
||||
// char* Serialized = SerializeItem((const ItemInst*)eq->inst, eq->slot_id, &Length, 0);
|
||||
//
|
||||
// if (Serialized) {
|
||||
//
|
||||
// uchar *OldBuffer = in->pBuffer;
|
||||
// in->pBuffer = new uchar[in->size + Length];
|
||||
// memcpy(in->pBuffer, OldBuffer, in->size);
|
||||
//
|
||||
// safe_delete_array(OldBuffer);
|
||||
//
|
||||
// memcpy(in->pBuffer + in->size, Serialized, Length);
|
||||
// in->size += Length;
|
||||
//
|
||||
// safe_delete_array(Serialized);
|
||||
//
|
||||
// }
|
||||
// else {
|
||||
// Log.Out(Logs::General, Logs::Netcode, "[ERROR] Serialization failed on item slot %d during OP_CharInventory. Item skipped.", eq->slot_id);
|
||||
// }
|
||||
//}
|
||||
//
|
||||
//delete[] __emu_buffer;
|
||||
//
|
||||
////Log.LogDebugType(Logs::General, Logs::Netcode, "[ERROR] Sending inventory to client");
|
||||
////Log.Hex(Logs::Netcode, in->pBuffer, in->size);
|
||||
//
|
||||
//dest->FastQueuePacket(&in, ack_req);
|
||||
}
|
||||
|
||||
ENCODE(OP_ClientUpdate)
|
||||
@@ -1266,14 +1267,14 @@ namespace SoD
|
||||
|
||||
ENCODE(OP_MoveItem)
|
||||
{
|
||||
ENCODE_LENGTH_EXACT(MoveItem_Struct);
|
||||
SETUP_DIRECT_ENCODE(MoveItem_Struct, structs::MoveItem_Struct);
|
||||
|
||||
eq->from_slot = ServerToSoDSlot(emu->from_slot);
|
||||
eq->to_slot = ServerToSoDSlot(emu->to_slot);
|
||||
OUT(number_in_stack);
|
||||
|
||||
FINISH_ENCODE();
|
||||
//ENCODE_LENGTH_EXACT(MoveItem_Struct);
|
||||
//SETUP_DIRECT_ENCODE(MoveItem_Struct, structs::MoveItem_Struct);
|
||||
//
|
||||
//eq->from_slot = ServerToSoDSlot(emu->from_slot);
|
||||
//eq->to_slot = ServerToSoDSlot(emu->to_slot);
|
||||
//OUT(number_in_stack);
|
||||
//
|
||||
//FINISH_ENCODE();
|
||||
}
|
||||
|
||||
ENCODE(OP_NewSpawn) { ENCODE_FORWARD(OP_ZoneSpawns); }
|
||||
@@ -3264,16 +3265,16 @@ namespace SoD
|
||||
|
||||
DECODE(OP_MoveItem)
|
||||
{
|
||||
DECODE_LENGTH_EXACT(structs::MoveItem_Struct);
|
||||
SETUP_DIRECT_DECODE(MoveItem_Struct, structs::MoveItem_Struct);
|
||||
|
||||
Log.Out(Logs::General, Logs::Netcode, "[SoD] Moved item from %u to %u", eq->from_slot, eq->to_slot);
|
||||
|
||||
emu->from_slot = SoDToServerSlot(eq->from_slot);
|
||||
emu->to_slot = SoDToServerSlot(eq->to_slot);
|
||||
IN(number_in_stack);
|
||||
|
||||
FINISH_DIRECT_DECODE();
|
||||
//DECODE_LENGTH_EXACT(structs::MoveItem_Struct);
|
||||
//SETUP_DIRECT_DECODE(MoveItem_Struct, structs::MoveItem_Struct);
|
||||
//
|
||||
//Log.Out(Logs::General, Logs::Netcode, "[SoD] Moved item from %u to %u", eq->from_slot, eq->to_slot);
|
||||
//
|
||||
//emu->from_slot = SoDToServerSlot(eq->from_slot);
|
||||
//emu->to_slot = SoDToServerSlot(eq->to_slot);
|
||||
//IN(number_in_stack);
|
||||
//
|
||||
//FINISH_DIRECT_DECODE();
|
||||
}
|
||||
|
||||
DECODE(OP_PetCommands)
|
||||
@@ -3559,7 +3560,7 @@ namespace SoD
|
||||
|
||||
std::stringstream ss(std::stringstream::in | std::stringstream::out | std::stringstream::binary);
|
||||
|
||||
const Item_Struct *item = inst->GetUnscaledItem();
|
||||
const ItemData *item = inst->GetUnscaledItem();
|
||||
//Log.LogDebugType(Logs::General, Logs::Netcode, "[ERROR] Serialize called for: %s", item->Name);
|
||||
SoD::structs::ItemSerializationHeader hdr;
|
||||
hdr.stacksize = stackable ? charges : 1;
|
||||
@@ -3957,7 +3958,7 @@ namespace SoD
|
||||
|
||||
/*
|
||||
// TEST CODE: <watch>
|
||||
SubSlotNumber = Inventory::CalcSlotID(slot_id_in, x);
|
||||
SubSlotNumber = InventoryOld::CalcSlotID(slot_id_in, x);
|
||||
*/
|
||||
|
||||
SubSerializations[x] = SerializeItem(subitem, SubSlotNumber, &SubLengths[x], depth + 1);
|
||||
|
||||
@@ -1973,7 +1973,7 @@ struct AdventureLeaderboard_Struct
|
||||
/*struct Item_Shop_Struct {
|
||||
uint16 merchantid;
|
||||
uint8 itemtype;
|
||||
Item_Struct item;
|
||||
ItemData item;
|
||||
uint8 iss_unknown001[6];
|
||||
};*/
|
||||
|
||||
|
||||
+83
-82
@@ -318,69 +318,70 @@ namespace SoF
|
||||
{
|
||||
//consume the packet
|
||||
EQApplicationPacket *in = *p;
|
||||
delete in;
|
||||
|
||||
*p = nullptr;
|
||||
|
||||
if (in->size == 0) {
|
||||
in->size = 4;
|
||||
in->pBuffer = new uchar[in->size];
|
||||
*((uint32 *)in->pBuffer) = 0;
|
||||
|
||||
dest->FastQueuePacket(&in, ack_req);
|
||||
return;
|
||||
}
|
||||
|
||||
//store away the emu struct
|
||||
unsigned char *__emu_buffer = in->pBuffer;
|
||||
|
||||
int ItemCount = in->size / sizeof(InternalSerializedItem_Struct);
|
||||
|
||||
if (ItemCount == 0 || (in->size % sizeof(InternalSerializedItem_Struct)) != 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(InternalSerializedItem_Struct));
|
||||
|
||||
delete in;
|
||||
return;
|
||||
}
|
||||
|
||||
InternalSerializedItem_Struct *eq = (InternalSerializedItem_Struct *)in->pBuffer;
|
||||
|
||||
in->pBuffer = new uchar[4];
|
||||
*(uint32 *)in->pBuffer = ItemCount;
|
||||
in->size = 4;
|
||||
|
||||
for (int r = 0; r < ItemCount; r++, eq++) {
|
||||
|
||||
uint32 Length = 0;
|
||||
|
||||
char* Serialized = SerializeItem((const ItemInst*)eq->inst, eq->slot_id, &Length, 0);
|
||||
|
||||
if (Serialized) {
|
||||
uchar *OldBuffer = in->pBuffer;
|
||||
|
||||
in->pBuffer = new uchar[in->size + Length];
|
||||
memcpy(in->pBuffer, OldBuffer, in->size);
|
||||
|
||||
safe_delete_array(OldBuffer);
|
||||
|
||||
memcpy(in->pBuffer + in->size, Serialized, Length);
|
||||
in->size += Length;
|
||||
|
||||
safe_delete_array(Serialized);
|
||||
|
||||
}
|
||||
else {
|
||||
Log.Out(Logs::General, Logs::Netcode, "[ERROR] Serialization failed on item slot %d during OP_CharInventory. Item skipped.", eq->slot_id);
|
||||
}
|
||||
}
|
||||
|
||||
delete[] __emu_buffer;
|
||||
|
||||
//Log.LogDebugType(Logs::General, Logs::Netcode, "[ERROR] Sending inventory to client");
|
||||
//Log.Hex(Logs::Netcode, in->pBuffer, in->size);
|
||||
|
||||
dest->FastQueuePacket(&in, ack_req);
|
||||
//*p = nullptr;
|
||||
//
|
||||
//if (in->size == 0) {
|
||||
// in->size = 4;
|
||||
// in->pBuffer = new uchar[in->size];
|
||||
// *((uint32 *)in->pBuffer) = 0;
|
||||
//
|
||||
// dest->FastQueuePacket(&in, ack_req);
|
||||
// return;
|
||||
//}
|
||||
//
|
||||
////store away the emu struct
|
||||
//unsigned char *__emu_buffer = in->pBuffer;
|
||||
//
|
||||
//int ItemCount = in->size / sizeof(InternalSerializedItem_Struct);
|
||||
//
|
||||
//if (ItemCount == 0 || (in->size % sizeof(InternalSerializedItem_Struct)) != 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(InternalSerializedItem_Struct));
|
||||
//
|
||||
// delete in;
|
||||
// return;
|
||||
//}
|
||||
//
|
||||
//InternalSerializedItem_Struct *eq = (InternalSerializedItem_Struct *)in->pBuffer;
|
||||
//
|
||||
//in->pBuffer = new uchar[4];
|
||||
//*(uint32 *)in->pBuffer = ItemCount;
|
||||
//in->size = 4;
|
||||
//
|
||||
//for (int r = 0; r < ItemCount; r++, eq++) {
|
||||
//
|
||||
// uint32 Length = 0;
|
||||
//
|
||||
// char* Serialized = SerializeItem((const ItemInst*)eq->inst, eq->slot_id, &Length, 0);
|
||||
//
|
||||
// if (Serialized) {
|
||||
// uchar *OldBuffer = in->pBuffer;
|
||||
//
|
||||
// in->pBuffer = new uchar[in->size + Length];
|
||||
// memcpy(in->pBuffer, OldBuffer, in->size);
|
||||
//
|
||||
// safe_delete_array(OldBuffer);
|
||||
//
|
||||
// memcpy(in->pBuffer + in->size, Serialized, Length);
|
||||
// in->size += Length;
|
||||
//
|
||||
// safe_delete_array(Serialized);
|
||||
//
|
||||
// }
|
||||
// else {
|
||||
// Log.Out(Logs::General, Logs::Netcode, "[ERROR] Serialization failed on item slot %d during OP_CharInventory. Item skipped.", eq->slot_id);
|
||||
// }
|
||||
//}
|
||||
//
|
||||
//delete[] __emu_buffer;
|
||||
//
|
||||
////Log.LogDebugType(Logs::General, Logs::Netcode, "[ERROR] Sending inventory to client");
|
||||
////Log.Hex(Logs::Netcode, in->pBuffer, in->size);
|
||||
//
|
||||
//dest->FastQueuePacket(&in, ack_req);
|
||||
}
|
||||
|
||||
ENCODE(OP_ClientUpdate)
|
||||
@@ -931,14 +932,14 @@ namespace SoF
|
||||
|
||||
ENCODE(OP_MoveItem)
|
||||
{
|
||||
ENCODE_LENGTH_EXACT(MoveItem_Struct);
|
||||
SETUP_DIRECT_ENCODE(MoveItem_Struct, structs::MoveItem_Struct);
|
||||
|
||||
eq->from_slot = ServerToSoFSlot(emu->from_slot);
|
||||
eq->to_slot = ServerToSoFSlot(emu->to_slot);
|
||||
OUT(number_in_stack);
|
||||
|
||||
FINISH_ENCODE();
|
||||
//ENCODE_LENGTH_EXACT(MoveItem_Struct);
|
||||
//SETUP_DIRECT_ENCODE(MoveItem_Struct, structs::MoveItem_Struct);
|
||||
//
|
||||
//eq->from_slot = ServerToSoFSlot(emu->from_slot);
|
||||
//eq->to_slot = ServerToSoFSlot(emu->to_slot);
|
||||
//OUT(number_in_stack);
|
||||
//
|
||||
//FINISH_ENCODE();
|
||||
}
|
||||
|
||||
ENCODE(OP_NewSpawn) { ENCODE_FORWARD(OP_ZoneSpawns); }
|
||||
@@ -2603,16 +2604,16 @@ namespace SoF
|
||||
|
||||
DECODE(OP_MoveItem)
|
||||
{
|
||||
DECODE_LENGTH_EXACT(structs::MoveItem_Struct);
|
||||
SETUP_DIRECT_DECODE(MoveItem_Struct, structs::MoveItem_Struct);
|
||||
|
||||
Log.Out(Logs::General, Logs::Netcode, "[SoF] Moved item from %u to %u", eq->from_slot, eq->to_slot);
|
||||
|
||||
emu->from_slot = SoFToServerSlot(eq->from_slot);
|
||||
emu->to_slot = SoFToServerSlot(eq->to_slot);
|
||||
IN(number_in_stack);
|
||||
|
||||
FINISH_DIRECT_DECODE();
|
||||
//DECODE_LENGTH_EXACT(structs::MoveItem_Struct);
|
||||
//SETUP_DIRECT_DECODE(MoveItem_Struct, structs::MoveItem_Struct);
|
||||
//
|
||||
//Log.Out(Logs::General, Logs::Netcode, "[SoF] Moved item from %u to %u", eq->from_slot, eq->to_slot);
|
||||
//
|
||||
//emu->from_slot = SoFToServerSlot(eq->from_slot);
|
||||
//emu->to_slot = SoFToServerSlot(eq->to_slot);
|
||||
//IN(number_in_stack);
|
||||
//
|
||||
//FINISH_DIRECT_DECODE();
|
||||
}
|
||||
|
||||
DECODE(OP_PetCommands)
|
||||
@@ -2884,7 +2885,7 @@ namespace SoF
|
||||
|
||||
std::stringstream ss(std::stringstream::in | std::stringstream::out | std::stringstream::binary);
|
||||
|
||||
const Item_Struct *item = inst->GetUnscaledItem();
|
||||
const ItemData *item = inst->GetUnscaledItem();
|
||||
//Log.LogDebugType(Logs::General, Logs::Netcode, "[ERROR] Serialize called for: %s", item->Name);
|
||||
SoF::structs::ItemSerializationHeader hdr;
|
||||
hdr.stacksize = stackable ? charges : 1;
|
||||
@@ -3280,7 +3281,7 @@ namespace SoF
|
||||
|
||||
/*
|
||||
// TEST CODE: <watch>
|
||||
SubSlotNumber = Inventory::CalcSlotID(slot_id_in, x);
|
||||
SubSlotNumber = InventoryOld::CalcSlotID(slot_id_in, x);
|
||||
*/
|
||||
|
||||
SubSerializations[x] = SerializeItem(subitem, SubSlotNumber, &SubLengths[x], depth + 1);
|
||||
|
||||
@@ -1948,7 +1948,7 @@ struct AdventureLeaderboard_Struct
|
||||
/*struct Item_Shop_Struct {
|
||||
uint16 merchantid;
|
||||
uint8 itemtype;
|
||||
Item_Struct item;
|
||||
ItemData item;
|
||||
uint8 iss_unknown001[6];
|
||||
};*/
|
||||
|
||||
|
||||
+54
-52
@@ -263,40 +263,42 @@ namespace Titanium
|
||||
EQApplicationPacket *in = *p;
|
||||
*p = nullptr;
|
||||
|
||||
//store away the emu struct
|
||||
unsigned char *__emu_buffer = in->pBuffer;
|
||||
delete in;
|
||||
|
||||
int itemcount = in->size / sizeof(InternalSerializedItem_Struct);
|
||||
if (itemcount == 0 || (in->size % sizeof(InternalSerializedItem_Struct)) != 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(InternalSerializedItem_Struct));
|
||||
delete in;
|
||||
return;
|
||||
}
|
||||
InternalSerializedItem_Struct *eq = (InternalSerializedItem_Struct *)in->pBuffer;
|
||||
|
||||
//do the transform...
|
||||
int r;
|
||||
std::string serial_string;
|
||||
for (r = 0; r < itemcount; r++, eq++) {
|
||||
uint32 length;
|
||||
char *serialized = SerializeItem((const ItemInst*)eq->inst, eq->slot_id, &length, 0);
|
||||
if (serialized) {
|
||||
serial_string.append(serialized, length + 1);
|
||||
safe_delete_array(serialized);
|
||||
}
|
||||
else {
|
||||
Log.Out(Logs::General, Logs::Netcode, "[STRUCTS] Serialization failed on item slot %d during OP_CharInventory. Item skipped.", eq->slot_id);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
in->size = serial_string.length();
|
||||
in->pBuffer = new unsigned char[in->size];
|
||||
memcpy(in->pBuffer, serial_string.c_str(), serial_string.length());
|
||||
|
||||
delete[] __emu_buffer;
|
||||
|
||||
dest->FastQueuePacket(&in, ack_req);
|
||||
////store away the emu struct
|
||||
//unsigned char *__emu_buffer = in->pBuffer;
|
||||
//
|
||||
//int itemcount = in->size / sizeof(InternalSerializedItem_Struct);
|
||||
//if (itemcount == 0 || (in->size % sizeof(InternalSerializedItem_Struct)) != 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(InternalSerializedItem_Struct));
|
||||
// delete in;
|
||||
// return;
|
||||
//}
|
||||
//InternalSerializedItem_Struct *eq = (InternalSerializedItem_Struct *)in->pBuffer;
|
||||
//
|
||||
////do the transform...
|
||||
//int r;
|
||||
//std::string serial_string;
|
||||
//for (r = 0; r < itemcount; r++, eq++) {
|
||||
// uint32 length;
|
||||
// char *serialized = SerializeItem((const ItemInst*)eq->inst, eq->slot_id, &length, 0);
|
||||
// if (serialized) {
|
||||
// serial_string.append(serialized, length + 1);
|
||||
// safe_delete_array(serialized);
|
||||
// }
|
||||
// else {
|
||||
// Log.Out(Logs::General, Logs::Netcode, "[STRUCTS] Serialization failed on item slot %d during OP_CharInventory. Item skipped.", eq->slot_id);
|
||||
// }
|
||||
//
|
||||
//}
|
||||
//
|
||||
//in->size = serial_string.length();
|
||||
//in->pBuffer = new unsigned char[in->size];
|
||||
//memcpy(in->pBuffer, serial_string.c_str(), serial_string.length());
|
||||
//
|
||||
//delete[] __emu_buffer;
|
||||
//
|
||||
//dest->FastQueuePacket(&in, ack_req);
|
||||
}
|
||||
|
||||
ENCODE(OP_DeleteCharge) { ENCODE_FORWARD(OP_MoveItem); }
|
||||
@@ -776,14 +778,14 @@ namespace Titanium
|
||||
|
||||
ENCODE(OP_MoveItem)
|
||||
{
|
||||
ENCODE_LENGTH_EXACT(MoveItem_Struct);
|
||||
SETUP_DIRECT_ENCODE(MoveItem_Struct, structs::MoveItem_Struct);
|
||||
|
||||
eq->from_slot = ServerToTitaniumSlot(emu->from_slot);
|
||||
eq->to_slot = ServerToTitaniumSlot(emu->to_slot);
|
||||
OUT(number_in_stack);
|
||||
|
||||
FINISH_ENCODE();
|
||||
//ENCODE_LENGTH_EXACT(MoveItem_Struct);
|
||||
//SETUP_DIRECT_ENCODE(MoveItem_Struct, structs::MoveItem_Struct);
|
||||
//
|
||||
//eq->from_slot = ServerToTitaniumSlot(emu->from_slot);
|
||||
//eq->to_slot = ServerToTitaniumSlot(emu->to_slot);
|
||||
//OUT(number_in_stack);
|
||||
//
|
||||
//FINISH_ENCODE();
|
||||
}
|
||||
|
||||
ENCODE(OP_NewSpawn) { ENCODE_FORWARD(OP_ZoneSpawns); }
|
||||
@@ -1852,16 +1854,16 @@ namespace Titanium
|
||||
|
||||
DECODE(OP_MoveItem)
|
||||
{
|
||||
DECODE_LENGTH_EXACT(structs::MoveItem_Struct);
|
||||
SETUP_DIRECT_DECODE(MoveItem_Struct, structs::MoveItem_Struct);
|
||||
|
||||
Log.Out(Logs::General, Logs::Netcode, "[Titanium] Moved item from %u to %u", eq->from_slot, eq->to_slot);
|
||||
|
||||
emu->from_slot = TitaniumToServerSlot(eq->from_slot);
|
||||
emu->to_slot = TitaniumToServerSlot(eq->to_slot);
|
||||
IN(number_in_stack);
|
||||
|
||||
FINISH_DIRECT_DECODE();
|
||||
//DECODE_LENGTH_EXACT(structs::MoveItem_Struct);
|
||||
//SETUP_DIRECT_DECODE(MoveItem_Struct, structs::MoveItem_Struct);
|
||||
//
|
||||
//Log.Out(Logs::General, Logs::Netcode, "[Titanium] Moved item from %u to %u", eq->from_slot, eq->to_slot);
|
||||
//
|
||||
//emu->from_slot = TitaniumToServerSlot(eq->from_slot);
|
||||
//emu->to_slot = TitaniumToServerSlot(eq->to_slot);
|
||||
//IN(number_in_stack);
|
||||
//
|
||||
//FINISH_DIRECT_DECODE();
|
||||
}
|
||||
|
||||
DECODE(OP_PetCommands)
|
||||
@@ -2070,7 +2072,7 @@ namespace Titanium
|
||||
int16 slot_id = ServerToTitaniumSlot(slot_id_in);
|
||||
uint32 merchant_slot = inst->GetMerchantSlot();
|
||||
int16 charges = inst->GetCharges();
|
||||
const Item_Struct *item = inst->GetUnscaledItem();
|
||||
const ItemData *item = inst->GetUnscaledItem();
|
||||
int i;
|
||||
uint32 sub_length;
|
||||
|
||||
|
||||
@@ -1700,7 +1700,7 @@ struct AdventureRequestResponse_Struct{
|
||||
/*struct Item_Shop_Struct {
|
||||
uint16 merchantid;
|
||||
uint8 itemtype;
|
||||
Item_Struct item;
|
||||
ItemData item;
|
||||
uint8 iss_unknown001[6];
|
||||
};*/
|
||||
|
||||
|
||||
+84
-83
@@ -474,68 +474,69 @@ namespace UF
|
||||
{
|
||||
//consume the packet
|
||||
EQApplicationPacket *in = *p;
|
||||
|
||||
*p = nullptr;
|
||||
|
||||
if (in->size == 0) {
|
||||
|
||||
in->size = 4;
|
||||
in->pBuffer = new uchar[in->size];
|
||||
*((uint32 *)in->pBuffer) = 0;
|
||||
|
||||
dest->FastQueuePacket(&in, ack_req);
|
||||
return;
|
||||
}
|
||||
|
||||
//store away the emu struct
|
||||
unsigned char *__emu_buffer = in->pBuffer;
|
||||
|
||||
int ItemCount = in->size / sizeof(InternalSerializedItem_Struct);
|
||||
|
||||
if (ItemCount == 0 || (in->size % sizeof(InternalSerializedItem_Struct)) != 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(InternalSerializedItem_Struct));
|
||||
|
||||
delete in;
|
||||
return;
|
||||
}
|
||||
|
||||
InternalSerializedItem_Struct *eq = (InternalSerializedItem_Struct *)in->pBuffer;
|
||||
|
||||
in->pBuffer = new uchar[4];
|
||||
*(uint32 *)in->pBuffer = ItemCount;
|
||||
in->size = 4;
|
||||
|
||||
for (int r = 0; r < ItemCount; r++, eq++) {
|
||||
|
||||
uint32 Length = 0;
|
||||
char* Serialized = SerializeItem((const ItemInst*)eq->inst, eq->slot_id, &Length, 0);
|
||||
|
||||
if (Serialized) {
|
||||
|
||||
uchar *OldBuffer = in->pBuffer;
|
||||
in->pBuffer = new uchar[in->size + Length];
|
||||
memcpy(in->pBuffer, OldBuffer, in->size);
|
||||
|
||||
safe_delete_array(OldBuffer);
|
||||
|
||||
memcpy(in->pBuffer + in->size, Serialized, Length);
|
||||
in->size += Length;
|
||||
|
||||
safe_delete_array(Serialized);
|
||||
}
|
||||
else {
|
||||
Log.Out(Logs::General, Logs::Netcode, "[ERROR] Serialization failed on item slot %d during OP_CharInventory. Item skipped.", eq->slot_id);
|
||||
}
|
||||
}
|
||||
|
||||
delete[] __emu_buffer;
|
||||
|
||||
//Log.LogDebugType(Logs::General, Logs::Netcode, "[ERROR] Sending inventory to client");
|
||||
//Log.Hex(Logs::Netcode, in->pBuffer, in->size);
|
||||
|
||||
dest->FastQueuePacket(&in, ack_req);
|
||||
delete in;
|
||||
|
||||
//*p = nullptr;
|
||||
//
|
||||
//if (in->size == 0) {
|
||||
//
|
||||
// in->size = 4;
|
||||
// in->pBuffer = new uchar[in->size];
|
||||
// *((uint32 *)in->pBuffer) = 0;
|
||||
//
|
||||
// dest->FastQueuePacket(&in, ack_req);
|
||||
// return;
|
||||
//}
|
||||
//
|
||||
////store away the emu struct
|
||||
//unsigned char *__emu_buffer = in->pBuffer;
|
||||
//
|
||||
//int ItemCount = in->size / sizeof(InternalSerializedItem_Struct);
|
||||
//
|
||||
//if (ItemCount == 0 || (in->size % sizeof(InternalSerializedItem_Struct)) != 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(InternalSerializedItem_Struct));
|
||||
//
|
||||
// delete in;
|
||||
// return;
|
||||
//}
|
||||
//
|
||||
//InternalSerializedItem_Struct *eq = (InternalSerializedItem_Struct *)in->pBuffer;
|
||||
//
|
||||
//in->pBuffer = new uchar[4];
|
||||
//*(uint32 *)in->pBuffer = ItemCount;
|
||||
//in->size = 4;
|
||||
//
|
||||
//for (int r = 0; r < ItemCount; r++, eq++) {
|
||||
//
|
||||
// uint32 Length = 0;
|
||||
// char* Serialized = SerializeItem((const ItemInst*)eq->inst, eq->slot_id, &Length, 0);
|
||||
//
|
||||
// if (Serialized) {
|
||||
//
|
||||
// uchar *OldBuffer = in->pBuffer;
|
||||
// in->pBuffer = new uchar[in->size + Length];
|
||||
// memcpy(in->pBuffer, OldBuffer, in->size);
|
||||
//
|
||||
// safe_delete_array(OldBuffer);
|
||||
//
|
||||
// memcpy(in->pBuffer + in->size, Serialized, Length);
|
||||
// in->size += Length;
|
||||
//
|
||||
// safe_delete_array(Serialized);
|
||||
// }
|
||||
// else {
|
||||
// Log.Out(Logs::General, Logs::Netcode, "[ERROR] Serialization failed on item slot %d during OP_CharInventory. Item skipped.", eq->slot_id);
|
||||
// }
|
||||
//}
|
||||
//
|
||||
//delete[] __emu_buffer;
|
||||
//
|
||||
////Log.LogDebugType(Logs::General, Logs::Netcode, "[ERROR] Sending inventory to client");
|
||||
////Log.Hex(Logs::Netcode, in->pBuffer, in->size);
|
||||
//
|
||||
//dest->FastQueuePacket(&in, ack_req);
|
||||
}
|
||||
|
||||
ENCODE(OP_ClientUpdate)
|
||||
@@ -1505,14 +1506,14 @@ namespace UF
|
||||
|
||||
ENCODE(OP_MoveItem)
|
||||
{
|
||||
ENCODE_LENGTH_EXACT(MoveItem_Struct);
|
||||
SETUP_DIRECT_ENCODE(MoveItem_Struct, structs::MoveItem_Struct);
|
||||
|
||||
eq->from_slot = ServerToUFSlot(emu->from_slot);
|
||||
eq->to_slot = ServerToUFSlot(emu->to_slot);
|
||||
OUT(number_in_stack);
|
||||
|
||||
FINISH_ENCODE();
|
||||
//ENCODE_LENGTH_EXACT(MoveItem_Struct);
|
||||
//SETUP_DIRECT_ENCODE(MoveItem_Struct, structs::MoveItem_Struct);
|
||||
//
|
||||
//eq->from_slot = ServerToUFSlot(emu->from_slot);
|
||||
//eq->to_slot = ServerToUFSlot(emu->to_slot);
|
||||
//OUT(number_in_stack);
|
||||
//
|
||||
//FINISH_ENCODE();
|
||||
}
|
||||
|
||||
ENCODE(OP_NewSpawn) { ENCODE_FORWARD(OP_ZoneSpawns); }
|
||||
@@ -3586,16 +3587,16 @@ namespace UF
|
||||
|
||||
DECODE(OP_MoveItem)
|
||||
{
|
||||
DECODE_LENGTH_EXACT(structs::MoveItem_Struct);
|
||||
SETUP_DIRECT_DECODE(MoveItem_Struct, structs::MoveItem_Struct);
|
||||
|
||||
Log.Out(Logs::General, Logs::Netcode, "[UF] Moved item from %u to %u", eq->from_slot, eq->to_slot);
|
||||
|
||||
emu->from_slot = UFToServerSlot(eq->from_slot);
|
||||
emu->to_slot = UFToServerSlot(eq->to_slot);
|
||||
IN(number_in_stack);
|
||||
|
||||
FINISH_DIRECT_DECODE();
|
||||
//DECODE_LENGTH_EXACT(structs::MoveItem_Struct);
|
||||
//SETUP_DIRECT_DECODE(MoveItem_Struct, structs::MoveItem_Struct);
|
||||
//
|
||||
//Log.Out(Logs::General, Logs::Netcode, "[UF] Moved item from %u to %u", eq->from_slot, eq->to_slot);
|
||||
//
|
||||
//emu->from_slot = UFToServerSlot(eq->from_slot);
|
||||
//emu->to_slot = UFToServerSlot(eq->to_slot);
|
||||
//IN(number_in_stack);
|
||||
//
|
||||
//FINISH_DIRECT_DECODE();
|
||||
}
|
||||
|
||||
DECODE(OP_PetCommands)
|
||||
@@ -3811,7 +3812,7 @@ namespace UF
|
||||
|
||||
std::stringstream ss(std::stringstream::in | std::stringstream::out | std::stringstream::binary);
|
||||
|
||||
const Item_Struct *item = inst->GetUnscaledItem();
|
||||
const ItemData *item = inst->GetUnscaledItem();
|
||||
//Log.LogDebugType(Logs::General, Logs::Netcode, "[ERROR] Serialize called for: %s", item->Name);
|
||||
UF::structs::ItemSerializationHeader hdr;
|
||||
hdr.stacksize = stackable ? charges : 1;
|
||||
@@ -3849,7 +3850,7 @@ namespace UF
|
||||
//ORNAMENT IDFILE / ICON -
|
||||
uint16 ornaIcon = 0;
|
||||
if (inst->GetOrnamentationAug(ornamentationAugtype)) {
|
||||
const Item_Struct *aug_weap = inst->GetOrnamentationAug(ornamentationAugtype)->GetItem();
|
||||
const ItemData *aug_weap = inst->GetOrnamentationAug(ornamentationAugtype)->GetItem();
|
||||
ss.write(aug_weap->IDFile, strlen(aug_weap->IDFile));
|
||||
ss.write((const char*)&null_term, sizeof(uint8));
|
||||
ornaIcon = aug_weap->Icon;
|
||||
@@ -4265,7 +4266,7 @@ namespace UF
|
||||
|
||||
/*
|
||||
// TEST CODE: <watch>
|
||||
SubSlotNumber = Inventory::CalcSlotID(slot_id_in, x);
|
||||
SubSlotNumber = InventoryOld::CalcSlotID(slot_id_in, x);
|
||||
*/
|
||||
|
||||
SubSerializations[x] = SerializeItem(subitem, SubSlotNumber, &SubLengths[x], depth + 1);
|
||||
|
||||
@@ -2032,7 +2032,7 @@ struct AdventureLeaderboard_Struct
|
||||
/*struct Item_Shop_Struct {
|
||||
uint16 merchantid;
|
||||
uint8 itemtype;
|
||||
Item_Struct item;
|
||||
ItemData item;
|
||||
uint8 iss_unknown001[6];
|
||||
};*/
|
||||
|
||||
|
||||
@@ -584,27 +584,6 @@ RULE_CATEGORY_END()
|
||||
|
||||
RULE_CATEGORY(QueryServ)
|
||||
RULE_BOOL(QueryServ, PlayerLogChat, false) // Logs Player Chat
|
||||
RULE_BOOL(QueryServ, PlayerLogTrades, false) // Logs Player Trades
|
||||
RULE_BOOL(QueryServ, PlayerLogHandins, false) // Logs Player Handins
|
||||
RULE_BOOL(QueryServ, PlayerLogNPCKills, false) // Logs Player NPC Kills
|
||||
RULE_BOOL(QueryServ, PlayerLogDeletes, false) // Logs Player Deletes
|
||||
RULE_BOOL(QueryServ, PlayerLogMoves, false) // Logs Player Moves
|
||||
RULE_BOOL(QueryServ, PlayerLogMerchantTransactions, false) // Logs Merchant Transactions
|
||||
RULE_BOOL(QueryServ, PlayerLogPCCoordinates, false) // Logs Player Coordinates with certain events
|
||||
RULE_BOOL(QueryServ, PlayerLogDropItem, false) // Logs Player Drop Item
|
||||
RULE_BOOL(QueryServ, PlayerLogZone, false) // Logs Player Zone Events
|
||||
RULE_BOOL(QueryServ, PlayerLogDeaths, false) // Logs Player Deaths
|
||||
RULE_BOOL(QueryServ, PlayerLogConnectDisconnect, false) // Logs Player Connect Disconnect State
|
||||
RULE_BOOL(QueryServ, PlayerLogLevels, false) // Logs Player Leveling/Deleveling
|
||||
RULE_BOOL(QueryServ, PlayerLogAARate, false) // Logs Player AA Experience Rates
|
||||
RULE_BOOL(QueryServ, PlayerLogQGlobalUpdate, false) // Logs Player QGlobal Updates
|
||||
RULE_BOOL(QueryServ, PlayerLogTaskUpdates, false) // Logs Player Task Updates
|
||||
RULE_BOOL(QueryServ, PlayerLogKeyringAddition, false) // Log PLayer Keyring additions
|
||||
RULE_BOOL(QueryServ, PlayerLogAAPurchases, false) // Log Player AA Purchases
|
||||
RULE_BOOL(QueryServ, PlayerLogTradeSkillEvents, false) // Log Player Tradeskill Transactions
|
||||
RULE_BOOL(QueryServ, PlayerLogIssuedCommandes, false) // Log Player Issued Commands
|
||||
RULE_BOOL(QueryServ, PlayerLogMoneyTransactions, false) // Log Player Money Transaction/Splits
|
||||
RULE_BOOL(QueryServ, PlayerLogAlternateCurrencyTransactions, false) // Log Ploayer Alternate Currency Transactions
|
||||
RULE_CATEGORY_END()
|
||||
|
||||
RULE_CATEGORY(Inventory)
|
||||
|
||||
+1
-134
@@ -181,14 +181,7 @@
|
||||
#define ServerOP_CZMessagePlayer 0x4008
|
||||
#define ServerOP_ReloadWorld 0x4009
|
||||
#define ServerOP_ReloadLogs 0x4010
|
||||
/* Query Server OP Codes */
|
||||
#define ServerOP_QSPlayerLogTrades 0x5010
|
||||
#define ServerOP_QSPlayerLogHandins 0x5011
|
||||
#define ServerOP_QSPlayerLogNPCKills 0x5012
|
||||
#define ServerOP_QSPlayerLogDeletes 0x5013
|
||||
#define ServerOP_QSPlayerLogMoves 0x5014
|
||||
#define ServerOP_QSPlayerLogMerchantTransactions 0x5015
|
||||
#define ServerOP_QSSendQuery 0x5016
|
||||
#define ServerOP_QSSendQuery 0x5000
|
||||
#define ServerOP_CZSignalNPC 0x5017
|
||||
#define ServerOP_CZSetEntityVariableByNPCTypeID 0x5018
|
||||
|
||||
@@ -1113,132 +1106,6 @@ struct CZClientSignalByName_Struct {
|
||||
uint32 data;
|
||||
};
|
||||
|
||||
struct QSTradeItems_Struct {
|
||||
uint32 from_id;
|
||||
uint16 from_slot;
|
||||
uint32 to_id;
|
||||
uint16 to_slot;
|
||||
uint32 item_id;
|
||||
uint16 charges;
|
||||
uint32 aug_1;
|
||||
uint32 aug_2;
|
||||
uint32 aug_3;
|
||||
uint32 aug_4;
|
||||
uint32 aug_5;
|
||||
};
|
||||
|
||||
struct QSPlayerLogTrade_Struct {
|
||||
uint32 char1_id;
|
||||
MoneyUpdate_Struct char1_money;
|
||||
uint16 char1_count;
|
||||
uint32 char2_id;
|
||||
MoneyUpdate_Struct char2_money;
|
||||
uint16 char2_count;
|
||||
uint16 _detail_count;
|
||||
QSTradeItems_Struct items[0];
|
||||
};
|
||||
|
||||
struct QSHandinItems_Struct {
|
||||
char action_type[7]; // handin, return or reward
|
||||
uint16 char_slot;
|
||||
uint32 item_id;
|
||||
uint16 charges;
|
||||
uint32 aug_1;
|
||||
uint32 aug_2;
|
||||
uint32 aug_3;
|
||||
uint32 aug_4;
|
||||
uint32 aug_5;
|
||||
};
|
||||
|
||||
struct QSPlayerLogHandin_Struct {
|
||||
uint32 quest_id;
|
||||
uint32 char_id;
|
||||
MoneyUpdate_Struct char_money;
|
||||
uint16 char_count;
|
||||
uint32 npc_id;
|
||||
MoneyUpdate_Struct npc_money;
|
||||
uint16 npc_count;
|
||||
uint16 _detail_count;
|
||||
QSHandinItems_Struct items[0];
|
||||
};
|
||||
|
||||
struct QSPlayerLogNPCKillSub_Struct{
|
||||
uint32 NPCID;
|
||||
uint32 ZoneID;
|
||||
uint32 Type;
|
||||
};
|
||||
|
||||
struct QSPlayerLogNPCKillsPlayers_Struct{
|
||||
uint32 char_id;
|
||||
};
|
||||
|
||||
struct QSPlayerLogNPCKill_Struct{
|
||||
QSPlayerLogNPCKillSub_Struct s1;
|
||||
QSPlayerLogNPCKillsPlayers_Struct Chars[0];
|
||||
};
|
||||
|
||||
struct QSDeleteItems_Struct {
|
||||
uint16 char_slot;
|
||||
uint32 item_id;
|
||||
uint16 charges;
|
||||
uint32 aug_1;
|
||||
uint32 aug_2;
|
||||
uint32 aug_3;
|
||||
uint32 aug_4;
|
||||
uint32 aug_5;
|
||||
};
|
||||
|
||||
struct QSPlayerLogDelete_Struct {
|
||||
uint32 char_id;
|
||||
uint16 stack_size; // '0' indicates full stack or non-stackable item move
|
||||
uint16 char_count;
|
||||
QSDeleteItems_Struct items[0];
|
||||
};
|
||||
|
||||
struct QSMoveItems_Struct {
|
||||
uint16 from_slot;
|
||||
uint16 to_slot;
|
||||
uint32 item_id;
|
||||
uint16 charges;
|
||||
uint32 aug_1;
|
||||
uint32 aug_2;
|
||||
uint32 aug_3;
|
||||
uint32 aug_4;
|
||||
uint32 aug_5;
|
||||
};
|
||||
|
||||
struct QSPlayerLogMove_Struct {
|
||||
uint32 char_id;
|
||||
uint16 from_slot;
|
||||
uint16 to_slot;
|
||||
uint16 stack_size; // '0' indicates full stack or non-stackable item move
|
||||
uint16 char_count;
|
||||
bool postaction;
|
||||
QSMoveItems_Struct items[0];
|
||||
};
|
||||
|
||||
struct QSTransactionItems_Struct {
|
||||
uint16 char_slot;
|
||||
uint32 item_id;
|
||||
uint16 charges;
|
||||
uint32 aug_1;
|
||||
uint32 aug_2;
|
||||
uint32 aug_3;
|
||||
uint32 aug_4;
|
||||
uint32 aug_5;
|
||||
};
|
||||
|
||||
struct QSMerchantLogTransaction_Struct {
|
||||
uint32 zone_id;
|
||||
uint32 merchant_id;
|
||||
MoneyUpdate_Struct merchant_money;
|
||||
uint16 merchant_count;
|
||||
uint32 char_id;
|
||||
MoneyUpdate_Struct char_money;
|
||||
uint16 char_count;
|
||||
QSTransactionItems_Struct items[0];
|
||||
};
|
||||
|
||||
struct QSGeneralQuery_Struct {
|
||||
char QueryString[0];
|
||||
};
|
||||
|
||||
+160
-222
@@ -151,79 +151,77 @@ bool SharedDatabase::VerifyInventory(uint32 account_id, int16 slot_id, const Ite
|
||||
|
||||
bool SharedDatabase::SaveInventory(uint32 char_id, const ItemInst* inst, int16 slot_id) {
|
||||
|
||||
//never save tribute slots:
|
||||
if(slot_id >= EmuConstants::TRIBUTE_BEGIN && slot_id <= EmuConstants::TRIBUTE_END)
|
||||
return true;
|
||||
|
||||
if (slot_id >= EmuConstants::SHARED_BANK_BEGIN && slot_id <= EmuConstants::SHARED_BANK_BAGS_END) {
|
||||
// Shared bank inventory
|
||||
if (!inst) {
|
||||
return DeleteSharedBankSlot(char_id, slot_id);
|
||||
}
|
||||
else {
|
||||
// Needed to clear out bag slots that 'REPLACE' in UpdateSharedBankSlot does not overwrite..otherwise, duplication occurs
|
||||
// (This requires that parent then child items be sent..which should be how they are currently passed)
|
||||
if (Inventory::SupportsContainers(slot_id))
|
||||
DeleteSharedBankSlot(char_id, slot_id);
|
||||
return UpdateSharedBankSlot(char_id, inst, slot_id);
|
||||
}
|
||||
}
|
||||
else if (!inst) { // All other inventory
|
||||
return DeleteInventorySlot(char_id, slot_id);
|
||||
}
|
||||
|
||||
// Needed to clear out bag slots that 'REPLACE' in UpdateInventorySlot does not overwrite..otherwise, duplication occurs
|
||||
// (This requires that parent then child items be sent..which should be how they are currently passed)
|
||||
if (Inventory::SupportsContainers(slot_id))
|
||||
DeleteInventorySlot(char_id, slot_id);
|
||||
return UpdateInventorySlot(char_id, inst, slot_id);
|
||||
return true;
|
||||
//// If we never save tribute slots..how are we to ever benefit from them!!? The client
|
||||
//// object is destroyed upon zoning - including its inventory object..and if tributes
|
||||
//// don't exist in the database, then they will never be loaded when the new client
|
||||
//// object is created in the new zone object... Something to consider... -U
|
||||
////
|
||||
//// (we could add them to the 'NoRent' checks and dispose of after 30 minutes offline)
|
||||
//
|
||||
////never save tribute slots:
|
||||
//if(slot_id >= EmuConstants::TRIBUTE_BEGIN && slot_id <= EmuConstants::TRIBUTE_END)
|
||||
// return true;
|
||||
//
|
||||
//if (slot_id >= EmuConstants::SHARED_BANK_BEGIN && slot_id <= EmuConstants::SHARED_BANK_BAGS_END) {
|
||||
// // Shared bank inventory
|
||||
// if (!inst)
|
||||
// return DeleteSharedBankSlot(char_id, slot_id);
|
||||
// else
|
||||
// return UpdateSharedBankSlot(char_id, inst, slot_id);
|
||||
//}
|
||||
//else if (!inst) { // All other inventory
|
||||
// return DeleteInventorySlot(char_id, slot_id);
|
||||
//}
|
||||
//
|
||||
//return UpdateInventorySlot(char_id, inst, slot_id);
|
||||
}
|
||||
|
||||
bool SharedDatabase::UpdateInventorySlot(uint32 char_id, const ItemInst* inst, int16 slot_id) {
|
||||
// need to check 'inst' argument for valid pointer
|
||||
|
||||
uint32 augslot[EmuConstants::ITEM_COMMON_SIZE] = { NO_ITEM, NO_ITEM, NO_ITEM, NO_ITEM, NO_ITEM, NO_ITEM };
|
||||
if (inst->IsType(ItemClassCommon)) {
|
||||
for (int i = AUG_BEGIN; i < EmuConstants::ITEM_COMMON_SIZE; i++) {
|
||||
ItemInst *auginst = inst->GetItem(i);
|
||||
augslot[i] = (auginst && auginst->GetItem()) ? auginst->GetItem()->ID : NO_ITEM;
|
||||
}
|
||||
}
|
||||
|
||||
uint16 charges = 0;
|
||||
if(inst->GetCharges() >= 0)
|
||||
charges = inst->GetCharges();
|
||||
else
|
||||
charges = 0x7FFF;
|
||||
|
||||
// Update/Insert item
|
||||
std::string query = StringFormat("REPLACE INTO inventory "
|
||||
"(charid, slotid, itemid, charges, instnodrop, custom_data, color, "
|
||||
"augslot1, augslot2, augslot3, augslot4, augslot5, augslot6, ornamenticon, ornamentidfile, ornament_hero_model) "
|
||||
"VALUES( %lu, %lu, %lu, %lu, %lu, '%s', %lu, "
|
||||
"%lu, %lu, %lu, %lu, %lu, %lu, %lu, %lu, %lu)",
|
||||
(unsigned long)char_id, (unsigned long)slot_id, (unsigned long)inst->GetItem()->ID,
|
||||
(unsigned long)charges, (unsigned long)(inst->IsAttuned()? 1: 0),
|
||||
inst->GetCustomDataString().c_str(), (unsigned long)inst->GetColor(),
|
||||
(unsigned long)augslot[0], (unsigned long)augslot[1], (unsigned long)augslot[2],
|
||||
(unsigned long)augslot[3], (unsigned long)augslot[4], (unsigned long)augslot[5], (unsigned long)inst->GetOrnamentationIcon(),
|
||||
(unsigned long)inst->GetOrnamentationIDFile(), (unsigned long)inst->GetOrnamentHeroModel());
|
||||
auto results = QueryDatabase(query);
|
||||
|
||||
// Save bag contents, if slot supports bag contents
|
||||
if (inst->IsType(ItemClassContainer) && Inventory::SupportsContainers(slot_id))
|
||||
// Limiting to bag slot count will get rid of 'hidden' duplicated items and 'Invalid Slot ID'
|
||||
// messages through attrition (and the modded code in SaveInventory)
|
||||
for (uint8 idx = SUB_BEGIN; idx < inst->GetItem()->BagSlots && idx < EmuConstants::ITEM_CONTAINER_SIZE; idx++) {
|
||||
const ItemInst* baginst = inst->GetItem(idx);
|
||||
SaveInventory(char_id, baginst, Inventory::CalcSlotId(slot_id, idx));
|
||||
}
|
||||
|
||||
if (!results.Success()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
|
||||
// need to check 'inst' argument for valid pointer
|
||||
//
|
||||
//uint32 augslot[EmuConstants::ITEM_COMMON_SIZE] = { NO_ITEM, NO_ITEM, NO_ITEM, NO_ITEM, NO_ITEM, NO_ITEM };
|
||||
//if (inst->IsType(ItemClassCommon)) {
|
||||
// for (int i = AUG_BEGIN; i < EmuConstants::ITEM_COMMON_SIZE; i++) {
|
||||
// ItemInst *auginst = inst->GetItem(i);
|
||||
// augslot[i] = (auginst && auginst->GetItem()) ? auginst->GetItem()->ID : NO_ITEM;
|
||||
// }
|
||||
//}
|
||||
//
|
||||
//uint16 charges = 0;
|
||||
//if(inst->GetCharges() >= 0)
|
||||
// charges = inst->GetCharges();
|
||||
//else
|
||||
// charges = 0x7FFF;
|
||||
//
|
||||
//// Update/Insert item
|
||||
//std::string query = StringFormat("REPLACE INTO inventory "
|
||||
// "(charid, slotid, itemid, charges, instnodrop, custom_data, color, "
|
||||
// "augslot1, augslot2, augslot3, augslot4, augslot5, augslot6, ornamenticon, ornamentidfile, ornament_hero_model) "
|
||||
// "VALUES( %lu, %lu, %lu, %lu, %lu, '%s', %lu, "
|
||||
// "%lu, %lu, %lu, %lu, %lu, %lu, %lu, %lu, %lu)",
|
||||
// (unsigned long)char_id, (unsigned long)slot_id, (unsigned long)inst->GetItem()->ID,
|
||||
// (unsigned long)charges, (unsigned long)(inst->IsAttuned()? 1: 0),
|
||||
// inst->GetCustomDataString().c_str(), (unsigned long)inst->GetColor(),
|
||||
// (unsigned long)augslot[0], (unsigned long)augslot[1], (unsigned long)augslot[2],
|
||||
// (unsigned long)augslot[3], (unsigned long)augslot[4], (unsigned long)augslot[5], (unsigned long)inst->GetOrnamentationIcon(),
|
||||
// (unsigned long)inst->GetOrnamentationIDFile(), (unsigned long)inst->GetOrnamentHeroModel());
|
||||
//auto results = QueryDatabase(query);
|
||||
//
|
||||
//// Save bag contents, if slot supports bag contents
|
||||
//if (inst->IsType(ItemClassContainer) && InventoryOld::SupportsContainers(slot_id))
|
||||
// for (uint8 idx = SUB_BEGIN; idx < EmuConstants::ITEM_CONTAINER_SIZE; idx++) {
|
||||
// const ItemInst* baginst = inst->GetItem(idx);
|
||||
// SaveInventory(char_id, baginst, InventoryOld::CalcSlotId(slot_id, idx));
|
||||
// }
|
||||
//
|
||||
//if (!results.Success()) {
|
||||
// return false;
|
||||
//}
|
||||
//
|
||||
//return true;
|
||||
}
|
||||
|
||||
bool SharedDatabase::UpdateSharedBankSlot(uint32 char_id, const ItemInst* inst, int16 slot_id) {
|
||||
@@ -257,12 +255,12 @@ bool SharedDatabase::UpdateSharedBankSlot(uint32 char_id, const ItemInst* inst,
|
||||
auto results = QueryDatabase(query);
|
||||
|
||||
// Save bag contents, if slot supports bag contents
|
||||
if (inst->IsType(ItemClassContainer) && Inventory::SupportsContainers(slot_id)) {
|
||||
if (inst->IsType(ItemClassContainer) && InventoryOld::SupportsContainers(slot_id)) {
|
||||
// Limiting to bag slot count will get rid of 'hidden' duplicated items and 'Invalid Slot ID'
|
||||
// messages through attrition (and the modded code in SaveInventory)
|
||||
for (uint8 idx = SUB_BEGIN; idx < inst->GetItem()->BagSlots && idx < EmuConstants::ITEM_CONTAINER_SIZE; idx++) {
|
||||
const ItemInst* baginst = inst->GetItem(idx);
|
||||
SaveInventory(char_id, baginst, Inventory::CalcSlotId(slot_id, idx));
|
||||
SaveInventory(char_id, baginst, InventoryOld::CalcSlotId(slot_id, idx));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -283,10 +281,10 @@ bool SharedDatabase::DeleteInventorySlot(uint32 char_id, int16 slot_id) {
|
||||
}
|
||||
|
||||
// Delete bag slots, if need be
|
||||
if (!Inventory::SupportsContainers(slot_id))
|
||||
if (!InventoryOld::SupportsContainers(slot_id))
|
||||
return true;
|
||||
|
||||
int16 base_slot_id = Inventory::CalcSlotId(slot_id, SUB_BEGIN);
|
||||
int16 base_slot_id = InventoryOld::CalcSlotId(slot_id, SUB_BEGIN);
|
||||
query = StringFormat("DELETE FROM inventory WHERE charid = %i AND slotid >= %i AND slotid < %i",
|
||||
char_id, base_slot_id, (base_slot_id+10));
|
||||
results = QueryDatabase(query);
|
||||
@@ -309,10 +307,10 @@ bool SharedDatabase::DeleteSharedBankSlot(uint32 char_id, int16 slot_id) {
|
||||
}
|
||||
|
||||
// Delete bag slots, if need be
|
||||
if (!Inventory::SupportsContainers(slot_id))
|
||||
if (!InventoryOld::SupportsContainers(slot_id))
|
||||
return true;
|
||||
|
||||
int16 base_slot_id = Inventory::CalcSlotId(slot_id, SUB_BEGIN);
|
||||
int16 base_slot_id = InventoryOld::CalcSlotId(slot_id, SUB_BEGIN);
|
||||
query = StringFormat("DELETE FROM sharedbank WHERE acctid = %i "
|
||||
"AND slotid >= %i AND slotid < %i",
|
||||
account_id, base_slot_id, (base_slot_id+10));
|
||||
@@ -352,9 +350,9 @@ bool SharedDatabase::SetSharedPlatinum(uint32 account_id, int32 amount_to_add) {
|
||||
return true;
|
||||
}
|
||||
|
||||
bool SharedDatabase::SetStartingItems(PlayerProfile_Struct* pp, Inventory* inv, uint32 si_race, uint32 si_class, uint32 si_deity, uint32 si_current_zone, char* si_name, int admin_level) {
|
||||
bool SharedDatabase::SetStartingItems(PlayerProfile_Struct* pp, InventoryOld* inv, uint32 si_race, uint32 si_class, uint32 si_deity, uint32 si_current_zone, char* si_name, int admin_level) {
|
||||
|
||||
const Item_Struct* myitem;
|
||||
const ItemData* myitem;
|
||||
|
||||
std::string query = StringFormat("SELECT itemid, item_charges, slot FROM starting_items "
|
||||
"WHERE (race = %i or race = 0) AND (class = %i or class = 0) AND "
|
||||
@@ -375,7 +373,7 @@ bool SharedDatabase::SetStartingItems(PlayerProfile_Struct* pp, Inventory* inv,
|
||||
if(!myitem)
|
||||
continue;
|
||||
|
||||
ItemInst* myinst = CreateBaseItem(myitem, charges);
|
||||
ItemInst* myinst = CreateBaseItemOld(myitem, charges);
|
||||
|
||||
if(slot < 0)
|
||||
slot = inv->FindFreeSlot(0, 0);
|
||||
@@ -389,7 +387,7 @@ bool SharedDatabase::SetStartingItems(PlayerProfile_Struct* pp, Inventory* inv,
|
||||
|
||||
|
||||
// Retrieve shared bank inventory based on either account or character
|
||||
bool SharedDatabase::GetSharedBank(uint32 id, Inventory *inv, bool is_charid)
|
||||
bool SharedDatabase::GetSharedBank(uint32 id, InventoryOld *inv, bool is_charid)
|
||||
{
|
||||
std::string query;
|
||||
|
||||
@@ -426,7 +424,7 @@ bool SharedDatabase::GetSharedBank(uint32 id, Inventory *inv, bool is_charid)
|
||||
aug[4] = (uint32)atoi(row[7]);
|
||||
aug[5] = (uint32)atoi(row[8]);
|
||||
|
||||
const Item_Struct *item = GetItem(item_id);
|
||||
const ItemData *item = GetItem(item_id);
|
||||
|
||||
if (!item) {
|
||||
Log.Out(Logs::General, Logs::Error,
|
||||
@@ -437,7 +435,7 @@ bool SharedDatabase::GetSharedBank(uint32 id, Inventory *inv, bool is_charid)
|
||||
|
||||
int16 put_slot_id = INVALID_INDEX;
|
||||
|
||||
ItemInst *inst = CreateBaseItem(item, charges);
|
||||
ItemInst *inst = CreateBaseItemOld(item, charges);
|
||||
if (inst && item->ItemClass == ItemClassCommon) {
|
||||
for (int i = AUG_BEGIN; i < EmuConstants::ITEM_COMMON_SIZE; i++) {
|
||||
if (aug[i])
|
||||
@@ -489,150 +487,68 @@ bool SharedDatabase::GetSharedBank(uint32 id, Inventory *inv, bool is_charid)
|
||||
}
|
||||
|
||||
// Overloaded: Retrieve character inventory based on character id
|
||||
bool SharedDatabase::GetInventory(uint32 char_id, Inventory *inv)
|
||||
bool SharedDatabase::GetInventory(uint32 char_id, EQEmu::Inventory *inv)
|
||||
{
|
||||
// Retrieve character inventory
|
||||
std::string query =
|
||||
StringFormat("SELECT slotid, itemid, charges, color, augslot1, augslot2, augslot3, augslot4, augslot5, "
|
||||
"augslot6, instnodrop, custom_data, ornamenticon, ornamentidfile, ornament_hero_model FROM "
|
||||
"inventory WHERE charid = %i ORDER BY slotid",
|
||||
char_id);
|
||||
std::string query = StringFormat("SELECT type, slot, bag_index, aug_index, item_id, charges, color, attuned, "
|
||||
"custom_data, ornament_icon, ornament_idfile, ornament_hero_model, tracking_id "
|
||||
"FROM character_inventory WHERE id=%u ORDER BY type, slot, bag_index, aug_index",
|
||||
char_id);
|
||||
|
||||
auto results = QueryDatabase(query);
|
||||
|
||||
if (!results.Success()) {
|
||||
Log.Out(Logs::General, Logs::Error, "If you got an error related to the 'instnodrop' field, run the "
|
||||
"following SQL Queries:\nalter table inventory add instnodrop "
|
||||
"tinyint(1) unsigned default 0 not null;\n");
|
||||
Log.Out(Logs::General, Logs::Error, "Error with query in SharedDatabase::GetInventory, could not get inventory"
|
||||
" for character %u", char_id);
|
||||
return false;
|
||||
}
|
||||
|
||||
auto timestamps = GetItemRecastTimestamps(char_id);
|
||||
for(auto row : results) {
|
||||
int type = atoi(row[0]);
|
||||
int slot = atoi(row[1]);
|
||||
int bag_index = atoi(row[2]);
|
||||
int aug_index = atoi(row[3]);
|
||||
int item_id = atoi(row[4]);
|
||||
int charges = atoi(row[5]);
|
||||
|
||||
for (auto row = results.begin(); row != results.end(); ++row) {
|
||||
int16 slot_id = atoi(row[0]);
|
||||
uint32 item_id = atoi(row[1]);
|
||||
uint16 charges = atoi(row[2]);
|
||||
uint32 color = atoul(row[3]);
|
||||
auto inst = CreateItem(item_id, charges);
|
||||
if(inst) {
|
||||
uint32 color = (uint32)std::stoul(row[6]);
|
||||
int attuned = atoi(row[7]);
|
||||
uint32 ornament_icon = (uint32)std::stoul(row[9]);
|
||||
uint32 ornament_idfile = (uint32)std::stoul(row[10]);
|
||||
uint32 ornament_hero_model = (uint32)std::stoul(row[11]);
|
||||
|
||||
uint32 aug[EmuConstants::ITEM_COMMON_SIZE];
|
||||
|
||||
aug[0] = (uint32)atoul(row[4]);
|
||||
aug[1] = (uint32)atoul(row[5]);
|
||||
aug[2] = (uint32)atoul(row[6]);
|
||||
aug[3] = (uint32)atoul(row[7]);
|
||||
aug[4] = (uint32)atoul(row[8]);
|
||||
aug[5] = (uint32)atoul(row[9]);
|
||||
|
||||
bool instnodrop = (row[10] && (uint16)atoi(row[10])) ? true : false;
|
||||
|
||||
uint32 ornament_icon = (uint32)atoul(row[12]);
|
||||
uint32 ornament_idfile = (uint32)atoul(row[13]);
|
||||
uint32 ornament_hero_model = (uint32)atoul(row[14]);
|
||||
|
||||
const Item_Struct *item = GetItem(item_id);
|
||||
|
||||
if (!item) {
|
||||
Log.Out(Logs::General, Logs::Error,
|
||||
"Warning: charid %i has an invalid item_id %i in inventory slot %i", char_id, item_id,
|
||||
slot_id);
|
||||
continue;
|
||||
}
|
||||
|
||||
int16 put_slot_id = INVALID_INDEX;
|
||||
|
||||
ItemInst *inst = CreateBaseItem(item, charges);
|
||||
|
||||
if (inst == nullptr)
|
||||
continue;
|
||||
|
||||
if (row[11]) {
|
||||
std::string data_str(row[11]);
|
||||
std::string idAsString;
|
||||
std::string value;
|
||||
bool use_id = true;
|
||||
|
||||
for (int i = 0; i < data_str.length(); ++i) {
|
||||
if (data_str[i] == '^') {
|
||||
if (!use_id) {
|
||||
inst->SetCustomData(idAsString, value);
|
||||
idAsString.clear();
|
||||
value.clear();
|
||||
}
|
||||
|
||||
use_id = !use_id;
|
||||
continue;
|
||||
}
|
||||
|
||||
char v = data_str[i];
|
||||
if (use_id)
|
||||
idAsString.push_back(v);
|
||||
else
|
||||
value.push_back(v);
|
||||
}
|
||||
}
|
||||
|
||||
inst->SetOrnamentIcon(ornament_icon);
|
||||
inst->SetOrnamentationIDFile(ornament_idfile);
|
||||
inst->SetOrnamentHeroModel(ornament_hero_model);
|
||||
|
||||
if (instnodrop ||
|
||||
(((slot_id >= EmuConstants::EQUIPMENT_BEGIN && slot_id <= EmuConstants::EQUIPMENT_END) ||
|
||||
slot_id == MainPowerSource) &&
|
||||
inst->GetItem()->Attuneable))
|
||||
inst->SetAttuned(true);
|
||||
|
||||
if (color > 0)
|
||||
inst->SetColor(color);
|
||||
inst->SetAttuned(attuned ? true : false);
|
||||
inst->SetCustomData(row[8]);
|
||||
inst->SetOrnamentIcon(ornament_icon);
|
||||
inst->SetOrnamentIDFile(ornament_idfile);
|
||||
inst->SetOrnamentHeroModel(ornament_hero_model);
|
||||
inst->SetTrackingID(row[12]);
|
||||
|
||||
if (charges == 0x7FFF)
|
||||
inst->SetCharges(-1);
|
||||
else if (charges == 0 &&
|
||||
inst->IsStackable()) // Stackable items need a minimum charge of 1 remain moveable.
|
||||
inst->SetCharges(1);
|
||||
else
|
||||
inst->SetCharges(charges);
|
||||
|
||||
if (item->RecastDelay) {
|
||||
if (timestamps.count(item->RecastType))
|
||||
inst->SetRecastTimestamp(timestamps.at(item->RecastType));
|
||||
else
|
||||
inst->SetRecastTimestamp(0);
|
||||
}
|
||||
|
||||
if (item->ItemClass == ItemClassCommon) {
|
||||
for (int i = AUG_BEGIN; i < EmuConstants::ITEM_COMMON_SIZE; i++) {
|
||||
if (aug[i])
|
||||
inst->PutAugment(this, i, aug[i]);
|
||||
auto *item = inst->GetItem();
|
||||
if(item->RecastDelay) {
|
||||
if(timestamps.count(item->RecastType)) {
|
||||
inst->SetRecastTimestamp(timestamps.at(item->RecastType));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (slot_id >= 8000 && slot_id <= 8999) {
|
||||
put_slot_id = inv->PushCursor(*inst);
|
||||
} else if (slot_id >= 3111 && slot_id <= 3179) {
|
||||
// Admins: please report any occurrences of this error
|
||||
Log.Out(Logs::General, Logs::Error, "Warning: Defunct location for item in inventory: "
|
||||
"charid=%i, item_id=%i, slot_id=%i .. pushing to cursor...",
|
||||
char_id, item_id, slot_id);
|
||||
put_slot_id = inv->PushCursor(*inst);
|
||||
if(!inv->Put(EQEmu::InventorySlot(type, slot, bag_index, aug_index), inst)) {
|
||||
Log.Out(Logs::General, Logs::Error, "Error putting item %u into (%d, %d, %d, %d) for char %u.",
|
||||
item_id, type, slot, bag_index, aug_index, char_id);
|
||||
}
|
||||
} else {
|
||||
put_slot_id = inv->PutItem(slot_id, *inst);
|
||||
}
|
||||
|
||||
safe_delete(inst);
|
||||
|
||||
// Save ptr to item in inventory
|
||||
if (put_slot_id == INVALID_INDEX) {
|
||||
Log.Out(Logs::General, Logs::Error,
|
||||
"Warning: Invalid slot_id for item in inventory: charid=%i, item_id=%i, slot_id=%i",
|
||||
char_id, item_id, slot_id);
|
||||
Log.Out(Logs::General, Logs::Error, "Error putting item %u into (%d, %d, %d, %d) for char %u. Item does not exist.",
|
||||
item_id, type, slot, bag_index, aug_index, char_id);
|
||||
}
|
||||
}
|
||||
|
||||
// Retrieve shared inventory
|
||||
return GetSharedBank(char_id, inv, true);
|
||||
return true;
|
||||
}
|
||||
|
||||
// Overloaded: Retrieve character inventory based on account_id and character name
|
||||
bool SharedDatabase::GetInventory(uint32 account_id, char *name, Inventory *inv)
|
||||
bool SharedDatabase::GetInventory(uint32 account_id, char *name, InventoryOld *inv)
|
||||
{
|
||||
// Retrieve character inventory
|
||||
std::string query =
|
||||
@@ -669,12 +585,12 @@ bool SharedDatabase::GetInventory(uint32 account_id, char *name, Inventory *inv)
|
||||
uint32 ornament_idfile = (uint32)atoul(row[13]);
|
||||
uint32 ornament_hero_model = (uint32)atoul(row[14]);
|
||||
|
||||
const Item_Struct *item = GetItem(item_id);
|
||||
const ItemData *item = GetItem(item_id);
|
||||
int16 put_slot_id = INVALID_INDEX;
|
||||
if (!item)
|
||||
continue;
|
||||
|
||||
ItemInst *inst = CreateBaseItem(item, charges);
|
||||
ItemInst *inst = CreateBaseItemOld(item, charges);
|
||||
|
||||
if (inst == nullptr)
|
||||
continue;
|
||||
@@ -813,12 +729,12 @@ bool SharedDatabase::LoadItems() {
|
||||
if(items == -1) {
|
||||
EQ_EXCEPT("SharedDatabase", "Database returned no result");
|
||||
}
|
||||
uint32 size = static_cast<uint32>(EQEmu::FixedMemoryHashSet<Item_Struct>::estimated_size(items, max_item));
|
||||
uint32 size = static_cast<uint32>(EQEmu::FixedMemoryHashSet<ItemData>::estimated_size(items, max_item));
|
||||
if(items_mmf->Size() != size) {
|
||||
EQ_EXCEPT("SharedDatabase", "Couldn't load items because items_mmf->Size() != size");
|
||||
}
|
||||
|
||||
items_hash = new EQEmu::FixedMemoryHashSet<Item_Struct>(reinterpret_cast<uint8*>(items_mmf->Get()), size);
|
||||
items_hash = new EQEmu::FixedMemoryHashSet<ItemData>(reinterpret_cast<uint8*>(items_mmf->Get()), size);
|
||||
mutex.Unlock();
|
||||
} catch(std::exception& ex) {
|
||||
Log.Out(Logs::General, Logs::Error, "Error Loading Items: %s", ex.what());
|
||||
@@ -829,7 +745,7 @@ bool SharedDatabase::LoadItems() {
|
||||
}
|
||||
|
||||
void SharedDatabase::LoadItems(void *data, uint32 size, int32 items, uint32 max_item_id) {
|
||||
EQEmu::FixedMemoryHashSet<Item_Struct> hash(reinterpret_cast<uint8*>(data), size, items, max_item_id);
|
||||
EQEmu::FixedMemoryHashSet<ItemData> hash(reinterpret_cast<uint8*>(data), size, items, max_item_id);
|
||||
|
||||
char ndbuffer[4];
|
||||
bool disableNoRent = false;
|
||||
@@ -857,7 +773,7 @@ void SharedDatabase::LoadItems(void *data, uint32 size, int32 items, uint32 max_
|
||||
}
|
||||
}
|
||||
|
||||
Item_Struct item;
|
||||
ItemData item;
|
||||
|
||||
const std::string query = "SELECT source,"
|
||||
#define F(x) "`"#x"`,"
|
||||
@@ -870,7 +786,7 @@ void SharedDatabase::LoadItems(void *data, uint32 size, int32 items, uint32 max_
|
||||
}
|
||||
|
||||
for(auto row = results.begin(); row != results.end(); ++row) {
|
||||
memset(&item, 0, sizeof(Item_Struct));
|
||||
memset(&item, 0, sizeof(ItemData));
|
||||
|
||||
item.ItemClass = (uint8)atoi(row[ItemField::itemclass]);
|
||||
strcpy(item.Name,row[ItemField::name]);
|
||||
@@ -1085,7 +1001,7 @@ void SharedDatabase::LoadItems(void *data, uint32 size, int32 items, uint32 max_
|
||||
|
||||
}
|
||||
|
||||
const Item_Struct* SharedDatabase::GetItem(uint32 id) {
|
||||
const ItemData* SharedDatabase::GetItem(uint32 id) {
|
||||
if (id == 0)
|
||||
{
|
||||
return nullptr;
|
||||
@@ -1104,7 +1020,7 @@ const Item_Struct* SharedDatabase::GetItem(uint32 id) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
const Item_Struct* SharedDatabase::IterateItems(uint32* id) {
|
||||
const ItemData* SharedDatabase::IterateItems(uint32* id) {
|
||||
if(!items_hash || !id) {
|
||||
return nullptr;
|
||||
}
|
||||
@@ -1260,14 +1176,14 @@ bool SharedDatabase::LoadNPCFactionLists() {
|
||||
}
|
||||
|
||||
// Create appropriate ItemInst class
|
||||
ItemInst* SharedDatabase::CreateItem(uint32 item_id, int16 charges, uint32 aug1, uint32 aug2, uint32 aug3, uint32 aug4, uint32 aug5, uint32 aug6, uint8 attuned)
|
||||
ItemInst* SharedDatabase::CreateItemOld(uint32 item_id, int16 charges, uint32 aug1, uint32 aug2, uint32 aug3, uint32 aug4, uint32 aug5, uint32 aug6, uint8 attuned)
|
||||
{
|
||||
const Item_Struct* item = nullptr;
|
||||
const ItemData* item = nullptr;
|
||||
ItemInst* inst = nullptr;
|
||||
|
||||
item = GetItem(item_id);
|
||||
if (item) {
|
||||
inst = CreateBaseItem(item, charges);
|
||||
inst = CreateBaseItemOld(item, charges);
|
||||
|
||||
if (inst == nullptr) {
|
||||
Log.Out(Logs::General, Logs::Error, "Error: valid item data returned a null reference for ItemInst creation in SharedDatabase::CreateItem()");
|
||||
@@ -1289,14 +1205,14 @@ ItemInst* SharedDatabase::CreateItem(uint32 item_id, int16 charges, uint32 aug1,
|
||||
|
||||
|
||||
// Create appropriate ItemInst class
|
||||
ItemInst* SharedDatabase::CreateItem(const Item_Struct* item, int16 charges, uint32 aug1, uint32 aug2, uint32 aug3, uint32 aug4, uint32 aug5, uint32 aug6, uint8 attuned)
|
||||
ItemInst* SharedDatabase::CreateItemOld(const ItemData* item, int16 charges, uint32 aug1, uint32 aug2, uint32 aug3, uint32 aug4, uint32 aug5, uint32 aug6, uint8 attuned)
|
||||
{
|
||||
ItemInst* inst = nullptr;
|
||||
if (item) {
|
||||
inst = CreateBaseItem(item, charges);
|
||||
inst = CreateBaseItemOld(item, charges);
|
||||
|
||||
if (inst == nullptr) {
|
||||
Log.Out(Logs::General, Logs::Error, "Error: valid item data returned a null reference for ItemInst creation in SharedDatabase::CreateItem()");
|
||||
Log.Out(Logs::General, Logs::Error, "Error: valid item data returned a null reference for ItemInst creation in SharedDatabase::CreateItemOld()");
|
||||
Log.Out(Logs::General, Logs::Error, "Item Data = ID: %u, Name: %s, Charges: %i", item->ID, item->Name, charges);
|
||||
return nullptr;
|
||||
}
|
||||
@@ -1313,7 +1229,7 @@ ItemInst* SharedDatabase::CreateItem(const Item_Struct* item, int16 charges, uin
|
||||
return inst;
|
||||
}
|
||||
|
||||
ItemInst* SharedDatabase::CreateBaseItem(const Item_Struct* item, int16 charges) {
|
||||
ItemInst* SharedDatabase::CreateBaseItemOld(const ItemData* item, int16 charges) {
|
||||
ItemInst* inst = nullptr;
|
||||
if (item) {
|
||||
// if maxcharges is -1 that means it is an unlimited use item.
|
||||
@@ -1327,7 +1243,7 @@ ItemInst* SharedDatabase::CreateBaseItem(const Item_Struct* item, int16 charges)
|
||||
inst = new ItemInst(item, charges);
|
||||
|
||||
if (inst == nullptr) {
|
||||
Log.Out(Logs::General, Logs::Error, "Error: valid item data returned a null reference for ItemInst creation in SharedDatabase::CreateBaseItem()");
|
||||
Log.Out(Logs::General, Logs::Error, "Error: valid item data returned a null reference for ItemInst creation in SharedDatabase::CreateBaseItemOld()");
|
||||
Log.Out(Logs::General, Logs::Error, "Item Data = ID: %u, Name: %s, Charges: %i", item->ID, item->Name, charges);
|
||||
return nullptr;
|
||||
}
|
||||
@@ -1339,6 +1255,28 @@ ItemInst* SharedDatabase::CreateBaseItem(const Item_Struct* item, int16 charges)
|
||||
return inst;
|
||||
}
|
||||
|
||||
EQEmu::ItemInstance::pointer SharedDatabase::CreateItem(uint32 item_id, int16 charges, bool unique) {
|
||||
const ItemData* item = GetItem(item_id);
|
||||
if(item) {
|
||||
if(charges == 0 && item->MaxCharges == -1) {
|
||||
charges = 1;
|
||||
}
|
||||
|
||||
if(charges <= 0 && item->Stackable) {
|
||||
charges = 1;
|
||||
}
|
||||
|
||||
EQEmu::ItemInstance::pointer inst = EQEmu::ItemInstance::pointer(new EQEmu::ItemInstance(item, charges));
|
||||
if(unique) {
|
||||
inst->SetSerialNumber(EQEmu::GetNextItemInstanceSerial());
|
||||
//Set Tracking here
|
||||
}
|
||||
return inst;
|
||||
}
|
||||
|
||||
return EQEmu::ItemInstance::pointer(nullptr);
|
||||
}
|
||||
|
||||
int32 SharedDatabase::DeleteStalePlayerCorpses() {
|
||||
if(RuleB(Zone, EnableShadowrest)) {
|
||||
std::string query = StringFormat(
|
||||
|
||||
+14
-12
@@ -9,18 +9,19 @@
|
||||
#include "base_data.h"
|
||||
#include "fixed_memory_hash_set.h"
|
||||
#include "fixed_memory_variable_hash_set.h"
|
||||
#include "inventory.h"
|
||||
|
||||
#include <list>
|
||||
#include <map>
|
||||
|
||||
class EvolveInfo;
|
||||
class Inventory;
|
||||
class InventoryOld;
|
||||
class ItemInst;
|
||||
struct BaseDataStruct;
|
||||
struct InspectMessage_Struct;
|
||||
struct PlayerProfile_Struct;
|
||||
struct SPDat_Spell_Struct;
|
||||
struct Item_Struct;
|
||||
struct ItemData;
|
||||
struct NPCFactionList;
|
||||
struct LootTable_Struct;
|
||||
struct LootDrop_Struct;
|
||||
@@ -65,15 +66,15 @@ class SharedDatabase : public Database
|
||||
bool UpdateInventorySlot(uint32 char_id, const ItemInst* inst, int16 slot_id);
|
||||
bool UpdateSharedBankSlot(uint32 char_id, const ItemInst* inst, int16 slot_id);
|
||||
bool VerifyInventory(uint32 account_id, int16 slot_id, const ItemInst* inst);
|
||||
bool GetSharedBank(uint32 id, Inventory* inv, bool is_charid);
|
||||
bool GetSharedBank(uint32 id, InventoryOld* inv, bool is_charid);
|
||||
int32 GetSharedPlatinum(uint32 account_id);
|
||||
bool SetSharedPlatinum(uint32 account_id, int32 amount_to_add);
|
||||
bool GetInventory(uint32 char_id, Inventory* inv);
|
||||
bool GetInventory(uint32 account_id, char* name, Inventory* inv);
|
||||
bool GetInventory(uint32 char_id, EQEmu::Inventory* inv);
|
||||
bool GetInventory(uint32 account_id, char* name, InventoryOld* inv);
|
||||
std::map<uint32, uint32> GetItemRecastTimestamps(uint32 char_id);
|
||||
uint32 GetItemRecastTimestamp(uint32 char_id, uint32 recast_type);
|
||||
void ClearOldRecastTimestamps(uint32 char_id);
|
||||
bool SetStartingItems(PlayerProfile_Struct* pp, Inventory* inv, uint32 si_race, uint32 si_class, uint32 si_deity, uint32 si_current_zone, char* si_name, int admin);
|
||||
bool SetStartingItems(PlayerProfile_Struct* pp, InventoryOld* inv, uint32 si_race, uint32 si_class, uint32 si_deity, uint32 si_current_zone, char* si_name, int admin);
|
||||
|
||||
|
||||
std::string GetBook(const char *txtfile);
|
||||
@@ -81,9 +82,10 @@ class SharedDatabase : public Database
|
||||
/*
|
||||
Item Methods
|
||||
*/
|
||||
ItemInst* CreateItem(uint32 item_id, int16 charges = 0, uint32 aug1 = 0, uint32 aug2 = 0, uint32 aug3 = 0, uint32 aug4 = 0, uint32 aug5 = 0, uint32 aug6 = 0, uint8 attuned = 0);
|
||||
ItemInst* CreateItem(const Item_Struct* item, int16 charges = 0, uint32 aug1 = 0, uint32 aug2 = 0, uint32 aug3 = 0, uint32 aug4 = 0, uint32 aug5 = 0, uint32 aug6 = 0, uint8 attuned = 0);
|
||||
ItemInst* CreateBaseItem(const Item_Struct* item, int16 charges = 0);
|
||||
ItemInst* CreateItemOld(uint32 item_id, int16 charges = 0, uint32 aug1 = 0, uint32 aug2 = 0, uint32 aug3 = 0, uint32 aug4 = 0, uint32 aug5 = 0, uint32 aug6 = 0, uint8 attuned = 0);
|
||||
ItemInst* CreateItemOld(const ItemData* item, int16 charges = 0, uint32 aug1 = 0, uint32 aug2 = 0, uint32 aug3 = 0, uint32 aug4 = 0, uint32 aug5 = 0, uint32 aug6 = 0, uint8 attuned = 0);
|
||||
ItemInst* CreateBaseItemOld(const ItemData* item, int16 charges = 0);
|
||||
EQEmu::ItemInstance::pointer CreateItem(uint32 item_id, int16 charges = 0, bool unique = true);
|
||||
|
||||
/*
|
||||
Shared Memory crap
|
||||
@@ -93,8 +95,8 @@ class SharedDatabase : public Database
|
||||
void GetItemsCount(int32 &item_count, uint32 &max_id);
|
||||
void LoadItems(void *data, uint32 size, int32 items, uint32 max_item_id);
|
||||
bool LoadItems();
|
||||
const Item_Struct* IterateItems(uint32* id);
|
||||
const Item_Struct* GetItem(uint32 id);
|
||||
const ItemData* IterateItems(uint32* id);
|
||||
const ItemData* GetItem(uint32 id);
|
||||
const EvolveInfo* GetEvolveInfo(uint32 loregroup);
|
||||
|
||||
//faction lists
|
||||
@@ -130,7 +132,7 @@ class SharedDatabase : public Database
|
||||
|
||||
EQEmu::MemoryMappedFile *skill_caps_mmf;
|
||||
EQEmu::MemoryMappedFile *items_mmf;
|
||||
EQEmu::FixedMemoryHashSet<Item_Struct> *items_hash;
|
||||
EQEmu::FixedMemoryHashSet<ItemData> *items_hash;
|
||||
EQEmu::MemoryMappedFile *faction_mmf;
|
||||
EQEmu::FixedMemoryHashSet<NPCFactionList> *faction_hash;
|
||||
EQEmu::MemoryMappedFile *loot_table_mmf;
|
||||
|
||||
@@ -123,229 +123,6 @@ void Database::AddSpeech(const char* from, const char* to, const char* message,
|
||||
|
||||
}
|
||||
|
||||
void Database::LogPlayerTrade(QSPlayerLogTrade_Struct* QS, uint32 detailCount) {
|
||||
|
||||
std::string query = StringFormat("INSERT INTO `qs_player_trade_record` SET `time` = NOW(), "
|
||||
"`char1_id` = '%i', `char1_pp` = '%i', `char1_gp` = '%i', "
|
||||
"`char1_sp` = '%i', `char1_cp` = '%i', `char1_items` = '%i', "
|
||||
"`char2_id` = '%i', `char2_pp` = '%i', `char2_gp` = '%i', "
|
||||
"`char2_sp` = '%i', `char2_cp` = '%i', `char2_items` = '%i'",
|
||||
QS->char1_id, QS->char1_money.platinum, QS->char1_money.gold,
|
||||
QS->char1_money.silver, QS->char1_money.copper, QS->char1_count,
|
||||
QS->char2_id, QS->char2_money.platinum, QS->char2_money.gold,
|
||||
QS->char2_money.silver, QS->char2_money.copper, QS->char2_count);
|
||||
auto results = QueryDatabase(query);
|
||||
if(!results.Success()) {
|
||||
Log.Out(Logs::Detail, Logs::QS_Server, "Failed Trade Log Record Insert: %s", results.ErrorMessage().c_str());
|
||||
Log.Out(Logs::Detail, Logs::QS_Server, "%s", query.c_str());
|
||||
}
|
||||
|
||||
if(detailCount == 0)
|
||||
return;
|
||||
|
||||
int lastIndex = results.LastInsertedID();
|
||||
|
||||
for(int i = 0; i < detailCount; i++) {
|
||||
query = StringFormat("INSERT INTO `qs_player_trade_record_entries` SET `event_id` = '%i', "
|
||||
"`from_id` = '%i', `from_slot` = '%i', `to_id` = '%i', `to_slot` = '%i', "
|
||||
"`item_id` = '%i', `charges` = '%i', `aug_1` = '%i', `aug_2` = '%i', "
|
||||
"`aug_3` = '%i', `aug_4` = '%i', `aug_5` = '%i'",
|
||||
lastIndex, QS->items[i].from_id, QS->items[i].from_slot,
|
||||
QS->items[i].to_id, QS->items[i].to_slot, QS->items[i].item_id,
|
||||
QS->items[i].charges, QS->items[i].aug_1, QS->items[i].aug_2,
|
||||
QS->items[i].aug_3, QS->items[i].aug_4, QS->items[i].aug_5);
|
||||
results = QueryDatabase(query);
|
||||
if(!results.Success()) {
|
||||
Log.Out(Logs::Detail, Logs::QS_Server, "Failed Trade Log Record Entry Insert: %s", results.ErrorMessage().c_str());
|
||||
Log.Out(Logs::Detail, Logs::QS_Server, "%s", query.c_str());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void Database::LogPlayerHandin(QSPlayerLogHandin_Struct* QS, uint32 detailCount) {
|
||||
|
||||
std::string query = StringFormat("INSERT INTO `qs_player_handin_record` SET `time` = NOW(), "
|
||||
"`quest_id` = '%i', `char_id` = '%i', `char_pp` = '%i', "
|
||||
"`char_gp` = '%i', `char_sp` = '%i', `char_cp` = '%i', "
|
||||
"`char_items` = '%i', `npc_id` = '%i', `npc_pp` = '%i', "
|
||||
"`npc_gp` = '%i', `npc_sp` = '%i', `npc_cp` = '%i', "
|
||||
"`npc_items`='%i'",
|
||||
QS->quest_id, QS->char_id, QS->char_money.platinum,
|
||||
QS->char_money.gold, QS->char_money.silver, QS->char_money.copper,
|
||||
QS->char_count, QS->npc_id, QS->npc_money.platinum,
|
||||
QS->npc_money.gold, QS->npc_money.silver, QS->npc_money.copper,
|
||||
QS->npc_count);
|
||||
auto results = QueryDatabase(query);
|
||||
if(!results.Success()) {
|
||||
Log.Out(Logs::Detail, Logs::QS_Server, "Failed Handin Log Record Insert: %s", results.ErrorMessage().c_str());
|
||||
Log.Out(Logs::Detail, Logs::QS_Server, "%s", query.c_str());
|
||||
}
|
||||
|
||||
if(detailCount == 0)
|
||||
return;
|
||||
|
||||
int lastIndex = results.LastInsertedID();
|
||||
|
||||
for(int i = 0; i < detailCount; i++) {
|
||||
query = StringFormat("INSERT INTO `qs_player_handin_record_entries` SET `event_id` = '%i', "
|
||||
"`action_type` = '%s', `char_slot` = '%i', `item_id` = '%i', "
|
||||
"`charges` = '%i', `aug_1` = '%i', `aug_2` = '%i', `aug_3` = '%i', "
|
||||
"`aug_4` = '%i', `aug_5` = '%i'",
|
||||
lastIndex, QS->items[i].action_type, QS->items[i].char_slot,
|
||||
QS->items[i].item_id, QS->items[i].charges, QS->items[i].aug_1,
|
||||
QS->items[i].aug_2, QS->items[i].aug_3, QS->items[i].aug_4,
|
||||
QS->items[i].aug_5);
|
||||
if(!results.Success()) {
|
||||
Log.Out(Logs::Detail, Logs::QS_Server, "Failed Handin Log Record Entry Insert: %s", results.ErrorMessage().c_str());
|
||||
Log.Out(Logs::Detail, Logs::QS_Server, "%s", query.c_str());
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void Database::LogPlayerNPCKill(QSPlayerLogNPCKill_Struct* QS, uint32 members){
|
||||
|
||||
std::string query = StringFormat("INSERT INTO `qs_player_npc_kill_record` "
|
||||
"SET `npc_id` = '%i', `type` = '%i', "
|
||||
"`zone_id` = '%i', `time` = NOW()",
|
||||
QS->s1.NPCID, QS->s1.Type, QS->s1.ZoneID);
|
||||
auto results = QueryDatabase(query);
|
||||
if(!results.Success()) {
|
||||
Log.Out(Logs::Detail, Logs::QS_Server, "Failed NPC Kill Log Record Insert: %s", results.ErrorMessage().c_str());
|
||||
Log.Out(Logs::Detail, Logs::QS_Server, "%s", query.c_str());
|
||||
}
|
||||
|
||||
if(members == 0)
|
||||
return;
|
||||
|
||||
int lastIndex = results.LastInsertedID();
|
||||
|
||||
for (int i = 0; i < members; i++) {
|
||||
query = StringFormat("INSERT INTO `qs_player_npc_kill_record_entries` "
|
||||
"SET `event_id` = '%i', `char_id` = '%i'",
|
||||
lastIndex, QS->Chars[i].char_id);
|
||||
auto results = QueryDatabase(query);
|
||||
if(!results.Success()) {
|
||||
Log.Out(Logs::Detail, Logs::QS_Server, "Failed NPC Kill Log Entry Insert: %s", results.ErrorMessage().c_str());
|
||||
Log.Out(Logs::Detail, Logs::QS_Server, "%s", query.c_str());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void Database::LogPlayerDelete(QSPlayerLogDelete_Struct* QS, uint32 items) {
|
||||
|
||||
std::string query = StringFormat("INSERT INTO `qs_player_delete_record` SET `time` = NOW(), "
|
||||
"`char_id` = '%i', `stack_size` = '%i', `char_items` = '%i'",
|
||||
QS->char_id, QS->stack_size, QS->char_count, QS->char_count);
|
||||
auto results = QueryDatabase(query);
|
||||
if(!results.Success()) {
|
||||
Log.Out(Logs::Detail, Logs::QS_Server, "Failed Delete Log Record Insert: %s", results.ErrorMessage().c_str());
|
||||
Log.Out(Logs::Detail, Logs::QS_Server, "%s", query.c_str());
|
||||
}
|
||||
|
||||
if(items == 0)
|
||||
return;
|
||||
|
||||
int lastIndex = results.LastInsertedID();
|
||||
|
||||
for(int i = 0; i < items; i++) {
|
||||
query = StringFormat("INSERT INTO `qs_player_delete_record_entries` SET `event_id` = '%i', "
|
||||
"`char_slot` = '%i', `item_id` = '%i', `charges` = '%i', `aug_1` = '%i', "
|
||||
"`aug_2` = '%i', `aug_3` = '%i', `aug_4` = '%i', `aug_5` = '%i'",
|
||||
lastIndex, QS->items[i].char_slot, QS->items[i].item_id, QS->items[i].charges,
|
||||
QS->items[i].aug_1, QS->items[i].aug_2, QS->items[i].aug_3, QS->items[i].aug_4,
|
||||
QS->items[i].aug_5);
|
||||
results = QueryDatabase(query);
|
||||
if(!results.Success()) {
|
||||
Log.Out(Logs::Detail, Logs::QS_Server, "Failed Delete Log Record Entry Insert: %s", results.ErrorMessage().c_str());
|
||||
Log.Out(Logs::Detail, Logs::QS_Server, "%s", query.c_str());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void Database::LogPlayerMove(QSPlayerLogMove_Struct* QS, uint32 items) {
|
||||
/* These are item moves */
|
||||
|
||||
std::string query = StringFormat("INSERT INTO `qs_player_move_record` SET `time` = NOW(), "
|
||||
"`char_id` = '%i', `from_slot` = '%i', `to_slot` = '%i', "
|
||||
"`stack_size` = '%i', `char_items` = '%i', `postaction` = '%i'",
|
||||
QS->char_id, QS->from_slot, QS->to_slot, QS->stack_size,
|
||||
QS->char_count, QS->postaction);
|
||||
auto results = QueryDatabase(query);
|
||||
if(!results.Success()) {
|
||||
Log.Out(Logs::Detail, Logs::QS_Server, "Failed Move Log Record Insert: %s", results.ErrorMessage().c_str());
|
||||
Log.Out(Logs::Detail, Logs::QS_Server, "%s", query.c_str());
|
||||
}
|
||||
|
||||
if(items == 0)
|
||||
return;
|
||||
|
||||
int lastIndex = results.LastInsertedID();
|
||||
|
||||
for(int i = 0; i < items; i++) {
|
||||
query = StringFormat("INSERT INTO `qs_player_move_record_entries` SET `event_id` = '%i', "
|
||||
"`from_slot` = '%i', `to_slot` = '%i', `item_id` = '%i', `charges` = '%i', "
|
||||
"`aug_1` = '%i', `aug_2` = '%i', `aug_3` = '%i', `aug_4` = '%i', `aug_5` = '%i'",
|
||||
lastIndex, QS->items[i].from_slot, QS->items[i].to_slot, QS->items[i].item_id,
|
||||
QS->items[i].charges, QS->items[i].aug_1, QS->items[i].aug_2,
|
||||
QS->items[i].aug_3, QS->items[i].aug_4, QS->items[i].aug_5);
|
||||
results = QueryDatabase(query);
|
||||
if(!results.Success()) {
|
||||
Log.Out(Logs::Detail, Logs::QS_Server, "Failed Move Log Record Entry Insert: %s", results.ErrorMessage().c_str());
|
||||
Log.Out(Logs::Detail, Logs::QS_Server, "%s", query.c_str());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void Database::LogMerchantTransaction(QSMerchantLogTransaction_Struct* QS, uint32 items) {
|
||||
/* Merchant transactions are from the perspective of the merchant, not the player */
|
||||
std::string query = StringFormat("INSERT INTO `qs_merchant_transaction_record` SET `time` = NOW(), "
|
||||
"`zone_id` = '%i', `merchant_id` = '%i', `merchant_pp` = '%i', "
|
||||
"`merchant_gp` = '%i', `merchant_sp` = '%i', `merchant_cp` = '%i', "
|
||||
"`merchant_items` = '%i', `char_id` = '%i', `char_pp` = '%i', "
|
||||
"`char_gp` = '%i', `char_sp` = '%i', `char_cp` = '%i', "
|
||||
"`char_items` = '%i'",
|
||||
QS->zone_id, QS->merchant_id, QS->merchant_money.platinum,
|
||||
QS->merchant_money.gold, QS->merchant_money.silver,
|
||||
QS->merchant_money.copper, QS->merchant_count, QS->char_id,
|
||||
QS->char_money.platinum, QS->char_money.gold, QS->char_money.silver,
|
||||
QS->char_money.copper, QS->char_count);
|
||||
auto results = QueryDatabase(query);
|
||||
if(!results.Success()) {
|
||||
Log.Out(Logs::Detail, Logs::QS_Server, "Failed Transaction Log Record Insert: %s", results.ErrorMessage().c_str());
|
||||
Log.Out(Logs::Detail, Logs::QS_Server, "%s", query.c_str());
|
||||
}
|
||||
|
||||
if(items == 0)
|
||||
return;
|
||||
|
||||
int lastIndex = results.LastInsertedID();
|
||||
|
||||
for(int i = 0; i < items; i++) {
|
||||
query = StringFormat("INSERT INTO `qs_merchant_transaction_record_entries` SET `event_id` = '%i', "
|
||||
"`char_slot` = '%i', `item_id` = '%i', `charges` = '%i', `aug_1` = '%i', "
|
||||
"`aug_2` = '%i', `aug_3` = '%i', `aug_4` = '%i', `aug_5` = '%i'",
|
||||
lastIndex, QS->items[i].char_slot, QS->items[i].item_id, QS->items[i].charges,
|
||||
QS->items[i].aug_1, QS->items[i].aug_2, QS->items[i].aug_3, QS->items[i].aug_4,
|
||||
QS->items[i].aug_5);
|
||||
results = QueryDatabase(query);
|
||||
if(!results.Success()) {
|
||||
Log.Out(Logs::Detail, Logs::QS_Server, "Failed Transaction Log Record Entry Insert: %s", results.ErrorMessage().c_str());
|
||||
Log.Out(Logs::Detail, Logs::QS_Server, "%s", query.c_str());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void Database::GeneralQueryReceive(ServerPacket *pack) {
|
||||
/*
|
||||
These are general queries passed from anywhere in zone instead of packing structures and breaking them down again and again
|
||||
|
||||
@@ -44,12 +44,6 @@ public:
|
||||
~Database();
|
||||
|
||||
void AddSpeech(const char* from, const char* to, const char* message, uint16 minstatus, uint32 guilddbid, uint8 type);
|
||||
void LogPlayerTrade(QSPlayerLogTrade_Struct* QS, uint32 DetailCount);
|
||||
void LogPlayerHandin(QSPlayerLogHandin_Struct* QS, uint32 DetailCount);
|
||||
void LogPlayerNPCKill(QSPlayerLogNPCKill_Struct* QS, uint32 Members);
|
||||
void LogPlayerDelete(QSPlayerLogDelete_Struct* QS, uint32 Items);
|
||||
void LogPlayerMove(QSPlayerLogMove_Struct* QS, uint32 Items);
|
||||
void LogMerchantTransaction(QSMerchantLogTransaction_Struct* QS, uint32 Items);
|
||||
void GeneralQueryReceive(ServerPacket *pack);
|
||||
|
||||
void LoadLogSettings(EQEmuLogSys::LogSettings* log_settings);
|
||||
|
||||
@@ -81,41 +81,6 @@ void WorldServer::Process()
|
||||
database.AddSpeech(tmp1.c_str(), tmp2.c_str(), SSS->message, SSS->minstatus, SSS->guilddbid, SSS->type);
|
||||
break;
|
||||
}
|
||||
case ServerOP_QSPlayerLogTrades: {
|
||||
QSPlayerLogTrade_Struct *QS = (QSPlayerLogTrade_Struct*)pack->pBuffer;
|
||||
database.LogPlayerTrade(QS, QS->_detail_count);
|
||||
break;
|
||||
}
|
||||
case ServerOP_QSPlayerLogHandins: {
|
||||
QSPlayerLogHandin_Struct *QS = (QSPlayerLogHandin_Struct*)pack->pBuffer;
|
||||
database.LogPlayerHandin(QS, QS->_detail_count);
|
||||
break;
|
||||
}
|
||||
case ServerOP_QSPlayerLogNPCKills: {
|
||||
QSPlayerLogNPCKill_Struct *QS = (QSPlayerLogNPCKill_Struct*)pack->pBuffer;
|
||||
uint32 Members = pack->size - sizeof(QSPlayerLogNPCKill_Struct);
|
||||
if (Members > 0) Members = Members / sizeof(QSPlayerLogNPCKillsPlayers_Struct);
|
||||
database.LogPlayerNPCKill(QS, Members);
|
||||
break;
|
||||
}
|
||||
case ServerOP_QSPlayerLogDeletes: {
|
||||
QSPlayerLogDelete_Struct *QS = (QSPlayerLogDelete_Struct*)pack->pBuffer;
|
||||
uint32 Items = QS->char_count;
|
||||
database.LogPlayerDelete(QS, Items);
|
||||
break;
|
||||
}
|
||||
case ServerOP_QSPlayerLogMoves: {
|
||||
QSPlayerLogMove_Struct *QS = (QSPlayerLogMove_Struct*)pack->pBuffer;
|
||||
uint32 Items = QS->char_count;
|
||||
database.LogPlayerMove(QS, Items);
|
||||
break;
|
||||
}
|
||||
case ServerOP_QSPlayerLogMerchantTransactions: {
|
||||
QSMerchantLogTransaction_Struct *QS = (QSMerchantLogTransaction_Struct*)pack->pBuffer;
|
||||
uint32 Items = QS->char_count + QS->merchant_count;
|
||||
database.LogMerchantTransaction(QS, Items);
|
||||
break;
|
||||
}
|
||||
case ServerOP_QueryServGeneric: {
|
||||
/*
|
||||
The purpose of ServerOP_QueryServerGeneric is so that we don't have to add code to world just to relay packets
|
||||
|
||||
@@ -22,7 +22,7 @@
|
||||
#include "../common/ipc_mutex.h"
|
||||
#include "../common/memory_mapped_file.h"
|
||||
#include "../common/eqemu_exception.h"
|
||||
#include "../common/item_struct.h"
|
||||
#include "../common/item_data.h"
|
||||
|
||||
void LoadItems(SharedDatabase *database) {
|
||||
EQEmu::IPCMutex mutex("items");
|
||||
@@ -35,7 +35,7 @@ void LoadItems(SharedDatabase *database) {
|
||||
EQ_EXCEPT("Shared Memory", "Unable to get any items from the database.");
|
||||
}
|
||||
|
||||
uint32 size = static_cast<uint32>(EQEmu::FixedMemoryHashSet<Item_Struct>::estimated_size(items, max_item));
|
||||
uint32 size = static_cast<uint32>(EQEmu::FixedMemoryHashSet<ItemData>::estimated_size(items, max_item));
|
||||
EQEmu::MemoryMappedFile mmf("shared/items", size);
|
||||
mmf.ZeroFile();
|
||||
|
||||
|
||||
@@ -12,7 +12,9 @@ SET(tests_headers
|
||||
fixed_memory_test.h
|
||||
fixed_memory_variable_test.h
|
||||
hextoi_32_64_test.h
|
||||
inventory_test.h
|
||||
ipc_mutex_test.h
|
||||
memory_buffer_test.h
|
||||
memory_mapped_file_test.h
|
||||
string_util_test.h
|
||||
skills_util_test.h
|
||||
@@ -20,7 +22,7 @@ SET(tests_headers
|
||||
|
||||
ADD_EXECUTABLE(tests ${tests_sources} ${tests_headers})
|
||||
|
||||
TARGET_LINK_LIBRARIES(tests common cppunit)
|
||||
TARGET_LINK_LIBRARIES(tests common cppunit debug ${MySQL_LIBRARY_DEBUG} optimized ${MySQL_LIBRARY_RELEASE})
|
||||
|
||||
INSTALL(TARGETS tests RUNTIME DESTINATION ${CMAKE_INSTALL_PREFIX})
|
||||
|
||||
|
||||
+23
-23
@@ -27,7 +27,7 @@ class FixedMemoryHashTest : public Test::Suite {
|
||||
typedef void(FixedMemoryHashTest::*TestFunction)(void);
|
||||
public:
|
||||
FixedMemoryHashTest() {
|
||||
size_ = EQEmu::FixedMemoryHashSet<Item_Struct>::estimated_size(72000, 190000);
|
||||
size_ = EQEmu::FixedMemoryHashSet<ItemData>::estimated_size(72000, 190000);
|
||||
data_ = new uint8[size_];
|
||||
memset(data_, 0, size_);
|
||||
TEST_ADD(FixedMemoryHashTest::InitTest);
|
||||
@@ -49,7 +49,7 @@ public:
|
||||
|
||||
private:
|
||||
void InitTest() {
|
||||
EQEmu::FixedMemoryHashSet<Item_Struct> hash(data_, size_, 72000, 190000);
|
||||
EQEmu::FixedMemoryHashSet<ItemData> hash(data_, size_, 72000, 190000);
|
||||
TEST_ASSERT(!hash.exists(1001));
|
||||
TEST_ASSERT(hash.size() == 0);
|
||||
TEST_ASSERT(hash.max_size() == 72000);
|
||||
@@ -57,7 +57,7 @@ public:
|
||||
}
|
||||
|
||||
void LoadTest() {
|
||||
EQEmu::FixedMemoryHashSet<Item_Struct> hash(data_, size_);
|
||||
EQEmu::FixedMemoryHashSet<ItemData> hash(data_, size_);
|
||||
TEST_ASSERT(!hash.exists(1001));
|
||||
TEST_ASSERT(hash.size() == 0);
|
||||
TEST_ASSERT(hash.max_size() == 72000);
|
||||
@@ -65,8 +65,8 @@ public:
|
||||
}
|
||||
|
||||
void InsertTest() {
|
||||
EQEmu::FixedMemoryHashSet<Item_Struct> hash(data_, size_);
|
||||
Item_Struct item;
|
||||
EQEmu::FixedMemoryHashSet<ItemData> hash(data_, size_);
|
||||
ItemData item;
|
||||
memset(&item, 0, sizeof(item));
|
||||
strcpy(item.Name, "Iron Sword");
|
||||
item.ID = 1001;
|
||||
@@ -79,20 +79,20 @@ public:
|
||||
}
|
||||
|
||||
void RetrieveTest() {
|
||||
EQEmu::FixedMemoryHashSet<Item_Struct> hash(data_, size_);
|
||||
EQEmu::FixedMemoryHashSet<ItemData> hash(data_, size_);
|
||||
TEST_ASSERT(hash.exists(1001));
|
||||
TEST_ASSERT(hash.size() == 1);
|
||||
TEST_ASSERT(hash.max_size() == 72000);
|
||||
TEST_ASSERT(!hash.empty());
|
||||
|
||||
Item_Struct item = hash[1001];
|
||||
ItemData item = hash[1001];
|
||||
TEST_ASSERT(strcmp(item.Name, "Iron Sword") == 0);
|
||||
TEST_ASSERT(item.ID == 1001);
|
||||
}
|
||||
|
||||
void OverwriteTest() {
|
||||
EQEmu::FixedMemoryHashSet<Item_Struct> hash(data_, size_);
|
||||
Item_Struct item;
|
||||
EQEmu::FixedMemoryHashSet<ItemData> hash(data_, size_);
|
||||
ItemData item;
|
||||
memset(&item, 0, sizeof(item));
|
||||
strcpy(item.Name, "Steel Sword");
|
||||
item.ID = 1001;
|
||||
@@ -105,20 +105,20 @@ public:
|
||||
}
|
||||
|
||||
void OverwriteRetrieveTest() {
|
||||
EQEmu::FixedMemoryHashSet<Item_Struct> hash(data_, size_);
|
||||
EQEmu::FixedMemoryHashSet<ItemData> hash(data_, size_);
|
||||
TEST_ASSERT(hash.exists(1001));
|
||||
TEST_ASSERT(hash.size() == 1);
|
||||
TEST_ASSERT((hash.max_size() == 72000));
|
||||
TEST_ASSERT(!hash.empty());
|
||||
|
||||
Item_Struct item = hash[1001];
|
||||
ItemData item = hash[1001];
|
||||
TEST_ASSERT(strcmp(item.Name, "Steel Sword") == 0);
|
||||
TEST_ASSERT(item.ID == 1001);
|
||||
}
|
||||
|
||||
void InsertAgainTest() {
|
||||
EQEmu::FixedMemoryHashSet<Item_Struct> hash(data_, size_);
|
||||
Item_Struct item;
|
||||
EQEmu::FixedMemoryHashSet<ItemData> hash(data_, size_);
|
||||
ItemData item;
|
||||
memset(&item, 0, sizeof(item));
|
||||
strcpy(item.Name, "Iron Sword");
|
||||
item.ID = 1000;
|
||||
@@ -132,14 +132,14 @@ public:
|
||||
}
|
||||
|
||||
void RetrieveAgainTest() {
|
||||
EQEmu::FixedMemoryHashSet<Item_Struct> hash(data_, size_);
|
||||
EQEmu::FixedMemoryHashSet<ItemData> hash(data_, size_);
|
||||
TEST_ASSERT(hash.exists(1000));
|
||||
TEST_ASSERT(hash.exists(1001));
|
||||
TEST_ASSERT(hash.size() == 2);
|
||||
TEST_ASSERT(hash.max_size() == 72000);
|
||||
TEST_ASSERT(!hash.empty());
|
||||
|
||||
Item_Struct item = hash[1000];
|
||||
ItemData item = hash[1000];
|
||||
TEST_ASSERT(strcmp(item.Name, "Iron Sword") == 0);
|
||||
TEST_ASSERT(item.ID == 1000);
|
||||
|
||||
@@ -149,8 +149,8 @@ public:
|
||||
}
|
||||
|
||||
void InsertBeginTest() {
|
||||
EQEmu::FixedMemoryHashSet<Item_Struct> hash(data_, size_);
|
||||
Item_Struct item;
|
||||
EQEmu::FixedMemoryHashSet<ItemData> hash(data_, size_);
|
||||
ItemData item;
|
||||
memset(&item, 0, sizeof(item));
|
||||
strcpy(item.Name, "Bronze Sword");
|
||||
item.ID = 0;
|
||||
@@ -165,7 +165,7 @@ public:
|
||||
}
|
||||
|
||||
void RetrieveBeginTest() {
|
||||
EQEmu::FixedMemoryHashSet<Item_Struct> hash(data_, size_);
|
||||
EQEmu::FixedMemoryHashSet<ItemData> hash(data_, size_);
|
||||
TEST_ASSERT(hash.exists(1000));
|
||||
TEST_ASSERT(hash.exists(1001));
|
||||
TEST_ASSERT(hash.exists(0));
|
||||
@@ -173,7 +173,7 @@ public:
|
||||
TEST_ASSERT(hash.max_size() == 72000);
|
||||
TEST_ASSERT(!hash.empty());
|
||||
|
||||
Item_Struct item = hash[1000];
|
||||
ItemData item = hash[1000];
|
||||
TEST_ASSERT(strcmp(item.Name, "Iron Sword") == 0);
|
||||
TEST_ASSERT(item.ID == 1000);
|
||||
|
||||
@@ -187,8 +187,8 @@ public:
|
||||
}
|
||||
|
||||
void InsertEndTest() {
|
||||
EQEmu::FixedMemoryHashSet<Item_Struct> hash(data_, size_);
|
||||
Item_Struct item;
|
||||
EQEmu::FixedMemoryHashSet<ItemData> hash(data_, size_);
|
||||
ItemData item;
|
||||
memset(&item, 0, sizeof(item));
|
||||
strcpy(item.Name, "Jade Sword");
|
||||
item.ID = 190000;
|
||||
@@ -204,7 +204,7 @@ public:
|
||||
}
|
||||
|
||||
void RetrieveEndTest() {
|
||||
EQEmu::FixedMemoryHashSet<Item_Struct> hash(data_, size_);
|
||||
EQEmu::FixedMemoryHashSet<ItemData> hash(data_, size_);
|
||||
TEST_ASSERT(hash.exists(1000));
|
||||
TEST_ASSERT(hash.exists(1001));
|
||||
TEST_ASSERT(hash.exists(0));
|
||||
@@ -213,7 +213,7 @@ public:
|
||||
TEST_ASSERT(hash.max_size() == 72000);
|
||||
TEST_ASSERT(!hash.empty());
|
||||
|
||||
Item_Struct item = hash[1000];
|
||||
ItemData item = hash[1000];
|
||||
TEST_ASSERT(strcmp(item.Name, "Iron Sword") == 0);
|
||||
TEST_ASSERT(item.ID == 1000);
|
||||
|
||||
|
||||
@@ -0,0 +1,337 @@
|
||||
/* EQEMu: Everquest Server Emulator
|
||||
Copyright (C) 2001-2015 EQEMu Development Team (http://eqemulator.net)
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; version 2 of the License.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY except by those people which sell it, which
|
||||
are required to give you total support for your newly bought product;
|
||||
without even the implied warranty of MERCHANTABILITY or FITNESS FOR
|
||||
A PARTICULAR PURPOSE. See the GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#ifndef __EQEMU_TESTS_INVENTORY_H
|
||||
#define __EQEMU_TESTS_INVENTORY_H
|
||||
|
||||
#include "cppunit/cpptest.h"
|
||||
#include "../common/inventory.h"
|
||||
#include <string.h>
|
||||
|
||||
class InventoryTest : public Test::Suite {
|
||||
typedef void(InventoryTest::*TestFunction)(void);
|
||||
public:
|
||||
InventoryTest() : inv(1, 1, 1) {
|
||||
InitContainer();
|
||||
InitArmor();
|
||||
InitAugment();
|
||||
InitStackable();
|
||||
InitInventory();
|
||||
TEST_ADD(InventoryTest::InventoryVerifyInitialItemsTest);
|
||||
TEST_ADD(InventoryTest::InventoryCanEquipTest);
|
||||
TEST_ADD(InventoryTest::InventorySwapGeneral1ToCursor);
|
||||
TEST_ADD(InventoryTest::InventorySwapCursorToGeneral2);
|
||||
TEST_ADD(InventoryTest::InventorySplitStackToCursor);
|
||||
TEST_ADD(InventoryTest::InventoryStackCombine);
|
||||
TEST_ADD(InventoryTest::InventorySplitStackToCursor2);
|
||||
TEST_ADD(InventoryTest::InventoryStackCombine2);
|
||||
}
|
||||
|
||||
~InventoryTest() {
|
||||
}
|
||||
|
||||
private:
|
||||
void InitContainer() {
|
||||
memset(&container, 0, sizeof(container));
|
||||
strcpy(container.Name, "Backpack");
|
||||
strcpy(container.IDFile, "IT64");
|
||||
container.ID = 1000;
|
||||
container.BagSize = 3;
|
||||
container.BagSlots = 8;
|
||||
container.BagType = 5;
|
||||
container.BagWR = 50;
|
||||
container.ItemClass = 1;
|
||||
container.Classes = 65535U;
|
||||
container.Focus.Effect = -1;
|
||||
container.ItemType = 11;
|
||||
container.NoDrop = 1;
|
||||
container.NoRent = 1;
|
||||
container.Races = 131071U;
|
||||
container.Size = 3;
|
||||
container.SkillModType = -1;
|
||||
container.Click.Effect = -1;
|
||||
container.Weight = 30;
|
||||
container.StackSize = 1;
|
||||
container.Proc.Effect = -1;
|
||||
container.Worn.Effect = -1;
|
||||
container.Scroll.Effect = -1;
|
||||
}
|
||||
|
||||
void InitArmor() {
|
||||
memset(&armor, 0, sizeof(armor));
|
||||
strcpy(armor.Name, "Cloth Shirt");
|
||||
strcpy(armor.IDFile, "IT64");
|
||||
armor.ID = 1001;
|
||||
armor.AC = 4;
|
||||
armor.AugSlotType[0] = 7;
|
||||
for(int i = 0; i < 6; ++i)
|
||||
armor.AugSlotVisible[i] = 1;
|
||||
armor.Size = 2;
|
||||
armor.Slots = 131072;
|
||||
armor.Classes = 65535U;
|
||||
armor.Focus.Effect = -1;
|
||||
armor.ItemType = 10;
|
||||
armor.NoDrop = 1;
|
||||
armor.NoRent = 1;
|
||||
armor.Races = 131071U;
|
||||
armor.SkillModType = -1;
|
||||
armor.Click.Effect = -1;
|
||||
armor.Weight = 8;
|
||||
armor.StackSize = 1;
|
||||
armor.Proc.Effect = -1;
|
||||
armor.Worn.Effect = -1;
|
||||
armor.Scroll.Effect = -1;
|
||||
}
|
||||
|
||||
void InitAugment() {
|
||||
memset(&augment, 0, sizeof(augment));
|
||||
strcpy(augment.Name, "Cloth Augment");
|
||||
strcpy(augment.IDFile, "IT64");
|
||||
augment.ID = 1002;
|
||||
augment.AWis = 10;
|
||||
augment.AInt = 10;
|
||||
augment.AugType = 64;
|
||||
augment.Slots = 2072574;
|
||||
augment.Classes = 65535U;
|
||||
augment.Focus.Effect = -1;
|
||||
augment.ItemType = 54;
|
||||
augment.NoDrop = 1;
|
||||
augment.NoRent = 1;
|
||||
augment.Races = 131071U;
|
||||
augment.SkillModType = -1;
|
||||
augment.Click.Effect = -1;
|
||||
augment.Weight = 5;
|
||||
augment.StackSize = 1;
|
||||
augment.Size = 1;
|
||||
augment.Proc.Effect = -1;
|
||||
augment.Worn.Effect = -1;
|
||||
augment.Scroll.Effect = -1;
|
||||
}
|
||||
|
||||
void InitStackable() {
|
||||
memset(&stackable, 0, sizeof(stackable));
|
||||
strcpy(stackable.Name, "Stackable Item");
|
||||
strcpy(stackable.IDFile, "IT64");
|
||||
stackable.ID = 1003;
|
||||
stackable.Classes = 65535U;
|
||||
stackable.Focus.Effect = -1;
|
||||
stackable.ItemType = 54;
|
||||
stackable.NoDrop = 1;
|
||||
stackable.NoRent = 1;
|
||||
stackable.Races = 131071U;
|
||||
stackable.SkillModType = -1;
|
||||
stackable.Click.Effect = -1;
|
||||
stackable.Weight = 5;
|
||||
stackable.StackSize = 105;
|
||||
stackable.Stackable = 1;
|
||||
stackable.Size = 1;
|
||||
stackable.Proc.Effect = -1;
|
||||
stackable.Worn.Effect = -1;
|
||||
stackable.Scroll.Effect = -1;
|
||||
}
|
||||
|
||||
void InitInventory()
|
||||
{
|
||||
EQEmu::ItemInstance::pointer m_bag(new EQEmu::ItemInstance(&container));
|
||||
EQEmu::ItemInstance::pointer m_armor(new EQEmu::ItemInstance(&armor));
|
||||
EQEmu::ItemInstance::pointer m_augment(new EQEmu::ItemInstance(&augment));
|
||||
EQEmu::ItemInstance::pointer m_stackable(new EQEmu::ItemInstance(&stackable, 100));
|
||||
inv.Put(EQEmu::InventorySlot(EQEmu::InvTypePersonal, EQEmu::PersonalSlotGeneral1), m_bag);
|
||||
inv.Put(EQEmu::InventorySlot(EQEmu::InvTypePersonal, EQEmu::PersonalSlotGeneral1, 0), m_armor);
|
||||
inv.Put(EQEmu::InventorySlot(EQEmu::InvTypePersonal, EQEmu::PersonalSlotGeneral1, 1), m_augment);
|
||||
inv.Put(EQEmu::InventorySlot(EQEmu::InvTypePersonal, EQEmu::PersonalSlotGeneral1, 7), m_stackable);
|
||||
}
|
||||
|
||||
void InventoryVerifyInitialItemsTest()
|
||||
{
|
||||
auto m_bag = inv.Get(EQEmu::InventorySlot(EQEmu::InvTypePersonal, EQEmu::PersonalSlotGeneral1));
|
||||
TEST_ASSERT(m_bag);
|
||||
TEST_ASSERT(m_bag->GetItem());
|
||||
TEST_ASSERT(m_bag->GetItem()->ID == 1000);
|
||||
|
||||
auto m_armor = m_bag->Get(0);
|
||||
TEST_ASSERT(m_armor);
|
||||
TEST_ASSERT(m_armor->GetItem());
|
||||
TEST_ASSERT(m_armor->GetItem()->ID == 1001);
|
||||
|
||||
auto m_augment = m_bag->Get(1);
|
||||
TEST_ASSERT(m_augment);
|
||||
TEST_ASSERT(m_augment->GetItem());
|
||||
TEST_ASSERT(m_augment->GetItem()->ID == 1002);
|
||||
|
||||
auto m_stackable = m_bag->Get(7);
|
||||
TEST_ASSERT(m_stackable);
|
||||
TEST_ASSERT(m_stackable->GetItem());
|
||||
TEST_ASSERT(m_stackable->GetItem()->ID == 1003);
|
||||
}
|
||||
|
||||
void InventoryCanEquipTest() {
|
||||
auto m_bag = inv.Get(EQEmu::InventorySlot(EQEmu::InvTypePersonal, EQEmu::PersonalSlotGeneral1));
|
||||
TEST_ASSERT(m_bag);
|
||||
TEST_ASSERT(m_bag->GetItem());
|
||||
TEST_ASSERT(m_bag->GetItem()->ID == 1000);
|
||||
|
||||
auto m_armor = m_bag->Get(0);
|
||||
TEST_ASSERT(m_armor);
|
||||
TEST_ASSERT(m_armor->GetItem());
|
||||
TEST_ASSERT(m_armor->GetItem()->ID == 1001);
|
||||
|
||||
auto can_equip = inv.CanEquip(m_armor, EQEmu::InventorySlot(EQEmu::InvTypePersonal, EQEmu::PersonalSlotChest));
|
||||
TEST_ASSERT(can_equip);
|
||||
|
||||
can_equip = inv.CanEquip(m_armor, EQEmu::InventorySlot(EQEmu::InvTypePersonal, EQEmu::PersonalSlotWaist));
|
||||
TEST_ASSERT(!can_equip);
|
||||
|
||||
armor.Classes -= 1;
|
||||
can_equip = inv.CanEquip(m_armor, EQEmu::InventorySlot(EQEmu::InvTypePersonal, EQEmu::PersonalSlotChest));
|
||||
TEST_ASSERT(!can_equip);
|
||||
armor.Classes += 1;
|
||||
|
||||
armor.Races -= 1;
|
||||
can_equip = inv.CanEquip(m_armor, EQEmu::InventorySlot(EQEmu::InvTypePersonal, EQEmu::PersonalSlotChest));
|
||||
TEST_ASSERT(!can_equip);
|
||||
armor.Races += 1;
|
||||
}
|
||||
|
||||
void InventorySwapGeneral1ToCursor() {
|
||||
auto swap_result = inv.Swap(EQEmu::InventorySlot(EQEmu::InvTypePersonal, EQEmu::PersonalSlotGeneral1),
|
||||
EQEmu::InventorySlot(EQEmu::InvTypePersonal, EQEmu::PersonalSlotCursor), 0);
|
||||
|
||||
TEST_ASSERT(swap_result == true);
|
||||
|
||||
auto m_bag = inv.Get(EQEmu::InventorySlot(EQEmu::InvTypePersonal, EQEmu::PersonalSlotCursor));
|
||||
TEST_ASSERT(m_bag);
|
||||
TEST_ASSERT(m_bag->GetItem());
|
||||
TEST_ASSERT(m_bag->GetItem()->ID == 1000);
|
||||
|
||||
auto m_armor = m_bag->Get(0);
|
||||
TEST_ASSERT(m_armor);
|
||||
TEST_ASSERT(m_armor->GetItem());
|
||||
TEST_ASSERT(m_armor->GetItem()->ID == 1001);
|
||||
|
||||
auto m_augment = m_bag->Get(1);
|
||||
TEST_ASSERT(m_augment);
|
||||
TEST_ASSERT(m_augment->GetItem());
|
||||
TEST_ASSERT(m_augment->GetItem()->ID == 1002);
|
||||
|
||||
auto m_stackable = m_bag->Get(7);
|
||||
TEST_ASSERT(m_stackable);
|
||||
TEST_ASSERT(m_stackable->GetItem());
|
||||
TEST_ASSERT(m_stackable->GetItem()->ID == 1003);
|
||||
}
|
||||
|
||||
void InventorySwapCursorToGeneral2() {
|
||||
auto swap_result = inv.Swap(EQEmu::InventorySlot(EQEmu::InvTypePersonal, EQEmu::PersonalSlotCursor),
|
||||
EQEmu::InventorySlot(EQEmu::InvTypePersonal, EQEmu::PersonalSlotGeneral2), 0);
|
||||
|
||||
TEST_ASSERT(swap_result == true);
|
||||
|
||||
auto m_bag = inv.Get(EQEmu::InventorySlot(EQEmu::InvTypePersonal, EQEmu::PersonalSlotGeneral2));
|
||||
TEST_ASSERT(m_bag);
|
||||
TEST_ASSERT(m_bag->GetItem());
|
||||
TEST_ASSERT(m_bag->GetItem()->ID == 1000);
|
||||
|
||||
auto m_armor = m_bag->Get(0);
|
||||
TEST_ASSERT(m_armor);
|
||||
TEST_ASSERT(m_armor->GetItem());
|
||||
TEST_ASSERT(m_armor->GetItem()->ID == 1001);
|
||||
|
||||
auto m_augment = m_bag->Get(1);
|
||||
TEST_ASSERT(m_augment);
|
||||
TEST_ASSERT(m_augment->GetItem());
|
||||
TEST_ASSERT(m_augment->GetItem()->ID == 1002);
|
||||
|
||||
auto m_stackable = m_bag->Get(7);
|
||||
TEST_ASSERT(m_stackable);
|
||||
TEST_ASSERT(m_stackable->GetItem());
|
||||
TEST_ASSERT(m_stackable->GetItem()->ID == 1003);
|
||||
}
|
||||
|
||||
void InventorySplitStackToCursor() {
|
||||
auto swap_result = inv.Swap(EQEmu::InventorySlot(EQEmu::InvTypePersonal, EQEmu::PersonalSlotGeneral2, 7),
|
||||
EQEmu::InventorySlot(EQEmu::InvTypePersonal, EQEmu::PersonalSlotCursor), 10);
|
||||
|
||||
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, 7));
|
||||
|
||||
TEST_ASSERT(m_stackable_cursor);
|
||||
TEST_ASSERT(m_stackable);
|
||||
|
||||
TEST_ASSERT(m_stackable_cursor->GetCharges() == 10);
|
||||
TEST_ASSERT(m_stackable->GetCharges() == 90);
|
||||
}
|
||||
|
||||
void InventoryStackCombine() {
|
||||
auto swap_result = inv.Swap(EQEmu::InventorySlot(EQEmu::InvTypePersonal, EQEmu::PersonalSlotCursor),
|
||||
EQEmu::InventorySlot(EQEmu::InvTypePersonal, EQEmu::PersonalSlotGeneral2, 7), 0);
|
||||
|
||||
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() == 100);
|
||||
}
|
||||
|
||||
void InventorySplitStackToCursor2() {
|
||||
EQEmu::ItemInstance::pointer 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;
|
||||
ItemData container;
|
||||
ItemData armor;
|
||||
ItemData augment;
|
||||
ItemData stackable;
|
||||
};
|
||||
|
||||
#endif
|
||||
+8
-1
@@ -20,6 +20,7 @@
|
||||
#include <iostream>
|
||||
#include <fstream>
|
||||
#include <memory>
|
||||
#include "../common/eqemu_logsys.h"
|
||||
#include "memory_mapped_file_test.h"
|
||||
#include "ipc_mutex_test.h"
|
||||
#include "fixed_memory_test.h"
|
||||
@@ -29,6 +30,10 @@
|
||||
#include "string_util_test.h"
|
||||
#include "data_verification_test.h"
|
||||
#include "skills_util_test.h"
|
||||
#include "inventory_test.h"
|
||||
#include "memory_buffer_test.h"
|
||||
|
||||
EQEmuLogSys Log;
|
||||
|
||||
int main() {
|
||||
try {
|
||||
@@ -44,7 +49,9 @@ int main() {
|
||||
tests.add(new StringUtilTest());
|
||||
tests.add(new DataVerificationTest());
|
||||
tests.add(new SkillsUtilsTest());
|
||||
tests.run(*output, true);
|
||||
tests.add(new InventoryTest());
|
||||
tests.add(new MemoryBufferTest());
|
||||
tests.run(*output, false);
|
||||
} catch(...) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,605 @@
|
||||
/* EQEMu: Everquest Server Emulator
|
||||
Copyright (C) 2001-2013 EQEMu Development Team (http://eqemulator.net)
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; version 2 of the License.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY except by those people which sell it, which
|
||||
are required to give you total support for your newly bought product;
|
||||
without even the implied warranty of MERCHANTABILITY or FITNESS FOR
|
||||
A PARTICULAR PURPOSE. See the GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#ifndef __EQEMU_TESTS_MEMORY_BUFFER_H
|
||||
#define __EQEMU_TESTS_MEMORY_BUFFER_H
|
||||
|
||||
#include "cppunit/cpptest.h"
|
||||
#include "../common/memory_buffer.h"
|
||||
|
||||
class MemoryBufferTest : public Test::Suite {
|
||||
typedef void(MemoryBufferTest::*TestFunction)(void);
|
||||
public:
|
||||
MemoryBufferTest() {
|
||||
TEST_ADD(MemoryBufferTest::WriteTest);
|
||||
TEST_ADD(MemoryBufferTest::ReadTest);
|
||||
TEST_ADD(MemoryBufferTest::ConvertTest);
|
||||
TEST_ADD(MemoryBufferTest::ResizeTest);
|
||||
TEST_ADD(MemoryBufferTest::CopyTest);
|
||||
TEST_ADD(MemoryBufferTest::AssignTest);
|
||||
TEST_ADD(MemoryBufferTest::MoveTest);
|
||||
TEST_ADD(MemoryBufferTest::SelfTest);
|
||||
TEST_ADD(MemoryBufferTest::ZeroTest);
|
||||
TEST_ADD(MemoryBufferTest::ClearTest);
|
||||
TEST_ADD(MemoryBufferTest::AddTest)
|
||||
}
|
||||
|
||||
~MemoryBufferTest() {
|
||||
}
|
||||
|
||||
private:
|
||||
void WriteTest() {
|
||||
uint8 a = 0;
|
||||
uint16 b = 5 ;
|
||||
uint32 c = 10;
|
||||
uint64 d = 15;
|
||||
std::string s2 = "test2";
|
||||
|
||||
mb.Write(a);
|
||||
mb.Write(b);
|
||||
mb.Write(c);
|
||||
mb.Write(d);
|
||||
mb.Write("test1");
|
||||
mb.Write(s2);
|
||||
|
||||
TEST_ASSERT(mb.Size() == 27);
|
||||
|
||||
uchar *data = (uchar*)mb;
|
||||
TEST_ASSERT(data != nullptr);
|
||||
TEST_ASSERT(data[0] == 0);
|
||||
TEST_ASSERT(data[1] == 5);
|
||||
TEST_ASSERT(data[2] == 0);
|
||||
TEST_ASSERT(data[3] == 10);
|
||||
TEST_ASSERT(data[4] == 0);
|
||||
TEST_ASSERT(data[5] == 0);
|
||||
TEST_ASSERT(data[6] == 0);
|
||||
TEST_ASSERT(data[7] == 15);
|
||||
TEST_ASSERT(data[8] == 0);
|
||||
TEST_ASSERT(data[9] == 0);
|
||||
TEST_ASSERT(data[10] == 0);
|
||||
TEST_ASSERT(data[11] == 0);
|
||||
TEST_ASSERT(data[12] == 0);
|
||||
TEST_ASSERT(data[13] == 0);
|
||||
TEST_ASSERT(data[14] == 0);
|
||||
TEST_ASSERT(data[15] == 't');
|
||||
TEST_ASSERT(data[16] == 'e');
|
||||
TEST_ASSERT(data[17] == 's');
|
||||
TEST_ASSERT(data[18] == 't');
|
||||
TEST_ASSERT(data[19] == '1');
|
||||
TEST_ASSERT(data[20] == 0);
|
||||
TEST_ASSERT(data[21] == 't');
|
||||
TEST_ASSERT(data[22] == 'e');
|
||||
TEST_ASSERT(data[23] == 's');
|
||||
TEST_ASSERT(data[24] == 't');
|
||||
TEST_ASSERT(data[25] == '2');
|
||||
TEST_ASSERT(data[26] == 0);
|
||||
}
|
||||
|
||||
void ReadTest() {
|
||||
uint8 a = mb.Read<uint8>();
|
||||
uint16 b = mb.Read<uint16>();
|
||||
uint32 c = mb.Read<uint32>();
|
||||
uint64 d = mb.Read<uint64>();
|
||||
std::string s1 = mb.ReadString();
|
||||
std::string s2 = mb.ReadString();
|
||||
|
||||
TEST_ASSERT(a == 0);
|
||||
TEST_ASSERT(b == 5);
|
||||
TEST_ASSERT(c == 10);
|
||||
TEST_ASSERT(d == 15);
|
||||
TEST_ASSERT(s1.compare("test1") == 0);
|
||||
TEST_ASSERT(s2.compare("test2") == 0);
|
||||
}
|
||||
|
||||
#pragma pack(1)
|
||||
struct ConvertStruct
|
||||
{
|
||||
uint8 a;
|
||||
uint16 b;
|
||||
uint32 c;
|
||||
uint64 d;
|
||||
char test1[6];
|
||||
char test2[6];
|
||||
};
|
||||
#pragma pack()
|
||||
|
||||
void ConvertTest()
|
||||
{
|
||||
uchar *v1 = mb;
|
||||
char *v2 = mb;
|
||||
ConvertStruct *cs = (ConvertStruct*)mb;
|
||||
|
||||
TEST_ASSERT(v1 != nullptr);
|
||||
TEST_ASSERT(v1[0] == 0);
|
||||
TEST_ASSERT(v1[1] == 5);
|
||||
TEST_ASSERT(v1[2] == 0);
|
||||
TEST_ASSERT(v1[3] == 10);
|
||||
TEST_ASSERT(v1[4] == 0);
|
||||
TEST_ASSERT(v1[5] == 0);
|
||||
TEST_ASSERT(v1[6] == 0);
|
||||
TEST_ASSERT(v1[7] == 15);
|
||||
TEST_ASSERT(v1[8] == 0);
|
||||
TEST_ASSERT(v1[9] == 0);
|
||||
TEST_ASSERT(v1[10] == 0);
|
||||
TEST_ASSERT(v1[11] == 0);
|
||||
TEST_ASSERT(v1[12] == 0);
|
||||
TEST_ASSERT(v1[13] == 0);
|
||||
TEST_ASSERT(v1[14] == 0);
|
||||
TEST_ASSERT(v1[15] == 't');
|
||||
TEST_ASSERT(v1[16] == 'e');
|
||||
TEST_ASSERT(v1[17] == 's');
|
||||
TEST_ASSERT(v1[18] == 't');
|
||||
TEST_ASSERT(v1[19] == '1');
|
||||
TEST_ASSERT(v1[20] == 0);
|
||||
TEST_ASSERT(v1[21] == 't');
|
||||
TEST_ASSERT(v1[22] == 'e');
|
||||
TEST_ASSERT(v1[23] == 's');
|
||||
TEST_ASSERT(v1[24] == 't');
|
||||
TEST_ASSERT(v1[25] == '2');
|
||||
TEST_ASSERT(v1[26] == 0);
|
||||
|
||||
TEST_ASSERT(v2 != nullptr);
|
||||
TEST_ASSERT(v2[0] == 0);
|
||||
TEST_ASSERT(v2[1] == 5);
|
||||
TEST_ASSERT(v2[2] == 0);
|
||||
TEST_ASSERT(v2[3] == 10);
|
||||
TEST_ASSERT(v2[4] == 0);
|
||||
TEST_ASSERT(v2[5] == 0);
|
||||
TEST_ASSERT(v2[6] == 0);
|
||||
TEST_ASSERT(v2[7] == 15);
|
||||
TEST_ASSERT(v2[8] == 0);
|
||||
TEST_ASSERT(v2[9] == 0);
|
||||
TEST_ASSERT(v2[10] == 0);
|
||||
TEST_ASSERT(v2[11] == 0);
|
||||
TEST_ASSERT(v2[12] == 0);
|
||||
TEST_ASSERT(v2[13] == 0);
|
||||
TEST_ASSERT(v2[14] == 0);
|
||||
TEST_ASSERT(v2[15] == 't');
|
||||
TEST_ASSERT(v2[16] == 'e');
|
||||
TEST_ASSERT(v2[17] == 's');
|
||||
TEST_ASSERT(v2[18] == 't');
|
||||
TEST_ASSERT(v2[19] == '1');
|
||||
TEST_ASSERT(v2[20] == 0);
|
||||
TEST_ASSERT(v2[21] == 't');
|
||||
TEST_ASSERT(v2[22] == 'e');
|
||||
TEST_ASSERT(v2[23] == 's');
|
||||
TEST_ASSERT(v2[24] == 't');
|
||||
TEST_ASSERT(v2[25] == '2');
|
||||
TEST_ASSERT(v2[26] == 0);
|
||||
|
||||
TEST_ASSERT(cs != nullptr);
|
||||
TEST_ASSERT(cs->a == 0);
|
||||
TEST_ASSERT(cs->b == 5);
|
||||
TEST_ASSERT(cs->c == 10);
|
||||
TEST_ASSERT(cs->d == 15);
|
||||
TEST_ASSERT(strcmp(cs->test1, "test1") == 0);
|
||||
TEST_ASSERT(strcmp(cs->test2, "test2") == 0);
|
||||
}
|
||||
|
||||
void ResizeTest()
|
||||
{
|
||||
mb.Resize(21);
|
||||
TEST_ASSERT(mb.Size() == 21);
|
||||
|
||||
mb.Resize(27);
|
||||
uchar *data = (uchar*)mb;
|
||||
TEST_ASSERT(data != nullptr);
|
||||
TEST_ASSERT(data[21] == 't');
|
||||
TEST_ASSERT(data[22] == 'e');
|
||||
TEST_ASSERT(data[23] == 's');
|
||||
TEST_ASSERT(data[24] == 't');
|
||||
TEST_ASSERT(data[25] == '2');
|
||||
TEST_ASSERT(data[26] == 0);
|
||||
|
||||
mb.Resize(40);
|
||||
data = (uchar*)mb;
|
||||
TEST_ASSERT(data != nullptr);
|
||||
TEST_ASSERT(mb.Capacity() >= 40);
|
||||
TEST_ASSERT(mb.Size() == 40);
|
||||
TEST_ASSERT(data[0] == 0);
|
||||
TEST_ASSERT(data[1] == 5);
|
||||
TEST_ASSERT(data[2] == 0);
|
||||
TEST_ASSERT(data[3] == 10);
|
||||
TEST_ASSERT(data[4] == 0);
|
||||
TEST_ASSERT(data[5] == 0);
|
||||
TEST_ASSERT(data[6] == 0);
|
||||
TEST_ASSERT(data[7] == 15);
|
||||
TEST_ASSERT(data[8] == 0);
|
||||
TEST_ASSERT(data[9] == 0);
|
||||
TEST_ASSERT(data[10] == 0);
|
||||
TEST_ASSERT(data[11] == 0);
|
||||
TEST_ASSERT(data[12] == 0);
|
||||
TEST_ASSERT(data[13] == 0);
|
||||
TEST_ASSERT(data[14] == 0);
|
||||
TEST_ASSERT(data[15] == 't');
|
||||
TEST_ASSERT(data[16] == 'e');
|
||||
TEST_ASSERT(data[17] == 's');
|
||||
TEST_ASSERT(data[18] == 't');
|
||||
TEST_ASSERT(data[19] == '1');
|
||||
TEST_ASSERT(data[20] == 0);
|
||||
TEST_ASSERT(data[21] == 't');
|
||||
TEST_ASSERT(data[22] == 'e');
|
||||
TEST_ASSERT(data[23] == 's');
|
||||
TEST_ASSERT(data[24] == 't');
|
||||
TEST_ASSERT(data[25] == '2');
|
||||
TEST_ASSERT(data[26] == 0);
|
||||
}
|
||||
|
||||
void CopyTest()
|
||||
{
|
||||
EQEmu::MemoryBuffer mb2(mb);
|
||||
|
||||
uchar *data = (uchar*)mb2;
|
||||
TEST_ASSERT(data != nullptr);
|
||||
TEST_ASSERT(mb.Size() == 40);
|
||||
TEST_ASSERT(data[0] == 0);
|
||||
TEST_ASSERT(data[1] == 5);
|
||||
TEST_ASSERT(data[2] == 0);
|
||||
TEST_ASSERT(data[3] == 10);
|
||||
TEST_ASSERT(data[4] == 0);
|
||||
TEST_ASSERT(data[5] == 0);
|
||||
TEST_ASSERT(data[6] == 0);
|
||||
TEST_ASSERT(data[7] == 15);
|
||||
TEST_ASSERT(data[8] == 0);
|
||||
TEST_ASSERT(data[9] == 0);
|
||||
TEST_ASSERT(data[10] == 0);
|
||||
TEST_ASSERT(data[11] == 0);
|
||||
TEST_ASSERT(data[12] == 0);
|
||||
TEST_ASSERT(data[13] == 0);
|
||||
TEST_ASSERT(data[14] == 0);
|
||||
TEST_ASSERT(data[15] == 't');
|
||||
TEST_ASSERT(data[16] == 'e');
|
||||
TEST_ASSERT(data[17] == 's');
|
||||
TEST_ASSERT(data[18] == 't');
|
||||
TEST_ASSERT(data[19] == '1');
|
||||
TEST_ASSERT(data[20] == 0);
|
||||
TEST_ASSERT(data[21] == 't');
|
||||
TEST_ASSERT(data[22] == 'e');
|
||||
TEST_ASSERT(data[23] == 's');
|
||||
TEST_ASSERT(data[24] == 't');
|
||||
TEST_ASSERT(data[25] == '2');
|
||||
TEST_ASSERT(data[26] == 0);
|
||||
|
||||
data = (uchar*)mb;
|
||||
TEST_ASSERT(data != nullptr);
|
||||
TEST_ASSERT(mb.Size() == 40);
|
||||
TEST_ASSERT(data[0] == 0);
|
||||
TEST_ASSERT(data[1] == 5);
|
||||
TEST_ASSERT(data[2] == 0);
|
||||
TEST_ASSERT(data[3] == 10);
|
||||
TEST_ASSERT(data[4] == 0);
|
||||
TEST_ASSERT(data[5] == 0);
|
||||
TEST_ASSERT(data[6] == 0);
|
||||
TEST_ASSERT(data[7] == 15);
|
||||
TEST_ASSERT(data[8] == 0);
|
||||
TEST_ASSERT(data[9] == 0);
|
||||
TEST_ASSERT(data[10] == 0);
|
||||
TEST_ASSERT(data[11] == 0);
|
||||
TEST_ASSERT(data[12] == 0);
|
||||
TEST_ASSERT(data[13] == 0);
|
||||
TEST_ASSERT(data[14] == 0);
|
||||
TEST_ASSERT(data[15] == 't');
|
||||
TEST_ASSERT(data[16] == 'e');
|
||||
TEST_ASSERT(data[17] == 's');
|
||||
TEST_ASSERT(data[18] == 't');
|
||||
TEST_ASSERT(data[19] == '1');
|
||||
TEST_ASSERT(data[20] == 0);
|
||||
TEST_ASSERT(data[21] == 't');
|
||||
TEST_ASSERT(data[22] == 'e');
|
||||
TEST_ASSERT(data[23] == 's');
|
||||
TEST_ASSERT(data[24] == 't');
|
||||
TEST_ASSERT(data[25] == '2');
|
||||
TEST_ASSERT(data[26] == 0);
|
||||
TEST_ASSERT((void*)mb != (void*)mb2);
|
||||
}
|
||||
|
||||
void AssignTest()
|
||||
{
|
||||
EQEmu::MemoryBuffer mb2 = mb;
|
||||
|
||||
uchar *data = (uchar*)mb2;
|
||||
TEST_ASSERT(data != nullptr);
|
||||
TEST_ASSERT(mb.Size() == 40);
|
||||
TEST_ASSERT(data[0] == 0);
|
||||
TEST_ASSERT(data[1] == 5);
|
||||
TEST_ASSERT(data[2] == 0);
|
||||
TEST_ASSERT(data[3] == 10);
|
||||
TEST_ASSERT(data[4] == 0);
|
||||
TEST_ASSERT(data[5] == 0);
|
||||
TEST_ASSERT(data[6] == 0);
|
||||
TEST_ASSERT(data[7] == 15);
|
||||
TEST_ASSERT(data[8] == 0);
|
||||
TEST_ASSERT(data[9] == 0);
|
||||
TEST_ASSERT(data[10] == 0);
|
||||
TEST_ASSERT(data[11] == 0);
|
||||
TEST_ASSERT(data[12] == 0);
|
||||
TEST_ASSERT(data[13] == 0);
|
||||
TEST_ASSERT(data[14] == 0);
|
||||
TEST_ASSERT(data[15] == 't');
|
||||
TEST_ASSERT(data[16] == 'e');
|
||||
TEST_ASSERT(data[17] == 's');
|
||||
TEST_ASSERT(data[18] == 't');
|
||||
TEST_ASSERT(data[19] == '1');
|
||||
TEST_ASSERT(data[20] == 0);
|
||||
TEST_ASSERT(data[21] == 't');
|
||||
TEST_ASSERT(data[22] == 'e');
|
||||
TEST_ASSERT(data[23] == 's');
|
||||
TEST_ASSERT(data[24] == 't');
|
||||
TEST_ASSERT(data[25] == '2');
|
||||
TEST_ASSERT(data[26] == 0);
|
||||
|
||||
data = (uchar*)mb;
|
||||
TEST_ASSERT(data != nullptr);
|
||||
TEST_ASSERT(mb.Size() == 40);
|
||||
TEST_ASSERT(data[0] == 0);
|
||||
TEST_ASSERT(data[1] == 5);
|
||||
TEST_ASSERT(data[2] == 0);
|
||||
TEST_ASSERT(data[3] == 10);
|
||||
TEST_ASSERT(data[4] == 0);
|
||||
TEST_ASSERT(data[5] == 0);
|
||||
TEST_ASSERT(data[6] == 0);
|
||||
TEST_ASSERT(data[7] == 15);
|
||||
TEST_ASSERT(data[8] == 0);
|
||||
TEST_ASSERT(data[9] == 0);
|
||||
TEST_ASSERT(data[10] == 0);
|
||||
TEST_ASSERT(data[11] == 0);
|
||||
TEST_ASSERT(data[12] == 0);
|
||||
TEST_ASSERT(data[13] == 0);
|
||||
TEST_ASSERT(data[14] == 0);
|
||||
TEST_ASSERT(data[15] == 't');
|
||||
TEST_ASSERT(data[16] == 'e');
|
||||
TEST_ASSERT(data[17] == 's');
|
||||
TEST_ASSERT(data[18] == 't');
|
||||
TEST_ASSERT(data[19] == '1');
|
||||
TEST_ASSERT(data[20] == 0);
|
||||
TEST_ASSERT(data[21] == 't');
|
||||
TEST_ASSERT(data[22] == 'e');
|
||||
TEST_ASSERT(data[23] == 's');
|
||||
TEST_ASSERT(data[24] == 't');
|
||||
TEST_ASSERT(data[25] == '2');
|
||||
TEST_ASSERT(data[26] == 0);
|
||||
TEST_ASSERT((void*)mb != (void*)mb2);
|
||||
}
|
||||
|
||||
void MoveTest()
|
||||
{
|
||||
EQEmu::MemoryBuffer mb2 = std::move(mb);
|
||||
uchar *data = (uchar*)mb;
|
||||
uchar *data2 = (uchar*)mb2;
|
||||
TEST_ASSERT(data == nullptr);
|
||||
TEST_ASSERT(data2 != nullptr);
|
||||
TEST_ASSERT(mb.Size() == 0);
|
||||
TEST_ASSERT(mb2.Size() == 40);
|
||||
TEST_ASSERT(data2[0] == 0);
|
||||
TEST_ASSERT(data2[1] == 5);
|
||||
TEST_ASSERT(data2[2] == 0);
|
||||
TEST_ASSERT(data2[3] == 10);
|
||||
TEST_ASSERT(data2[4] == 0);
|
||||
TEST_ASSERT(data2[5] == 0);
|
||||
TEST_ASSERT(data2[6] == 0);
|
||||
TEST_ASSERT(data2[7] == 15);
|
||||
TEST_ASSERT(data2[8] == 0);
|
||||
TEST_ASSERT(data2[9] == 0);
|
||||
TEST_ASSERT(data2[10] == 0);
|
||||
TEST_ASSERT(data2[11] == 0);
|
||||
TEST_ASSERT(data2[12] == 0);
|
||||
TEST_ASSERT(data2[13] == 0);
|
||||
TEST_ASSERT(data2[14] == 0);
|
||||
TEST_ASSERT(data2[15] == 't');
|
||||
TEST_ASSERT(data2[16] == 'e');
|
||||
TEST_ASSERT(data2[17] == 's');
|
||||
TEST_ASSERT(data2[18] == 't');
|
||||
TEST_ASSERT(data2[19] == '1');
|
||||
TEST_ASSERT(data2[20] == 0);
|
||||
TEST_ASSERT(data2[21] == 't');
|
||||
TEST_ASSERT(data2[22] == 'e');
|
||||
TEST_ASSERT(data2[23] == 's');
|
||||
TEST_ASSERT(data2[24] == 't');
|
||||
TEST_ASSERT(data2[25] == '2');
|
||||
TEST_ASSERT(data2[26] == 0);
|
||||
|
||||
mb = std::move(mb2);
|
||||
|
||||
data = (uchar*)mb;
|
||||
data2 = (uchar*)mb2;
|
||||
TEST_ASSERT(data != nullptr);
|
||||
TEST_ASSERT(data2 == nullptr);
|
||||
TEST_ASSERT(mb.Size() == 40);
|
||||
TEST_ASSERT(mb2.Size() == 0);
|
||||
TEST_ASSERT(data[0] == 0);
|
||||
TEST_ASSERT(data[1] == 5);
|
||||
TEST_ASSERT(data[2] == 0);
|
||||
TEST_ASSERT(data[3] == 10);
|
||||
TEST_ASSERT(data[4] == 0);
|
||||
TEST_ASSERT(data[5] == 0);
|
||||
TEST_ASSERT(data[6] == 0);
|
||||
TEST_ASSERT(data[7] == 15);
|
||||
TEST_ASSERT(data[8] == 0);
|
||||
TEST_ASSERT(data[9] == 0);
|
||||
TEST_ASSERT(data[10] == 0);
|
||||
TEST_ASSERT(data[11] == 0);
|
||||
TEST_ASSERT(data[12] == 0);
|
||||
TEST_ASSERT(data[13] == 0);
|
||||
TEST_ASSERT(data[14] == 0);
|
||||
TEST_ASSERT(data[15] == 't');
|
||||
TEST_ASSERT(data[16] == 'e');
|
||||
TEST_ASSERT(data[17] == 's');
|
||||
TEST_ASSERT(data[18] == 't');
|
||||
TEST_ASSERT(data[19] == '1');
|
||||
TEST_ASSERT(data[20] == 0);
|
||||
TEST_ASSERT(data[21] == 't');
|
||||
TEST_ASSERT(data[22] == 'e');
|
||||
TEST_ASSERT(data[23] == 's');
|
||||
TEST_ASSERT(data[24] == 't');
|
||||
TEST_ASSERT(data[25] == '2');
|
||||
TEST_ASSERT(data[26] == 0);
|
||||
}
|
||||
|
||||
void SelfTest()
|
||||
{
|
||||
EQEmu::MemoryBuffer mb2(mb);
|
||||
void *addr = (void*)mb2;
|
||||
|
||||
mb2 = mb2;
|
||||
void *addr2 = (void*)mb2;
|
||||
|
||||
TEST_ASSERT(addr == addr2);
|
||||
|
||||
mb2 = std::move(mb2);
|
||||
addr2 = (void*)mb2;
|
||||
|
||||
TEST_ASSERT(addr2 != nullptr);
|
||||
}
|
||||
|
||||
void ZeroTest()
|
||||
{
|
||||
mb.Zero();
|
||||
uchar *data = (uchar*)mb;
|
||||
TEST_ASSERT(data != nullptr);
|
||||
TEST_ASSERT(mb.Size() == 40);
|
||||
TEST_ASSERT(data[0] == 0);
|
||||
TEST_ASSERT(data[1] == 0);
|
||||
TEST_ASSERT(data[2] == 0);
|
||||
TEST_ASSERT(data[3] == 0);
|
||||
TEST_ASSERT(data[4] == 0);
|
||||
TEST_ASSERT(data[5] == 0);
|
||||
TEST_ASSERT(data[6] == 0);
|
||||
TEST_ASSERT(data[7] == 0);
|
||||
TEST_ASSERT(data[8] == 0);
|
||||
TEST_ASSERT(data[9] == 0);
|
||||
TEST_ASSERT(data[10] == 0);
|
||||
TEST_ASSERT(data[11] == 0);
|
||||
TEST_ASSERT(data[12] == 0);
|
||||
TEST_ASSERT(data[13] == 0);
|
||||
TEST_ASSERT(data[14] == 0);
|
||||
TEST_ASSERT(data[15] == 0);
|
||||
TEST_ASSERT(data[16] == 0);
|
||||
TEST_ASSERT(data[17] == 0);
|
||||
TEST_ASSERT(data[18] == 0);
|
||||
TEST_ASSERT(data[19] == 0);
|
||||
TEST_ASSERT(data[20] == 0);
|
||||
TEST_ASSERT(data[21] == 0);
|
||||
TEST_ASSERT(data[22] == 0);
|
||||
TEST_ASSERT(data[23] == 0);
|
||||
TEST_ASSERT(data[24] == 0);
|
||||
TEST_ASSERT(data[25] == 0);
|
||||
TEST_ASSERT(data[26] == 0);
|
||||
TEST_ASSERT(data[27] == 0);
|
||||
TEST_ASSERT(data[28] == 0);
|
||||
TEST_ASSERT(data[29] == 0);
|
||||
TEST_ASSERT(data[30] == 0);
|
||||
TEST_ASSERT(data[31] == 0);
|
||||
TEST_ASSERT(data[32] == 0);
|
||||
TEST_ASSERT(data[33] == 0);
|
||||
TEST_ASSERT(data[34] == 0);
|
||||
TEST_ASSERT(data[35] == 0);
|
||||
TEST_ASSERT(data[36] == 0);
|
||||
TEST_ASSERT(data[37] == 0);
|
||||
TEST_ASSERT(data[38] == 0);
|
||||
TEST_ASSERT(data[39] == 0);
|
||||
}
|
||||
|
||||
void ClearTest()
|
||||
{
|
||||
mb.Clear();
|
||||
TEST_ASSERT(!mb);
|
||||
uchar *data = (uchar*)mb;
|
||||
TEST_ASSERT(data == nullptr);
|
||||
}
|
||||
|
||||
void AddTest()
|
||||
{
|
||||
EQEmu::MemoryBuffer mb2;
|
||||
EQEmu::MemoryBuffer mb3;
|
||||
|
||||
mb2 += mb3;
|
||||
|
||||
TEST_ASSERT(!mb2);
|
||||
TEST_ASSERT(mb2.Size() == 0);
|
||||
|
||||
mb2.Write("test1");
|
||||
mb2.Write("test2");
|
||||
|
||||
mb2 += mb3;
|
||||
TEST_ASSERT(mb2);
|
||||
TEST_ASSERT(mb2.Size() == 12);
|
||||
|
||||
uchar *data = (uchar*)mb2;
|
||||
TEST_ASSERT(data != nullptr);
|
||||
TEST_ASSERT(data[0] == 't');
|
||||
TEST_ASSERT(data[1] == 'e');
|
||||
TEST_ASSERT(data[2] == 's');
|
||||
TEST_ASSERT(data[3] == 't');
|
||||
TEST_ASSERT(data[4] == '1');
|
||||
TEST_ASSERT(data[5] == 0);
|
||||
TEST_ASSERT(data[6] == 't');
|
||||
TEST_ASSERT(data[7] == 'e');
|
||||
TEST_ASSERT(data[8] == 's');
|
||||
TEST_ASSERT(data[9] == 't');
|
||||
TEST_ASSERT(data[10] == '2');
|
||||
TEST_ASSERT(data[11] == 0);
|
||||
|
||||
mb3 += mb2;
|
||||
TEST_ASSERT(mb3);
|
||||
TEST_ASSERT(mb3.Size() == 12);
|
||||
|
||||
data = (uchar*)mb3;
|
||||
TEST_ASSERT(data != nullptr);
|
||||
TEST_ASSERT(data[0] == 't');
|
||||
TEST_ASSERT(data[1] == 'e');
|
||||
TEST_ASSERT(data[2] == 's');
|
||||
TEST_ASSERT(data[3] == 't');
|
||||
TEST_ASSERT(data[4] == '1');
|
||||
TEST_ASSERT(data[5] == 0);
|
||||
TEST_ASSERT(data[6] == 't');
|
||||
TEST_ASSERT(data[7] == 'e');
|
||||
TEST_ASSERT(data[8] == 's');
|
||||
TEST_ASSERT(data[9] == 't');
|
||||
TEST_ASSERT(data[10] == '2');
|
||||
TEST_ASSERT(data[11] == 0);
|
||||
|
||||
mb2.Clear();
|
||||
mb3.Clear();
|
||||
|
||||
mb2.Write("test1");
|
||||
mb3.Write("test2");
|
||||
|
||||
mb2 += mb3;
|
||||
TEST_ASSERT(mb2);
|
||||
TEST_ASSERT(mb2.Size() == 12);
|
||||
|
||||
data = (uchar*)mb2;
|
||||
TEST_ASSERT(data != nullptr);
|
||||
TEST_ASSERT(data[0] == 't');
|
||||
TEST_ASSERT(data[1] == 'e');
|
||||
TEST_ASSERT(data[2] == 's');
|
||||
TEST_ASSERT(data[3] == 't');
|
||||
TEST_ASSERT(data[4] == '1');
|
||||
TEST_ASSERT(data[5] == 0);
|
||||
TEST_ASSERT(data[6] == 't');
|
||||
TEST_ASSERT(data[7] == 'e');
|
||||
TEST_ASSERT(data[8] == 's');
|
||||
TEST_ASSERT(data[9] == 't');
|
||||
TEST_ASSERT(data[10] == '2');
|
||||
TEST_ASSERT(data[11] == 0);
|
||||
}
|
||||
|
||||
EQEmu::MemoryBuffer mb;
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,21 @@
|
||||
DROP TABLE IF EXISTS `character_inventory`;
|
||||
CREATE TABLE `character_inventory` (
|
||||
`id` INT(10) UNSIGNED NOT NULL,
|
||||
`type` SMALLINT(6) NOT NULL,
|
||||
`slot` SMALLINT(6) NOT NULL,
|
||||
`bag_index` SMALLINT(6) NOT NULL,
|
||||
`aug_index` SMALLINT(6) NOT NULL,
|
||||
`item_id` INT(10) UNSIGNED NOT NULL,
|
||||
`charges` SMALLINT(6) NOT NULL,
|
||||
`color` INT(10) UNSIGNED NOT NULL,
|
||||
`attuned` TINYINT(3) UNSIGNED NOT NULL,
|
||||
`custom_data` TEXT NOT NULL,
|
||||
`ornament_icon` INT(10) UNSIGNED NOT NULL,
|
||||
`ornament_idfile` INT(10) UNSIGNED NOT NULL,
|
||||
`ornament_hero_model` INT(10) UNSIGNED NOT NULL,
|
||||
`tracking_id` BIGINT(20) UNSIGNED NOT NULL,
|
||||
PRIMARY KEY (`id`, `type`, `slot`, `bag_index`, `aug_index`),
|
||||
INDEX `tracking_id` (`tracking_id`)
|
||||
)
|
||||
COLLATE='latin1_swedish_ci'
|
||||
ENGINE=InnoDB;
|
||||
+1
-1
@@ -1356,7 +1356,7 @@ bool Client::OPCharCreate(char *name, CharCreate_Struct *cc)
|
||||
{
|
||||
PlayerProfile_Struct pp;
|
||||
ExtendedProfile_Struct ext;
|
||||
Inventory inv;
|
||||
InventoryOld inv;
|
||||
time_t bday = time(nullptr);
|
||||
char startzone[50]={0};
|
||||
uint32 i;
|
||||
|
||||
+4
-3
@@ -97,7 +97,7 @@ void WorldDatabase::GetCharSelectInfo(uint32 accountID, EQApplicationPacket **ou
|
||||
for (auto row = results.begin(); row != results.end(); ++row) {
|
||||
CharacterSelectEntry_Struct *cse = (CharacterSelectEntry_Struct *)buff_ptr;
|
||||
PlayerProfile_Struct pp;
|
||||
Inventory inv;
|
||||
InventoryOld inv;
|
||||
uint32 character_id = (uint32)atoi(row[0]);
|
||||
uint8 has_home = 0;
|
||||
uint8 has_bind = 0;
|
||||
@@ -219,12 +219,13 @@ void WorldDatabase::GetCharSelectInfo(uint32 accountID, EQApplicationPacket **ou
|
||||
/* Load Inventory */
|
||||
// If we ensure that the material data is updated appropriately, we can do away with inventory loads
|
||||
if (GetInventory(accountID, cse->Name, &inv)) {
|
||||
const Item_Struct* item = nullptr;
|
||||
const ItemData* item = nullptr;
|
||||
const ItemInst* inst = nullptr;
|
||||
int16 invslot = 0;
|
||||
|
||||
for (uint32 matslot = 0; matslot < _MaterialCount; matslot++) {
|
||||
invslot = Inventory::CalcSlotFromMaterial(matslot);
|
||||
invslot = InventoryOld::CalcSlotFromMaterial(matslot);
|
||||
|
||||
if (invslot == INVALID_INDEX) { continue; }
|
||||
inst = inv.GetItem(invslot);
|
||||
if (inst == nullptr) { continue; }
|
||||
|
||||
@@ -1268,15 +1268,8 @@ bool ZoneServer::Process() {
|
||||
UCSLink.SendPacket(pack);
|
||||
break;
|
||||
}
|
||||
case ServerOP_QSSendQuery:
|
||||
case ServerOP_QueryServGeneric:
|
||||
case ServerOP_Speech:
|
||||
case ServerOP_QSPlayerLogTrades:
|
||||
case ServerOP_QSPlayerLogHandins:
|
||||
case ServerOP_QSPlayerLogNPCKills:
|
||||
case ServerOP_QSPlayerLogDeletes:
|
||||
case ServerOP_QSPlayerLogMoves:
|
||||
case ServerOP_QSPlayerLogMerchantTransactions:
|
||||
{
|
||||
QSLink.SendPacket(pack);
|
||||
break;
|
||||
|
||||
+2
-14
@@ -879,7 +879,7 @@ void Mob::WakeTheDead(uint16 spell_id, Mob *target, uint32 duration)
|
||||
uint32 sitem = 0;
|
||||
sitem = CorpseToUse->GetWornItem(x);
|
||||
if(sitem){
|
||||
const Item_Struct * itm = database.GetItem(sitem);
|
||||
const ItemData * itm = database.GetItem(sitem);
|
||||
npca->AddLootDrop(itm, &npca->itemlist, 1, 1, 127, true, true);
|
||||
}
|
||||
}
|
||||
@@ -1035,24 +1035,12 @@ void Client::BuyAA(AA_Action* action)
|
||||
*/
|
||||
|
||||
/* Initial purchase of an AA ability */
|
||||
if (cur_level < 1){
|
||||
if (cur_level < 1) {
|
||||
Message(15, "You have gained the ability \"%s\" at a cost of %d ability %s.", aa2->name, real_cost, (real_cost>1) ? "points" : "point");
|
||||
|
||||
/* QS: Player_Log_AA_Purchases */
|
||||
if (RuleB(QueryServ, PlayerLogAAPurchases)){
|
||||
std::string event_desc = StringFormat("Initial AA Purchase :: aa_name:%s aa_id:%i at cost:%i in zoneid:%i instid:%i", aa2->name, aa2->id, real_cost, this->GetZoneID(), this->GetInstanceID());
|
||||
QServ->PlayerLogEvent(Player_Log_AA_Purchases, this->CharacterID(), event_desc);
|
||||
}
|
||||
}
|
||||
/* Ranked purchase of an AA ability */
|
||||
else{
|
||||
Message(15, "You have improved %s %d at a cost of %d ability %s.", aa2->name, cur_level + 1, real_cost, (real_cost > 1) ? "points" : "point");
|
||||
|
||||
/* QS: Player_Log_AA_Purchases */
|
||||
if (RuleB(QueryServ, PlayerLogAAPurchases)){
|
||||
std::string event_desc = StringFormat("Ranked AA Purchase :: aa_name:%s aa_id:%i at cost:%i in zoneid:%i instid:%i", aa2->name, aa2->id, real_cost, this->GetZoneID(), this->GetInstanceID());
|
||||
QServ->PlayerLogEvent(Player_Log_AA_Purchases, this->CharacterID(), event_desc);
|
||||
}
|
||||
}
|
||||
|
||||
SendAAStats();
|
||||
|
||||
+15
-79
@@ -55,7 +55,7 @@ bool Mob::AttackAnimation(SkillUseTypes &skillinuse, int Hand, const ItemInst* w
|
||||
// Determine animation
|
||||
int type = 0;
|
||||
if (weapon && weapon->IsType(ItemClassCommon)) {
|
||||
const Item_Struct* item = weapon->GetItem();
|
||||
const ItemData* item = weapon->GetItem();
|
||||
|
||||
Log.Out(Logs::Detail, Logs::Attack, "Weapon skill : %i", item->ItemType);
|
||||
|
||||
@@ -806,9 +806,9 @@ int32 Client::GetMeleeMitDmg(Mob *attacker, int32 damage, int32 minhit,
|
||||
//Returns the weapon damage against the input mob
|
||||
//if we cannot hit the mob with the current weapon we will get a value less than or equal to zero
|
||||
//Else we know we can hit.
|
||||
//GetWeaponDamage(mob*, const Item_Struct*) is intended to be used for mobs or any other situation where we do not have a client inventory item
|
||||
//GetWeaponDamage(mob*, const ItemData*) is intended to be used for mobs or any other situation where we do not have a client inventory item
|
||||
//GetWeaponDamage(mob*, const ItemInst*) is intended to be used for situations where we have a client inventory item
|
||||
int Mob::GetWeaponDamage(Mob *against, const Item_Struct *weapon_item) {
|
||||
int Mob::GetWeaponDamage(Mob *against, const ItemData *weapon_item) {
|
||||
int dmg = 0;
|
||||
int banedmg = 0;
|
||||
|
||||
@@ -925,7 +925,7 @@ int Mob::GetWeaponDamage(Mob *against, const ItemInst *weapon_item, uint32 *hate
|
||||
|
||||
//check for items being illegally attained
|
||||
if(weapon_item){
|
||||
const Item_Struct *mWeaponItem = weapon_item->GetItem();
|
||||
const ItemData *mWeaponItem = weapon_item->GetItem();
|
||||
if(mWeaponItem){
|
||||
if(mWeaponItem->ReqLevel > GetLevel()){
|
||||
return 0;
|
||||
@@ -1267,7 +1267,7 @@ bool Client::Attack(Mob* other, int Hand, bool bRiposte, bool IsStrikethrough, b
|
||||
// Damage bonuses apply only to hits from the main hand (Hand == MainPrimary) by characters level 28 and above
|
||||
// who belong to a melee class. If we're here, then all of these conditions apply.
|
||||
|
||||
ucDamageBonus = GetWeaponDamageBonus( weapon ? weapon->GetItem() : (const Item_Struct*) nullptr );
|
||||
ucDamageBonus = GetWeaponDamageBonus( weapon ? weapon->GetItem() : (const ItemData*) nullptr );
|
||||
|
||||
min_hit += (int) ucDamageBonus;
|
||||
max_hit += (int) ucDamageBonus;
|
||||
@@ -1278,7 +1278,7 @@ bool Client::Attack(Mob* other, int Hand, bool bRiposte, bool IsStrikethrough, b
|
||||
if (Hand == MainSecondary) {
|
||||
if (aabonuses.SecondaryDmgInc || itembonuses.SecondaryDmgInc || spellbonuses.SecondaryDmgInc){
|
||||
|
||||
ucDamageBonus = GetWeaponDamageBonus( weapon ? weapon->GetItem() : (const Item_Struct*) nullptr );
|
||||
ucDamageBonus = GetWeaponDamageBonus( weapon ? weapon->GetItem() : (const ItemData*) nullptr );
|
||||
|
||||
min_hit += (int) ucDamageBonus;
|
||||
max_hit += (int) ucDamageBonus;
|
||||
@@ -1706,14 +1706,6 @@ bool Client::Death(Mob* killerMob, int32 damage, uint16 spell, SkillUseTypes att
|
||||
GoToDeath();
|
||||
}
|
||||
|
||||
/* QS: PlayerLogDeaths */
|
||||
if (RuleB(QueryServ, PlayerLogDeaths)){
|
||||
const char * killer_name = "";
|
||||
if (killerMob && killerMob->GetCleanName()){ killer_name = killerMob->GetCleanName(); }
|
||||
std::string event_desc = StringFormat("Died in zoneid:%i instid:%i by '%s', spellid:%i, damage:%i", this->GetZoneID(), this->GetInstanceID(), killer_name, spell, damage);
|
||||
QServ->PlayerLogEvent(Player_Log_Deaths, this->CharacterID(), event_desc);
|
||||
}
|
||||
|
||||
parse->EventPlayer(EVENT_DEATH_COMPLETE, this, buffer, 0);
|
||||
return true;
|
||||
}
|
||||
@@ -1760,7 +1752,7 @@ bool NPC::Attack(Mob* other, int Hand, bool bRiposte, bool IsStrikethrough, bool
|
||||
}
|
||||
|
||||
//figure out what weapon they are using, if any
|
||||
const Item_Struct* weapon = nullptr;
|
||||
const ItemData* weapon = nullptr;
|
||||
if (Hand == MainPrimary && equipment[MainPrimary] > 0)
|
||||
weapon = database.GetItem(equipment[MainPrimary]);
|
||||
else if (equipment[MainSecondary])
|
||||
@@ -2180,27 +2172,6 @@ bool NPC::Death(Mob* killerMob, int32 damage, uint16 spell, SkillUseTypes attack
|
||||
PlayerCount++;
|
||||
}
|
||||
}
|
||||
|
||||
// QueryServ Logging - Raid Kills
|
||||
if(RuleB(QueryServ, PlayerLogNPCKills)){
|
||||
ServerPacket* pack = new ServerPacket(ServerOP_QSPlayerLogNPCKills, sizeof(QSPlayerLogNPCKill_Struct) + (sizeof(QSPlayerLogNPCKillsPlayers_Struct) * PlayerCount));
|
||||
PlayerCount = 0;
|
||||
QSPlayerLogNPCKill_Struct* QS = (QSPlayerLogNPCKill_Struct*) pack->pBuffer;
|
||||
QS->s1.NPCID = this->GetNPCTypeID();
|
||||
QS->s1.ZoneID = this->GetZoneID();
|
||||
QS->s1.Type = 2; // Raid Fight
|
||||
for (int i = 0; i < MAX_RAID_MEMBERS; i++) {
|
||||
if (kr->members[i].member != nullptr && kr->members[i].member->IsClient()) { // If Group Member is Client
|
||||
Client *c = kr->members[i].member;
|
||||
QS->Chars[PlayerCount].char_id = c->CharacterID();
|
||||
PlayerCount++;
|
||||
}
|
||||
}
|
||||
worldserver.SendPacket(pack); // Send Packet to World
|
||||
safe_delete(pack);
|
||||
}
|
||||
// End QueryServ Logging
|
||||
|
||||
}
|
||||
else if (give_exp_client->IsGrouped() && kg != nullptr)
|
||||
{
|
||||
@@ -2227,26 +2198,6 @@ bool NPC::Death(Mob* killerMob, int32 damage, uint16 spell, SkillUseTypes attack
|
||||
PlayerCount++;
|
||||
}
|
||||
}
|
||||
|
||||
// QueryServ Logging - Group Kills
|
||||
if(RuleB(QueryServ, PlayerLogNPCKills)){
|
||||
ServerPacket* pack = new ServerPacket(ServerOP_QSPlayerLogNPCKills, sizeof(QSPlayerLogNPCKill_Struct) + (sizeof(QSPlayerLogNPCKillsPlayers_Struct) * PlayerCount));
|
||||
PlayerCount = 0;
|
||||
QSPlayerLogNPCKill_Struct* QS = (QSPlayerLogNPCKill_Struct*) pack->pBuffer;
|
||||
QS->s1.NPCID = this->GetNPCTypeID();
|
||||
QS->s1.ZoneID = this->GetZoneID();
|
||||
QS->s1.Type = 1; // Group Fight
|
||||
for (int i = 0; i < MAX_GROUP_MEMBERS; i++) {
|
||||
if (kg->members[i] != nullptr && kg->members[i]->IsClient()) { // If Group Member is Client
|
||||
Client *c = kg->members[i]->CastToClient();
|
||||
QS->Chars[PlayerCount].char_id = c->CharacterID();
|
||||
PlayerCount++;
|
||||
}
|
||||
}
|
||||
worldserver.SendPacket(pack); // Send Packet to World
|
||||
safe_delete(pack);
|
||||
}
|
||||
// End QueryServ Logging
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -2273,21 +2224,6 @@ bool NPC::Death(Mob* killerMob, int32 damage, uint16 spell, SkillUseTypes attack
|
||||
|
||||
if(RuleB(TaskSystem, EnableTaskSystem))
|
||||
give_exp_client->UpdateTasksOnKill(GetNPCTypeID());
|
||||
|
||||
// QueryServ Logging - Solo
|
||||
if(RuleB(QueryServ, PlayerLogNPCKills)){
|
||||
ServerPacket* pack = new ServerPacket(ServerOP_QSPlayerLogNPCKills, sizeof(QSPlayerLogNPCKill_Struct) + (sizeof(QSPlayerLogNPCKillsPlayers_Struct) * 1));
|
||||
QSPlayerLogNPCKill_Struct* QS = (QSPlayerLogNPCKill_Struct*) pack->pBuffer;
|
||||
QS->s1.NPCID = this->GetNPCTypeID();
|
||||
QS->s1.ZoneID = this->GetZoneID();
|
||||
QS->s1.Type = 0; // Solo Fight
|
||||
Client *c = give_exp_client;
|
||||
QS->Chars[0].char_id = c->CharacterID();
|
||||
PlayerCount++;
|
||||
worldserver.SendPacket(pack); // Send Packet to World
|
||||
safe_delete(pack);
|
||||
}
|
||||
// End QueryServ Logging
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2663,7 +2599,7 @@ void Mob::DamageShield(Mob* attacker, bool spell_ds) {
|
||||
}
|
||||
}
|
||||
|
||||
uint8 Mob::GetWeaponDamageBonus( const Item_Struct *Weapon )
|
||||
uint8 Mob::GetWeaponDamageBonus( const ItemData *Weapon )
|
||||
{
|
||||
// This function calculates and returns the damage bonus for the weapon identified by the parameter "Weapon".
|
||||
// Modified 9/21/2008 by Cantus
|
||||
@@ -3985,12 +3921,12 @@ void Mob::TryWeaponProc(const ItemInst* weapon_g, Mob *on, uint16 hand) {
|
||||
}
|
||||
|
||||
if(!weapon_g) {
|
||||
TrySpellProc(nullptr, (const Item_Struct*)nullptr, on);
|
||||
TrySpellProc(nullptr, (const ItemData*)nullptr, on);
|
||||
return;
|
||||
}
|
||||
|
||||
if(!weapon_g->IsType(ItemClassCommon)) {
|
||||
TrySpellProc(nullptr, (const Item_Struct*)nullptr, on);
|
||||
TrySpellProc(nullptr, (const ItemData*)nullptr, on);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -4003,7 +3939,7 @@ void Mob::TryWeaponProc(const ItemInst* weapon_g, Mob *on, uint16 hand) {
|
||||
return;
|
||||
}
|
||||
|
||||
void Mob::TryWeaponProc(const ItemInst *inst, const Item_Struct *weapon, Mob *on, uint16 hand)
|
||||
void Mob::TryWeaponProc(const ItemInst *inst, const ItemData *weapon, Mob *on, uint16 hand)
|
||||
{
|
||||
|
||||
if (!weapon)
|
||||
@@ -4056,7 +3992,7 @@ void Mob::TryWeaponProc(const ItemInst *inst, const Item_Struct *weapon, Mob *on
|
||||
const ItemInst *aug_i = inst->GetAugment(r);
|
||||
if (!aug_i) // no aug, try next slot!
|
||||
continue;
|
||||
const Item_Struct *aug = aug_i->GetItem();
|
||||
const ItemData *aug = aug_i->GetItem();
|
||||
if (!aug)
|
||||
continue;
|
||||
|
||||
@@ -4086,7 +4022,7 @@ void Mob::TryWeaponProc(const ItemInst *inst, const Item_Struct *weapon, Mob *on
|
||||
return;
|
||||
}
|
||||
|
||||
void Mob::TrySpellProc(const ItemInst *inst, const Item_Struct *weapon, Mob *on, uint16 hand)
|
||||
void Mob::TrySpellProc(const ItemInst *inst, const ItemData *weapon, Mob *on, uint16 hand)
|
||||
{
|
||||
float ProcBonus = static_cast<float>(spellbonuses.SpellProcChance +
|
||||
itembonuses.SpellProcChance + aabonuses.SpellProcChance);
|
||||
@@ -4906,7 +4842,7 @@ void Client::SetAttackTimer()
|
||||
attack_timer.SetAtTrigger(4000, true);
|
||||
|
||||
Timer *TimerToUse = nullptr;
|
||||
const Item_Struct *PrimaryWeapon = nullptr;
|
||||
const ItemData *PrimaryWeapon = nullptr;
|
||||
|
||||
for (int i = MainRange; i <= MainSecondary; i++) {
|
||||
//pick a timer
|
||||
@@ -4919,7 +4855,7 @@ void Client::SetAttackTimer()
|
||||
else //invalid slot (hands will always hit this)
|
||||
continue;
|
||||
|
||||
const Item_Struct *ItemToUse = nullptr;
|
||||
const ItemData *ItemToUse = nullptr;
|
||||
|
||||
//find our item
|
||||
ItemInst *ci = GetInv().GetItem(i);
|
||||
|
||||
+8
-8
@@ -153,7 +153,7 @@ void Client::CalcItemBonuses(StatBonuses* newbon) {
|
||||
AddItemBonuses(inst, newbon);
|
||||
|
||||
//These are given special flags due to how often they are checked for various spell effects.
|
||||
const Item_Struct *item = inst->GetItem();
|
||||
const ItemData *item = inst->GetItem();
|
||||
if (i == MainSecondary && (item && item->ItemType == ItemTypeShield))
|
||||
SetShieldEquiped(true);
|
||||
else if (i == MainPrimary && (item && item->ItemType == ItemType2HBlunt))
|
||||
@@ -216,7 +216,7 @@ void Client::AddItemBonuses(const ItemInst *inst, StatBonuses* newbon, bool isAu
|
||||
return;
|
||||
}
|
||||
|
||||
const Item_Struct *item = inst->GetItem();
|
||||
const ItemData *item = inst->GetItem();
|
||||
|
||||
if(!isTribute && !inst->IsEquipable(GetBaseRace(),GetClass()))
|
||||
{
|
||||
@@ -572,7 +572,7 @@ void Client::AdditiveWornBonuses(const ItemInst *inst, StatBonuses* newbon, bool
|
||||
if(inst->GetAugmentType()==0 && isAug == true)
|
||||
return;
|
||||
|
||||
const Item_Struct *item = inst->GetItem();
|
||||
const ItemData *item = inst->GetItem();
|
||||
|
||||
if(!inst->IsEquipable(GetBaseRace(),GetClass()))
|
||||
return;
|
||||
@@ -604,7 +604,7 @@ void Client::CalcEdibleBonuses(StatBonuses* newbon) {
|
||||
break;
|
||||
const ItemInst* inst = GetInv().GetItem(i);
|
||||
if (inst && inst->GetItem() && inst->IsType(ItemClassCommon)) {
|
||||
const Item_Struct *item=inst->GetItem();
|
||||
const ItemData *item=inst->GetItem();
|
||||
if (item->ItemType == ItemTypeFood && !food)
|
||||
food = true;
|
||||
else if (item->ItemType == ItemTypeDrink && !drink)
|
||||
@@ -620,7 +620,7 @@ void Client::CalcEdibleBonuses(StatBonuses* newbon) {
|
||||
break;
|
||||
const ItemInst* inst = GetInv().GetItem(i);
|
||||
if (inst && inst->GetItem() && inst->IsType(ItemClassCommon)) {
|
||||
const Item_Struct *item=inst->GetItem();
|
||||
const ItemData *item=inst->GetItem();
|
||||
if (item->ItemType == ItemTypeFood && !food)
|
||||
food = true;
|
||||
else if (item->ItemType == ItemTypeDrink && !drink)
|
||||
@@ -3056,7 +3056,7 @@ void NPC::CalcItemBonuses(StatBonuses *newbon)
|
||||
if(newbon){
|
||||
|
||||
for(int i = 0; i < EmuConstants::EQUIPMENT_SIZE; i++){
|
||||
const Item_Struct *cur = database.GetItem(equipment[i]);
|
||||
const ItemData *cur = database.GetItem(equipment[i]);
|
||||
if(cur){
|
||||
//basic stats
|
||||
newbon->AC += cur->AC;
|
||||
@@ -3176,7 +3176,7 @@ bool Client::CalcItemScale(uint32 slot_x, uint32 slot_y) {
|
||||
// TEST CODE: test for bazaar trader crashing with charm items
|
||||
if (Trader)
|
||||
if (i >= EmuConstants::GENERAL_BAGS_BEGIN && i <= EmuConstants::GENERAL_BAGS_END) {
|
||||
ItemInst* parent_item = m_inv.GetItem(Inventory::CalcSlotId(i));
|
||||
ItemInst* parent_item = m_inv.GetItem(InventoryOld::CalcSlotId(i));
|
||||
if (parent_item && parent_item->GetItem()->ID == 17899) // trader satchel
|
||||
continue;
|
||||
}
|
||||
@@ -3269,7 +3269,7 @@ bool Client::DoItemEnterZone(uint32 slot_x, uint32 slot_y) {
|
||||
// TEST CODE: test for bazaar trader crashing with charm items
|
||||
if (Trader)
|
||||
if (i >= EmuConstants::GENERAL_BAGS_BEGIN && i <= EmuConstants::GENERAL_BAGS_END) {
|
||||
ItemInst* parent_item = m_inv.GetItem(Inventory::CalcSlotId(i));
|
||||
ItemInst* parent_item = m_inv.GetItem(InventoryOld::CalcSlotId(i));
|
||||
if (parent_item && parent_item->GetItem()->ID == 17899) // trader satchel
|
||||
continue;
|
||||
}
|
||||
|
||||
+48
-41
@@ -5,6 +5,7 @@
|
||||
#include "doors.h"
|
||||
#include "quest_parser_collection.h"
|
||||
#include "../common/string_util.h"
|
||||
#include "../common/item.h"
|
||||
|
||||
extern volatile bool ZoneLoaded;
|
||||
|
||||
@@ -212,8 +213,8 @@ uint32 Bot::GetBotArcheryRange() {
|
||||
if (!range_inst || !ammo_inst)
|
||||
return 0;
|
||||
|
||||
const Item_Struct *range_item = range_inst->GetItem();
|
||||
const Item_Struct *ammo_item = ammo_inst->GetItem();
|
||||
const ItemData *range_item = range_inst->GetItem();
|
||||
const ItemData *ammo_item = ammo_inst->GetItem();
|
||||
if (!range_item || !ammo_item || range_item->ItemType != ItemTypeBow || ammo_item->ItemType != ItemTypeArrow)
|
||||
return 0;
|
||||
|
||||
@@ -2623,12 +2624,12 @@ void Bot::BotRangedAttack(Mob* other) {
|
||||
}
|
||||
|
||||
ItemInst* rangedItem = GetBotItem(MainRange);
|
||||
const Item_Struct* RangeWeapon = 0;
|
||||
const ItemData* RangeWeapon = 0;
|
||||
if(rangedItem)
|
||||
RangeWeapon = rangedItem->GetItem();
|
||||
|
||||
ItemInst* ammoItem = GetBotItem(MainAmmo);
|
||||
const Item_Struct* Ammo = 0;
|
||||
const ItemData* Ammo = 0;
|
||||
if(ammoItem)
|
||||
Ammo = ammoItem->GetItem();
|
||||
|
||||
@@ -2735,7 +2736,7 @@ void Bot::DoMeleeSkillAttackDmg(Mob* other, uint16 weapon_damage, SkillUseTypes
|
||||
int32 min_hit = 1;
|
||||
int32 max_hit = ((2 * weapon_damage * GetDamageTable(skillinuse)) / 100);
|
||||
if(GetLevel() >= 28 && IsWarriorClass()) {
|
||||
int ucDamageBonus = GetWeaponDamageBonus((const Item_Struct*) nullptr);
|
||||
int ucDamageBonus = GetWeaponDamageBonus((const ItemData*) nullptr);
|
||||
min_hit += (int) ucDamageBonus;
|
||||
max_hit += (int) ucDamageBonus;
|
||||
hate += ucDamageBonus;
|
||||
@@ -2776,7 +2777,7 @@ void Bot::DoMeleeSkillAttackDmg(Mob* other, uint16 weapon_damage, SkillUseTypes
|
||||
|
||||
if(skillinuse == SkillBash){
|
||||
const ItemInst* inst = GetBotItem(MainSecondary);
|
||||
const Item_Struct* botweapon = 0;
|
||||
const ItemData* botweapon = 0;
|
||||
if(inst)
|
||||
botweapon = inst->GetItem();
|
||||
|
||||
@@ -2836,7 +2837,7 @@ void Bot::ApplySpecialAttackMod(SkillUseTypes skill, int32 &dmg, int32 &mindmg)
|
||||
|
||||
if (item_slot >= EmuConstants::EQUIPMENT_BEGIN){
|
||||
const ItemInst* inst = GetBotItem(item_slot);
|
||||
const Item_Struct* botweapon = 0;
|
||||
const ItemData* botweapon = 0;
|
||||
if(inst)
|
||||
botweapon = inst->GetItem();
|
||||
|
||||
@@ -3190,7 +3191,7 @@ void Bot::AI_Process() {
|
||||
//now off hand
|
||||
if(GetTarget() && attack_dw_timer.Check() && CanThisClassDualWield()) {
|
||||
const ItemInst* instweapon = GetBotItem(MainSecondary);
|
||||
const Item_Struct* weapon = 0;
|
||||
const ItemData* weapon = 0;
|
||||
//can only dual wield without a weapon if you're a monk
|
||||
if(instweapon || (botClass == MONK)) {
|
||||
if(instweapon)
|
||||
@@ -3596,8 +3597,9 @@ void Bot::Spawn(Client* botCharacterOwner, std::string* errorMessage) {
|
||||
uint8 materialFromSlot = 0xFF;
|
||||
for(int i = EmuConstants::EQUIPMENT_BEGIN; i <= EmuConstants::EQUIPMENT_END; ++i) {
|
||||
itemID = GetBotItemBySlot(i);
|
||||
if(itemID != 0) {
|
||||
materialFromSlot = Inventory::CalcMaterialFromSlot(i);
|
||||
if(itemID != 0) {
|
||||
materialFromSlot = InventoryOld::CalcMaterialFromSlot(i);
|
||||
|
||||
if(materialFromSlot != 0xFF)
|
||||
this->SendWearChange(materialFromSlot);
|
||||
}
|
||||
@@ -3645,7 +3647,7 @@ void Bot::RemoveBotItemBySlot(uint32 slotID, std::string *errorMessage) {
|
||||
}
|
||||
|
||||
// Retrieves all the inventory records from the database for this bot.
|
||||
void Bot::GetBotItems(std::string* errorMessage, Inventory &inv) {
|
||||
void Bot::GetBotItems(std::string* errorMessage, InventoryOld &inv) {
|
||||
if(this->GetBotID() == 0)
|
||||
return;
|
||||
|
||||
@@ -3671,7 +3673,8 @@ void Bot::GetBotItems(std::string* errorMessage, Inventory &inv) {
|
||||
aug[3] = (uint32)atoul(row[7]);
|
||||
aug[4] = (uint32)atoul(row[8]);
|
||||
bool instnodrop = (row[9] && (uint16)atoi(row[9])) ? true : false;
|
||||
ItemInst* inst = database.CreateItem(item_id, charges, aug[0], aug[1], aug[2], aug[3], aug[4]);
|
||||
|
||||
ItemInst* inst = database.CreateItemOld(item_id, charges, aug[0], aug[1], aug[2], aug[3], aug[4]);
|
||||
if (!inst) {
|
||||
Log.Out(Logs::General, Logs::Error, "Warning: botid %i has an invalid item_id %i in inventory slot %i", this->GetBotID(), item_id, slot_id);
|
||||
continue;
|
||||
@@ -3805,7 +3808,7 @@ void Bot::FillSpawnStruct(NewSpawn_Struct* ns, Mob* ForWho) {
|
||||
ns->spawn.light = m_Light.Type.Active;
|
||||
ns->spawn.helm = (GetShowHelm() ? helmtexture : 0); //0xFF;
|
||||
ns->spawn.equip_chest2 = texture; //0xFF;
|
||||
const Item_Struct* item = 0;
|
||||
const ItemData* item = 0;
|
||||
const ItemInst* inst = 0;
|
||||
uint32 spawnedbotid = 0;
|
||||
spawnedbotid = this->GetBotID();
|
||||
@@ -4421,7 +4424,7 @@ ItemInst* Bot::GetBotItem(uint32 slotID) {
|
||||
// Adds the specified item it bot to the NPC equipment array and to the bot inventory collection.
|
||||
void Bot::BotAddEquipItem(int slot, uint32 id) {
|
||||
if(slot > 0 && id > 0) {
|
||||
uint8 materialFromSlot = Inventory::CalcMaterialFromSlot(slot);
|
||||
uint8 materialFromSlot = InventoryOld::CalcMaterialFromSlot(slot);
|
||||
|
||||
if(materialFromSlot != _MaterialInvalid) {
|
||||
equipment[slot] = id; // npc has more than just material slots. Valid material should mean valid inventory index
|
||||
@@ -4437,7 +4440,7 @@ void Bot::BotAddEquipItem(int slot, uint32 id) {
|
||||
// Erases the specified item from bot the NPC equipment array and from the bot inventory collection.
|
||||
void Bot::BotRemoveEquipItem(int slot) {
|
||||
if(slot > 0) {
|
||||
uint8 materialFromSlot = Inventory::CalcMaterialFromSlot(slot);
|
||||
uint8 materialFromSlot = InventoryOld::CalcMaterialFromSlot(slot);
|
||||
|
||||
if(materialFromSlot != _MaterialInvalid) {
|
||||
equipment[slot] = 0; // npc has more than just material slots. Valid material should mean valid inventory index
|
||||
@@ -4903,7 +4906,7 @@ void Bot::PerformTradeWithClient(int16 beginSlotID, int16 endSlotID, Client* cli
|
||||
bool UpdateClient = false;
|
||||
bool already_returned = false;
|
||||
|
||||
Inventory& clientInventory = client->GetInv();
|
||||
InventoryOld& clientInventory = client->GetInv();
|
||||
const ItemInst* inst = clientInventory[i];
|
||||
if(inst) {
|
||||
items[i] = inst->GetItem()->ID;
|
||||
@@ -4916,7 +4919,7 @@ void Bot::PerformTradeWithClient(int16 beginSlotID, int16 endSlotID, Client* cli
|
||||
//EQoffline: will give the items to the bots and change the bot stats
|
||||
if(inst && (GetBotOwner() == client->CastToMob()) && !IsEngaged()) {
|
||||
std::string TempErrorMessage;
|
||||
const Item_Struct* mWeaponItem = inst->GetItem();
|
||||
const ItemData* mWeaponItem = inst->GetItem();
|
||||
bool failedLoreCheck = false;
|
||||
for (int m = AUG_BEGIN; m <EmuConstants::ITEM_COMMON_SIZE; ++m) {
|
||||
ItemInst *itm = inst->GetAugment(m);
|
||||
@@ -5095,7 +5098,7 @@ void Bot::PerformTradeWithClient(int16 beginSlotID, int16 endSlotID, Client* cli
|
||||
}
|
||||
}
|
||||
|
||||
const Item_Struct* item2 = 0;
|
||||
const ItemData* item2 = 0;
|
||||
for(int y = beginSlotID; y <= endSlotID; ++y) {
|
||||
item2 = database.GetItem(items[y]);
|
||||
if(item2) {
|
||||
@@ -5335,7 +5338,7 @@ bool Bot::Attack(Mob* other, int Hand, bool FromRiposte, bool IsStrikethrough, b
|
||||
if(Hand == MainPrimary && GetLevel() >= 28 && IsWarriorClass()) {
|
||||
// Damage bonuses apply only to hits from the main hand (Hand == MainPrimary) by characters level 28 and above
|
||||
// who belong to a melee class. If we're here, then all of these conditions apply.
|
||||
ucDamageBonus = GetWeaponDamageBonus(weapon ? weapon->GetItem() : (const Item_Struct*) nullptr);
|
||||
ucDamageBonus = GetWeaponDamageBonus( weapon ? weapon->GetItem() : (const ItemData*) nullptr );
|
||||
min_hit += (int) ucDamageBonus;
|
||||
max_hit += (int) ucDamageBonus;
|
||||
hate += ucDamageBonus;
|
||||
@@ -5344,7 +5347,7 @@ bool Bot::Attack(Mob* other, int Hand, bool FromRiposte, bool IsStrikethrough, b
|
||||
//Live AA - Sinister Strikes *Adds weapon damage bonus to offhand weapon.
|
||||
if (Hand==MainSecondary) {
|
||||
if (aabonuses.SecondaryDmgInc || itembonuses.SecondaryDmgInc || spellbonuses.SecondaryDmgInc){
|
||||
ucDamageBonus = GetWeaponDamageBonus(weapon ? weapon->GetItem() : (const Item_Struct*) nullptr);
|
||||
ucDamageBonus = GetWeaponDamageBonus( weapon ? weapon->GetItem() : (const ItemData*) nullptr );
|
||||
min_hit += (int) ucDamageBonus;
|
||||
max_hit += (int) ucDamageBonus;
|
||||
hate += ucDamageBonus;
|
||||
@@ -5809,8 +5812,8 @@ int32 Bot::GetBotFocusEffect(BotfocusType bottype, uint16 spell_id) {
|
||||
|
||||
//Check if item focus effect exists for the client.
|
||||
if (itembonuses.FocusEffects[bottype]) {
|
||||
const Item_Struct* TempItem = 0;
|
||||
const Item_Struct* UsedItem = 0;
|
||||
const ItemData* TempItem = 0;
|
||||
const ItemData* UsedItem = 0;
|
||||
const ItemInst* TempInst = 0;
|
||||
uint16 UsedFocusID = 0;
|
||||
int32 Total = 0;
|
||||
@@ -5845,8 +5848,9 @@ int32 Bot::GetBotFocusEffect(BotfocusType bottype, uint16 spell_id) {
|
||||
for (int y = AUG_BEGIN; y < EmuConstants::ITEM_COMMON_SIZE; ++y) {
|
||||
ItemInst *aug = nullptr;
|
||||
aug = ins->GetAugment(y);
|
||||
if(aug) {
|
||||
const Item_Struct* TempItemAug = aug->GetItem();
|
||||
if(aug)
|
||||
{
|
||||
const ItemData* TempItemAug = aug->GetItem();
|
||||
if (TempItemAug && TempItemAug->Focus.Effect > 0 && TempItemAug->Focus.Effect != SPELL_UNKNOWN) {
|
||||
if(rand_effectiveness) {
|
||||
focus_max = CalcBotFocusEffect(bottype, TempItemAug->Focus.Effect, spell_id, true);
|
||||
@@ -6498,7 +6502,7 @@ void Bot::DoSpecialAttackDamage(Mob *who, SkillUseTypes skill, int32 max_damage,
|
||||
|
||||
if(skill == SkillBash) {
|
||||
const ItemInst* inst = GetBotItem(MainSecondary);
|
||||
const Item_Struct* botweapon = 0;
|
||||
const ItemData* botweapon = 0;
|
||||
if(inst)
|
||||
botweapon = inst->GetItem();
|
||||
|
||||
@@ -6565,7 +6569,7 @@ void Bot::TryBackstab(Mob *other, int ReuseTime) {
|
||||
bool bIsBehind = false;
|
||||
bool bCanFrontalBS = false;
|
||||
const ItemInst* inst = GetBotItem(MainPrimary);
|
||||
const Item_Struct* botpiercer = nullptr;
|
||||
const ItemData* botpiercer = nullptr;
|
||||
if(inst)
|
||||
botpiercer = inst->GetItem();
|
||||
|
||||
@@ -7002,7 +7006,7 @@ bool Bot::IsBotAttackAllowed(Mob* attacker, Mob* target, bool& hasRuleDefined) {
|
||||
void Bot::EquipBot(std::string* errorMessage) {
|
||||
GetBotItems(errorMessage, m_inv);
|
||||
const ItemInst* inst = 0;
|
||||
const Item_Struct* item = 0;
|
||||
const ItemData* item = 0;
|
||||
for(int i = EmuConstants::EQUIPMENT_BEGIN; i <= EmuConstants::EQUIPMENT_END; ++i) {
|
||||
inst = GetBotItem(i);
|
||||
if(inst) {
|
||||
@@ -7149,7 +7153,8 @@ void Bot::SetAttackTimer() {
|
||||
float haste_mod = (GetHaste() * 0.01f);
|
||||
attack_timer.SetAtTrigger(4000, true);
|
||||
Timer* TimerToUse = nullptr;
|
||||
const Item_Struct* PrimaryWeapon = nullptr;
|
||||
const ItemData* PrimaryWeapon = nullptr;
|
||||
|
||||
for (int i = MainRange; i <= MainSecondary; i++) {
|
||||
if (i == MainPrimary)
|
||||
TimerToUse = &attack_timer;
|
||||
@@ -7160,7 +7165,7 @@ void Bot::SetAttackTimer() {
|
||||
else
|
||||
continue;
|
||||
|
||||
const Item_Struct* ItemToUse = nullptr;
|
||||
const ItemData* ItemToUse = nullptr;
|
||||
ItemInst* ci = GetBotItem(i);
|
||||
if (ci)
|
||||
ItemToUse = ci->GetItem();
|
||||
@@ -8918,7 +8923,7 @@ void Bot::ProcessBotInspectionRequest(Bot* inspectedBot, Client* client) {
|
||||
insr->TargetID = inspectedBot->GetNPCTypeID();
|
||||
insr->playerid = inspectedBot->GetID();
|
||||
|
||||
const Item_Struct* item = 0;
|
||||
const ItemData* item = 0;
|
||||
const ItemInst* inst = 0;
|
||||
|
||||
// Modded to display power source items (will only show up on SoF+ client inspect windows though.)
|
||||
@@ -8970,7 +8975,8 @@ void Bot::ProcessBotInspectionRequest(Bot* inspectedBot, Client* client) {
|
||||
|
||||
void Bot::CalcItemBonuses(StatBonuses* newbon)
|
||||
{
|
||||
const Item_Struct* itemtmp = 0;
|
||||
memset(&itembonuses, 0, sizeof(StatBonuses));
|
||||
const ItemData* itemtmp = 0;
|
||||
|
||||
for (int i = EmuConstants::EQUIPMENT_BEGIN; i <= (EmuConstants::EQUIPMENT_END + 1); ++i) {
|
||||
const ItemInst* item = GetBotItem((i == 22 ? 9999 : i));
|
||||
@@ -9001,7 +9007,7 @@ void Bot::AddItemBonuses(const ItemInst *inst, StatBonuses* newbon, bool isAug,
|
||||
return;
|
||||
}
|
||||
|
||||
const Item_Struct *item = inst->GetItem();
|
||||
const ItemData *item = inst->GetItem();
|
||||
|
||||
if(!isTribute && !inst->IsEquipable(GetBaseRace(),GetClass()))
|
||||
{
|
||||
@@ -9370,7 +9376,7 @@ void Bot::CalcBotStats(bool showtext) {
|
||||
}
|
||||
}
|
||||
|
||||
bool Bot::CheckLoreConflict(const Item_Struct* item) {
|
||||
bool Bot::CheckLoreConflict(const ItemData* item) {
|
||||
if (!item || !(item->LoreFlag))
|
||||
return false;
|
||||
|
||||
@@ -9530,7 +9536,7 @@ void Bot::ProcessBotCommands(Client *c, const Seperator *sep) {
|
||||
return;
|
||||
|
||||
for (int i = 0; i < 7; i++) {
|
||||
uint8 slotmaterial = Inventory::CalcMaterialFromSlot((uint8)slots[i]);
|
||||
uint8 slotmaterial = InventoryOld::CalcMaterialFromSlot((uint8)slots[i]);
|
||||
c->GetTarget()->CastToBot()->SendWearChange(slotmaterial);
|
||||
}
|
||||
} else {
|
||||
@@ -9539,10 +9545,9 @@ void Bot::ProcessBotCommands(Client *c, const Seperator *sep) {
|
||||
if (!results.Success())
|
||||
return;
|
||||
|
||||
uint8 slotmaterial = Inventory::CalcMaterialFromSlot(setslot);
|
||||
uint8 slotmaterial = InventoryOld::CalcMaterialFromSlot(setslot);
|
||||
c->GetTarget()->CastToBot()->SendWearChange(slotmaterial);
|
||||
}
|
||||
|
||||
}
|
||||
else {
|
||||
c->Message(15, "You must target a bot you own to do this.");
|
||||
@@ -9938,7 +9943,7 @@ void Bot::ProcessBotCommands(Client *c, const Seperator *sep) {
|
||||
"Left Finger", "Right Finger", "Chest", "Legs", "Feet", "Waist", "Ammo", "Powersource" };
|
||||
|
||||
const ItemInst* inst = nullptr;
|
||||
const Item_Struct* item = nullptr;
|
||||
const ItemData* item = nullptr;
|
||||
bool is2Hweapon = false;
|
||||
|
||||
std::string item_link;
|
||||
@@ -10003,7 +10008,7 @@ void Bot::ProcessBotCommands(Client *c, const Seperator *sep) {
|
||||
"Left Wrist", "Right Wrist", "Range", "Hands", "Primary Hand", "Secondary Hand",
|
||||
"Left Finger", "Right Finger", "Chest", "Legs", "Feet", "Waist", "Ammo", "Powersource" };
|
||||
|
||||
const Item_Struct* itm = nullptr;
|
||||
const ItemData* itm = nullptr;
|
||||
const ItemInst* itminst = c->GetTarget()->CastToBot()->GetBotItem(slotId);
|
||||
if(itminst)
|
||||
itm = itminst->GetItem();
|
||||
@@ -13512,7 +13517,9 @@ uint8 Bot::GetNumberNeedingHealedInGroup(uint8 hpr, bool includePets) {
|
||||
uint32 Bot::GetEquipmentColor(uint8 material_slot) const {
|
||||
int16 slotid = 0;
|
||||
uint32 botid = this->GetBotID();
|
||||
slotid = Inventory::CalcSlotFromMaterial(material_slot);
|
||||
|
||||
//Translate code slot # to DB slot #
|
||||
slotid = InventoryOld::CalcSlotFromMaterial(material_slot);
|
||||
if (slotid == INVALID_INDEX)
|
||||
return 0;
|
||||
|
||||
@@ -13545,7 +13552,7 @@ int Bot::GetRawACNoShield(int &shield_ac) {
|
||||
}
|
||||
|
||||
uint32 Bot::CalcCurrentWeight() {
|
||||
const Item_Struct* TempItem = 0;
|
||||
const ItemData* TempItem = 0;
|
||||
ItemInst* inst;
|
||||
uint32 Total = 0;
|
||||
for(int i = EmuConstants::EQUIPMENT_BEGIN; i <= EmuConstants::EQUIPMENT_END; ++i) {
|
||||
@@ -14031,4 +14038,4 @@ void Bot::BotHealRotationsClear(Client* c) {
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
#endif
|
||||
|
||||
+3
-3
@@ -333,7 +333,7 @@ public:
|
||||
void BotTradeSwapItem(Client* client, int16 lootSlot, const ItemInst* inst, const ItemInst* inst_swap, uint32 equipableSlots, std::string* errorMessage, bool swap = true);
|
||||
void BotTradeAddItem(uint32 id, const ItemInst* inst, int16 charges, uint32 equipableSlots, uint16 lootSlot, std::string* errorMessage, bool addToDb = true);
|
||||
void EquipBot(std::string* errorMessage);
|
||||
bool CheckLoreConflict(const Item_Struct* item);
|
||||
bool CheckLoreConflict(const ItemData* item);
|
||||
uint32 GetEquipmentColor(uint8 material_slot) const;
|
||||
virtual void UpdateEquipmentLight() { m_Light.Type.Equipment = m_inv.FindBrightestLightType(); m_Light.Level.Equipment = m_Light.TypeToLevel(m_Light.Type.Equipment); }
|
||||
|
||||
@@ -584,7 +584,7 @@ private:
|
||||
bool _petChooser;
|
||||
uint8 _petChooserID;
|
||||
bool berserk;
|
||||
Inventory m_inv;
|
||||
InventoryOld m_inv;
|
||||
double _lastTotalPlayTime;
|
||||
time_t _startTotalPlayTime;
|
||||
Mob* _previousTarget;
|
||||
@@ -657,7 +657,7 @@ private:
|
||||
void SetBotID(uint32 botID);
|
||||
|
||||
// Private "Inventory" Methods
|
||||
void GetBotItems(std::string* errorMessage, Inventory &inv);
|
||||
void GetBotItems(std::string* errorMessage, InventoryOld &inv);
|
||||
void BotRemoveEquipItem(int slot);
|
||||
void BotAddEquipItem(int slot, uint32 id);
|
||||
uint32 GetBotItemBySlot(uint32 slotID);
|
||||
|
||||
+62
-121
@@ -2113,80 +2113,19 @@ bool Client::TakeMoneyFromPP(uint64 copper, bool updateclient) {
|
||||
}
|
||||
}
|
||||
|
||||
void Client::AddMoneyToPP(uint64 copper, bool updateclient){
|
||||
uint64 tmp;
|
||||
uint64 tmp2;
|
||||
tmp = copper;
|
||||
void Client::AddMoneyToPP(uint64 copper, bool updateclient) {
|
||||
|
||||
/* Add Amount of Platinum */
|
||||
tmp2 = tmp/1000;
|
||||
int32 new_val = m_pp.platinum + tmp2;
|
||||
if(new_val < 0) { m_pp.platinum = 0; }
|
||||
else { m_pp.platinum = m_pp.platinum + tmp2; }
|
||||
tmp-=tmp2*1000;
|
||||
|
||||
//if (updateclient)
|
||||
// SendClientMoneyUpdate(3,tmp2);
|
||||
|
||||
/* Add Amount of Gold */
|
||||
tmp2 = tmp/100;
|
||||
new_val = m_pp.gold + tmp2;
|
||||
if(new_val < 0) { m_pp.gold = 0; }
|
||||
else { m_pp.gold = m_pp.gold + tmp2; }
|
||||
|
||||
tmp-=tmp2*100;
|
||||
//if (updateclient)
|
||||
// SendClientMoneyUpdate(2,tmp2);
|
||||
|
||||
/* Add Amount of Silver */
|
||||
tmp2 = tmp/10;
|
||||
new_val = m_pp.silver + tmp2;
|
||||
if(new_val < 0) {
|
||||
m_pp.silver = 0;
|
||||
} else {
|
||||
m_pp.silver = m_pp.silver + tmp2;
|
||||
}
|
||||
tmp-=tmp2*10;
|
||||
//if (updateclient)
|
||||
// SendClientMoneyUpdate(1,tmp2);
|
||||
|
||||
// Add Copper
|
||||
//tmp = tmp - (tmp2* 10);
|
||||
//if (updateclient)
|
||||
// SendClientMoneyUpdate(0,tmp);
|
||||
tmp2 = tmp;
|
||||
new_val = m_pp.copper + tmp2;
|
||||
if(new_val < 0) {
|
||||
m_pp.copper = 0;
|
||||
} else {
|
||||
m_pp.copper = m_pp.copper + tmp2;
|
||||
}
|
||||
|
||||
|
||||
//send them all at once, since the above code stopped working.
|
||||
if(updateclient)
|
||||
SendMoneyUpdate();
|
||||
|
||||
RecalcWeight();
|
||||
|
||||
SaveCurrency();
|
||||
|
||||
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);
|
||||
uint64 plat = copper / 1000;
|
||||
copper -= plat * 1000;
|
||||
uint64 gold = copper / 100;
|
||||
copper -= gold * 100;
|
||||
uint64 silver = copper / 10;
|
||||
copper -= silver * 10;
|
||||
AddMoneyToPP(copper, silver, gold, plat, updateclient);
|
||||
}
|
||||
|
||||
void Client::EVENT_ITEM_ScriptStopReturn(){
|
||||
/* 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
|
||||
*/
|
||||
struct timeval read_time;
|
||||
char buffer[50];
|
||||
gettimeofday(&read_time, 0);
|
||||
sprintf(buffer, "%li.%li \n", read_time.tv_sec, read_time.tv_usec);
|
||||
this->SetEntityVariable("Stop_Return", buffer);
|
||||
}
|
||||
|
||||
void Client::AddMoneyToPP(uint32 copper, uint32 silver, uint32 gold, uint32 platinum, bool updateclient){
|
||||
this->EVENT_ITEM_ScriptStopReturn();
|
||||
void Client::AddMoneyToPP(uint32 copper, uint32 silver, uint32 gold, uint32 platinum, bool updateclient) {
|
||||
ItemScriptStopReturn();
|
||||
|
||||
int32 new_value = m_pp.platinum + platinum;
|
||||
if(new_value >= 0 && new_value > m_pp.platinum)
|
||||
@@ -2209,11 +2148,17 @@ void Client::AddMoneyToPP(uint32 copper, uint32 silver, uint32 gold, uint32 plat
|
||||
|
||||
RecalcWeight();
|
||||
SaveCurrency();
|
||||
}
|
||||
|
||||
#if (EQDEBUG>=5)
|
||||
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);
|
||||
#endif
|
||||
void Client::ItemScriptStopReturn() {
|
||||
/* 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
|
||||
*/
|
||||
struct timeval read_time;
|
||||
char buffer[50];
|
||||
gettimeofday(&read_time, 0);
|
||||
sprintf(buffer, "%li.%li \n", read_time.tv_sec, read_time.tv_usec);
|
||||
SetEntityVariable("Stop_Return", buffer);
|
||||
}
|
||||
|
||||
void Client::SendMoneyUpdate() {
|
||||
@@ -2515,33 +2460,34 @@ void Client::SetFeigned(bool in_feigned) {
|
||||
feigned=in_feigned;
|
||||
}
|
||||
|
||||
void Client::LogMerchant(Client* player, Mob* merchant, uint32 quantity, uint32 price, const Item_Struct* item, bool buying)
|
||||
void Client::LogMerchant(Client* player, Mob* merchant, uint32 quantity, uint32 price, const ItemData* item, bool buying)
|
||||
{
|
||||
if(!player || !merchant || !item)
|
||||
return;
|
||||
|
||||
std::string LogText = "Qty: ";
|
||||
|
||||
char Buffer[255];
|
||||
memset(Buffer, 0, sizeof(Buffer));
|
||||
|
||||
snprintf(Buffer, sizeof(Buffer)-1, "%3i", quantity);
|
||||
LogText += Buffer;
|
||||
snprintf(Buffer, sizeof(Buffer)-1, "%10i", price);
|
||||
LogText += " TotalValue: ";
|
||||
LogText += Buffer;
|
||||
snprintf(Buffer, sizeof(Buffer)-1, " ItemID: %7i", item->ID);
|
||||
LogText += Buffer;
|
||||
LogText += " ";
|
||||
snprintf(Buffer, sizeof(Buffer)-1, " %s", item->Name);
|
||||
LogText += Buffer;
|
||||
|
||||
if (buying==true) {
|
||||
database.logevents(player->AccountName(),player->AccountID(),player->admin,player->GetName(),merchant->GetName(),"Buying from Merchant",LogText.c_str(),2);
|
||||
}
|
||||
else {
|
||||
database.logevents(player->AccountName(),player->AccountID(),player->admin,player->GetName(),merchant->GetName(),"Selling to Merchant",LogText.c_str(),3);
|
||||
}
|
||||
//Inv2 redo or remove
|
||||
//if(!player || !merchant || !item)
|
||||
// return;
|
||||
//
|
||||
//std::string LogText = "Qty: ";
|
||||
//
|
||||
//char Buffer[255];
|
||||
//memset(Buffer, 0, sizeof(Buffer));
|
||||
//
|
||||
//snprintf(Buffer, sizeof(Buffer)-1, "%3i", quantity);
|
||||
//LogText += Buffer;
|
||||
//snprintf(Buffer, sizeof(Buffer)-1, "%10i", price);
|
||||
//LogText += " TotalValue: ";
|
||||
//LogText += Buffer;
|
||||
//snprintf(Buffer, sizeof(Buffer)-1, " ItemID: %7i", item->ID);
|
||||
//LogText += Buffer;
|
||||
//LogText += " ";
|
||||
//snprintf(Buffer, sizeof(Buffer)-1, " %s", item->Name);
|
||||
//LogText += Buffer;
|
||||
//
|
||||
//if (buying==true) {
|
||||
// database.logevents(player->AccountName(),player->AccountID(),player->admin,player->GetName(),merchant->GetName(),"Buying from Merchant",LogText.c_str(),2);
|
||||
//}
|
||||
//else {
|
||||
// database.logevents(player->AccountName(),player->AccountID(),player->admin,player->GetName(),merchant->GetName(),"Selling to Merchant",LogText.c_str(),3);
|
||||
//}
|
||||
}
|
||||
|
||||
bool Client::BindWound(Mob* bindmob, bool start, bool fail){
|
||||
@@ -2709,10 +2655,10 @@ bool Client::BindWound(Mob* bindmob, bool start, bool fail){
|
||||
}
|
||||
|
||||
void Client::SetMaterial(int16 in_slot, uint32 item_id) {
|
||||
const Item_Struct* item = database.GetItem(item_id);
|
||||
const ItemData* item = database.GetItem(item_id);
|
||||
if (item && (item->ItemClass==ItemClassCommon))
|
||||
{
|
||||
uint8 matslot = Inventory::CalcMaterialFromSlot(in_slot);
|
||||
uint8 matslot = InventoryOld::CalcMaterialFromSlot(in_slot);
|
||||
if (matslot != _MaterialInvalid)
|
||||
{
|
||||
m_pp.item_material[matslot] = GetEquipmentMaterial(matslot);
|
||||
@@ -3054,7 +3000,7 @@ void Client::SetTint(int16 in_slot, uint32 color) {
|
||||
// Still need to reconcile bracer01 versus bracer02
|
||||
void Client::SetTint(int16 in_slot, Color_Struct& color) {
|
||||
|
||||
uint8 matslot = Inventory::CalcMaterialFromSlot(in_slot);
|
||||
uint8 matslot = InventoryOld::CalcMaterialFromSlot(in_slot);
|
||||
if (matslot != _MaterialInvalid)
|
||||
{
|
||||
m_pp.item_tint[matslot].Color = color.Color;
|
||||
@@ -3755,7 +3701,7 @@ void Client::SendOPTranslocateConfirm(Mob *Caster, uint16 SpellID) {
|
||||
|
||||
return;
|
||||
}
|
||||
void Client::SendPickPocketResponse(Mob *from, uint32 amt, int type, const Item_Struct* item){
|
||||
void Client::SendPickPocketResponse(Mob *from, uint32 amt, int type, const ItemData* item){
|
||||
EQApplicationPacket* outapp = new EQApplicationPacket(OP_PickPocket, sizeof(sPickPocket_Struct));
|
||||
sPickPocket_Struct* pick_out = (sPickPocket_Struct*) outapp->pBuffer;
|
||||
pick_out->coin = amt;
|
||||
@@ -3927,7 +3873,7 @@ bool Client::KeyRingCheck(uint32 item_id)
|
||||
void Client::KeyRingList()
|
||||
{
|
||||
Message(4,"Keys on Keyring:");
|
||||
const Item_Struct *item = 0;
|
||||
const ItemData *item = 0;
|
||||
for(std::list<uint32>::iterator iter = keyring.begin();
|
||||
iter != keyring.end();
|
||||
++iter)
|
||||
@@ -5427,7 +5373,7 @@ bool Client::TryReward(uint32 claim_id)
|
||||
}
|
||||
|
||||
auto &ivr = (*iter);
|
||||
ItemInst *claim = database.CreateItem(ivr.items[0].item_id, ivr.items[0].charges);
|
||||
ItemInst *claim = database.CreateItemOld(ivr.items[0].item_id, ivr.items[0].charges);
|
||||
if (!claim) {
|
||||
Save();
|
||||
return true;
|
||||
@@ -5437,7 +5383,7 @@ bool Client::TryReward(uint32 claim_id)
|
||||
|
||||
for (int y = 1; y < 8; y++)
|
||||
if (ivr.items[y].item_id && claim->GetItem()->ItemClass == 1) {
|
||||
ItemInst *item_temp = database.CreateItem(ivr.items[y].item_id, ivr.items[y].charges);
|
||||
ItemInst *item_temp = database.CreateItemOld(ivr.items[y].item_id, ivr.items[y].charges);
|
||||
if (item_temp) {
|
||||
if (CheckLoreConflict(item_temp->GetItem())) {
|
||||
lore_conflict = true;
|
||||
@@ -5697,7 +5643,7 @@ void Client::ProcessInspectRequest(Client* requestee, Client* requester) {
|
||||
insr->TargetID = requester->GetID();
|
||||
insr->playerid = requestee->GetID();
|
||||
|
||||
const Item_Struct* item = nullptr;
|
||||
const ItemData* item = nullptr;
|
||||
const ItemInst* inst = nullptr;
|
||||
int ornamentationAugtype = RuleI(Character, OrnamentationAugmentType);
|
||||
for(int16 L = 0; L <= 20; L++) {
|
||||
@@ -5709,7 +5655,7 @@ void Client::ProcessInspectRequest(Client* requestee, Client* requester) {
|
||||
strcpy(insr->itemnames[L], item->Name);
|
||||
if (inst && inst->GetOrnamentationAug(ornamentationAugtype))
|
||||
{
|
||||
const Item_Struct *aug_item = inst->GetOrnamentationAug(ornamentationAugtype)->GetItem();
|
||||
const ItemData *aug_item = inst->GetOrnamentationAug(ornamentationAugtype)->GetItem();
|
||||
insr->itemicons[L] = aug_item->Icon;
|
||||
}
|
||||
else if (inst && inst->GetOrnamentationIcon())
|
||||
@@ -6890,7 +6836,7 @@ void Client::SendAltCurrencies() {
|
||||
uint32 i = 0;
|
||||
std::list<AltCurrencyDefinition_Struct>::iterator iter = zone->AlternateCurrencies.begin();
|
||||
while(iter != zone->AlternateCurrencies.end()) {
|
||||
const Item_Struct* item = database.GetItem((*iter).item_id);
|
||||
const ItemData* item = database.GetItem((*iter).item_id);
|
||||
altc->entries[i].currency_number = (*iter).id;
|
||||
altc->entries[i].unknown00 = 1;
|
||||
altc->entries[i].currency_number2 = (*iter).id;
|
||||
@@ -6922,11 +6868,7 @@ void Client::AddAlternateCurrencyValue(uint32 currency_id, int32 amount, int8 me
|
||||
|
||||
/* Added via Quest, rest of the logging methods may be done inline due to information available in that area of the code */
|
||||
if (method == 1){
|
||||
/* QS: PlayerLogAlternateCurrencyTransactions :: Cursor to Item Storage */
|
||||
if (RuleB(QueryServ, PlayerLogAlternateCurrencyTransactions)){
|
||||
std::string event_desc = StringFormat("Added via Quest :: Cursor to Item :: alt_currency_id:%i amount:%i in zoneid:%i instid:%i", currency_id, this->GetZoneID(), this->GetInstanceID());
|
||||
QServ->PlayerLogEvent(Player_Log_Alternate_Currency_Transactions, this->CharacterID(), event_desc);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if(amount == 0) {
|
||||
@@ -7482,7 +7424,7 @@ void Client::DuplicateLoreMessage(uint32 ItemID)
|
||||
return;
|
||||
}
|
||||
|
||||
const Item_Struct *item = database.GetItem(ItemID);
|
||||
const ItemData *item = database.GetItem(ItemID);
|
||||
|
||||
if(!item)
|
||||
return;
|
||||
@@ -8244,7 +8186,7 @@ void Client::SetConsumption(int32 in_hunger, int32 in_thirst)
|
||||
safe_delete(outapp);
|
||||
}
|
||||
|
||||
void Client::Consume(const Item_Struct *item, uint8 type, int16 slot, bool auto_consume)
|
||||
void Client::Consume(const ItemData *item, uint8 type, int16 slot, bool auto_consume)
|
||||
{
|
||||
if(!item) { return; }
|
||||
|
||||
@@ -8447,8 +8389,7 @@ void Client::TextLink::generate_body()
|
||||
*/
|
||||
|
||||
memset(&m_LinkBodyStruct, 0, sizeof(TextLinkBody_Struct));
|
||||
|
||||
const Item_Struct* item_data = nullptr;
|
||||
const ItemData* item_data = nullptr;
|
||||
|
||||
switch (m_LinkType) {
|
||||
case linkBlank:
|
||||
@@ -8528,7 +8469,7 @@ void Client::TextLink::generate_text()
|
||||
return;
|
||||
}
|
||||
|
||||
const Item_Struct* item_data = nullptr;
|
||||
const ItemData* item_data = nullptr;
|
||||
|
||||
switch (m_LinkType) {
|
||||
case linkBlank:
|
||||
|
||||
+45
-20
@@ -27,7 +27,7 @@ class Object;
|
||||
class Raid;
|
||||
class Seperator;
|
||||
class ServerPacket;
|
||||
struct Item_Struct;
|
||||
struct ItemData;
|
||||
|
||||
#include "../common/timer.h"
|
||||
#include "../common/ptimer.h"
|
||||
@@ -42,7 +42,7 @@ struct Item_Struct;
|
||||
#include "../common/seperator.h"
|
||||
#include "../common/item.h"
|
||||
#include "../common/guilds.h"
|
||||
#include "../common/item_struct.h"
|
||||
#include "../common/item_data.h"
|
||||
#include "../common/clientversions.h"
|
||||
|
||||
#include "aa.h"
|
||||
@@ -288,7 +288,7 @@ public:
|
||||
|
||||
void FillSpawnStruct(NewSpawn_Struct* ns, Mob* ForWho);
|
||||
virtual bool Process();
|
||||
void LogMerchant(Client* player, Mob* merchant, uint32 quantity, uint32 price, const Item_Struct* item, bool buying);
|
||||
void LogMerchant(Client* player, Mob* merchant, uint32 quantity, uint32 price, const ItemData* item, bool buying);
|
||||
void SendPacketQueue(bool Block = true);
|
||||
void QueuePacket(const EQApplicationPacket* app, bool ack_req = true, CLIENT_CONN_STATUS = CLIENT_CONNECTINGALL, eqFilterType filter=FilterNone);
|
||||
void FastQueuePacket(EQApplicationPacket** app, bool ack_req = true, CLIENT_CONN_STATUS = CLIENT_CONNECTINGALL);
|
||||
@@ -333,8 +333,8 @@ public:
|
||||
inline uint8 GetAnon() const { return m_pp.anon; }
|
||||
inline PlayerProfile_Struct& GetPP() { return m_pp; }
|
||||
inline ExtendedProfile_Struct& GetEPP() { return m_epp; }
|
||||
inline Inventory& GetInv() { return m_inv; }
|
||||
inline const Inventory& GetInv() const { return m_inv; }
|
||||
inline InventoryOld& GetInv() { return m_inv; }
|
||||
inline const InventoryOld& GetInv() const { return m_inv; }
|
||||
inline PetInfo* GetPetInfo(uint16 pet) { return (pet==1)?&m_suspendedminion:&m_petinfo; }
|
||||
inline InspectMessage_Struct& GetInspectMessage() { return m_inspect_message; }
|
||||
inline const InspectMessage_Struct& GetInspectMessage() const { return m_inspect_message; }
|
||||
@@ -396,7 +396,7 @@ public:
|
||||
|
||||
inline uint8 GetLanguageSkill(uint16 n) const { return m_pp.languages[n]; }
|
||||
|
||||
void SendPickPocketResponse(Mob *from, uint32 amt, int type, const Item_Struct* item = nullptr);
|
||||
void SendPickPocketResponse(Mob *from, uint32 amt, int type, const ItemData* item = nullptr);
|
||||
|
||||
inline const char* GetLastName() const { return lastname; }
|
||||
|
||||
@@ -593,7 +593,7 @@ public:
|
||||
void AssignToInstance(uint16 instance_id);
|
||||
void RemoveFromInstance(uint16 instance_id);
|
||||
void WhoAll();
|
||||
bool CheckLoreConflict(const Item_Struct* item);
|
||||
bool CheckLoreConflict(const ItemData* item);
|
||||
void ChangeLastName(const char* in_lastname);
|
||||
void GetGroupAAs(GroupLeadershipAA_Struct *into) const;
|
||||
void GetRaidAAs(RaidLeadershipAA_Struct *into) const;
|
||||
@@ -801,7 +801,7 @@ public:
|
||||
int32 acmod();
|
||||
|
||||
// Item methods
|
||||
void EVENT_ITEM_ScriptStopReturn();
|
||||
void ItemScriptStopReturn();
|
||||
uint32 NukeItem(uint32 itemnum, uint8 where_to_check =
|
||||
(invWhereWorn | invWherePersonal | invWhereBank | invWhereSharedBank | invWhereTrading | invWhereCursor));
|
||||
void SetTint(int16 slot_id, uint32 color);
|
||||
@@ -814,16 +814,38 @@ public:
|
||||
bool PushItemOnCursor(const ItemInst& inst, bool client_update = false);
|
||||
void SendCursorBuffer();
|
||||
void DeleteItemInInventory(int16 slot_id, int8 quantity = 0, bool client_update = false, bool update_db = true);
|
||||
bool SwapItem(MoveItem_Struct* move_in);
|
||||
void SwapItemResync(MoveItem_Struct* move_slots);
|
||||
void QSSwapItemAuditor(MoveItem_Struct* move_in, bool postaction_call = false);
|
||||
bool SwapItem(MoveItemOld_Struct* move_in);
|
||||
void SwapItemResync(MoveItemOld_Struct* move_slots);
|
||||
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);
|
||||
|
||||
//inv2: New Inventory methods, will probably move these to Mob in a future update as there's
|
||||
//little reason for them to be in client except for simplicity of implementation atm
|
||||
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 = EQEmu::InventorySlot(EQEmu::InvTypePersonal, EQEmu::PersonalSlotCursor),
|
||||
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);
|
||||
bool PutItemInInventory(const EQEmu::InventorySlot &slot, EQEmu::ItemInstance::pointer &inst, bool client_update = false);
|
||||
bool CanPutItemInInventory(EQEmu::ItemInstance::pointer &inst, int container_id, int slot_id_start, int slot_id_end);
|
||||
void StackItem(EQEmu::ItemInstance::pointer &inst, int container_id, int slot_id_start, int slot_id_end, bool client_update);
|
||||
void PutItemInInventory(EQEmu::ItemInstance::pointer &inst, int container_id, int slot_id_start, int slot_id_end, bool client_update);
|
||||
|
||||
//
|
||||
// class Client::TextLink
|
||||
//
|
||||
@@ -834,7 +856,7 @@ public:
|
||||
TextLink() { Reset(); }
|
||||
|
||||
void SetLinkType(LinkType linkType) { m_LinkType = linkType; }
|
||||
void SetItemData(const Item_Struct* itemData) { m_ItemData = itemData; }
|
||||
void SetItemData(const ItemData* itemData) { m_ItemData = itemData; }
|
||||
void SetLootData(const ServerLootItem_Struct* lootData) { m_LootData = lootData; }
|
||||
void SetItemInst(const ItemInst* itemInst) { m_ItemInst = itemInst; }
|
||||
void SetProxyItemID(uint32 proxyItemID) { m_ProxyItemID = proxyItemID; } // mainly for saylinks..but, not limited to
|
||||
@@ -858,7 +880,7 @@ public:
|
||||
void generate_text();
|
||||
|
||||
int m_LinkType;
|
||||
const Item_Struct* m_ItemData;
|
||||
const ItemData* m_ItemData;
|
||||
const ServerLootItem_Struct* m_LootData;
|
||||
const ItemInst* m_ItemInst;
|
||||
uint32 m_ProxyItemID;
|
||||
@@ -871,7 +893,7 @@ public:
|
||||
bool m_Error;
|
||||
};
|
||||
|
||||
int GetItemLinkHash(const ItemInst* inst); // move to Item_Struct..or make use of the pre-calculated database field
|
||||
int GetItemLinkHash(const ItemInst* inst); // move to ItemData..or make use of the pre-calculated database field
|
||||
|
||||
void SendItemLink(const ItemInst* inst, bool sendtoall=false);
|
||||
void SendLootItemInPacket(const ItemInst* inst, int16 slot_id);
|
||||
@@ -879,6 +901,9 @@ public:
|
||||
bool IsValidSlot(uint32 slot);
|
||||
bool IsBankSlot(uint32 slot);
|
||||
|
||||
//inv2
|
||||
void SendItemPacket(const EQEmu::InventorySlot &slot, EQEmu::ItemInstance::pointer &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]; }
|
||||
@@ -1217,7 +1242,7 @@ public:
|
||||
void LoadAccountFlags();
|
||||
void SetAccountFlag(std::string flag, std::string val);
|
||||
std::string GetAccountFlag(std::string flag); float GetDamageMultiplier(SkillUseTypes);
|
||||
void Consume(const Item_Struct *item, uint8 type, int16 slot, bool auto_consume);
|
||||
void Consume(const ItemData *item, uint8 type, int16 slot, bool auto_consume);
|
||||
void PlayMP3(const char* fname);
|
||||
void ExpeditionSay(const char *str, int ExpID);
|
||||
int mod_client_damage(int damage, SkillUseTypes skillinuse, int hand, const ItemInst* weapon, Mob* other);
|
||||
@@ -1239,9 +1264,9 @@ public:
|
||||
int32 mod_client_xp(int32 in_exp, NPC *npc);
|
||||
uint32 mod_client_xp_for_level(uint32 xp, uint16 check_level);
|
||||
int mod_client_haste_cap(int cap);
|
||||
int mod_consume(Item_Struct *item, ItemUseTypes type, int change);
|
||||
int mod_food_value(const Item_Struct *item, int change);
|
||||
int mod_drink_value(const Item_Struct *item, int change);
|
||||
int mod_consume(ItemData *item, ItemUseTypes type, int change);
|
||||
int mod_food_value(const ItemData *item, int change);
|
||||
int mod_drink_value(const ItemData *item, int change);
|
||||
|
||||
void SetEngagedRaidTarget(bool value) { EngagedRaidTarget = value; }
|
||||
bool GetEngagedRaidTarget() const { return EngagedRaidTarget; }
|
||||
@@ -1413,7 +1438,7 @@ private:
|
||||
|
||||
PlayerProfile_Struct m_pp;
|
||||
ExtendedProfile_Struct m_epp;
|
||||
Inventory m_inv;
|
||||
InventoryOld m_inv;
|
||||
Object* m_tradeskill_object;
|
||||
PetInfo m_petinfo; // current pet data, used while loading from and saving to DB
|
||||
PetInfo m_suspendedminion; // pet data for our suspended minion.
|
||||
|
||||
@@ -1302,7 +1302,7 @@ int32 Client::CalcManaRegenCap()
|
||||
|
||||
uint32 Client::CalcCurrentWeight()
|
||||
{
|
||||
const Item_Struct* TempItem = 0;
|
||||
const ItemData* TempItem = 0;
|
||||
ItemInst* ins;
|
||||
uint32 Total = 0;
|
||||
int x;
|
||||
|
||||
+144
-372
@@ -47,6 +47,7 @@
|
||||
#include "../common/spdat.h"
|
||||
#include "../common/string_util.h"
|
||||
#include "../common/zone_numbers.h"
|
||||
#include "../common/inventory_db_data_model.h"
|
||||
#include "event_codes.h"
|
||||
#include "guild_mgr.h"
|
||||
#include "merc.h"
|
||||
@@ -782,11 +783,6 @@ void Client::CompleteConnect()
|
||||
/* This sub event is for if a player logs in for the first time since entering world. */
|
||||
if (firstlogon == 1){
|
||||
parse->EventPlayer(EVENT_CONNECT, this, "", 0);
|
||||
/* QS: PlayerLogConnectDisconnect */
|
||||
if (RuleB(QueryServ, PlayerLogConnectDisconnect)){
|
||||
std::string event_desc = StringFormat("Connect :: Logged into zoneid:%i instid:%i", this->GetZoneID(), this->GetInstanceID());
|
||||
QServ->PlayerLogEvent(Player_Log_Connect_State, this->CharacterID(), event_desc);
|
||||
}
|
||||
}
|
||||
|
||||
if (zone) {
|
||||
@@ -1279,7 +1275,6 @@ void Client::Handle_Connect_OP_ZoneEntry(const EQApplicationPacket *app)
|
||||
m_pp.platinum_shared = database.GetSharedPlatinum(this->AccountID());
|
||||
|
||||
database.ClearOldRecastTimestamps(cid); /* Clear out our old recast timestamps to keep the DB clean */
|
||||
loaditems = database.GetInventory(cid, &m_inv); /* Load Character Inventory */
|
||||
database.LoadCharacterBandolier(cid, &m_pp); /* Load Character Bandolier */
|
||||
database.LoadCharacterBindPoint(cid, &m_pp); /* Load Character Bind */
|
||||
database.LoadCharacterMaterialColor(cid, &m_pp); /* Load Character Material */
|
||||
@@ -1295,6 +1290,12 @@ void Client::Handle_Connect_OP_ZoneEntry(const EQApplicationPacket *app)
|
||||
database.LoadCharacterLeadershipAA(cid, &m_pp); /* Load Character Leadership AA's */
|
||||
database.LoadCharacterTribute(cid, &m_pp); /* Load CharacterTribute */
|
||||
|
||||
m_inventory.SetRace(GetBaseRace());
|
||||
m_inventory.SetClass(GetBaseClass());
|
||||
m_inventory.SetDeity(GetDeity());
|
||||
m_inventory.SetDataModel(new EQEmu::InventoryDatabaseDataModel(&database, CharacterID()));
|
||||
loaditems = database.GetInventory(cid, &m_inventory); /* Load Character Inventory */
|
||||
|
||||
/* Load AdventureStats */
|
||||
AdventureStats_Struct as;
|
||||
if(database.GetAdventureStats(cid, &as))
|
||||
@@ -1730,13 +1731,10 @@ 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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1927,7 +1925,7 @@ void Client::Handle_OP_AdventureMerchantPurchase(const EQApplicationPacket *app)
|
||||
|
||||
merchantid = tmp->CastToNPC()->MerchantType;
|
||||
|
||||
const Item_Struct* item = nullptr;
|
||||
const ItemData* item = nullptr;
|
||||
bool found = false;
|
||||
std::list<MerchantList> merlist = zone->merchanttable[merchantid];
|
||||
std::list<MerchantList>::const_iterator itr;
|
||||
@@ -2070,7 +2068,7 @@ void Client::Handle_OP_AdventureMerchantPurchase(const EQApplicationPacket *app)
|
||||
if (item->MaxCharges != 0)
|
||||
charges = item->MaxCharges;
|
||||
|
||||
ItemInst *inst = database.CreateItem(item, charges);
|
||||
ItemInst *inst = database.CreateItemOld(item, charges);
|
||||
if (!AutoPutLootInInventory(*inst, true, true))
|
||||
{
|
||||
PutLootInInventory(MainCursor, *inst);
|
||||
@@ -2103,7 +2101,7 @@ void Client::Handle_OP_AdventureMerchantRequest(const EQApplicationPacket *app)
|
||||
merchantid = tmp->CastToNPC()->MerchantType;
|
||||
tmp->CastToNPC()->FaceTarget(this->CastToMob());
|
||||
|
||||
const Item_Struct *item = 0;
|
||||
const ItemData *item = 0;
|
||||
std::list<MerchantList> merlist = zone->merchanttable[merchantid];
|
||||
std::list<MerchantList>::const_iterator itr;
|
||||
for (itr = merlist.begin(); itr != merlist.end() && count<255; ++itr){
|
||||
@@ -2202,7 +2200,7 @@ void Client::Handle_OP_AdventureMerchantSell(const EQApplicationPacket *app)
|
||||
return;
|
||||
}
|
||||
|
||||
const Item_Struct* item = database.GetItem(itemid);
|
||||
const ItemData* item = database.GetItem(itemid);
|
||||
ItemInst* inst = GetInv().GetItem(ams_in->slot);
|
||||
if (!item || !inst){
|
||||
Message(13, "You seemed to have misplaced that item...");
|
||||
@@ -2477,7 +2475,7 @@ void Client::Handle_OP_AltCurrencyMerchantRequest(const EQApplicationPacket *app
|
||||
ss << alt_cur_id << "|1|" << alt_cur_id;
|
||||
uint32 count = 0;
|
||||
uint32 merchant_id = tar->MerchantType;
|
||||
const Item_Struct *item = nullptr;
|
||||
const ItemData *item = nullptr;
|
||||
|
||||
std::list<MerchantList> merlist = zone->merchanttable[merchant_id];
|
||||
std::list<MerchantList>::const_iterator itr;
|
||||
@@ -2537,7 +2535,7 @@ void Client::Handle_OP_AltCurrencyPurchase(const EQApplicationPacket *app)
|
||||
return;
|
||||
}
|
||||
|
||||
const Item_Struct* item = nullptr;
|
||||
const ItemData* item = nullptr;
|
||||
uint32 cost = 0;
|
||||
uint32 current_currency = GetAlternateCurrencyValue(alt_cur_id);
|
||||
uint32 merchant_id = tar->MerchantType;
|
||||
@@ -2582,18 +2580,12 @@ void Client::Handle_OP_AltCurrencyPurchase(const EQApplicationPacket *app)
|
||||
return;
|
||||
}
|
||||
|
||||
/* QS: PlayerLogAlternateCurrencyTransactions :: Merchant Purchase */
|
||||
if (RuleB(QueryServ, PlayerLogAlternateCurrencyTransactions)){
|
||||
std::string event_desc = StringFormat("Merchant Purchase :: Spent alt_currency_id:%i cost:%i for itemid:%i in zoneid:%i instid:%i", alt_cur_id, cost, item->ID, this->GetZoneID(), this->GetInstanceID());
|
||||
QServ->PlayerLogEvent(Player_Log_Alternate_Currency_Transactions, this->CharacterID(), event_desc);
|
||||
}
|
||||
|
||||
AddAlternateCurrencyValue(alt_cur_id, -((int32)cost));
|
||||
int16 charges = 1;
|
||||
if (item->MaxCharges != 0)
|
||||
charges = item->MaxCharges;
|
||||
|
||||
ItemInst *inst = database.CreateItem(item, charges);
|
||||
ItemInst *inst = database.CreateItemOld(item, charges);
|
||||
if (!AutoPutLootInInventory(*inst, true, true))
|
||||
{
|
||||
PutLootInInventory(MainCursor, *inst);
|
||||
@@ -2625,12 +2617,6 @@ void Client::Handle_OP_AltCurrencyReclaim(const EQApplicationPacket *app)
|
||||
uint32 removed = NukeItem(item_id, invWhereWorn | invWherePersonal | invWhereCursor);
|
||||
if (removed > 0) {
|
||||
AddAlternateCurrencyValue(reclaim->currency_id, removed);
|
||||
|
||||
/* QS: PlayerLogAlternateCurrencyTransactions :: Item to Currency */
|
||||
if (RuleB(QueryServ, PlayerLogAlternateCurrencyTransactions)){
|
||||
std::string event_desc = StringFormat("Reclaim :: Item to Currency :: alt_currency_id:%i amount:%i to currency tab in zoneid:%i instid:%i", reclaim->currency_id, removed, this->GetZoneID(), this->GetInstanceID());
|
||||
QServ->PlayerLogEvent(Player_Log_Alternate_Currency_Transactions, this->CharacterID(), event_desc);
|
||||
}
|
||||
}
|
||||
}
|
||||
/* Cursor to Item storage */
|
||||
@@ -2642,18 +2628,13 @@ void Client::Handle_OP_AltCurrencyReclaim(const EQApplicationPacket *app)
|
||||
|
||||
/* If you input more than you have currency wise, just give the max of the currency you currently have */
|
||||
if (reclaim->count > max_currency) {
|
||||
SummonItem(item_id, max_currency);
|
||||
SummonItem(item_id, max_currency, 0);
|
||||
SetAlternateCurrencyValue(reclaim->currency_id, 0);
|
||||
}
|
||||
else {
|
||||
SummonItem(item_id, reclaim->count, 0, 0, 0, 0, 0, 0, false, MainCursor);
|
||||
AddAlternateCurrencyValue(reclaim->currency_id, -((int32)reclaim->count));
|
||||
}
|
||||
/* QS: PlayerLogAlternateCurrencyTransactions :: Cursor to Item Storage */
|
||||
if (RuleB(QueryServ, PlayerLogAlternateCurrencyTransactions)){
|
||||
std::string event_desc = StringFormat("Reclaim :: Cursor to Item :: alt_currency_id:%i amount:-%i in zoneid:%i instid:%i", reclaim->currency_id, reclaim->count, this->GetZoneID(), this->GetInstanceID());
|
||||
QServ->PlayerLogEvent(Player_Log_Alternate_Currency_Transactions, this->CharacterID(), event_desc);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2686,7 +2667,7 @@ void Client::Handle_OP_AltCurrencySell(const EQApplicationPacket *app)
|
||||
return;
|
||||
}
|
||||
|
||||
const Item_Struct* item = nullptr;
|
||||
const ItemData* item = nullptr;
|
||||
uint32 cost = 0;
|
||||
uint32 current_currency = GetAlternateCurrencyValue(alt_cur_id);
|
||||
uint32 merchant_id = tar->MerchantType;
|
||||
@@ -2743,12 +2724,6 @@ void Client::Handle_OP_AltCurrencySell(const EQApplicationPacket *app)
|
||||
|
||||
sell->cost = cost;
|
||||
|
||||
/* QS: PlayerLogAlternateCurrencyTransactions :: Sold to Merchant*/
|
||||
if (RuleB(QueryServ, PlayerLogAlternateCurrencyTransactions)){
|
||||
std::string event_desc = StringFormat("Sold to Merchant :: itemid:%u npcid:%u alt_currency_id:%u cost:%u in zoneid:%u instid:%i", item->ID, npc_id, alt_cur_id, cost, this->GetZoneID(), this->GetInstanceID());
|
||||
QServ->PlayerLogEvent(Player_Log_Alternate_Currency_Transactions, this->CharacterID(), event_desc);
|
||||
}
|
||||
|
||||
FastQueuePacket(&outapp);
|
||||
AddAlternateCurrencyValue(alt_cur_id, cost);
|
||||
Save(1);
|
||||
@@ -2779,7 +2754,7 @@ void Client::Handle_OP_AltCurrencySellSelection(const EQApplicationPacket *app)
|
||||
return;
|
||||
}
|
||||
|
||||
const Item_Struct* item = nullptr;
|
||||
const ItemData* item = nullptr;
|
||||
uint32 cost = 0;
|
||||
uint32 current_currency = GetAlternateCurrencyValue(alt_cur_id);
|
||||
uint32 merchant_id = tar->MerchantType;
|
||||
@@ -2953,7 +2928,7 @@ void Client::Handle_OP_AugmentInfo(const EQApplicationPacket *app)
|
||||
}
|
||||
|
||||
AugmentInfo_Struct* AugInfo = (AugmentInfo_Struct*)app->pBuffer;
|
||||
const Item_Struct * item = database.GetItem(AugInfo->itemid);
|
||||
const ItemData * item = database.GetItem(AugInfo->itemid);
|
||||
|
||||
if (item) {
|
||||
strn0cpy(AugInfo->augment_info, item->Name, 64);
|
||||
@@ -2984,7 +2959,7 @@ void Client::Handle_OP_AugmentItem(const EQApplicationPacket *app)
|
||||
{
|
||||
ItemInst *tobe_auged = nullptr, *auged_with = nullptr;
|
||||
int8 slot = -1;
|
||||
Inventory& user_inv = GetInv();
|
||||
InventoryOld& user_inv = GetInv();
|
||||
|
||||
uint16 slot_id = in_augment->container_slot;
|
||||
uint16 aug_slot_id = in_augment->augment_slot;
|
||||
@@ -3054,7 +3029,7 @@ void Client::Handle_OP_AugmentItem(const EQApplicationPacket *app)
|
||||
{
|
||||
ItemInst *tobe_auged = nullptr, *auged_with = nullptr;
|
||||
int8 slot = -1;
|
||||
Inventory& user_inv = GetInv();
|
||||
InventoryOld& user_inv = GetInv();
|
||||
|
||||
uint16 slot_id = in_augment->container_slot;
|
||||
uint16 aug_slot_id = in_augment->augment_slot; //it's actually solvent slot
|
||||
@@ -3393,13 +3368,13 @@ void Client::Handle_OP_Barter(const EQApplicationPacket *app)
|
||||
{
|
||||
BarterItemSearchLinkRequest_Struct* bislr = (BarterItemSearchLinkRequest_Struct*)app->pBuffer;
|
||||
|
||||
const Item_Struct* item = database.GetItem(bislr->ItemID);
|
||||
const ItemData* item = database.GetItem(bislr->ItemID);
|
||||
|
||||
if (!item)
|
||||
Message(13, "Error: This item does not exist!");
|
||||
else
|
||||
{
|
||||
ItemInst* inst = database.CreateItem(item);
|
||||
ItemInst* inst = database.CreateItemOld(item);
|
||||
if (inst)
|
||||
{
|
||||
SendItemPacket(0, inst, ItemPacketViewLink);
|
||||
@@ -3426,13 +3401,13 @@ void Client::Handle_OP_Barter(const EQApplicationPacket *app)
|
||||
{
|
||||
BuyerItemSearchLinkRequest_Struct* bislr = (BuyerItemSearchLinkRequest_Struct*)app->pBuffer;
|
||||
|
||||
const Item_Struct* item = database.GetItem(bislr->ItemID);
|
||||
const ItemData* item = database.GetItem(bislr->ItemID);
|
||||
|
||||
if (!item)
|
||||
Message(13, "Error: This item does not exist!");
|
||||
else
|
||||
{
|
||||
ItemInst* inst = database.CreateItem(item);
|
||||
ItemInst* inst = database.CreateItemOld(item);
|
||||
if (inst)
|
||||
{
|
||||
SendItemPacket(0, inst, ItemPacketViewLink);
|
||||
@@ -3465,14 +3440,14 @@ void Client::Handle_OP_BazaarInspect(const EQApplicationPacket *app)
|
||||
|
||||
BazaarInspect_Struct* bis = (BazaarInspect_Struct*)app->pBuffer;
|
||||
|
||||
const Item_Struct* item = database.GetItem(bis->ItemID);
|
||||
const ItemData* item = database.GetItem(bis->ItemID);
|
||||
|
||||
if (!item) {
|
||||
Message(13, "Error: This item does not exist!");
|
||||
return;
|
||||
}
|
||||
|
||||
ItemInst* inst = database.CreateItem(item);
|
||||
ItemInst* inst = database.CreateItemOld(item);
|
||||
|
||||
if (inst) {
|
||||
SendItemPacket(0, inst, ItemPacketViewLink);
|
||||
@@ -3920,7 +3895,7 @@ void Client::Handle_OP_CastSpell(const EQApplicationPacket *app)
|
||||
//bool cancast = true;
|
||||
if (inst && inst->IsType(ItemClassCommon))
|
||||
{
|
||||
const Item_Struct* item = inst->GetItem();
|
||||
const ItemData* item = inst->GetItem();
|
||||
if (item->Click.Effect != (uint32)castspell->spell_id)
|
||||
{
|
||||
database.SetMQDetectionFlag(account_name, name, "OP_CastSpell with item, tried to cast a different spell.", zone->GetShortName());
|
||||
@@ -4772,7 +4747,7 @@ void Client::Handle_OP_Consume(const EQApplicationPacket *app)
|
||||
return;
|
||||
}
|
||||
|
||||
const Item_Struct* eat_item = myitem->GetItem();
|
||||
const ItemData* eat_item = myitem->GetItem();
|
||||
if (pcs->type == 0x01) {
|
||||
Consume(eat_item, ItemTypeFood, pcs->slot, (pcs->auto_consumed == 0xffffffff));
|
||||
}
|
||||
@@ -4913,14 +4888,14 @@ void Client::Handle_OP_CrystalCreate(const EQApplicationPacket *app)
|
||||
|
||||
if (cr->type == 5) {
|
||||
if (cr->amount > GetEbonCrystals()) {
|
||||
SummonItem(RuleI(Zone, EbonCrystalItemID), GetEbonCrystals());
|
||||
SummonItem(RuleI(Zone, EbonCrystalItemID), GetEbonCrystals(), 0);
|
||||
m_pp.currentEbonCrystals = 0;
|
||||
m_pp.careerEbonCrystals = 0;
|
||||
SaveCurrency();
|
||||
SendCrystalCounts();
|
||||
}
|
||||
else {
|
||||
SummonItem(RuleI(Zone, EbonCrystalItemID), cr->amount);
|
||||
SummonItem(RuleI(Zone, EbonCrystalItemID), cr->amount, 0);
|
||||
m_pp.currentEbonCrystals -= cr->amount;
|
||||
m_pp.careerEbonCrystals -= cr->amount;
|
||||
SaveCurrency();
|
||||
@@ -4929,14 +4904,14 @@ void Client::Handle_OP_CrystalCreate(const EQApplicationPacket *app)
|
||||
}
|
||||
else if (cr->type == 4) {
|
||||
if (cr->amount > GetRadiantCrystals()) {
|
||||
SummonItem(RuleI(Zone, RadiantCrystalItemID), GetRadiantCrystals());
|
||||
SummonItem(RuleI(Zone, RadiantCrystalItemID), GetRadiantCrystals(), 0);
|
||||
m_pp.currentRadCrystals = 0;
|
||||
m_pp.careerRadCrystals = 0;
|
||||
SaveCurrency();
|
||||
SendCrystalCounts();
|
||||
}
|
||||
else {
|
||||
SummonItem(RuleI(Zone, RadiantCrystalItemID), cr->amount);
|
||||
SummonItem(RuleI(Zone, RadiantCrystalItemID), cr->amount, 0);
|
||||
m_pp.currentRadCrystals -= cr->amount;
|
||||
m_pp.careerRadCrystals -= cr->amount;
|
||||
SaveCurrency();
|
||||
@@ -6863,7 +6838,7 @@ void Client::Handle_OP_GuildBank(const EQApplicationPacket *app)
|
||||
return;
|
||||
}
|
||||
|
||||
const Item_Struct* CursorItem = CursorItemInst->GetItem();
|
||||
const ItemData* CursorItem = CursorItemInst->GetItem();
|
||||
|
||||
if (!CursorItem->NoDrop || CursorItemInst->IsAttuned())
|
||||
{
|
||||
@@ -7932,7 +7907,7 @@ void Client::Handle_OP_InspectAnswer(const EQApplicationPacket *app)
|
||||
EQApplicationPacket* outapp = app->Copy();
|
||||
InspectResponse_Struct* insr = (InspectResponse_Struct*)outapp->pBuffer;
|
||||
Mob* tmp = entity_list.GetMob(insr->TargetID);
|
||||
const Item_Struct* item = nullptr;
|
||||
const ItemData* item = nullptr;
|
||||
|
||||
int ornamentationAugtype = RuleI(Character, OrnamentationAugmentType);
|
||||
for (int16 L = EmuConstants::EQUIPMENT_BEGIN; L <= MainWaist; L++) {
|
||||
@@ -7942,7 +7917,7 @@ void Client::Handle_OP_InspectAnswer(const EQApplicationPacket *app)
|
||||
if (item) {
|
||||
strcpy(insr->itemnames[L], item->Name);
|
||||
if (inst && inst->GetOrnamentationAug(ornamentationAugtype)) {
|
||||
const Item_Struct *aug_item = inst->GetOrnamentationAug(ornamentationAugtype)->GetItem();
|
||||
const ItemData *aug_item = inst->GetOrnamentationAug(ornamentationAugtype)->GetItem();
|
||||
insr->itemicons[L] = aug_item->Icon;
|
||||
}
|
||||
else if (inst->GetOrnamentationIcon()) {
|
||||
@@ -8040,7 +8015,7 @@ void Client::Handle_OP_ItemLinkClick(const EQApplicationPacket *app)
|
||||
|
||||
//todo: verify ivrs->link_hash based on a rule, in case we don't care about people being able to sniff data from the item DB
|
||||
|
||||
const Item_Struct* item = database.GetItem(ivrs->item_id);
|
||||
const ItemData* item = database.GetItem(ivrs->item_id);
|
||||
if (!item) {
|
||||
if (ivrs->item_id > 500000)
|
||||
{
|
||||
@@ -8119,7 +8094,7 @@ void Client::Handle_OP_ItemLinkClick(const EQApplicationPacket *app)
|
||||
|
||||
}
|
||||
|
||||
ItemInst* inst = database.CreateItem(item, item->MaxCharges, ivrs->augments[0], ivrs->augments[1], ivrs->augments[2], ivrs->augments[3], ivrs->augments[4], ivrs->augments[5]);
|
||||
ItemInst* inst = database.CreateItemOld(item, item->MaxCharges, ivrs->augments[0], ivrs->augments[1], ivrs->augments[2], ivrs->augments[3], ivrs->augments[4], ivrs->augments[5]);
|
||||
if (inst) {
|
||||
SendItemPacket(0, inst, ItemPacketViewLink);
|
||||
safe_delete(inst);
|
||||
@@ -8134,7 +8109,7 @@ void Client::Handle_OP_ItemLinkResponse(const EQApplicationPacket *app)
|
||||
return;
|
||||
}
|
||||
LDONItemViewRequest_Struct* item = (LDONItemViewRequest_Struct*)app->pBuffer;
|
||||
ItemInst* inst = database.CreateItem(item->item_id);
|
||||
ItemInst* inst = database.CreateItemOld(item->item_id);
|
||||
if (inst) {
|
||||
SendItemPacket(0, inst, ItemPacketViewLink);
|
||||
safe_delete(inst);
|
||||
@@ -8150,7 +8125,7 @@ void Client::Handle_OP_ItemName(const EQApplicationPacket *app)
|
||||
return;
|
||||
}
|
||||
ItemNamePacket_Struct *p = (ItemNamePacket_Struct*)app->pBuffer;
|
||||
const Item_Struct *item = 0;
|
||||
const ItemData *item = 0;
|
||||
if ((item = database.GetItem(p->item_id)) != nullptr) {
|
||||
EQApplicationPacket* outapp = new EQApplicationPacket(OP_ItemName, sizeof(ItemNamePacket_Struct));
|
||||
p = (ItemNamePacket_Struct*)outapp->pBuffer;
|
||||
@@ -8166,7 +8141,7 @@ void Client::Handle_OP_ItemPreview(const EQApplicationPacket *app)
|
||||
VERIFY_PACKET_LENGTH(OP_ItemPreview, app, ItemPreview_Struct);
|
||||
ItemPreview_Struct *ips = (ItemPreview_Struct *)app->pBuffer;
|
||||
|
||||
const Item_Struct* item = database.GetItem(ips->itemid);
|
||||
const ItemData* item = database.GetItem(ips->itemid);
|
||||
|
||||
if (item) {
|
||||
EQApplicationPacket* outapp = new EQApplicationPacket(OP_ItemPreview, strlen(item->Name) + strlen(item->Lore) + strlen(item->IDFile) + 898);
|
||||
@@ -8382,7 +8357,7 @@ void Client::Handle_OP_ItemVerifyRequest(const EQApplicationPacket *app)
|
||||
return;
|
||||
}
|
||||
|
||||
const Item_Struct* item = inst->GetItem();
|
||||
const ItemData* item = inst->GetItem();
|
||||
if (!item) {
|
||||
Message(0, "Error: item not found in inventory slot #%i", slot_id);
|
||||
DeleteItemInInventory(slot_id, 0, true);
|
||||
@@ -8430,13 +8405,13 @@ void Client::Handle_OP_ItemVerifyRequest(const EQApplicationPacket *app)
|
||||
int r;
|
||||
bool tryaug = false;
|
||||
ItemInst* clickaug = 0;
|
||||
Item_Struct* augitem = 0;
|
||||
ItemData* augitem = 0;
|
||||
|
||||
for (r = 0; r < EmuConstants::ITEM_COMMON_SIZE; r++) {
|
||||
const ItemInst* aug_i = inst->GetAugment(r);
|
||||
if (!aug_i)
|
||||
continue;
|
||||
const Item_Struct* aug = aug_i->GetItem();
|
||||
const ItemData* aug = aug_i->GetItem();
|
||||
if (!aug)
|
||||
continue;
|
||||
|
||||
@@ -8444,7 +8419,7 @@ void Client::Handle_OP_ItemVerifyRequest(const EQApplicationPacket *app)
|
||||
{
|
||||
tryaug = true;
|
||||
clickaug = (ItemInst*)aug_i;
|
||||
augitem = (Item_Struct*)aug;
|
||||
augitem = (ItemData*)aug;
|
||||
spell_id = aug->Click.Effect;
|
||||
break;
|
||||
}
|
||||
@@ -9624,68 +9599,18 @@ void Client::Handle_OP_MoveItem(const EQApplicationPacket *app)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
if (app->size != sizeof(MoveItem_Struct)) {
|
||||
Log.Out(Logs::General, Logs::Error, "Wrong size: OP_MoveItem, size=%i, expected %i", app->size, sizeof(MoveItem_Struct));
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
MoveItem_Struct* mi = (MoveItem_Struct*)app->pBuffer;
|
||||
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;
|
||||
}
|
||||
EQEmu::InventorySlot src(mi->from_type, mi->from_slot, mi->from_bag_slot, mi->from_aug_slot);
|
||||
EQEmu::InventorySlot dest(mi->to_type, mi->to_slot, mi->to_bag_slot, mi->to_aug_slot);
|
||||
if(!SwapItem(src, dest, mi->number_in_stack)) {
|
||||
//Send Resync Here
|
||||
}
|
||||
|
||||
// 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)
|
||||
@@ -10503,7 +10428,7 @@ void Client::Handle_OP_PotionBelt(const EQApplicationPacket *app)
|
||||
}
|
||||
|
||||
if (mptbs->Action == 0) {
|
||||
const Item_Struct *BaseItem = database.GetItem(mptbs->ItemID);
|
||||
const ItemData *BaseItem = database.GetItem(mptbs->ItemID);
|
||||
if (BaseItem) {
|
||||
m_pp.potionbelt.Items[mptbs->SlotNumber].ID = BaseItem->ID;
|
||||
m_pp.potionbelt.Items[mptbs->SlotNumber].Icon = BaseItem->Icon;
|
||||
@@ -11980,7 +11905,7 @@ void Client::Handle_OP_Shielding(const EQApplicationPacket *app)
|
||||
return;
|
||||
if (inst)
|
||||
{
|
||||
const Item_Struct* shield = inst->GetItem();
|
||||
const ItemData* shield = inst->GetItem();
|
||||
if (shield && shield->ItemType == ItemTypeShield)
|
||||
{
|
||||
for (int x = 0; x < 2; x++)
|
||||
@@ -12046,29 +11971,24 @@ void Client::Handle_OP_ShopPlayerBuy(const EQApplicationPacket *app)
|
||||
sizeof(Merchant_Sell_Struct), app->size);
|
||||
return;
|
||||
}
|
||||
RDTSC_Timer t1;
|
||||
t1.start();
|
||||
Merchant_Sell_Struct* mp = (Merchant_Sell_Struct*)app->pBuffer;
|
||||
#if EQDEBUG >= 5
|
||||
Log.Out(Logs::General, Logs::None, "%s, purchase item..", GetName());
|
||||
DumpPacket(app);
|
||||
#endif
|
||||
|
||||
|
||||
int merchantid;
|
||||
bool tmpmer_used = false;
|
||||
Mob* tmp = entity_list.GetMob(mp->npcid);
|
||||
|
||||
if (tmp == 0 || !tmp->IsNPC() || tmp->GetClass() != MERCHANT)
|
||||
|
||||
if (!tmp || !tmp->IsNPC() || tmp->GetClass() != MERCHANT)
|
||||
return;
|
||||
|
||||
if (mp->quantity < 1) return;
|
||||
|
||||
|
||||
if (mp->quantity < 1)
|
||||
return;
|
||||
|
||||
//you have to be somewhat close to them to be properly using them
|
||||
if (DistanceSquared(m_Position, tmp->GetPosition()) > USE_NPC_RANGE2)
|
||||
return;
|
||||
|
||||
|
||||
merchantid = tmp->CastToNPC()->MerchantType;
|
||||
|
||||
|
||||
uint32 item_id = 0;
|
||||
std::list<MerchantList> merlist = zone->merchanttable[merchantid];
|
||||
std::list<MerchantList>::const_iterator itr;
|
||||
@@ -12077,18 +11997,18 @@ void Client::Handle_OP_ShopPlayerBuy(const EQApplicationPacket *app)
|
||||
if (GetLevel() < ml.level_required) {
|
||||
continue;
|
||||
}
|
||||
|
||||
|
||||
int32 fac = tmp->GetPrimaryFaction();
|
||||
if (fac != 0 && GetModCharacterFactionLevel(fac) < ml.faction_required) {
|
||||
continue;
|
||||
}
|
||||
|
||||
|
||||
if (mp->itemslot == ml.slot){
|
||||
item_id = ml.item;
|
||||
break;
|
||||
}
|
||||
}
|
||||
const Item_Struct* item = nullptr;
|
||||
|
||||
uint32 prevcharges = 0;
|
||||
if (item_id == 0) { //check to see if its on the temporary table
|
||||
std::list<TempMerchantList> tmp_merlist = zone->tmpmerchanttable[tmp->GetNPCTypeID()];
|
||||
@@ -12104,7 +12024,8 @@ void Client::Handle_OP_ShopPlayerBuy(const EQApplicationPacket *app)
|
||||
}
|
||||
}
|
||||
}
|
||||
item = database.GetItem(item_id);
|
||||
|
||||
const ItemData* item = database.GetItem(item_id);
|
||||
if (!item){
|
||||
//error finding item, client didnt get the update packet for whatever reason, roleplay a tad
|
||||
Message(15, "%s tells you 'Sorry, that item is for display purposes only.' as they take the item off the shelf.", tmp->GetCleanName());
|
||||
@@ -12118,11 +12039,13 @@ void Client::Handle_OP_ShopPlayerBuy(const EQApplicationPacket *app)
|
||||
safe_delete(delitempacket);
|
||||
return;
|
||||
}
|
||||
if (CheckLoreConflict(item))
|
||||
|
||||
if (m_inventory.CheckLoreConflict(item))
|
||||
{
|
||||
Message(15, "You can only have one of a lore item.");
|
||||
return;
|
||||
}
|
||||
|
||||
if (tmpmer_used && (mp->quantity > prevcharges || item->MaxCharges > 1))
|
||||
{
|
||||
if (prevcharges > item->MaxCharges && item->MaxCharges > 1)
|
||||
@@ -12130,95 +12053,75 @@ void Client::Handle_OP_ShopPlayerBuy(const EQApplicationPacket *app)
|
||||
else
|
||||
mp->quantity = prevcharges;
|
||||
}
|
||||
|
||||
|
||||
// Item's stackable, but the quantity they want to buy exceeds the max stackable quantity.
|
||||
if (item->Stackable && mp->quantity > item->StackSize)
|
||||
mp->quantity = item->StackSize;
|
||||
|
||||
|
||||
EQApplicationPacket* outapp = new EQApplicationPacket(OP_ShopPlayerBuy, sizeof(Merchant_Sell_Struct));
|
||||
Merchant_Sell_Struct* mpo = (Merchant_Sell_Struct*)outapp->pBuffer;
|
||||
mpo->quantity = mp->quantity;
|
||||
mpo->playerid = mp->playerid;
|
||||
mpo->npcid = mp->npcid;
|
||||
mpo->itemslot = mp->itemslot;
|
||||
|
||||
int16 freeslotid = INVALID_INDEX;
|
||||
int16 charges = 0;
|
||||
|
||||
EQEmu::InventorySlot free_slot;
|
||||
int charges = 0;
|
||||
if (item->Stackable || item->MaxCharges > 1)
|
||||
charges = mp->quantity;
|
||||
else
|
||||
charges = item->MaxCharges;
|
||||
|
||||
ItemInst* inst = database.CreateItem(item, charges);
|
||||
|
||||
|
||||
int SinglePrice = 0;
|
||||
if (RuleB(Merchant, UsePriceMod))
|
||||
SinglePrice = (item->Price * (RuleR(Merchant, SellCostMod)) * item->SellRate * Client::CalcPriceMod(tmp, false));
|
||||
else
|
||||
SinglePrice = (item->Price * (RuleR(Merchant, SellCostMod)) * item->SellRate);
|
||||
|
||||
|
||||
if (item->MaxCharges > 1)
|
||||
mpo->price = SinglePrice;
|
||||
else
|
||||
mpo->price = SinglePrice * mp->quantity;
|
||||
|
||||
|
||||
if (mpo->price < 0)
|
||||
{
|
||||
safe_delete(outapp);
|
||||
safe_delete(inst);
|
||||
return;
|
||||
}
|
||||
|
||||
if(m_inventory.Get(EQEmu::InventorySlot(EQEmu::InvTypePersonal, EQEmu::PersonalSlotCursor))) {
|
||||
safe_delete(outapp);
|
||||
return;
|
||||
}
|
||||
|
||||
auto inst = database.CreateItem(item->ID, charges);
|
||||
|
||||
if(!CanPutItemInInventory(inst, EQEmu::InvTypePersonal, EQEmu::PersonalSlotGeneral1, EQEmu::PersonalSlotGeneral10)) {
|
||||
Message(13, "You do not have room for any more items.");
|
||||
|
||||
QueuePacket(outapp);
|
||||
safe_delete(outapp);
|
||||
return;
|
||||
}
|
||||
|
||||
// this area needs some work..two inventory insertion check failure points
|
||||
// below do not return player's money..is this the intended behavior?
|
||||
|
||||
if (!TakeMoneyFromPP(mpo->price))
|
||||
{
|
||||
char *hacker_str = nullptr;
|
||||
MakeAnyLenString(&hacker_str, "Vendor Cheat: attempted to buy %i of %i: %s that cost %d cp but only has %d pp %d gp %d sp %d cp\n",
|
||||
std::string hacker_str = StringFormat("Vendor Cheat: attempted to buy %i of %i: %s that cost %d cp but only has %d pp %d gp %d sp %d cp\n",
|
||||
mpo->quantity, item->ID, item->Name,
|
||||
mpo->price, m_pp.platinum, m_pp.gold, m_pp.silver, m_pp.copper);
|
||||
database.SetMQDetectionFlag(AccountName(), GetName(), hacker_str, zone->GetShortName());
|
||||
safe_delete_array(hacker_str);
|
||||
database.SetMQDetectionFlag(AccountName(), GetName(), hacker_str.c_str(), zone->GetShortName());
|
||||
safe_delete(outapp);
|
||||
safe_delete(inst);
|
||||
return;
|
||||
}
|
||||
|
||||
bool stacked = TryStacking(inst);
|
||||
if (!stacked)
|
||||
freeslotid = m_inv.FindFreeSlot(false, true, item->Size);
|
||||
|
||||
// shouldn't we be reimbursing if these two fail?
|
||||
|
||||
//make sure we are not completely full...
|
||||
if (freeslotid == MainCursor) {
|
||||
if (m_inv.GetItem(MainCursor) != nullptr) {
|
||||
Message(13, "You do not have room for any more items.");
|
||||
safe_delete(outapp);
|
||||
safe_delete(inst);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (!stacked && freeslotid == INVALID_INDEX)
|
||||
{
|
||||
Message(13, "You do not have room for any more items.");
|
||||
safe_delete(outapp);
|
||||
safe_delete(inst);
|
||||
return;
|
||||
}
|
||||
|
||||
std::string packet;
|
||||
if (!stacked && inst) {
|
||||
PutItemInInventory(freeslotid, *inst);
|
||||
SendItemPacket(freeslotid, inst, ItemPacketTrade);
|
||||
}
|
||||
else if (!stacked){
|
||||
Log.Out(Logs::General, Logs::Error, "OP_ShopPlayerBuy: item->ItemClass Unknown! Type: %i", item->ItemClass);
|
||||
}
|
||||
QueuePacket(outapp);
|
||||
if (inst && tmpmer_used){
|
||||
safe_delete(outapp);
|
||||
|
||||
PutItemInInventory(inst, EQEmu::InvTypePersonal, EQEmu::PersonalSlotGeneral1, EQEmu::PersonalSlotGeneral10, true);
|
||||
|
||||
if (inst && tmpmer_used) {
|
||||
int32 new_charges = prevcharges - mp->quantity;
|
||||
zone->SaveTempItem(merchantid, tmp->GetNPCTypeID(), item_id, new_charges);
|
||||
if (new_charges <= 0){
|
||||
@@ -12237,70 +12140,17 @@ void Client::Handle_OP_ShopPlayerBuy(const EQApplicationPacket *app)
|
||||
inst->SetPrice(SinglePrice);
|
||||
inst->SetMerchantSlot(mp->itemslot);
|
||||
inst->SetMerchantCount(new_charges);
|
||||
|
||||
SendItemPacket(mp->itemslot, inst, ItemPacketMerchant);
|
||||
|
||||
SendItemPacket(EQEmu::InventorySlot(EQEmu::InvTypeMerchant, mp->itemslot), inst, ItemPacketMerchant);
|
||||
}
|
||||
}
|
||||
safe_delete(inst);
|
||||
safe_delete(outapp);
|
||||
|
||||
// start QS code
|
||||
// stacking purchases not supported at this time - entire process will need some work to catch them properly
|
||||
if (RuleB(QueryServ, PlayerLogMerchantTransactions)) {
|
||||
ServerPacket* qspack = new ServerPacket(ServerOP_QSPlayerLogMerchantTransactions, sizeof(QSMerchantLogTransaction_Struct)+sizeof(QSTransactionItems_Struct));
|
||||
QSMerchantLogTransaction_Struct* qsaudit = (QSMerchantLogTransaction_Struct*)qspack->pBuffer;
|
||||
|
||||
qsaudit->zone_id = zone->GetZoneID();
|
||||
qsaudit->merchant_id = tmp->CastToNPC()->MerchantType;
|
||||
qsaudit->merchant_money.platinum = 0;
|
||||
qsaudit->merchant_money.gold = 0;
|
||||
qsaudit->merchant_money.silver = 0;
|
||||
qsaudit->merchant_money.copper = 0;
|
||||
qsaudit->merchant_count = 1;
|
||||
qsaudit->char_id = character_id;
|
||||
qsaudit->char_money.platinum = (mpo->price / 1000);
|
||||
qsaudit->char_money.gold = (mpo->price / 100) % 10;
|
||||
qsaudit->char_money.silver = (mpo->price / 10) % 10;
|
||||
qsaudit->char_money.copper = mpo->price % 10;
|
||||
qsaudit->char_count = 0;
|
||||
|
||||
qsaudit->items[0].char_slot = freeslotid == INVALID_INDEX ? 0 : freeslotid;
|
||||
qsaudit->items[0].item_id = item->ID;
|
||||
qsaudit->items[0].charges = mpo->quantity;
|
||||
|
||||
if (freeslotid == INVALID_INDEX) {
|
||||
qsaudit->items[0].aug_1 = 0;
|
||||
qsaudit->items[0].aug_2 = 0;
|
||||
qsaudit->items[0].aug_3 = 0;
|
||||
qsaudit->items[0].aug_4 = 0;
|
||||
qsaudit->items[0].aug_5 = 0;
|
||||
}
|
||||
else {
|
||||
qsaudit->items[0].aug_1 = m_inv[freeslotid]->GetAugmentItemID(0);
|
||||
qsaudit->items[0].aug_2 = m_inv[freeslotid]->GetAugmentItemID(1);
|
||||
qsaudit->items[0].aug_3 = m_inv[freeslotid]->GetAugmentItemID(2);
|
||||
qsaudit->items[0].aug_4 = m_inv[freeslotid]->GetAugmentItemID(3);
|
||||
qsaudit->items[0].aug_5 = m_inv[freeslotid]->GetAugmentItemID(4);
|
||||
}
|
||||
|
||||
qspack->Deflate();
|
||||
if (worldserver.Connected()) { worldserver.SendPacket(qspack); }
|
||||
safe_delete(qspack);
|
||||
}
|
||||
// end QS code
|
||||
|
||||
if (RuleB(EventLog, RecordBuyFromMerchant))
|
||||
LogMerchant(this, tmp, mpo->quantity, mpo->price, item, true);
|
||||
|
||||
|
||||
zone->LogEvent(EventLogItemBuy, this, StringFormat("Merc(%i) -> player %s(%i) %i charges for %ic", merchantid, item->Name, item->ID, mpo->quantity, mpo->price));
|
||||
if ((RuleB(Character, EnableDiscoveredItems)))
|
||||
{
|
||||
if (!GetGM() && !IsDiscovered(item_id))
|
||||
DiscoverItem(item_id);
|
||||
}
|
||||
|
||||
t1.stop();
|
||||
std::cout << "At 1: " << t1.getDuration() << std::endl;
|
||||
return;
|
||||
}
|
||||
void Client::Handle_OP_ShopPlayerSell(const EQApplicationPacket *app)
|
||||
{
|
||||
@@ -12309,7 +12159,6 @@ void Client::Handle_OP_ShopPlayerSell(const EQApplicationPacket *app)
|
||||
sizeof(Merchant_Purchase_Struct), app->size);
|
||||
return;
|
||||
}
|
||||
RDTSC_Timer t1(true);
|
||||
Merchant_Purchase_Struct* mp = (Merchant_Purchase_Struct*)app->pBuffer;
|
||||
|
||||
Mob* vendor = entity_list.GetMob(mp->npcid);
|
||||
@@ -12325,7 +12174,7 @@ void Client::Handle_OP_ShopPlayerSell(const EQApplicationPacket *app)
|
||||
uint32 itemid = GetItemIDAt(mp->itemslot);
|
||||
if (itemid == 0)
|
||||
return;
|
||||
const Item_Struct* item = database.GetItem(itemid);
|
||||
const ItemData* item = database.GetItem(itemid);
|
||||
ItemInst* inst = GetInv().GetItem(mp->itemslot);
|
||||
if (!item || !inst){
|
||||
Message(13, "You seemed to have misplaced that item..");
|
||||
@@ -12338,7 +12187,6 @@ void Client::Handle_OP_ShopPlayerSell(const EQApplicationPacket *app)
|
||||
}
|
||||
|
||||
if (!item->NoDrop) {
|
||||
//Message(13,"%s tells you, 'LOL NOPE'", vendor->GetName());
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -12399,38 +12247,38 @@ void Client::Handle_OP_ShopPlayerSell(const EQApplicationPacket *app)
|
||||
}
|
||||
|
||||
// start QS code
|
||||
if (RuleB(QueryServ, PlayerLogMerchantTransactions)) {
|
||||
ServerPacket* qspack = new ServerPacket(ServerOP_QSPlayerLogMerchantTransactions, sizeof(QSMerchantLogTransaction_Struct)+sizeof(QSTransactionItems_Struct));
|
||||
QSMerchantLogTransaction_Struct* qsaudit = (QSMerchantLogTransaction_Struct*)qspack->pBuffer;
|
||||
|
||||
qsaudit->zone_id = zone->GetZoneID();
|
||||
qsaudit->merchant_id = vendor->CastToNPC()->MerchantType;
|
||||
qsaudit->merchant_money.platinum = (price / 1000);
|
||||
qsaudit->merchant_money.gold = (price / 100) % 10;
|
||||
qsaudit->merchant_money.silver = (price / 10) % 10;
|
||||
qsaudit->merchant_money.copper = price % 10;
|
||||
qsaudit->merchant_count = 0;
|
||||
qsaudit->char_id = character_id;
|
||||
qsaudit->char_money.platinum = 0;
|
||||
qsaudit->char_money.gold = 0;
|
||||
qsaudit->char_money.silver = 0;
|
||||
qsaudit->char_money.copper = 0;
|
||||
qsaudit->char_count = 1;
|
||||
|
||||
qsaudit->items[0].char_slot = mp->itemslot;
|
||||
qsaudit->items[0].item_id = itemid;
|
||||
qsaudit->items[0].charges = charges;
|
||||
qsaudit->items[0].aug_1 = m_inv[mp->itemslot]->GetAugmentItemID(1);
|
||||
qsaudit->items[0].aug_2 = m_inv[mp->itemslot]->GetAugmentItemID(2);
|
||||
qsaudit->items[0].aug_3 = m_inv[mp->itemslot]->GetAugmentItemID(3);
|
||||
qsaudit->items[0].aug_4 = m_inv[mp->itemslot]->GetAugmentItemID(4);
|
||||
qsaudit->items[0].aug_5 = m_inv[mp->itemslot]->GetAugmentItemID(5);
|
||||
|
||||
qspack->Deflate();
|
||||
if (worldserver.Connected()) { worldserver.SendPacket(qspack); }
|
||||
safe_delete(qspack);
|
||||
}
|
||||
// end QS code
|
||||
//if (RuleB(QueryServ, PlayerLogMerchantTransactions)) {
|
||||
// ServerPacket* qspack = new ServerPacket(ServerOP_QSPlayerLogMerchantTransactions, sizeof(QSMerchantLogTransaction_Struct)+sizeof(QSTransactionItems_Struct));
|
||||
// QSMerchantLogTransaction_Struct* qsaudit = (QSMerchantLogTransaction_Struct*)qspack->pBuffer;
|
||||
//
|
||||
// qsaudit->zone_id = zone->GetZoneID();
|
||||
// qsaudit->merchant_id = vendor->CastToNPC()->MerchantType;
|
||||
// qsaudit->merchant_money.platinum = (price / 1000);
|
||||
// qsaudit->merchant_money.gold = (price / 100) % 10;
|
||||
// qsaudit->merchant_money.silver = (price / 10) % 10;
|
||||
// qsaudit->merchant_money.copper = price % 10;
|
||||
// qsaudit->merchant_count = 0;
|
||||
// qsaudit->char_id = character_id;
|
||||
// qsaudit->char_money.platinum = 0;
|
||||
// qsaudit->char_money.gold = 0;
|
||||
// qsaudit->char_money.silver = 0;
|
||||
// qsaudit->char_money.copper = 0;
|
||||
// qsaudit->char_count = 1;
|
||||
//
|
||||
// qsaudit->items[0].char_slot = mp->itemslot;
|
||||
// qsaudit->items[0].item_id = itemid;
|
||||
// qsaudit->items[0].charges = charges;
|
||||
// qsaudit->items[0].aug_1 = m_inv[mp->itemslot]->GetAugmentItemID(1);
|
||||
// qsaudit->items[0].aug_2 = m_inv[mp->itemslot]->GetAugmentItemID(2);
|
||||
// qsaudit->items[0].aug_3 = m_inv[mp->itemslot]->GetAugmentItemID(3);
|
||||
// qsaudit->items[0].aug_4 = m_inv[mp->itemslot]->GetAugmentItemID(4);
|
||||
// qsaudit->items[0].aug_5 = m_inv[mp->itemslot]->GetAugmentItemID(5);
|
||||
//
|
||||
// qspack->Deflate();
|
||||
// if (worldserver.Connected()) { worldserver.SendPacket(qspack); }
|
||||
// safe_delete(qspack);
|
||||
//}
|
||||
//// end QS code
|
||||
|
||||
// Now remove the item from the player, this happens regardless of outcome
|
||||
if (!inst->IsStackable())
|
||||
@@ -12451,10 +12299,7 @@ void Client::Handle_OP_ShopPlayerSell(const EQApplicationPacket *app)
|
||||
QueuePacket(outapp);
|
||||
safe_delete(outapp);
|
||||
SendMoneyUpdate();
|
||||
t1.start();
|
||||
Save(1);
|
||||
t1.stop();
|
||||
std::cout << "Save took: " << t1.getDuration() << std::endl;
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -13221,46 +13066,8 @@ void Client::Handle_OP_TradeAcceptClick(const EQApplicationPacket *app)
|
||||
other->trade->LogTrade();
|
||||
trade->LogTrade();
|
||||
|
||||
// start QS code
|
||||
if (RuleB(QueryServ, PlayerLogTrades)) {
|
||||
QSPlayerLogTrade_Struct event_entry;
|
||||
std::list<void*> event_details;
|
||||
|
||||
memset(&event_entry, 0, sizeof(QSPlayerLogTrade_Struct));
|
||||
|
||||
// Perform actual trade
|
||||
this->FinishTrade(other, true, &event_entry, &event_details);
|
||||
other->FinishTrade(this, false, &event_entry, &event_details);
|
||||
|
||||
event_entry._detail_count = event_details.size();
|
||||
|
||||
ServerPacket* qs_pack = new ServerPacket(ServerOP_QSPlayerLogTrades, sizeof(QSPlayerLogTrade_Struct)+(sizeof(QSTradeItems_Struct)* event_entry._detail_count));
|
||||
QSPlayerLogTrade_Struct* qs_buf = (QSPlayerLogTrade_Struct*)qs_pack->pBuffer;
|
||||
|
||||
memcpy(qs_buf, &event_entry, sizeof(QSPlayerLogTrade_Struct));
|
||||
|
||||
int offset = 0;
|
||||
|
||||
for (std::list<void*>::iterator iter = event_details.begin(); iter != event_details.end(); ++iter, ++offset) {
|
||||
QSTradeItems_Struct* detail = reinterpret_cast<QSTradeItems_Struct*>(*iter);
|
||||
qs_buf->items[offset] = *detail;
|
||||
safe_delete(detail);
|
||||
}
|
||||
|
||||
event_details.clear();
|
||||
|
||||
qs_pack->Deflate();
|
||||
|
||||
if (worldserver.Connected())
|
||||
worldserver.SendPacket(qs_pack);
|
||||
|
||||
safe_delete(qs_pack);
|
||||
// end QS code
|
||||
}
|
||||
else {
|
||||
this->FinishTrade(other);
|
||||
other->FinishTrade(this);
|
||||
}
|
||||
this->FinishTrade(other);
|
||||
other->FinishTrade(this);
|
||||
|
||||
other->trade->Reset();
|
||||
trade->Reset();
|
||||
@@ -13277,42 +13084,7 @@ void Client::Handle_OP_TradeAcceptClick(const EQApplicationPacket *app)
|
||||
QueuePacket(outapp);
|
||||
safe_delete(outapp);
|
||||
if (with->IsNPC()) {
|
||||
// Audit trade to database for player trade stream
|
||||
if (RuleB(QueryServ, PlayerLogHandins)) {
|
||||
QSPlayerLogHandin_Struct event_entry;
|
||||
std::list<void*> event_details;
|
||||
|
||||
memset(&event_entry, 0, sizeof(QSPlayerLogHandin_Struct));
|
||||
|
||||
FinishTrade(with->CastToNPC(), false, &event_entry, &event_details);
|
||||
|
||||
event_entry._detail_count = event_details.size();
|
||||
|
||||
ServerPacket* qs_pack = new ServerPacket(ServerOP_QSPlayerLogHandins, sizeof(QSPlayerLogHandin_Struct)+(sizeof(QSHandinItems_Struct)* event_entry._detail_count));
|
||||
QSPlayerLogHandin_Struct* qs_buf = (QSPlayerLogHandin_Struct*)qs_pack->pBuffer;
|
||||
|
||||
memcpy(qs_buf, &event_entry, sizeof(QSPlayerLogHandin_Struct));
|
||||
|
||||
int offset = 0;
|
||||
|
||||
for (std::list<void*>::iterator iter = event_details.begin(); iter != event_details.end(); ++iter, ++offset) {
|
||||
QSHandinItems_Struct* detail = reinterpret_cast<QSHandinItems_Struct*>(*iter);
|
||||
qs_buf->items[offset] = *detail;
|
||||
safe_delete(detail);
|
||||
}
|
||||
|
||||
event_details.clear();
|
||||
|
||||
qs_pack->Deflate();
|
||||
|
||||
if (worldserver.Connected())
|
||||
worldserver.SendPacket(qs_pack);
|
||||
|
||||
safe_delete(qs_pack);
|
||||
}
|
||||
else {
|
||||
FinishTrade(with->CastToNPC());
|
||||
}
|
||||
FinishTrade(with->CastToNPC());
|
||||
}
|
||||
#ifdef BOTS
|
||||
// TODO: Log Bot trades
|
||||
@@ -13422,7 +13194,7 @@ void Client::Handle_OP_Trader(const EQApplicationPacket *app)
|
||||
TradeItemsValid = false;
|
||||
break;
|
||||
}
|
||||
const Item_Struct *Item = database.GetItem(gis->Items[i]);
|
||||
const ItemData *Item = database.GetItem(gis->Items[i]);
|
||||
|
||||
if (!Item) {
|
||||
Message(13, "Unexpected error. Unable to start trader mode");
|
||||
|
||||
+13
-164
@@ -782,12 +782,6 @@ void Client::OnDisconnect(bool hard_disconnect) {
|
||||
MyRaid->MemberZoned(this);
|
||||
|
||||
parse->EventPlayer(EVENT_DISCONNECT, this, "", 0);
|
||||
|
||||
/* QS: PlayerLogConnectDisconnect */
|
||||
if (RuleB(QueryServ, PlayerLogConnectDisconnect)){
|
||||
std::string event_desc = StringFormat("Disconnect :: in zoneid:%i instid:%i", this->GetZoneID(), this->GetInstanceID());
|
||||
QServ->PlayerLogEvent(Player_Log_Connect_State, this->CharacterID(), event_desc);
|
||||
}
|
||||
}
|
||||
|
||||
Mob *Other = trade->With();
|
||||
@@ -815,168 +809,24 @@ void Client::OnDisconnect(bool hard_disconnect) {
|
||||
Disconnect();
|
||||
}
|
||||
|
||||
// Sends the client complete inventory used in character login
|
||||
|
||||
// DO WE STILL NEED THE 'ITEMCOMBINED' CONDITIONAL CODE?
|
||||
|
||||
//#ifdef ITEMCOMBINED
|
||||
void Client::BulkSendInventoryItems() {
|
||||
int16 slot_id = 0;
|
||||
|
||||
// LINKDEAD TRADE ITEMS
|
||||
// Move trade slot items back into normal inventory..need them there now for the proceeding validity checks
|
||||
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);
|
||||
}
|
||||
EQEmu::MemoryBuffer items;
|
||||
if(!m_inventory.Serialize(items)) {
|
||||
return;
|
||||
}
|
||||
|
||||
bool deletenorent = database.NoRentExpired(GetName());
|
||||
if (deletenorent) { //client was offline for more than 30 minutes, delete no rent items
|
||||
if (RuleB(Inventory, TransformSummonedBags))
|
||||
DisenchantSummonedBags(false);
|
||||
RemoveNoRent(false);
|
||||
}
|
||||
|
||||
RemoveDuplicateLore(false);
|
||||
MoveSlotNotAllowed(false);
|
||||
|
||||
// The previous three method calls took care of moving/removing expired/illegal item placements
|
||||
|
||||
//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);
|
||||
|
||||
EQApplicationPacket outapp(OP_CharInventory, items.Size());
|
||||
memcpy(outapp.pBuffer, items, items.Size());
|
||||
QueuePacket(&outapp);
|
||||
}
|
||||
/*#else
|
||||
void Client::BulkSendInventoryItems()
|
||||
{
|
||||
// Search all inventory buckets for items
|
||||
bool deletenorent=database.NoRentExpired(GetName());
|
||||
// Worn items and Inventory items
|
||||
int16 slot_id = 0;
|
||||
if(deletenorent){//client was offline for more than 30 minutes, delete no rent items
|
||||
RemoveNoRent();
|
||||
}
|
||||
for (slot_id=EmuConstants::POSSESSIONS_BEGIN; slot_id<=EmuConstants::POSSESSIONS_END; slot_id++) {
|
||||
const ItemInst* inst = m_inv[slot_id];
|
||||
if (inst){
|
||||
SendItemPacket(slot_id, inst, ItemPacketCharInventory);
|
||||
}
|
||||
}
|
||||
// Bank items
|
||||
for (slot_id=EmuConstants::BANK_BEGIN; slot_id<=EmuConstants::BANK_END; slot_id++) { // 2015...
|
||||
const ItemInst* inst = m_inv[slot_id];
|
||||
if (inst){
|
||||
SendItemPacket(slot_id, inst, ItemPacketCharInventory);
|
||||
}
|
||||
}
|
||||
|
||||
// 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){
|
||||
SendItemPacket(slot_id, inst, ItemPacketCharInventory);
|
||||
}
|
||||
}
|
||||
|
||||
// LINKDEAD TRADE ITEMS
|
||||
// If player went LD during a trade, they have items in the trade inventory
|
||||
// slots. These items are now being put into their inventory (then queue up on cursor)
|
||||
for (int16 trade_slot_id=EmuConstants::TRADE_BEGIN; trade_slot_id<=EmuConstants::TRADE_END; trade_slot_id++) {
|
||||
const ItemInst* inst = m_inv[slot_id];
|
||||
if (inst) {
|
||||
int16 free_slot_id = m_inv.FindFreeSlot(inst->IsType(ItemClassContainer), true, inst->GetItem()->Size);
|
||||
DeleteItemInInventory(trade_slot_id, 0, false);
|
||||
PutItemInInventory(free_slot_id, *inst, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif*/
|
||||
|
||||
void Client::BulkSendMerchantInventory(int merchant_id, int npcid) {
|
||||
const Item_Struct* handyitem = nullptr;
|
||||
const ItemData* handyitem = nullptr;
|
||||
uint32 numItemSlots = 80; //The max number of items passed in the transaction.
|
||||
if (m_ClientVersionBit & BIT_RoFAndLater) { // RoF+ can send 200 items
|
||||
numItemSlots = 200;
|
||||
}
|
||||
const Item_Struct *item;
|
||||
const ItemData *item;
|
||||
std::list<MerchantList> merlist = zone->merchanttable[merchant_id];
|
||||
std::list<MerchantList>::const_iterator itr;
|
||||
Mob* merch = entity_list.GetMobByNpcTypeID(npcid);
|
||||
@@ -1017,7 +867,7 @@ void Client::BulkSendMerchantInventory(int merchant_id, int npcid) {
|
||||
int charges = 1;
|
||||
if (item->ItemClass == ItemClassCommon)
|
||||
charges = item->MaxCharges;
|
||||
ItemInst* inst = database.CreateItem(item, charges);
|
||||
auto inst = database.CreateItem(item->ID, charges, false);
|
||||
if (inst) {
|
||||
if (RuleB(Merchant, UsePriceMod)) {
|
||||
inst->SetPrice((item->Price * (RuleR(Merchant, SellCostMod)) * item->SellRate * Client::CalcPriceMod(merch, false)));
|
||||
@@ -1031,8 +881,7 @@ void Client::BulkSendMerchantInventory(int merchant_id, int npcid) {
|
||||
else
|
||||
inst->SetCharges(1);
|
||||
|
||||
SendItemPacket(ml.slot - 1, inst, ItemPacketMerchant);
|
||||
safe_delete(inst);
|
||||
SendItemPacket(EQEmu::InventorySlot(EQEmu::InvTypePersonal, ml.slot - 1), inst, ItemPacketMerchant);
|
||||
}
|
||||
}
|
||||
// Account for merchant lists with gaps.
|
||||
@@ -1058,7 +907,7 @@ void Client::BulkSendMerchantInventory(int merchant_id, int npcid) {
|
||||
// charges=ml.charges;
|
||||
//else
|
||||
charges = item->MaxCharges;
|
||||
ItemInst* inst = database.CreateItem(item, charges);
|
||||
ItemInst* inst = database.CreateItemOld(item, charges);
|
||||
if (inst) {
|
||||
if (RuleB(Merchant, UsePriceMod)) {
|
||||
inst->SetPrice((item->Price * (RuleR(Merchant, SellCostMod)) * item->SellRate * Client::CalcPriceMod(merch, false)));
|
||||
@@ -1234,7 +1083,7 @@ void Client::OPMemorizeSpell(const EQApplicationPacket* app)
|
||||
|
||||
if(inst && inst->IsType(ItemClassCommon))
|
||||
{
|
||||
const Item_Struct* item = inst->GetItem();
|
||||
const ItemData* item = inst->GetItem();
|
||||
|
||||
if(item && item->Scroll.Effect == (int32)(memspell->spell_id))
|
||||
{
|
||||
|
||||
+117
-174
@@ -547,8 +547,6 @@ int command_realdispatch(Client *c, const char *message)
|
||||
{
|
||||
Seperator sep(message, ' ', 10, 100, true); // "three word argument" should be considered 1 arg
|
||||
|
||||
command_logcommand(c, message);
|
||||
|
||||
std::string cstr(sep.arg[0]+1);
|
||||
|
||||
if(commandlist.count(cstr) != 1) {
|
||||
@@ -561,12 +559,6 @@ int command_realdispatch(Client *c, const char *message)
|
||||
return(-1);
|
||||
}
|
||||
|
||||
/* QS: Player_Log_Issued_Commands */
|
||||
if (RuleB(QueryServ, PlayerLogIssuedCommandes)){
|
||||
std::string event_desc = StringFormat("Issued command :: '%s' in zoneid:%i instid:%i", message, c->GetZoneID(), c->GetInstanceID());
|
||||
QServ->PlayerLogEvent(Player_Log_Issued_Commands, c->CharacterID(), event_desc);
|
||||
}
|
||||
|
||||
if(cur->access >= COMMANDS_LOGGING_MIN_STATUS) {
|
||||
Log.Out(Logs::General, Logs::Commands, "%s (%s) used command: %s (target=%s)", c->GetName(), c->AccountName(), message, c->GetTarget()?c->GetTarget()->GetName():"NONE");
|
||||
}
|
||||
@@ -582,71 +574,6 @@ int command_realdispatch(Client *c, const char *message)
|
||||
|
||||
}
|
||||
|
||||
void command_logcommand(Client *c, const char *message)
|
||||
{
|
||||
int admin=c->Admin();
|
||||
|
||||
bool continueevents=false;
|
||||
switch (zone->loglevelvar){ //catch failsafe
|
||||
case 9: { // log only LeadGM
|
||||
if ((admin>= 150) && (admin <200))
|
||||
continueevents=true;
|
||||
break;
|
||||
}
|
||||
case 8: { // log only GM
|
||||
if ((admin>= 100) && (admin <150))
|
||||
continueevents=true;
|
||||
break;
|
||||
}
|
||||
case 1: {
|
||||
if ((admin>= 200))
|
||||
continueevents=true;
|
||||
break;
|
||||
}
|
||||
case 2: {
|
||||
if ((admin>= 150))
|
||||
continueevents=true;
|
||||
break;
|
||||
}
|
||||
case 3: {
|
||||
if ((admin>= 100))
|
||||
continueevents=true;
|
||||
break;
|
||||
}
|
||||
case 4: {
|
||||
if ((admin>= 80))
|
||||
continueevents=true;
|
||||
break;
|
||||
}
|
||||
case 5: {
|
||||
if ((admin>= 20))
|
||||
continueevents=true;
|
||||
break;
|
||||
}
|
||||
case 6: {
|
||||
if ((admin>= 10))
|
||||
continueevents=true;
|
||||
break;
|
||||
}
|
||||
case 7: {
|
||||
continueevents=true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (continueevents)
|
||||
database.logevents(
|
||||
c->AccountName(),
|
||||
c->AccountID(),
|
||||
admin,c->GetName(),
|
||||
c->GetTarget()?c->GetTarget()->GetName():"None",
|
||||
"Command",
|
||||
message,
|
||||
1
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* commands go below here
|
||||
*/
|
||||
@@ -2553,7 +2480,7 @@ void command_peekinv(Client *c, const Seperator *sep)
|
||||
Client* targetClient = c->GetTarget()->CastToClient();
|
||||
const ItemInst* inst_main = nullptr;
|
||||
const ItemInst* inst_sub = nullptr;
|
||||
const Item_Struct* item_data = nullptr;
|
||||
const ItemData* item_data = nullptr;
|
||||
std::string item_link;
|
||||
Client::TextLink linker;
|
||||
linker.SetLinkType(linker.linkItemInst);
|
||||
@@ -2602,7 +2529,7 @@ void command_peekinv(Client *c, const Seperator *sep)
|
||||
item_link = linker.GenerateLink();
|
||||
|
||||
c->Message((item_data == nullptr), " InvBagSlot: %i (Slot #%i, Bag #%i), Item: %i (%s), Charges: %i",
|
||||
Inventory::CalcSlotId(indexMain, indexSub), indexMain, indexSub, ((item_data == nullptr) ? 0 : item_data->ID), item_link.c_str(), ((inst_sub == nullptr) ? 0 : inst_sub->GetCharges()));
|
||||
InventoryOld::CalcSlotId(indexMain, indexSub), indexMain, indexSub, ((item_data == nullptr) ? 0 : item_data->ID), item_link.c_str(), ((inst_sub == nullptr) ? 0 : inst_sub->GetCharges()));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2636,7 +2563,7 @@ void command_peekinv(Client *c, const Seperator *sep)
|
||||
item_link = linker.GenerateLink();
|
||||
|
||||
c->Message((item_data == nullptr), " CursorBagSlot: %i (Slot #%i, Bag #%i), Item: %i (%s), Charges: %i",
|
||||
Inventory::CalcSlotId(MainCursor, indexSub), MainCursor, indexSub, ((item_data == nullptr) ? 0 : item_data->ID), item_link.c_str(), ((inst_sub == nullptr) ? 0 : inst_sub->GetCharges()));
|
||||
InventoryOld::CalcSlotId(MainCursor, indexSub), MainCursor, indexSub, ((item_data == nullptr) ? 0 : item_data->ID), item_link.c_str(), ((inst_sub == nullptr) ? 0 : inst_sub->GetCharges()));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -2673,7 +2600,7 @@ void command_peekinv(Client *c, const Seperator *sep)
|
||||
item_link = linker.GenerateLink();
|
||||
|
||||
c->Message((item_data == nullptr), " BankBagSlot: %i (Slot #%i, Bag #%i), Item: %i (%s), Charges: %i",
|
||||
Inventory::CalcSlotId(indexMain, indexSub), indexMain, indexSub, ((item_data == nullptr) ? 0 : item_data->ID), item_link.c_str(), ((inst_sub == nullptr) ? 0 : inst_sub->GetCharges()));
|
||||
InventoryOld::CalcSlotId(indexMain, indexSub), indexMain, indexSub, ((item_data == nullptr) ? 0 : item_data->ID), item_link.c_str(), ((inst_sub == nullptr) ? 0 : inst_sub->GetCharges()));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2695,7 +2622,7 @@ void command_peekinv(Client *c, const Seperator *sep)
|
||||
item_link = linker.GenerateLink();
|
||||
|
||||
c->Message((item_data == nullptr), " SharedBankBagSlot: %i (Slot #%i, Bag #%i), Item: %i (%s), Charges: %i",
|
||||
Inventory::CalcSlotId(indexMain, indexSub), indexMain, indexSub, ((item_data == nullptr) ? 0 : item_data->ID), item_link.c_str(), ((inst_sub == nullptr) ? 0 : inst_sub->GetCharges()));
|
||||
InventoryOld::CalcSlotId(indexMain, indexSub), indexMain, indexSub, ((item_data == nullptr) ? 0 : item_data->ID), item_link.c_str(), ((inst_sub == nullptr) ? 0 : inst_sub->GetCharges()));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2718,7 +2645,7 @@ void command_peekinv(Client *c, const Seperator *sep)
|
||||
item_link = linker.GenerateLink();
|
||||
|
||||
c->Message((item_data == nullptr), " TradeBagSlot: %i (Slot #%i, Bag #%i), Item: %i (%s), Charges: %i",
|
||||
Inventory::CalcSlotId(indexMain, indexSub), indexMain, indexSub, ((item_data == nullptr) ? 0 : item_data->ID), item_link.c_str(), ((inst_sub == nullptr) ? 0 : inst_sub->GetCharges()));
|
||||
InventoryOld::CalcSlotId(indexMain, indexSub), indexMain, indexSub, ((item_data == nullptr) ? 0 : item_data->ID), item_link.c_str(), ((inst_sub == nullptr) ? 0 : inst_sub->GetCharges()));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3119,77 +3046,77 @@ void command_listpetition(Client *c, const Seperator *sep)
|
||||
|
||||
void command_equipitem(Client *c, const Seperator *sep)
|
||||
{
|
||||
uint32 slot_id = atoi(sep->arg[1]);
|
||||
if (sep->IsNumber(1) && ((slot_id >= EmuConstants::EQUIPMENT_BEGIN) && (slot_id <= EmuConstants::EQUIPMENT_END) || (slot_id == MainPowerSource))) {
|
||||
const ItemInst* from_inst = c->GetInv().GetItem(MainCursor);
|
||||
const ItemInst* to_inst = c->GetInv().GetItem(slot_id); // added (desync issue when forcing stack to stack)
|
||||
bool partialmove = false;
|
||||
int16 movecount;
|
||||
|
||||
if (from_inst && from_inst->IsType(ItemClassCommon)) {
|
||||
EQApplicationPacket* outapp = new EQApplicationPacket(OP_MoveItem, sizeof(MoveItem_Struct));
|
||||
MoveItem_Struct* mi = (MoveItem_Struct*)outapp->pBuffer;
|
||||
mi->from_slot = MainCursor;
|
||||
mi->to_slot = slot_id;
|
||||
// mi->number_in_stack = from_inst->GetCharges(); // replaced with con check for stacking
|
||||
|
||||
// crude stackable check to only 'move' the difference count on client instead of entire stack when applicable
|
||||
if (to_inst && to_inst->IsStackable() &&
|
||||
(to_inst->GetItem()->ID == from_inst->GetItem()->ID) &&
|
||||
(to_inst->GetCharges() < to_inst->GetItem()->StackSize) &&
|
||||
(from_inst->GetCharges() > to_inst->GetItem()->StackSize - to_inst->GetCharges())) {
|
||||
movecount = to_inst->GetItem()->StackSize - to_inst->GetCharges();
|
||||
mi->number_in_stack = (uint32)movecount;
|
||||
partialmove = true;
|
||||
}
|
||||
else
|
||||
mi->number_in_stack = from_inst->GetCharges();
|
||||
|
||||
// Save move changes
|
||||
// Added conditional check to packet send..would have sent change even on a swap failure..whoops!
|
||||
|
||||
if (partialmove) { // remove this con check if someone can figure out removing charges from cursor stack issue below
|
||||
// mi->number_in_stack is always from_inst->GetCharges() when partialmove is false
|
||||
c->Message(13, "Error: Partial stack added to existing stack exceeds allowable stacksize");
|
||||
return;
|
||||
}
|
||||
else if(c->SwapItem(mi)) {
|
||||
c->FastQueuePacket(&outapp);
|
||||
|
||||
// if the below code is still needed..just send an an item trade packet to each slot..it should overwrite the client instance
|
||||
|
||||
// below code has proper logic, but client does not like to have cursor charges changed
|
||||
// (we could delete the cursor item and resend, but issues would arise if there are queued items)
|
||||
//if (partialmove) {
|
||||
// EQApplicationPacket* outapp2 = new EQApplicationPacket(OP_DeleteItem, sizeof(DeleteItem_Struct));
|
||||
// DeleteItem_Struct* di = (DeleteItem_Struct*)outapp2->pBuffer;
|
||||
// di->from_slot = SLOT_CURSOR;
|
||||
// di->to_slot = 0xFFFFFFFF;
|
||||
// di->number_in_stack = 0xFFFFFFFF;
|
||||
|
||||
// c->Message(0, "Deleting %i charges from stack", movecount); // debug line..delete
|
||||
|
||||
// for (int16 deletecount=0; deletecount < movecount; deletecount++)
|
||||
// have to use 'movecount' because mi->number_in_stack is 'ENCODED' at this point (i.e., 99 charges returns 22...)
|
||||
// c->QueuePacket(outapp2);
|
||||
|
||||
// safe_delete(outapp2);
|
||||
//}
|
||||
}
|
||||
else {
|
||||
c->Message(13, "Error: Unable to equip current item");
|
||||
}
|
||||
safe_delete(outapp);
|
||||
|
||||
// also send out a wear change packet?
|
||||
}
|
||||
else if (from_inst == nullptr)
|
||||
c->Message(13, "Error: There is no item on your cursor");
|
||||
else
|
||||
c->Message(13, "Error: Item on your cursor cannot be equipped");
|
||||
}
|
||||
else
|
||||
c->Message(0, "Usage: #equipitem slotid[0-21] - equips the item on your cursor to the position");
|
||||
// uint32 slot_id = atoi(sep->arg[1]);
|
||||
// if (sep->IsNumber(1) && ((slot_id >= EmuConstants::EQUIPMENT_BEGIN) && (slot_id <= EmuConstants::EQUIPMENT_END) || (slot_id == MainPowerSource))) {
|
||||
// const ItemInst* from_inst = c->GetInv().GetItem(MainCursor);
|
||||
// const ItemInst* to_inst = c->GetInv().GetItem(slot_id); // added (desync issue when forcing stack to stack)
|
||||
// bool partialmove = false;
|
||||
// int16 movecount;
|
||||
//
|
||||
// if (from_inst && from_inst->IsType(ItemClassCommon)) {
|
||||
// EQApplicationPacket* outapp = new EQApplicationPacket(OP_MoveItem, sizeof(MoveItem_Struct));
|
||||
// MoveItem_Struct* mi = (MoveItem_Struct*)outapp->pBuffer;
|
||||
// mi->from_slot = MainCursor;
|
||||
// mi->to_slot = slot_id;
|
||||
// // mi->number_in_stack = from_inst->GetCharges(); // replaced with con check for stacking
|
||||
//
|
||||
// // crude stackable check to only 'move' the difference count on client instead of entire stack when applicable
|
||||
// if (to_inst && to_inst->IsStackable() &&
|
||||
// (to_inst->GetItem()->ID == from_inst->GetItem()->ID) &&
|
||||
// (to_inst->GetCharges() < to_inst->GetItem()->StackSize) &&
|
||||
// (from_inst->GetCharges() > to_inst->GetItem()->StackSize - to_inst->GetCharges())) {
|
||||
// movecount = to_inst->GetItem()->StackSize - to_inst->GetCharges();
|
||||
// mi->number_in_stack = (uint32)movecount;
|
||||
// partialmove = true;
|
||||
// }
|
||||
// else
|
||||
// mi->number_in_stack = from_inst->GetCharges();
|
||||
//
|
||||
// // Save move changes
|
||||
// // Added conditional check to packet send..would have sent change even on a swap failure..whoops!
|
||||
//
|
||||
// if (partialmove) { // remove this con check if someone can figure out removing charges from cursor stack issue below
|
||||
// // mi->number_in_stack is always from_inst->GetCharges() when partialmove is false
|
||||
// c->Message(13, "Error: Partial stack added to existing stack exceeds allowable stacksize");
|
||||
// return;
|
||||
// }
|
||||
// else if(c->SwapItem(mi)) {
|
||||
// c->FastQueuePacket(&outapp);
|
||||
//
|
||||
// // if the below code is still needed..just send an an item trade packet to each slot..it should overwrite the client instance
|
||||
//
|
||||
// // below code has proper logic, but client does not like to have cursor charges changed
|
||||
// // (we could delete the cursor item and resend, but issues would arise if there are queued items)
|
||||
// //if (partialmove) {
|
||||
// // EQApplicationPacket* outapp2 = new EQApplicationPacket(OP_DeleteItem, sizeof(DeleteItem_Struct));
|
||||
// // DeleteItem_Struct* di = (DeleteItem_Struct*)outapp2->pBuffer;
|
||||
// // di->from_slot = SLOT_CURSOR;
|
||||
// // di->to_slot = 0xFFFFFFFF;
|
||||
// // di->number_in_stack = 0xFFFFFFFF;
|
||||
//
|
||||
// // c->Message(0, "Deleting %i charges from stack", movecount); // debug line..delete
|
||||
//
|
||||
// // for (int16 deletecount=0; deletecount < movecount; deletecount++)
|
||||
// // have to use 'movecount' because mi->number_in_stack is 'ENCODED' at this point (i.e., 99 charges returns 22...)
|
||||
// // c->QueuePacket(outapp2);
|
||||
//
|
||||
// // safe_delete(outapp2);
|
||||
// //}
|
||||
// }
|
||||
// else {
|
||||
// c->Message(13, "Error: Unable to equip current item");
|
||||
// }
|
||||
// safe_delete(outapp);
|
||||
//
|
||||
// // also send out a wear change packet?
|
||||
// }
|
||||
// else if (from_inst == nullptr)
|
||||
// c->Message(13, "Error: There is no item on your cursor");
|
||||
// else
|
||||
// c->Message(13, "Error: Item on your cursor cannot be equipped");
|
||||
// }
|
||||
// else
|
||||
// c->Message(0, "Usage: #equipitem slotid[0-21] - equips the item on your cursor to the position");
|
||||
}
|
||||
|
||||
void command_zonelock(Client *c, const Seperator *sep)
|
||||
@@ -5413,29 +5340,37 @@ void command_summonitem(Client *c, const Seperator *sep)
|
||||
else {
|
||||
uint32 itemid = atoi(sep->arg[1]);
|
||||
int16 item_status = 0;
|
||||
const Item_Struct* item = database.GetItem(itemid);
|
||||
const ItemData* item = database.GetItem(itemid);
|
||||
if(item) {
|
||||
item_status = static_cast<int16>(item->MinStatus);
|
||||
}
|
||||
|
||||
if (item_status > c->Admin())
|
||||
EQEmu::InventorySlot cursor(EQEmu::InvTypePersonal, EQEmu::PersonalSlotCursor);
|
||||
bool v = false;
|
||||
if (item_status > c->Admin()) {
|
||||
c->Message(13, "Error: Insufficient status to summon this item.");
|
||||
return;
|
||||
}
|
||||
else if (sep->argnum==2 && sep->IsNumber(2))
|
||||
c->SummonItem(itemid, atoi(sep->arg[2]));
|
||||
v = c->SummonItem(itemid, atoi(sep->arg[2]), cursor);
|
||||
else if (sep->argnum==3)
|
||||
c->SummonItem(itemid, atoi(sep->arg[2]), atoi(sep->arg[3]));
|
||||
v = 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]));
|
||||
v = 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]));
|
||||
v = 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]));
|
||||
v = 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]));
|
||||
v = 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]));
|
||||
v = 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);
|
||||
v = c->SummonItem(itemid, -1, cursor);
|
||||
}
|
||||
|
||||
if(!v) {
|
||||
c->Message(13, "Error: unable to summon item.");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -5452,29 +5387,37 @@ void command_giveitem(Client *c, const Seperator *sep)
|
||||
Client *t = c->GetTarget()->CastToClient();
|
||||
uint32 itemid = atoi(sep->arg[1]);
|
||||
int16 item_status = 0;
|
||||
const Item_Struct* item = database.GetItem(itemid);
|
||||
const ItemData* item = database.GetItem(itemid);
|
||||
if(item) {
|
||||
item_status = static_cast<int16>(item->MinStatus);
|
||||
}
|
||||
|
||||
if (item_status > c->Admin())
|
||||
EQEmu::InventorySlot cursor(EQEmu::InvTypePersonal, EQEmu::PersonalSlotCursor);
|
||||
bool v = false;
|
||||
if (item_status > c->Admin()) {
|
||||
c->Message(13, "Error: Insufficient status to summon this item.");
|
||||
return;
|
||||
}
|
||||
else if (sep->argnum==2 && sep->IsNumber(2))
|
||||
t->SummonItem(itemid, atoi(sep->arg[2]));
|
||||
v = t->SummonItem(itemid, atoi(sep->arg[2]), cursor);
|
||||
else if (sep->argnum==3)
|
||||
t->SummonItem(itemid, atoi(sep->arg[2]), atoi(sep->arg[3]));
|
||||
v = t->SummonItem(itemid, atoi(sep->arg[2]), cursor, atoi(sep->arg[3]));
|
||||
else if (sep->argnum==4)
|
||||
t->SummonItem(itemid, atoi(sep->arg[2]), atoi(sep->arg[3]), atoi(sep->arg[4]));
|
||||
v = t->SummonItem(itemid, atoi(sep->arg[2]), cursor, atoi(sep->arg[3]), atoi(sep->arg[4]));
|
||||
else if (sep->argnum==5)
|
||||
t->SummonItem(itemid, atoi(sep->arg[2]), atoi(sep->arg[3]), atoi(sep->arg[4]), atoi(sep->arg[5]));
|
||||
v = t->SummonItem(itemid, atoi(sep->arg[2]), cursor, atoi(sep->arg[3]), atoi(sep->arg[4]), atoi(sep->arg[5]));
|
||||
else if (sep->argnum==6)
|
||||
t->SummonItem(itemid, atoi(sep->arg[2]), atoi(sep->arg[3]), atoi(sep->arg[4]), atoi(sep->arg[5]), atoi(sep->arg[6]));
|
||||
v = t->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)
|
||||
t->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]));
|
||||
v = t->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 == 7)
|
||||
t->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]));
|
||||
v = t->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 {
|
||||
t->SummonItem(itemid);
|
||||
v = t->SummonItem(itemid, -1, cursor);
|
||||
}
|
||||
|
||||
if(!v) {
|
||||
c->Message(13, "Error: Unable to summon item on target.");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -5505,7 +5448,7 @@ void command_itemsearch(Client *c, const Seperator *sep)
|
||||
{
|
||||
const char *search_criteria=sep->argplus[1];
|
||||
|
||||
const Item_Struct* item = nullptr;
|
||||
const ItemData* item = nullptr;
|
||||
std::string item_link;
|
||||
Client::TextLink linker;
|
||||
linker.SetLinkType(linker.linkItemData);
|
||||
@@ -10179,7 +10122,7 @@ void command_zopp(Client *c, const Seperator *sep)
|
||||
uint32 itemid = atoi(sep->arg[3]);
|
||||
int16 charges = sep->argnum == 4 ? atoi(sep->arg[4]) : 1; // defaults to 1 charge if not specified
|
||||
|
||||
const Item_Struct* FakeItem = database.GetItem(itemid);
|
||||
const ItemData* FakeItem = database.GetItem(itemid);
|
||||
|
||||
if (!FakeItem) {
|
||||
c->Message(13, "Error: Item [%u] is not a valid item id.", itemid);
|
||||
@@ -10187,7 +10130,7 @@ void command_zopp(Client *c, const Seperator *sep)
|
||||
}
|
||||
|
||||
int16 item_status = 0;
|
||||
const Item_Struct* item = database.GetItem(itemid);
|
||||
const ItemData* item = database.GetItem(itemid);
|
||||
if(item) {
|
||||
item_status = static_cast<int16>(item->MinStatus);
|
||||
}
|
||||
@@ -10201,7 +10144,7 @@ void command_zopp(Client *c, const Seperator *sep)
|
||||
c->Message(0, "Processing request..results may cause unpredictable behavior.");
|
||||
}
|
||||
|
||||
ItemInst* FakeItemInst = database.CreateItem(FakeItem, charges);
|
||||
ItemInst* FakeItemInst = database.CreateItemOld(FakeItem, charges);
|
||||
c->SendItemPacket(slotid, FakeItemInst, packettype);
|
||||
c->Message(0, "Sending zephyr op packet to client - [%s] %s (%u) with %i %s to slot %i.",
|
||||
packettype == ItemPacketTrade ? "Trade" : "Summon", FakeItem->Name, itemid, charges,
|
||||
|
||||
@@ -60,7 +60,6 @@ void command_deinit(void);
|
||||
int command_add(const char *command_string, const char *desc, int access, CmdFuncPtr function);
|
||||
int command_notavail(Client *c, const char *message);
|
||||
int command_realdispatch(Client *c, char const *message);
|
||||
void command_logcommand(Client *c, const char *message);
|
||||
|
||||
//commands
|
||||
void command_resetaa(Client* c,const Seperator *sep);
|
||||
|
||||
+15
-15
@@ -411,7 +411,7 @@ void Corpse::MoveItemToCorpse(Client *client, ItemInst *inst, int16 equipSlot, s
|
||||
if (equipSlot < EmuConstants::GENERAL_BEGIN || equipSlot > MainCursor) { break; }
|
||||
|
||||
for (auto sub_index = SUB_BEGIN; sub_index < EmuConstants::ITEM_CONTAINER_SIZE; ++sub_index) {
|
||||
int16 real_bag_slot = Inventory::CalcSlotId(equipSlot, sub_index);
|
||||
int16 real_bag_slot = InventoryOld::CalcSlotId(equipSlot, sub_index);
|
||||
auto bag_inst = client->GetInv().GetItem(real_bag_slot);
|
||||
if (bag_inst == nullptr) { continue; }
|
||||
|
||||
@@ -690,8 +690,8 @@ ServerLootItem_Struct* Corpse::GetItem(uint16 lootslot, ServerLootItem_Struct**
|
||||
}
|
||||
}
|
||||
|
||||
if (sitem && bag_item_data && Inventory::SupportsContainers(sitem->equip_slot)) {
|
||||
int16 bagstart = Inventory::CalcSlotId(sitem->equip_slot, SUB_BEGIN);
|
||||
if (sitem && bag_item_data && InventoryOld::SupportsContainers(sitem->equip_slot)) {
|
||||
int16 bagstart = InventoryOld::CalcSlotId(sitem->equip_slot, SUB_BEGIN);
|
||||
|
||||
cur = itemlist.begin();
|
||||
end = itemlist.end();
|
||||
@@ -745,7 +745,7 @@ void Corpse::RemoveItem(ServerLootItem_Struct* item_data)
|
||||
is_corpse_changed = true;
|
||||
itemlist.erase(iter);
|
||||
|
||||
uint8 material = Inventory::CalcMaterialFromSlot(sitem->equip_slot); // autos to unsigned char
|
||||
uint8 material = InventoryOld::CalcMaterialFromSlot(sitem->equip_slot); // autos to unsigned char
|
||||
if (material != _MaterialInvalid)
|
||||
SendWearChange(material);
|
||||
|
||||
@@ -978,8 +978,8 @@ void Corpse::MakeLootRequestPackets(Client* client, const EQApplicationPacket* a
|
||||
safe_delete(outapp);
|
||||
if(Loot_Request_Type == 5) {
|
||||
int pkitem = GetPlayerKillItem();
|
||||
const Item_Struct* item = database.GetItem(pkitem);
|
||||
ItemInst* inst = database.CreateItem(item, item->MaxCharges);
|
||||
const ItemData* item = database.GetItem(pkitem);
|
||||
ItemInst* inst = database.CreateItemOld(item, item->MaxCharges);
|
||||
if(inst) {
|
||||
if (item->RecastDelay)
|
||||
inst->SetRecastTimestamp(timestamps.count(item->RecastType) ? timestamps.at(item->RecastType) : 0);
|
||||
@@ -993,7 +993,7 @@ void Corpse::MakeLootRequestPackets(Client* client, const EQApplicationPacket* a
|
||||
}
|
||||
|
||||
int i = 0;
|
||||
const Item_Struct* item = 0;
|
||||
const ItemData* item = 0;
|
||||
ItemList::iterator cur,end;
|
||||
cur = itemlist.begin();
|
||||
end = itemlist.end();
|
||||
@@ -1012,7 +1012,7 @@ void Corpse::MakeLootRequestPackets(Client* client, const EQApplicationPacket* a
|
||||
if(i < corpselootlimit) {
|
||||
item = database.GetItem(item_data->item_id);
|
||||
if(client && item) {
|
||||
ItemInst* inst = database.CreateItem(item, item_data->charges, item_data->aug_1, item_data->aug_2, item_data->aug_3, item_data->aug_4, item_data->aug_5, item_data->aug_6, item_data->attuned);
|
||||
ItemInst* inst = database.CreateItemOld(item, item_data->charges, item_data->aug_1, item_data->aug_2, item_data->aug_3, item_data->aug_4, item_data->aug_5, item_data->aug_6, item_data->attuned);
|
||||
if(inst) {
|
||||
if (item->RecastDelay)
|
||||
inst->SetRecastTimestamp(timestamps.count(item->RecastType) ? timestamps.at(item->RecastType) : 0);
|
||||
@@ -1108,7 +1108,7 @@ void Corpse::LootItem(Client* client, const EQApplicationPacket* app) {
|
||||
being_looted_by = 0xFFFFFFFF;
|
||||
return;
|
||||
}
|
||||
const Item_Struct* item = 0;
|
||||
const ItemData* item = 0;
|
||||
ItemInst *inst = 0;
|
||||
ServerLootItem_Struct* item_data = nullptr, *bag_item_data[10];
|
||||
|
||||
@@ -1129,10 +1129,10 @@ void Corpse::LootItem(Client* client, const EQApplicationPacket* app) {
|
||||
|
||||
if (item != 0) {
|
||||
if (item_data){
|
||||
inst = database.CreateItem(item, item_data ? item_data->charges : 0, item_data->aug_1, item_data->aug_2, item_data->aug_3, item_data->aug_4, item_data->aug_5, item_data->aug_6, item_data->attuned);
|
||||
inst = database.CreateItemOld(item, item_data ? item_data->charges : 0, item_data->aug_1, item_data->aug_2, item_data->aug_3, item_data->aug_4, item_data->aug_5, item_data->aug_6, item_data->attuned);
|
||||
}
|
||||
else {
|
||||
inst = database.CreateItem(item);
|
||||
inst = database.CreateItemOld(item);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1303,7 +1303,7 @@ void Corpse::QueryLoot(Client* to) {
|
||||
else
|
||||
x < corpselootlimit ? sitem->lootslot = x : sitem->lootslot = 0xFFFF;
|
||||
|
||||
const Item_Struct* item = database.GetItem(sitem->item_id);
|
||||
const ItemData* item = database.GetItem(sitem->item_id);
|
||||
|
||||
if (item)
|
||||
to->Message((sitem->lootslot == 0xFFFF), "LootSlot: %i (EquipSlot: %i) Item: %s (%d), Count: %i", static_cast<int16>(sitem->lootslot), sitem->equip_slot, item->Name, item->ID, sitem->charges);
|
||||
@@ -1317,7 +1317,7 @@ void Corpse::QueryLoot(Client* to) {
|
||||
}
|
||||
else {
|
||||
sitem->lootslot=y;
|
||||
const Item_Struct* item = database.GetItem(sitem->item_id);
|
||||
const ItemData* item = database.GetItem(sitem->item_id);
|
||||
|
||||
if (item)
|
||||
to->Message(0, "LootSlot: %i Item: %s (%d), Count: %i", sitem->lootslot, item->Name, item->ID, sitem->charges);
|
||||
@@ -1404,7 +1404,7 @@ uint32 Corpse::GetEquipment(uint8 material_slot) const {
|
||||
return NO_ITEM;
|
||||
}
|
||||
|
||||
invslot = Inventory::CalcSlotFromMaterial(material_slot);
|
||||
invslot = InventoryOld::CalcSlotFromMaterial(material_slot);
|
||||
if(invslot == INVALID_INDEX) // GetWornItem() should be returning a NO_ITEM for any invalid index...
|
||||
return NO_ITEM;
|
||||
|
||||
@@ -1412,7 +1412,7 @@ uint32 Corpse::GetEquipment(uint8 material_slot) const {
|
||||
}
|
||||
|
||||
uint32 Corpse::GetEquipmentColor(uint8 material_slot) const {
|
||||
const Item_Struct *item;
|
||||
const ItemData *item;
|
||||
|
||||
if(material_slot > EmuConstants::MATERIAL_END) {
|
||||
return 0;
|
||||
|
||||
+1
-1
@@ -464,7 +464,7 @@ int32 Client::GetActSpellCasttime(uint16 spell_id, int32 casttime)
|
||||
bool Client::TrainDiscipline(uint32 itemid) {
|
||||
|
||||
//get the item info
|
||||
const Item_Struct *item = database.GetItem(itemid);
|
||||
const ItemData *item = database.GetItem(itemid);
|
||||
if(item == nullptr) {
|
||||
Message(13, "Unable to find the tome you turned in!");
|
||||
Log.Out(Logs::General, Logs::Error, "Unable to find turned in tome id %lu\n", (unsigned long)itemid);
|
||||
|
||||
+2
-2
@@ -863,8 +863,8 @@ void PerlembParser::GetQuestPackageName(bool &isPlayerQuest, bool &isGlobalPlaye
|
||||
}
|
||||
}
|
||||
else if(isItemQuest) {
|
||||
// need a valid ItemInst pointer check here..unsure how to cancel this process
|
||||
const Item_Struct* item = iteminst->GetItem();
|
||||
// need a valid ItemInst pointer check here..unsure how to cancel this process -U
|
||||
const ItemData* item = iteminst->GetItem();
|
||||
package_name = "qst_item_";
|
||||
package_name += itoa(item->ID);
|
||||
}
|
||||
|
||||
@@ -3520,10 +3520,11 @@ XS(XS__qs_player_event)
|
||||
if (items != 2){
|
||||
Perl_croak(aTHX_ "Usage: qs_player_event(char_id, event_desc)");
|
||||
}
|
||||
else{
|
||||
else {
|
||||
int char_id = (int)SvIV(ST(0));
|
||||
std::string event_desc = (std::string)SvPV_nolen(ST(1));
|
||||
QServ->PlayerLogEvent(Player_Log_Quest, char_id, event_desc);
|
||||
Client *c = entity_list.GetClientByCharID(char_id);
|
||||
zone->LogEvent(EventLogQuest, c, event_desc);
|
||||
}
|
||||
XSRETURN_EMPTY;
|
||||
}
|
||||
|
||||
+1
-1
@@ -29,7 +29,7 @@
|
||||
|
||||
const char *getItemName(unsigned itemid)
|
||||
{
|
||||
const Item_Struct* item = nullptr;
|
||||
const ItemData* item = nullptr;
|
||||
item = database.GetItem(itemid);
|
||||
|
||||
if (item)
|
||||
|
||||
+2
-2
@@ -1935,7 +1935,7 @@ void EntityList::QueueClientsGuildBankItemUpdate(const GuildBankItemUpdate_Struc
|
||||
|
||||
memcpy(outgbius, gbius, sizeof(GuildBankItemUpdate_Struct));
|
||||
|
||||
const Item_Struct *Item = database.GetItem(gbius->ItemID);
|
||||
const ItemData *Item = database.GetItem(gbius->ItemID);
|
||||
|
||||
auto it = client_list.begin();
|
||||
while (it != client_list.end()) {
|
||||
@@ -3831,7 +3831,7 @@ void EntityList::GroupMessage(uint32 gid, const char *from, const char *message)
|
||||
|
||||
uint16 EntityList::CreateGroundObject(uint32 itemid, const glm::vec4& position, uint32 decay_time)
|
||||
{
|
||||
const Item_Struct *is = database.GetItem(itemid);
|
||||
const ItemData *is = database.GetItem(itemid);
|
||||
if (!is)
|
||||
return 0;
|
||||
|
||||
|
||||
+1
-20
@@ -152,7 +152,7 @@ uint32 Client::CalcEXP(uint8 conlevel) {
|
||||
|
||||
void Client::AddEXP(uint32 in_add_exp, uint8 conlevel, bool resexp) {
|
||||
|
||||
this->EVENT_ITEM_ScriptStopReturn();
|
||||
ItemScriptStopReturn();
|
||||
|
||||
uint32 add_exp = in_add_exp;
|
||||
|
||||
@@ -430,13 +430,6 @@ void Client::SetEXP(uint32 set_exp, uint32 set_aaxp, bool isrezzexp) {
|
||||
//Message(15, "You have gained %d skill points!!", m_pp.aapoints - last_unspentAA);
|
||||
char val1[20]={0};
|
||||
Message_StringID(MT_Experience, GAIN_ABILITY_POINT,ConvertArray(m_pp.aapoints, val1),m_pp.aapoints == 1 ? "" : "(s)"); //You have gained an ability point! You now have %1 ability point%2.
|
||||
|
||||
/* QS: PlayerLogAARate */
|
||||
if (RuleB(QueryServ, PlayerLogAARate)){
|
||||
int add_points = (m_pp.aapoints - last_unspentAA);
|
||||
std::string query = StringFormat("INSERT INTO `qs_player_aa_rate_hourly` (char_id, aa_count, hour_time) VALUES (%i, %i, UNIX_TIMESTAMP() - MOD(UNIX_TIMESTAMP(), 3600)) ON DUPLICATE KEY UPDATE `aa_count` = `aa_count` + %i", this->CharacterID(), add_points, add_points);
|
||||
QServ->SendQuery(query.c_str());
|
||||
}
|
||||
|
||||
//Message(15, "You now have %d skill points available to spend.", m_pp.aapoints);
|
||||
}
|
||||
@@ -571,18 +564,6 @@ void Client::SetLevel(uint8 set_level, bool command)
|
||||
}
|
||||
if(set_level > m_pp.level) {
|
||||
parse->EventPlayer(EVENT_LEVEL_UP, this, "", 0);
|
||||
/* QS: PlayerLogLevels */
|
||||
if (RuleB(QueryServ, PlayerLogLevels)){
|
||||
std::string event_desc = StringFormat("Leveled UP :: to Level:%i from Level:%i in zoneid:%i instid:%i", set_level, m_pp.level, this->GetZoneID(), this->GetInstanceID());
|
||||
QServ->PlayerLogEvent(Player_Log_Levels, this->CharacterID(), event_desc);
|
||||
}
|
||||
}
|
||||
else if (set_level < m_pp.level){
|
||||
/* QS: PlayerLogLevels */
|
||||
if (RuleB(QueryServ, PlayerLogLevels)){
|
||||
std::string event_desc = StringFormat("Leveled DOWN :: to Level:%i from Level:%i in zoneid:%i instid:%i", set_level, m_pp.level, this->GetZoneID(), this->GetInstanceID());
|
||||
QServ->PlayerLogEvent(Player_Log_Levels, this->CharacterID(), event_desc);
|
||||
}
|
||||
}
|
||||
|
||||
m_pp.level = set_level;
|
||||
|
||||
+4
-4
@@ -304,10 +304,10 @@ void Client::GoFish()
|
||||
food_id = common_fish_ids[index];
|
||||
}
|
||||
|
||||
const Item_Struct* food_item = database.GetItem(food_id);
|
||||
const ItemData* food_item = database.GetItem(food_id);
|
||||
|
||||
Message_StringID(MT_Skills, FISHING_SUCCESS);
|
||||
ItemInst* inst = database.CreateItem(food_item, 1);
|
||||
ItemInst* inst = database.CreateItemOld(food_item, 1);
|
||||
if(inst != nullptr) {
|
||||
if(CheckLoreConflict(inst->GetItem()))
|
||||
{
|
||||
@@ -396,7 +396,7 @@ void Client::ForageItem(bool guarantee) {
|
||||
foragedfood = common_food_ids[index];
|
||||
}
|
||||
|
||||
const Item_Struct* food_item = database.GetItem(foragedfood);
|
||||
const ItemData* food_item = database.GetItem(foragedfood);
|
||||
|
||||
if(!food_item) {
|
||||
Log.Out(Logs::General, Logs::Error, "nullptr returned from database.GetItem in ClientForageItem");
|
||||
@@ -423,7 +423,7 @@ void Client::ForageItem(bool guarantee) {
|
||||
}
|
||||
|
||||
Message_StringID(MT_Skills, stringid);
|
||||
ItemInst* inst = database.CreateItem(food_item, 1);
|
||||
ItemInst* inst = database.CreateItemOld(food_item, 1);
|
||||
if(inst != nullptr) {
|
||||
// check to make sure it isn't a foraged lore item
|
||||
if(CheckLoreConflict(inst->GetItem()))
|
||||
|
||||
+10
-10
@@ -692,7 +692,7 @@ void GuildBankManager::SendGuildBank(Client *c)
|
||||
{
|
||||
if((*Iterator)->Items.DepositArea[i].ItemID > 0)
|
||||
{
|
||||
const Item_Struct *Item = database.GetItem((*Iterator)->Items.DepositArea[i].ItemID);
|
||||
const ItemData *Item = database.GetItem((*Iterator)->Items.DepositArea[i].ItemID);
|
||||
|
||||
if(!Item)
|
||||
continue;
|
||||
@@ -728,7 +728,7 @@ void GuildBankManager::SendGuildBank(Client *c)
|
||||
{
|
||||
if((*Iterator)->Items.MainArea[i].ItemID > 0)
|
||||
{
|
||||
const Item_Struct *Item = database.GetItem((*Iterator)->Items.MainArea[i].ItemID);
|
||||
const ItemData *Item = database.GetItem((*Iterator)->Items.MainArea[i].ItemID);
|
||||
|
||||
if(!Item)
|
||||
continue;
|
||||
@@ -859,7 +859,7 @@ bool GuildBankManager::AddItem(uint32 GuildID, uint8 Area, uint32 ItemID, int32
|
||||
return false;
|
||||
}
|
||||
|
||||
const Item_Struct *Item = database.GetItem(ItemID);
|
||||
const ItemData *Item = database.GetItem(ItemID);
|
||||
|
||||
GuildBankItemUpdate_Struct gbius;
|
||||
|
||||
@@ -925,7 +925,7 @@ int GuildBankManager::Promote(uint32 guildID, int slotID)
|
||||
|
||||
(*iter)->Items.DepositArea[slotID].ItemID = 0;
|
||||
|
||||
const Item_Struct *Item = database.GetItem((*iter)->Items.MainArea[mainSlot].ItemID);
|
||||
const ItemData *Item = database.GetItem((*iter)->Items.MainArea[mainSlot].ItemID);
|
||||
|
||||
GuildBankItemUpdate_Struct gbius;
|
||||
|
||||
@@ -981,7 +981,7 @@ void GuildBankManager::SetPermissions(uint32 guildID, uint16 slotID, uint32 perm
|
||||
else
|
||||
(*iter)->Items.MainArea[slotID].WhoFor[0] = '\0';
|
||||
|
||||
const Item_Struct *Item = database.GetItem((*iter)->Items.MainArea[slotID].ItemID);
|
||||
const ItemData *Item = database.GetItem((*iter)->Items.MainArea[slotID].ItemID);
|
||||
|
||||
GuildBankItemUpdate_Struct gbius;
|
||||
|
||||
@@ -1021,7 +1021,7 @@ ItemInst* GuildBankManager::GetItem(uint32 GuildID, uint16 Area, uint16 SlotID,
|
||||
if((SlotID > (GUILD_BANK_DEPOSIT_AREA_SIZE - 1)))
|
||||
return nullptr;
|
||||
|
||||
inst = database.CreateItem((*Iterator)->Items.DepositArea[SlotID].ItemID);
|
||||
inst = database.CreateItemOld((*Iterator)->Items.DepositArea[SlotID].ItemID);
|
||||
|
||||
if(!inst)
|
||||
return nullptr;
|
||||
@@ -1034,7 +1034,7 @@ ItemInst* GuildBankManager::GetItem(uint32 GuildID, uint16 Area, uint16 SlotID,
|
||||
if((SlotID > (GUILD_BANK_MAIN_AREA_SIZE - 1)))
|
||||
return nullptr;
|
||||
|
||||
inst = database.CreateItem((*Iterator)->Items.MainArea[SlotID].ItemID);
|
||||
inst = database.CreateItemOld((*Iterator)->Items.MainArea[SlotID].ItemID);
|
||||
|
||||
if(!inst)
|
||||
return nullptr;
|
||||
@@ -1112,7 +1112,7 @@ bool GuildBankManager::DeleteItem(uint32 guildID, uint16 area, uint16 slotID, ui
|
||||
|
||||
bool deleted = true;
|
||||
|
||||
const Item_Struct *Item = database.GetItem(BankArea[slotID].ItemID);
|
||||
const ItemData *Item = database.GetItem(BankArea[slotID].ItemID);
|
||||
|
||||
if(!Item->Stackable || (quantity >= BankArea[slotID].Quantity)) {
|
||||
std::string query = StringFormat("DELETE FROM `guild_bank` WHERE `guildid` = %i "
|
||||
@@ -1173,7 +1173,7 @@ bool GuildBankManager::MergeStacks(uint32 GuildID, uint16 SlotID)
|
||||
if(BankArea[SlotID].ItemID == 0)
|
||||
return false;
|
||||
|
||||
const Item_Struct *Item = database.GetItem(BankArea[SlotID].ItemID);
|
||||
const ItemData *Item = database.GetItem(BankArea[SlotID].ItemID);
|
||||
|
||||
if(!Item->Stackable)
|
||||
return false;
|
||||
@@ -1271,7 +1271,7 @@ bool GuildBankManager::SplitStack(uint32 GuildID, uint16 SlotID, uint32 Quantity
|
||||
if(BankArea[SlotID].Quantity <= Quantity || Quantity == 0)
|
||||
return false;
|
||||
|
||||
const Item_Struct *Item = database.GetItem(BankArea[SlotID].ItemID);
|
||||
const ItemData *Item = database.GetItem(BankArea[SlotID].ItemID);
|
||||
|
||||
if(!Item->Stackable)
|
||||
return false;
|
||||
|
||||
+661
-423
File diff suppressed because it is too large
Load Diff
+9
-9
@@ -119,8 +119,8 @@ void ZoneDatabase::AddLootDropToNPC(NPC* npc,uint32 lootdrop_id, ItemList* iteml
|
||||
int charges = lds->Entries[i].multiplier;
|
||||
for(int j = 0; j < charges; ++j) {
|
||||
if(zone->random.Real(0.0, 100.0) <= lds->Entries[i].chance) {
|
||||
const Item_Struct* dbitem = GetItem(lds->Entries[i].item_id);
|
||||
npc->AddLootDrop(dbitem, itemlist, lds->Entries[i].item_charges, lds->Entries[i].minlevel,
|
||||
const ItemData* dbitem = GetItem(lds->Entries[i].item_id);
|
||||
npc->AddLootDrop(dbitem, itemlist, lds->Entries[i].item_charges, lds->Entries[i].minlevel,
|
||||
lds->Entries[i].maxlevel, lds->Entries[i].equip_item > 0 ? true : false, false);
|
||||
}
|
||||
}
|
||||
@@ -140,7 +140,7 @@ void ZoneDatabase::AddLootDropToNPC(NPC* npc,uint32 lootdrop_id, ItemList* iteml
|
||||
float roll_t_min = 0.0f;
|
||||
bool active_item_list = false;
|
||||
for(uint32 i = 0; i < lds->NumEntries; ++i) {
|
||||
const Item_Struct* db_item = GetItem(lds->Entries[i].item_id);
|
||||
const ItemData* db_item = GetItem(lds->Entries[i].item_id);
|
||||
if(db_item) {
|
||||
roll_t += lds->Entries[i].chance;
|
||||
active_item_list = true;
|
||||
@@ -157,7 +157,7 @@ void ZoneDatabase::AddLootDropToNPC(NPC* npc,uint32 lootdrop_id, ItemList* iteml
|
||||
for(int i = 0; i < mindrop; ++i) {
|
||||
float roll = (float)zone->random.Real(0.0, roll_t_min);
|
||||
for(uint32 j = 0; j < lds->NumEntries; ++j) {
|
||||
const Item_Struct* db_item = GetItem(lds->Entries[j].item_id);
|
||||
const ItemData* db_item = GetItem(lds->Entries[j].item_id);
|
||||
if(db_item) {
|
||||
if(roll < lds->Entries[j].chance) {
|
||||
npc->AddLootDrop(db_item, itemlist, lds->Entries[j].item_charges, lds->Entries[j].minlevel,
|
||||
@@ -187,7 +187,7 @@ void ZoneDatabase::AddLootDropToNPC(NPC* npc,uint32 lootdrop_id, ItemList* iteml
|
||||
for(int i = mindrop; i < droplimit; ++i) {
|
||||
float roll = (float)zone->random.Real(0.0, roll_t);
|
||||
for(uint32 j = 0; j < lds->NumEntries; ++j) {
|
||||
const Item_Struct* db_item = GetItem(lds->Entries[j].item_id);
|
||||
const ItemData* db_item = GetItem(lds->Entries[j].item_id);
|
||||
if(db_item) {
|
||||
if(roll < lds->Entries[j].chance) {
|
||||
npc->AddLootDrop(db_item, itemlist, lds->Entries[j].item_charges, lds->Entries[j].minlevel,
|
||||
@@ -221,7 +221,7 @@ void ZoneDatabase::AddLootDropToNPC(NPC* npc,uint32 lootdrop_id, ItemList* iteml
|
||||
}
|
||||
|
||||
//if itemlist is null, just send wear changes
|
||||
void NPC::AddLootDrop(const Item_Struct *item2, ItemList* itemlist, int16 charges, uint8 minlevel, uint8 maxlevel, bool equipit, bool wearchange) {
|
||||
void NPC::AddLootDrop(const ItemData *item2, ItemList* itemlist, int16 charges, uint8 minlevel, uint8 maxlevel, bool equipit, bool wearchange) {
|
||||
if(item2 == nullptr)
|
||||
return;
|
||||
|
||||
@@ -258,7 +258,7 @@ void NPC::AddLootDrop(const Item_Struct *item2, ItemList* itemlist, int16 charge
|
||||
if (equipit) {
|
||||
uint8 eslot = 0xFF;
|
||||
char newid[20];
|
||||
const Item_Struct* compitem = nullptr;
|
||||
const ItemData* compitem = nullptr;
|
||||
bool found = false; // track if we found an empty slot we fit into
|
||||
int32 foundslot = -1; // for multi-slot items
|
||||
|
||||
@@ -414,14 +414,14 @@ void NPC::AddLootDrop(const Item_Struct *item2, ItemList* itemlist, int16 charge
|
||||
SendAppearancePacket(AT_Light, GetActiveLightType());
|
||||
}
|
||||
|
||||
void NPC::AddItem(const Item_Struct* item, uint16 charges, bool equipitem) {
|
||||
void NPC::AddItem(const ItemData* item, uint16 charges, bool equipitem) {
|
||||
//slot isnt needed, its determined from the item.
|
||||
AddLootDrop(item, &itemlist, charges, 1, 127, equipitem, equipitem);
|
||||
}
|
||||
|
||||
void NPC::AddItem(uint32 itemid, uint16 charges, bool equipitem) {
|
||||
//slot isnt needed, its determined from the item.
|
||||
const Item_Struct * i = database.GetItem(itemid);
|
||||
const ItemData * i = database.GetItem(itemid);
|
||||
if(i == nullptr)
|
||||
return;
|
||||
AddLootDrop(i, &itemlist, charges, 1, 127, equipitem, equipitem);
|
||||
|
||||
+1
-1
@@ -672,7 +672,7 @@ void Lua_Client::SummonItem(uint32 item_id) {
|
||||
|
||||
void Lua_Client::SummonItem(uint32 item_id, int charges) {
|
||||
Lua_Safe_Call_Void();
|
||||
self->SummonItem(item_id, charges);
|
||||
self->SummonItem(item_id, charges, 0);
|
||||
}
|
||||
|
||||
void Lua_Client::SummonItem(uint32 item_id, int charges, uint32 aug1) {
|
||||
|
||||
@@ -164,7 +164,7 @@ int Lua_Inventory::GetSlotByItemInst(Lua_ItemInst inst) {
|
||||
}
|
||||
|
||||
luabind::scope lua_register_inventory() {
|
||||
return luabind::class_<Lua_Inventory>("Inventory")
|
||||
return luabind::class_<Lua_Inventory>("InventoryOld")
|
||||
.def(luabind::constructor<>())
|
||||
.def("GetItem", (Lua_ItemInst(Lua_Inventory::*)(int))&Lua_Inventory::GetItem)
|
||||
.def("GetItem", (Lua_ItemInst(Lua_Inventory::*)(int,int))&Lua_Inventory::GetItem)
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
|
||||
#include "lua_ptr.h"
|
||||
|
||||
class Inventory;
|
||||
class InventoryOld;
|
||||
class Lua_ItemInst;
|
||||
class Lua_Item;
|
||||
|
||||
@@ -14,16 +14,16 @@ namespace luabind {
|
||||
|
||||
luabind::scope lua_register_inventory();
|
||||
|
||||
class Lua_Inventory : public Lua_Ptr<Inventory>
|
||||
class Lua_Inventory : public Lua_Ptr<InventoryOld>
|
||||
{
|
||||
typedef Inventory NativeType;
|
||||
typedef InventoryOld NativeType;
|
||||
public:
|
||||
Lua_Inventory() : Lua_Ptr(nullptr) { }
|
||||
Lua_Inventory(Inventory *d) : Lua_Ptr(d) { }
|
||||
Lua_Inventory(InventoryOld *d) : Lua_Ptr(d) { }
|
||||
virtual ~Lua_Inventory() { }
|
||||
|
||||
operator Inventory*() {
|
||||
return reinterpret_cast<Inventory*>(GetLuaPtrData());
|
||||
operator InventoryOld*() {
|
||||
return reinterpret_cast<InventoryOld*>(GetLuaPtrData());
|
||||
}
|
||||
|
||||
Lua_ItemInst GetItem(int slot_id);
|
||||
|
||||
+1
-1
@@ -7,7 +7,7 @@
|
||||
#include "lua_item.h"
|
||||
|
||||
Lua_Item::Lua_Item(uint32 item_id) {
|
||||
const Item_Struct *t = database.GetItem(item_id);
|
||||
const ItemData *t = database.GetItem(item_id);
|
||||
SetLuaPtrData(t);
|
||||
}
|
||||
|
||||
|
||||
+6
-6
@@ -4,7 +4,7 @@
|
||||
|
||||
#include "lua_ptr.h"
|
||||
|
||||
struct Item_Struct;
|
||||
struct ItemData;
|
||||
|
||||
namespace luabind {
|
||||
struct scope;
|
||||
@@ -12,17 +12,17 @@ namespace luabind {
|
||||
|
||||
luabind::scope lua_register_item();
|
||||
|
||||
class Lua_Item : public Lua_Ptr<const Item_Struct>
|
||||
class Lua_Item : public Lua_Ptr<const ItemData>
|
||||
{
|
||||
typedef const Item_Struct NativeType;
|
||||
typedef const ItemData NativeType;
|
||||
public:
|
||||
Lua_Item(uint32 item_id);
|
||||
Lua_Item() : Lua_Ptr(nullptr) { }
|
||||
Lua_Item(const Item_Struct *d) : Lua_Ptr(d) { }
|
||||
Lua_Item(const ItemData *d) : Lua_Ptr(d) { }
|
||||
virtual ~Lua_Item() { }
|
||||
|
||||
operator const Item_Struct*() {
|
||||
return reinterpret_cast<const Item_Struct*>(GetLuaPtrData());
|
||||
operator const ItemData*() {
|
||||
return reinterpret_cast<const ItemData*>(GetLuaPtrData());
|
||||
}
|
||||
|
||||
int GetMinStatus();
|
||||
|
||||
@@ -9,12 +9,12 @@
|
||||
#include "lua_item.h"
|
||||
|
||||
Lua_ItemInst::Lua_ItemInst(int item_id) {
|
||||
SetLuaPtrData(database.CreateItem(item_id));
|
||||
SetLuaPtrData(database.CreateItemOld(item_id));
|
||||
cloned_ = true;
|
||||
}
|
||||
|
||||
Lua_ItemInst::Lua_ItemInst(int item_id, int charges) {
|
||||
SetLuaPtrData(database.CreateItem(item_id, charges));
|
||||
SetLuaPtrData(database.CreateItemOld(item_id, charges));
|
||||
cloned_ = true;
|
||||
}
|
||||
|
||||
|
||||
@@ -298,7 +298,7 @@ void handle_player_timer(QuestInterface *parse, lua_State* L, Client* client, st
|
||||
|
||||
void handle_player_discover_item(QuestInterface *parse, lua_State* L, Client* client, std::string data, uint32 extra_data,
|
||||
std::vector<EQEmu::Any> *extra_pointers) {
|
||||
const Item_Struct *item = database.GetItem(extra_data);
|
||||
const ItemData *item = database.GetItem(extra_data);
|
||||
if(item) {
|
||||
Lua_Item l_item(item);
|
||||
luabind::adl::object l_item_o = luabind::adl::object(L, l_item);
|
||||
|
||||
+8
-8
@@ -209,7 +209,7 @@ void Merc::CalcItemBonuses(StatBonuses* newbon) {
|
||||
for (i=0; i<MainAmmo; i++) {
|
||||
if(equipment[i] == 0)
|
||||
continue;
|
||||
const Item_Struct * itm = database.GetItem(equipment[i]);
|
||||
const ItemData * itm = database.GetItem(equipment[i]);
|
||||
if(itm)
|
||||
AddItemBonuses(itm, newbon);
|
||||
}
|
||||
@@ -235,7 +235,7 @@ void Merc::CalcItemBonuses(StatBonuses* newbon) {
|
||||
SetAttackTimer();
|
||||
}
|
||||
|
||||
void Merc::AddItemBonuses(const Item_Struct *item, StatBonuses* newbon) {
|
||||
void Merc::AddItemBonuses(const ItemData *item, StatBonuses* newbon) {
|
||||
|
||||
if(GetLevel() < item->ReqLevel)
|
||||
{
|
||||
@@ -1213,7 +1213,7 @@ void Merc::FillSpawnStruct(NewSpawn_Struct* ns, Mob* ForWho) {
|
||||
{
|
||||
continue;
|
||||
}
|
||||
const Item_Struct* item = database.GetItem(equipment[i]);
|
||||
const ItemData* item = database.GetItem(equipment[i]);
|
||||
if(item)
|
||||
{
|
||||
ns->spawn.equipment[i].material = item->Material;
|
||||
@@ -2536,8 +2536,8 @@ int16 Merc::GetFocusEffect(focusType type, uint16 spell_id) {
|
||||
//Check if item focus effect exists for the client.
|
||||
if (itembonuses.FocusEffects[type]){
|
||||
|
||||
const Item_Struct* TempItem = 0;
|
||||
const Item_Struct* UsedItem = 0;
|
||||
const ItemData* TempItem = 0;
|
||||
const ItemData* UsedItem = 0;
|
||||
uint16 UsedFocusID = 0;
|
||||
int16 Total = 0;
|
||||
int16 focus_max = 0;
|
||||
@@ -4399,7 +4399,7 @@ void Merc::DoClassAttacks(Mob *target) {
|
||||
DoAnim(animKick);
|
||||
int32 dmg = 0;
|
||||
|
||||
if(GetWeaponDamage(target, (const Item_Struct*)nullptr) <= 0){
|
||||
if(GetWeaponDamage(target, (const ItemData*)nullptr) <= 0){
|
||||
dmg = -5;
|
||||
}
|
||||
else{
|
||||
@@ -4421,7 +4421,7 @@ void Merc::DoClassAttacks(Mob *target) {
|
||||
DoAnim(animTailRake);
|
||||
int32 dmg = 0;
|
||||
|
||||
if(GetWeaponDamage(target, (const Item_Struct*)nullptr) <= 0){
|
||||
if(GetWeaponDamage(target, (const ItemData*)nullptr) <= 0){
|
||||
dmg = -5;
|
||||
}
|
||||
else{
|
||||
@@ -5021,7 +5021,7 @@ void Merc::UpdateMercAppearance() {
|
||||
for(int i = EmuConstants::EQUIPMENT_BEGIN; i <= EmuConstants::EQUIPMENT_END; ++i) {
|
||||
itemID = equipment[i];
|
||||
if(itemID != NO_ITEM) {
|
||||
materialFromSlot = Inventory::CalcMaterialFromSlot(i);
|
||||
materialFromSlot = InventoryOld::CalcMaterialFromSlot(i);
|
||||
if(materialFromSlot != _MaterialInvalid)
|
||||
this->SendWearChange(materialFromSlot);
|
||||
}
|
||||
|
||||
+3
-3
@@ -8,7 +8,7 @@ class Corpse;
|
||||
class Group;
|
||||
class Mob;
|
||||
class Raid;
|
||||
struct Item_Struct;
|
||||
struct ItemData;
|
||||
struct MercTemplate;
|
||||
struct NPCType;
|
||||
struct NewSpawn_Struct;
|
||||
@@ -278,7 +278,7 @@ public:
|
||||
|
||||
protected:
|
||||
void CalcItemBonuses(StatBonuses* newbon);
|
||||
void AddItemBonuses(const Item_Struct *item, StatBonuses* newbon);
|
||||
void AddItemBonuses(const ItemData *item, StatBonuses* newbon);
|
||||
int CalcRecommendedLevelBonus(uint8 level, uint8 reclevel, int basestat);
|
||||
|
||||
int16 GetFocusEffect(focusType type, uint16 spell_id);
|
||||
@@ -381,7 +381,7 @@ private:
|
||||
uint8 _OwnerClientVersion;
|
||||
uint32 _currentStance;
|
||||
|
||||
Inventory m_inv;
|
||||
InventoryOld m_inv;
|
||||
int32 max_end;
|
||||
int32 cur_end;
|
||||
bool _medding;
|
||||
|
||||
+14
-13
@@ -108,7 +108,8 @@ Mob::Mob(const char* in_name,
|
||||
m_TargetLocation(glm::vec3()),
|
||||
m_TargetV(glm::vec3()),
|
||||
flee_timer(FLEE_CHECK_TIMER),
|
||||
m_Position(position)
|
||||
m_Position(position),
|
||||
m_inventory(in_race, in_class, in_deity)
|
||||
{
|
||||
targeted = 0;
|
||||
tar_ndx=0;
|
||||
@@ -2366,7 +2367,7 @@ bool Mob::CanThisClassDualWield(void) const {
|
||||
|
||||
// 2HS, 2HB, or 2HP
|
||||
if(pinst && pinst->IsWeapon()) {
|
||||
const Item_Struct* item = pinst->GetItem();
|
||||
const ItemData* item = pinst->GetItem();
|
||||
|
||||
if((item->ItemType == ItemType2HBlunt) || (item->ItemType == ItemType2HSlash) || (item->ItemType == ItemType2HPiercing))
|
||||
return false;
|
||||
@@ -2707,7 +2708,7 @@ uint32 NPC::GetEquipment(uint8 material_slot) const
|
||||
{
|
||||
if(material_slot > 8)
|
||||
return 0;
|
||||
int16 invslot = Inventory::CalcSlotFromMaterial(material_slot);
|
||||
int16 invslot = InventoryOld::CalcSlotFromMaterial(material_slot);
|
||||
if (invslot == INVALID_INDEX)
|
||||
return 0;
|
||||
return equipment[invslot];
|
||||
@@ -2728,7 +2729,7 @@ void Mob::SendArmorAppearance(Client *one_client)
|
||||
{
|
||||
if (!IsClient())
|
||||
{
|
||||
const Item_Struct *item;
|
||||
const ItemData *item;
|
||||
for (int i=0; i< 7 ; ++i)
|
||||
{
|
||||
item=database.GetItem(GetEquipment(i));
|
||||
@@ -2831,7 +2832,7 @@ int32 Mob::GetEquipmentMaterial(uint8 material_slot) const
|
||||
{
|
||||
uint32 equipmaterial = 0;
|
||||
int32 ornamentationAugtype = RuleI(Character, OrnamentationAugmentType);
|
||||
const Item_Struct *item;
|
||||
const ItemData *item;
|
||||
item = database.GetItem(GetEquipment(material_slot));
|
||||
|
||||
if (item != 0)
|
||||
@@ -2841,7 +2842,7 @@ int32 Mob::GetEquipmentMaterial(uint8 material_slot) const
|
||||
{
|
||||
if (this->IsClient())
|
||||
{
|
||||
int16 invslot = Inventory::CalcSlotFromMaterial(material_slot);
|
||||
int16 invslot = InventoryOld::CalcSlotFromMaterial(material_slot);
|
||||
if (invslot == INVALID_INDEX)
|
||||
{
|
||||
return 0;
|
||||
@@ -2884,9 +2885,9 @@ int32 Mob::GetHerosForgeModel(uint8 material_slot) const
|
||||
if (material_slot >= 0 && material_slot < MaterialPrimary)
|
||||
{
|
||||
uint32 ornamentationAugtype = RuleI(Character, OrnamentationAugmentType);
|
||||
const Item_Struct *item;
|
||||
const ItemData *item;
|
||||
item = database.GetItem(GetEquipment(material_slot));
|
||||
int16 invslot = Inventory::CalcSlotFromMaterial(material_slot);
|
||||
int16 invslot = InventoryOld::CalcSlotFromMaterial(material_slot);
|
||||
|
||||
if (item != 0 && invslot != INVALID_INDEX)
|
||||
{
|
||||
@@ -2938,7 +2939,7 @@ int32 Mob::GetHerosForgeModel(uint8 material_slot) const
|
||||
|
||||
uint32 Mob::GetEquipmentColor(uint8 material_slot) const
|
||||
{
|
||||
const Item_Struct *item;
|
||||
const ItemData *item;
|
||||
|
||||
if (armor_tint[material_slot])
|
||||
{
|
||||
@@ -2954,7 +2955,7 @@ uint32 Mob::GetEquipmentColor(uint8 material_slot) const
|
||||
|
||||
uint32 Mob::IsEliteMaterialItem(uint8 material_slot) const
|
||||
{
|
||||
const Item_Struct *item;
|
||||
const ItemData *item;
|
||||
|
||||
item = database.GetItem(GetEquipment(material_slot));
|
||||
if(item != 0)
|
||||
@@ -3863,11 +3864,11 @@ void Mob::TrySympatheticProc(Mob *target, uint32 spell_id)
|
||||
|
||||
int32 Mob::GetItemStat(uint32 itemid, const char *identifier)
|
||||
{
|
||||
const ItemInst* inst = database.CreateItem(itemid);
|
||||
const ItemInst* inst = database.CreateItemOld(itemid);
|
||||
if (!inst)
|
||||
return 0;
|
||||
|
||||
const Item_Struct* item = inst->GetItem();
|
||||
const ItemData* item = inst->GetItem();
|
||||
if (!item)
|
||||
return 0;
|
||||
|
||||
@@ -5597,7 +5598,7 @@ int32 Mob::GetSpellStat(uint32 spell_id, const char *identifier, uint8 slot)
|
||||
|
||||
bool Mob::CanClassEquipItem(uint32 item_id)
|
||||
{
|
||||
const Item_Struct* itm = nullptr;
|
||||
const ItemData* itm = nullptr;
|
||||
itm = database.GetItem(item_id);
|
||||
|
||||
if (!itm)
|
||||
|
||||
+15
-9
@@ -18,6 +18,7 @@
|
||||
#ifndef MOB_H
|
||||
#define MOB_H
|
||||
|
||||
#include "../common/inventory.h"
|
||||
#include "common.h"
|
||||
#include "entity.h"
|
||||
#include "hate_list.h"
|
||||
@@ -38,7 +39,7 @@ class Group;
|
||||
class ItemInst;
|
||||
class NPC;
|
||||
class Raid;
|
||||
struct Item_Struct;
|
||||
struct ItemData;
|
||||
struct NewSpawn_Struct;
|
||||
struct PlayerPositionUpdateServer_Struct;
|
||||
|
||||
@@ -725,7 +726,7 @@ public:
|
||||
inline void SetExtraHaste(int Haste) { ExtraHaste = Haste; }
|
||||
virtual int GetHaste();
|
||||
|
||||
uint8 GetWeaponDamageBonus(const Item_Struct* Weapon);
|
||||
uint8 GetWeaponDamageBonus(const ItemData* Weapon);
|
||||
uint16 GetDamageTable(SkillUseTypes skillinuse);
|
||||
virtual int GetMonkHandToHandDamage(void);
|
||||
|
||||
@@ -749,10 +750,10 @@ public:
|
||||
int32 ReduceAllDamage(int32 damage);
|
||||
|
||||
virtual void DoSpecialAttackDamage(Mob *who, SkillUseTypes skill, int32 max_damage, int32 min_damage = 1, int32 hate_override = -1, int ReuseTime = 10, bool HitChance=false, bool CanAvoid=true);
|
||||
virtual void DoThrowingAttackDmg(Mob* other, const ItemInst* RangeWeapon=nullptr, const Item_Struct* AmmoItem=nullptr, uint16 weapon_damage=0, int16 chance_mod=0,int16 focus=0, int ReuseTime=0, uint32 range_id=0, int AmmoSlot=0, float speed = 4.0f);
|
||||
virtual void DoThrowingAttackDmg(Mob* other, const ItemInst* RangeWeapon=nullptr, const ItemData* AmmoItem=nullptr, uint16 weapon_damage=0, int16 chance_mod=0,int16 focus=0, int ReuseTime=0, uint32 range_id=0, int AmmoSlot=0, float speed = 4.0f);
|
||||
virtual void DoMeleeSkillAttackDmg(Mob* other, uint16 weapon_damage, SkillUseTypes skillinuse, int16 chance_mod=0, int16 focus=0, bool CanRiposte=false, int ReuseTime=0);
|
||||
virtual void DoArcheryAttackDmg(Mob* other, const ItemInst* RangeWeapon=nullptr, const ItemInst* Ammo=nullptr, uint16 weapon_damage=0, int16 chance_mod=0, int16 focus=0, int ReuseTime=0, uint32 range_id=0, uint32 ammo_id=0, const Item_Struct *AmmoItem=nullptr, int AmmoSlot=0, float speed= 4.0f);
|
||||
bool TryProjectileAttack(Mob* other, const Item_Struct *item, SkillUseTypes skillInUse, uint16 weapon_dmg, const ItemInst* RangeWeapon, const ItemInst* Ammo, int AmmoSlot, float speed);
|
||||
virtual void DoArcheryAttackDmg(Mob* other, const ItemInst* RangeWeapon=nullptr, const ItemInst* Ammo=nullptr, uint16 weapon_damage=0, int16 chance_mod=0, int16 focus=0, int ReuseTime=0, uint32 range_id=0, uint32 ammo_id=0, const ItemData *AmmoItem=nullptr, int AmmoSlot=0, float speed= 4.0f);
|
||||
bool TryProjectileAttack(Mob* other, const ItemData *item, SkillUseTypes skillInUse, uint16 weapon_dmg, const ItemInst* RangeWeapon, const ItemInst* Ammo, int AmmoSlot, float speed);
|
||||
void ProjectileAttack();
|
||||
inline bool HasProjectileAttack() const { return ActiveProjectileATK; }
|
||||
inline void SetProjectileAttack(bool value) { ActiveProjectileATK = value; }
|
||||
@@ -871,7 +872,7 @@ public:
|
||||
// HP Event
|
||||
inline int GetNextHPEvent() const { return nexthpevent; }
|
||||
void SetNextHPEvent( int hpevent );
|
||||
void SendItemAnimation(Mob *to, const Item_Struct *item, SkillUseTypes skillInUse, float velocity= 4.0);
|
||||
void SendItemAnimation(Mob *to, const ItemData *item, SkillUseTypes skillInUse, float velocity= 4.0);
|
||||
inline int& GetNextIncHPEvent() { return nextinchpevent; }
|
||||
void SetNextIncHPEvent( int inchpevent );
|
||||
|
||||
@@ -956,6 +957,9 @@ public:
|
||||
void Tune_FindAccuaryByHitChance(Mob* defender, Mob *attacker, float hit_chance, int interval, int max_loop, int avoid_override, int Msg = 0);
|
||||
void Tune_FindAvoidanceByHitChance(Mob* defender, Mob *attacker, float hit_chance, int interval, int max_loop, int acc_override, int Msg = 0);
|
||||
|
||||
inline EQEmu::Inventory& GetInventory() { return m_inventory; }
|
||||
inline const EQEmu::Inventory& GetInventory() const { return m_inventory; }
|
||||
|
||||
protected:
|
||||
void CommonDamage(Mob* other, int32 &damage, const uint16 spell_id, const SkillUseTypes attack_skill, bool &avoidable, const int8 buffslot, const bool iBuffTic);
|
||||
static uint16 GetProcID(uint16 spell_id, uint8 effect_index);
|
||||
@@ -1077,8 +1081,8 @@ protected:
|
||||
bool PassLimitToSkill(uint16 spell_id, uint16 skill);
|
||||
bool PassLimitClass(uint32 Classes_, uint16 Class_);
|
||||
void TryDefensiveProc(const ItemInst* weapon, Mob *on, uint16 hand = MainPrimary);
|
||||
void TryWeaponProc(const ItemInst* inst, const Item_Struct* weapon, Mob *on, uint16 hand = MainPrimary);
|
||||
void TrySpellProc(const ItemInst* inst, const Item_Struct* weapon, Mob *on, uint16 hand = MainPrimary);
|
||||
void TryWeaponProc(const ItemInst* inst, const ItemData* weapon, Mob *on, uint16 hand = MainPrimary);
|
||||
void TrySpellProc(const ItemInst* inst, const ItemData* weapon, Mob *on, uint16 hand = MainPrimary);
|
||||
void TryWeaponProc(const ItemInst* weapon, Mob *on, uint16 hand = MainPrimary);
|
||||
void ExecWeaponProc(const ItemInst* weapon, uint16 spell_id, Mob *on, int level_override = -1);
|
||||
virtual float GetProcChances(float ProcBonus, uint16 hand = MainPrimary);
|
||||
@@ -1087,7 +1091,7 @@ protected:
|
||||
virtual float GetAssassinateProcChances(uint16 ReuseTime);
|
||||
virtual float GetSkillProcChances(uint16 ReuseTime, uint16 hand = 0); // hand = MainCharm?
|
||||
uint16 GetWeaponSpeedbyHand(uint16 hand);
|
||||
int GetWeaponDamage(Mob *against, const Item_Struct *weapon_item);
|
||||
int GetWeaponDamage(Mob *against, const ItemData *weapon_item);
|
||||
int GetWeaponDamage(Mob *against, const ItemInst *weapon_item, uint32 *hate = nullptr);
|
||||
int GetKickDamage();
|
||||
int GetBashDamage();
|
||||
@@ -1311,6 +1315,8 @@ protected:
|
||||
bool bEnraged;
|
||||
bool destructibleobject;
|
||||
|
||||
EQEmu::Inventory m_inventory;
|
||||
|
||||
private:
|
||||
void _StopSong(); //this is not what you think it is
|
||||
Mob* target;
|
||||
|
||||
@@ -9,7 +9,7 @@ class ItemInst;
|
||||
class Spawn2;
|
||||
struct Consider_Struct;
|
||||
struct DBTradeskillRecipe_Struct;
|
||||
struct Item_Struct;
|
||||
struct ItemData;
|
||||
|
||||
extern EntityList entity_list;
|
||||
extern Zone* zone;
|
||||
@@ -26,7 +26,7 @@ void Zone::mod_repop() { return; }
|
||||
void NPC::mod_prespawn(Spawn2 *sp) { return; }
|
||||
|
||||
//Base damage from NPC::Attack
|
||||
int NPC::mod_npc_damage(int damage, SkillUseTypes skillinuse, int hand, const Item_Struct* weapon, Mob* other) { return(damage); }
|
||||
int NPC::mod_npc_damage(int damage, SkillUseTypes skillinuse, int hand, const ItemData* weapon, Mob* other) { return(damage); }
|
||||
|
||||
//Mob c has been given credit for a kill. This is called after the regular EVENT_KILLED_MERIT event.
|
||||
void NPC::mod_npc_killed_merit(Mob* c) { return; }
|
||||
@@ -104,8 +104,8 @@ int32 Client::mod_client_xp(int32 in_xp, NPC *npc) { return(in_xp); }
|
||||
uint32 Client::mod_client_xp_for_level(uint32 xp, uint16 check_level) { return(xp); }
|
||||
|
||||
//Food and drink values as computed by consume requests. Return < 0 to abort the request.
|
||||
int Client::mod_food_value(const Item_Struct *item, int change) { return(change); }
|
||||
int Client::mod_drink_value(const Item_Struct *item, int change) { return(change); }
|
||||
int Client::mod_food_value(const ItemData *item, int change) { return(change); }
|
||||
int Client::mod_drink_value(const ItemData *item, int change) { return(change); }
|
||||
|
||||
//effect_vallue - Spell effect value as calculated by default formulas. You will want to ignore effects that don't lend themselves to scaling - pet ID's, gate coords, etc.
|
||||
int Mob::mod_effect_value(int effect_value, uint16 spell_id, int effect_type, Mob* caster) { return(effect_value); }
|
||||
|
||||
+8
-8
@@ -27,7 +27,7 @@
|
||||
#include "../common/clientversions.h"
|
||||
#include "../common/features.h"
|
||||
#include "../common/item.h"
|
||||
#include "../common/item_struct.h"
|
||||
#include "../common/item_data.h"
|
||||
#include "../common/linked_list.h"
|
||||
#include "../common/servertalk.h"
|
||||
|
||||
@@ -475,7 +475,7 @@ void NPC::CheckMinMaxLevel(Mob *them)
|
||||
|
||||
if(themlevel < (*cur)->min_level || themlevel > (*cur)->max_level)
|
||||
{
|
||||
material = Inventory::CalcMaterialFromSlot((*cur)->equip_slot);
|
||||
material = InventoryOld::CalcMaterialFromSlot((*cur)->equip_slot);
|
||||
if (material != _MaterialInvalid)
|
||||
SendWearChange(material);
|
||||
|
||||
@@ -511,7 +511,7 @@ void NPC::QueryLoot(Client* to)
|
||||
|
||||
int x = 0;
|
||||
for(ItemList::iterator cur = itemlist.begin(); cur != itemlist.end(); ++cur, ++x) {
|
||||
const Item_Struct* item = database.GetItem((*cur)->item_id);
|
||||
const ItemData* item = database.GetItem((*cur)->item_id);
|
||||
if (item == nullptr) {
|
||||
Log.Out(Logs::General, Logs::Error, "Database error, invalid item");
|
||||
continue;
|
||||
@@ -1301,7 +1301,7 @@ int32 NPC::GetEquipmentMaterial(uint8 material_slot) const
|
||||
if (material_slot >= _MaterialCount)
|
||||
return 0;
|
||||
|
||||
int16 invslot = Inventory::CalcSlotFromMaterial(material_slot);
|
||||
int16 invslot = InventoryOld::CalcSlotFromMaterial(material_slot);
|
||||
if (invslot == INVALID_INDEX)
|
||||
return 0;
|
||||
|
||||
@@ -1401,10 +1401,10 @@ void NPC::PickPocket(Client* thief) {
|
||||
end = itemlist.end();
|
||||
for(; cur != end && x < 49; ++cur) {
|
||||
ServerLootItem_Struct* citem = *cur;
|
||||
const Item_Struct* item = database.GetItem(citem->item_id);
|
||||
const ItemData* item = database.GetItem(citem->item_id);
|
||||
if (item)
|
||||
{
|
||||
inst = database.CreateItem(item, citem->charges);
|
||||
inst = database.CreateItemOld(item, citem->charges);
|
||||
bool is_arrow = (item->ItemType == ItemTypeArrow) ? true : false;
|
||||
int slot_id = thief->GetInv().FindFreeSlot(false, true, inst->GetItem()->Size, is_arrow);
|
||||
if (/*!Equipped(item->ID) &&*/
|
||||
@@ -1424,10 +1424,10 @@ void NPC::PickPocket(Client* thief) {
|
||||
if (x > 0)
|
||||
{
|
||||
int random = zone->random.Int(0, x-1);
|
||||
inst = database.CreateItem(steal_items[random], charges[random]);
|
||||
inst = database.CreateItemOld(steal_items[random], charges[random]);
|
||||
if (inst)
|
||||
{
|
||||
const Item_Struct* item = inst->GetItem();
|
||||
const ItemData* item = inst->GetItem();
|
||||
if (item)
|
||||
{
|
||||
if (/*item->StealSkill || */steal_skill >= stealchance)
|
||||
|
||||
+4
-4
@@ -90,7 +90,7 @@ class Client;
|
||||
class Group;
|
||||
class Raid;
|
||||
class Spawn2;
|
||||
struct Item_Struct;
|
||||
struct ItemData;
|
||||
|
||||
class NPC : public Mob
|
||||
{
|
||||
@@ -173,7 +173,7 @@ public:
|
||||
virtual void SpellProcess();
|
||||
virtual void FillSpawnStruct(NewSpawn_Struct* ns, Mob* ForWho);
|
||||
|
||||
void AddItem(const Item_Struct* item, uint16 charges, bool equipitem = true);
|
||||
void AddItem(const ItemData* item, uint16 charges, bool equipitem = true);
|
||||
void AddItem(uint32 itemid, uint16 charges, bool equipitem = true);
|
||||
void AddLootTable();
|
||||
void AddLootTable(uint32 ldid);
|
||||
@@ -265,7 +265,7 @@ public:
|
||||
bool IsTaunting() const { return taunting; }
|
||||
void PickPocket(Client* thief);
|
||||
void StartSwarmTimer(uint32 duration) { swarm_timer.Start(duration); }
|
||||
void AddLootDrop(const Item_Struct*dbitem, ItemList* itemlistconst, int16 charges, uint8 minlevel, uint8 maxlevel, bool equipit, bool wearchange = false);
|
||||
void AddLootDrop(const ItemData*dbitem, ItemList* itemlistconst, int16 charges, uint8 minlevel, uint8 maxlevel, bool equipit, bool wearchange = false);
|
||||
virtual void DoClassAttacks(Mob *target);
|
||||
void CheckSignal();
|
||||
inline bool IsNotTargetableWithHotkey() const { return no_target_hotkey; }
|
||||
@@ -398,7 +398,7 @@ public:
|
||||
void SetMerchantProbability(uint8 amt) { probability = amt; }
|
||||
uint8 GetMerchantProbability() { return probability; }
|
||||
void mod_prespawn(Spawn2 *sp);
|
||||
int mod_npc_damage(int damage, SkillUseTypes skillinuse, int hand, const Item_Struct* weapon, Mob* other);
|
||||
int mod_npc_damage(int damage, SkillUseTypes skillinuse, int hand, const ItemData* weapon, Mob* other);
|
||||
void mod_npc_killed_merit(Mob* c);
|
||||
void mod_npc_killed(Mob* oos);
|
||||
void AISpellsList(Client *c);
|
||||
|
||||
+4
-4
@@ -138,7 +138,7 @@ Object::Object(Client* client, const ItemInst* inst)
|
||||
|
||||
// Set object name
|
||||
if (inst) {
|
||||
const Item_Struct* item = inst->GetItem();
|
||||
const ItemData* item = inst->GetItem();
|
||||
if (item && item->IDFile) {
|
||||
if (strlen(item->IDFile) == 0) {
|
||||
strcpy(m_data.object_name, DEFAULT_OBJECT_NAME);
|
||||
@@ -194,7 +194,7 @@ Object::Object(const ItemInst *inst, float x, float y, float z, float heading, u
|
||||
|
||||
// Set object name
|
||||
if (inst) {
|
||||
const Item_Struct* item = inst->GetItem();
|
||||
const ItemData* item = inst->GetItem();
|
||||
if (item && item->IDFile) {
|
||||
if (strlen(item->IDFile) == 0) {
|
||||
strcpy(m_data.object_name, DEFAULT_OBJECT_NAME);
|
||||
@@ -875,7 +875,7 @@ uint32 Object::GetItemID()
|
||||
return 0;
|
||||
}
|
||||
|
||||
const Item_Struct* item = this->m_inst->GetItem();
|
||||
const ItemData* item = this->m_inst->GetItem();
|
||||
|
||||
if (item == 0)
|
||||
{
|
||||
@@ -891,7 +891,7 @@ void Object::SetItemID(uint32 itemid)
|
||||
|
||||
if (itemid)
|
||||
{
|
||||
this->m_inst = database.CreateItem(itemid);
|
||||
this->m_inst = database.CreateItemOld(itemid);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+1
-1
@@ -8044,7 +8044,7 @@ XS(XS_Mob_DoThrowingAttackDmg)
|
||||
Mob * THIS;
|
||||
Mob* target;
|
||||
ItemInst* RangeWeapon = nullptr;
|
||||
Item_Struct* item = nullptr;
|
||||
ItemData* item = nullptr;
|
||||
uint16 weapon_damage = (uint16)SvIV(ST(4));
|
||||
int16 chance_mod = (int16)SvIV(ST(5));
|
||||
int16 focus = (int16)SvIV(ST(6));
|
||||
|
||||
+2
-2
@@ -419,7 +419,7 @@ void Mob::MakePoweredPet(uint16 spell_id, const char* pettype, int16 petpower,
|
||||
// like the special back items some focused pets may receive.
|
||||
uint32 petinv[EmuConstants::EQUIPMENT_SIZE];
|
||||
memset(petinv, 0, sizeof(petinv));
|
||||
const Item_Struct *item = 0;
|
||||
const ItemData *item = 0;
|
||||
|
||||
if (database.GetBasePetItems(record.equipmentset, petinv)) {
|
||||
for (int i = 0; i<EmuConstants::EQUIPMENT_SIZE; i++)
|
||||
@@ -664,7 +664,7 @@ void NPC::SetPetState(SpellBuff_Struct *pet_buffs, uint32 *items) {
|
||||
if(items[i] == 0)
|
||||
continue;
|
||||
|
||||
const Item_Struct* item2 = database.GetItem(items[i]);
|
||||
const ItemData* item2 = database.GetItem(items[i]);
|
||||
if (item2 && item2->NoDrop != 0) {
|
||||
//dont bother saving item charges for now, NPCs never use them
|
||||
//and nobody should be able to get them off the corpse..?
|
||||
|
||||
@@ -42,10 +42,3 @@ void QueryServ::SendQuery(std::string Query)
|
||||
safe_delete(pack);
|
||||
}
|
||||
|
||||
void QueryServ::PlayerLogEvent(int Event_Type, int Character_ID, std::string Event_Desc)
|
||||
{
|
||||
std::string query = StringFormat(
|
||||
"INSERT INTO `qs_player_events` (event, char_id, event_desc, time) VALUES (%i, %i, '%s', UNIX_TIMESTAMP(now()))",
|
||||
Event_Type, Character_ID, EscapeString(Event_Desc).c_str());
|
||||
SendQuery(query);
|
||||
}
|
||||
|
||||
@@ -29,7 +29,6 @@ class QueryServ{
|
||||
QueryServ();
|
||||
~QueryServ();
|
||||
void SendQuery(std::string Query);
|
||||
void PlayerLogEvent(int Event_Type, int Character_ID, std::string Event_Desc);
|
||||
};
|
||||
|
||||
#endif /* QUERYSERV_ZONE_H */
|
||||
+6
-18
@@ -191,7 +191,7 @@ void QuestManager::summonitem(uint32 itemid, int16 charges) {
|
||||
QuestManagerCurrentQuestVars();
|
||||
if(!initiator)
|
||||
return;
|
||||
initiator->SummonItem(itemid, charges);
|
||||
initiator->SummonItem(itemid, charges, 0);
|
||||
}
|
||||
|
||||
void QuestManager::write(const char *file, const char *str) {
|
||||
@@ -812,7 +812,7 @@ void QuestManager::traindisc(int discipline_tome_item_id) {
|
||||
}
|
||||
|
||||
bool QuestManager::isdisctome(int item_id) {
|
||||
const Item_Struct *item = database.GetItem(item_id);
|
||||
const ItemData *item = database.GetItem(item_id);
|
||||
if(item == nullptr) {
|
||||
return(false);
|
||||
}
|
||||
@@ -1303,7 +1303,7 @@ void QuestManager::settime(uint8 new_hour, uint8 new_min, bool update_world /*=
|
||||
void QuestManager::itemlink(int item_id) {
|
||||
QuestManagerCurrentQuestVars();
|
||||
if (initiator) {
|
||||
const Item_Struct* item = database.GetItem(item_id);
|
||||
const ItemData* item = database.GetItem(item_id);
|
||||
if (item == nullptr)
|
||||
return;
|
||||
|
||||
@@ -1370,12 +1370,6 @@ void QuestManager::setglobal(const char *varname, const char *newvalue, int opti
|
||||
}
|
||||
|
||||
InsertQuestGlobal(qgCharid, qgNpcid, qgZoneid, varname, newvalue, QGVarDuration(duration));
|
||||
|
||||
/* QS: PlayerLogQGlobalUpdate */
|
||||
if (RuleB(QueryServ, PlayerLogQGlobalUpdate) && qgCharid && qgCharid > 0 && initiator && initiator->IsClient()){
|
||||
std::string event_desc = StringFormat("Update :: qglobal:%s to qvalue:%s zoneid:%i instid:%i", varname, newvalue, initiator->GetZoneID(), initiator->GetInstanceID());
|
||||
QServ->PlayerLogEvent(Player_Log_QGlobal_Update, qgCharid, event_desc);
|
||||
}
|
||||
}
|
||||
|
||||
/* Inserts global variable into quest_globals table */
|
||||
@@ -1462,12 +1456,6 @@ void QuestManager::delglobal(const char *varname) {
|
||||
else
|
||||
qgCharid=-qgNpcid; // make char id negative npc id as a fudge
|
||||
|
||||
/* QS: PlayerLogQGlobalUpdate */
|
||||
if (RuleB(QueryServ, PlayerLogQGlobalUpdate) && qgCharid && qgCharid > 0 && initiator && initiator->IsClient()){
|
||||
std::string event_desc = StringFormat("Deleted :: qglobal:%s zoneid:%i instid:%i", varname, initiator->GetZoneID(), initiator->GetInstanceID());
|
||||
QServ->PlayerLogEvent(Player_Log_QGlobal_Update, qgCharid, event_desc);
|
||||
}
|
||||
|
||||
std::string query = StringFormat("DELETE FROM quest_globals "
|
||||
"WHERE name = '%s' "
|
||||
"&& (npcid=0 || npcid=%i) "
|
||||
@@ -2501,7 +2489,7 @@ void QuestManager::MerchantSetItem(uint32 NPCid, uint32 itemid, uint32 quantity)
|
||||
if (merchant == 0 || !merchant->IsNPC() || (merchant->GetClass() != MERCHANT))
|
||||
return; // don't do anything if NPCid isn't a merchant
|
||||
|
||||
const Item_Struct* item = nullptr;
|
||||
const ItemData* item = nullptr;
|
||||
item = database.GetItem(itemid);
|
||||
if (!item) return; // if the item id doesn't correspond to a real item, do nothing
|
||||
|
||||
@@ -2514,7 +2502,7 @@ uint32 QuestManager::MerchantCountItem(uint32 NPCid, uint32 itemid) {
|
||||
if (merchant == 0 || !merchant->IsNPC() || (merchant->GetClass() != MERCHANT))
|
||||
return 0; // if it isn't a merchant, it doesn't have any items
|
||||
|
||||
const Item_Struct* item = nullptr;
|
||||
const ItemData* item = nullptr;
|
||||
item = database.GetItem(itemid);
|
||||
if (!item)
|
||||
return 0; // if it isn't a valid item, the merchant doesn't have any
|
||||
@@ -2537,7 +2525,7 @@ uint32 QuestManager::MerchantCountItem(uint32 NPCid, uint32 itemid) {
|
||||
// Item Link for use in Variables - "my $example_link = quest::varlink(item_id);"
|
||||
const char* QuestManager::varlink(char* perltext, int item_id) {
|
||||
QuestManagerCurrentQuestVars();
|
||||
const Item_Struct* item = database.GetItem(item_id);
|
||||
const ItemData* item = database.GetItem(item_id);
|
||||
if (!item)
|
||||
return "INVALID ITEM ID IN VARLINK";
|
||||
|
||||
|
||||
+27
-26
@@ -119,7 +119,8 @@ void Mob::DoSpecialAttackDamage(Mob *who, SkillUseTypes skill, int32 max_damage,
|
||||
{
|
||||
hate += item->GetItem()->AC;
|
||||
}
|
||||
const Item_Struct *itm = item->GetItem();
|
||||
|
||||
const ItemData *itm = item->GetItem();
|
||||
auto fbash = GetFuriousBash(itm->Focus.Effect);
|
||||
hate = hate * (100 + fbash) / 100;
|
||||
if (fbash)
|
||||
@@ -482,7 +483,7 @@ int Mob::MonkSpecialAttack(Mob* other, uint8 unchecked_type)
|
||||
}
|
||||
}
|
||||
else{
|
||||
if(GetWeaponDamage(other, (const Item_Struct*)nullptr) <= 0){
|
||||
if(GetWeaponDamage(other, (const ItemData*)nullptr) <= 0){
|
||||
ndamage = -5;
|
||||
}
|
||||
}
|
||||
@@ -713,8 +714,8 @@ void Client::RangedAttack(Mob* other, bool CanDoubleAttack) {
|
||||
return;
|
||||
}
|
||||
|
||||
const Item_Struct* RangeItem = RangeWeapon->GetItem();
|
||||
const Item_Struct* AmmoItem = Ammo->GetItem();
|
||||
const ItemData* RangeItem = RangeWeapon->GetItem();
|
||||
const ItemData* AmmoItem = Ammo->GetItem();
|
||||
|
||||
if(RangeItem->ItemType != ItemTypeBow) {
|
||||
Log.Out(Logs::Detail, Logs::Combat, "Ranged attack canceled. Ranged item is not a bow. type %d.", RangeItem->ItemType);
|
||||
@@ -738,7 +739,7 @@ void Client::RangedAttack(Mob* other, bool CanDoubleAttack) {
|
||||
const ItemInst *pi = m_inv[r];
|
||||
if(pi == nullptr || !pi->IsType(ItemClassContainer))
|
||||
continue;
|
||||
const Item_Struct* bagitem = pi->GetItem();
|
||||
const ItemData* bagitem = pi->GetItem();
|
||||
if(!bagitem || bagitem->BagType != BagTypeQuiver)
|
||||
continue;
|
||||
|
||||
@@ -816,13 +817,13 @@ void Client::RangedAttack(Mob* other, bool CanDoubleAttack) {
|
||||
CommonBreakInvisible();
|
||||
}
|
||||
|
||||
void Mob::DoArcheryAttackDmg(Mob* other, const ItemInst* RangeWeapon, const ItemInst* Ammo, uint16 weapon_damage, int16 chance_mod, int16 focus, int ReuseTime,
|
||||
uint32 range_id, uint32 ammo_id, const Item_Struct *AmmoItem, int AmmoSlot, float speed) {
|
||||
|
||||
if ((other == nullptr ||
|
||||
((IsClient() && CastToClient()->dead) ||
|
||||
(other->IsClient() && other->CastToClient()->dead)) ||
|
||||
HasDied() ||
|
||||
void Mob::DoArcheryAttackDmg(Mob* other, const ItemInst* RangeWeapon, const ItemInst* Ammo, uint16 weapon_damage, int16 chance_mod, int16 focus, int ReuseTime,
|
||||
uint32 range_id, uint32 ammo_id, const ItemData *AmmoItem, int AmmoSlot, float speed) {
|
||||
|
||||
if ((other == nullptr ||
|
||||
((IsClient() && CastToClient()->dead) ||
|
||||
(other->IsClient() && other->CastToClient()->dead)) ||
|
||||
HasDied() ||
|
||||
(!IsAttackAllowed(other)) ||
|
||||
(other->GetInvul() ||
|
||||
other->GetSpecialAbility(IMMUNE_MELEE))))
|
||||
@@ -832,7 +833,7 @@ void Mob::DoArcheryAttackDmg(Mob* other, const ItemInst* RangeWeapon, const Ite
|
||||
|
||||
const ItemInst* _RangeWeapon = nullptr;
|
||||
const ItemInst* _Ammo = nullptr;
|
||||
const Item_Struct* ammo_lost = nullptr;
|
||||
const ItemData* ammo_lost = nullptr;
|
||||
|
||||
/*
|
||||
If LaunchProjectile is false this function will do archery damage on target,
|
||||
@@ -1025,7 +1026,7 @@ void Mob::DoArcheryAttackDmg(Mob* other, const ItemInst* RangeWeapon, const Ite
|
||||
}
|
||||
}
|
||||
|
||||
bool Mob::TryProjectileAttack(Mob* other, const Item_Struct *item, SkillUseTypes skillInUse, uint16 weapon_dmg, const ItemInst* RangeWeapon, const ItemInst* Ammo, int AmmoSlot, float speed){
|
||||
bool Mob::TryProjectileAttack(Mob* other, const ItemData *item, SkillUseTypes skillInUse, uint16 weapon_dmg, const ItemInst* RangeWeapon, const ItemInst* Ammo, int AmmoSlot, float speed){
|
||||
|
||||
if (!other)
|
||||
return false;
|
||||
@@ -1329,7 +1330,7 @@ void NPC::DoRangedAttackDmg(Mob* other, bool Launch, int16 damage_mod, int16 cha
|
||||
|
||||
//try proc on hits and misses
|
||||
if(other && !other->HasDied())
|
||||
TrySpellProc(nullptr, (const Item_Struct*)nullptr, other, MainRange);
|
||||
TrySpellProc(nullptr, (const ItemData*)nullptr, other, MainRange);
|
||||
|
||||
if (HasSkillProcs() && other && !other->HasDied())
|
||||
TrySkillProc(other, skillInUse, 0, false, MainRange);
|
||||
@@ -1383,7 +1384,7 @@ void Client::ThrowingAttack(Mob* other, bool CanDoubleAttack) { //old was 51
|
||||
return;
|
||||
}
|
||||
|
||||
const Item_Struct* item = RangeWeapon->GetItem();
|
||||
const ItemData* item = RangeWeapon->GetItem();
|
||||
if(item->ItemType != ItemTypeLargeThrowing && item->ItemType != ItemTypeSmallThrowing) {
|
||||
Log.Out(Logs::Detail, Logs::Combat, "Ranged attack canceled. Ranged item %d is not a throwing weapon. type %d.", item->ItemType);
|
||||
Message(0, "Error: Rangeweapon: GetItem(%i)==0, you have nothing useful to throw!", GetItemIDAt(MainRange));
|
||||
@@ -1444,7 +1445,7 @@ void Client::ThrowingAttack(Mob* other, bool CanDoubleAttack) { //old was 51
|
||||
CommonBreakInvisible();
|
||||
}
|
||||
|
||||
void Mob::DoThrowingAttackDmg(Mob* other, const ItemInst* RangeWeapon, const Item_Struct* AmmoItem, uint16 weapon_damage, int16 chance_mod,int16 focus, int ReuseTime, uint32 range_id, int AmmoSlot, float speed)
|
||||
void Mob::DoThrowingAttackDmg(Mob* other, const ItemInst* RangeWeapon, const ItemData* AmmoItem, uint16 weapon_damage, int16 chance_mod,int16 focus, int ReuseTime, uint32 range_id, int AmmoSlot, float speed)
|
||||
{
|
||||
if ((other == nullptr ||
|
||||
((IsClient() && CastToClient()->dead) ||
|
||||
@@ -1458,7 +1459,7 @@ void Mob::DoThrowingAttackDmg(Mob* other, const ItemInst* RangeWeapon, const Ite
|
||||
}
|
||||
|
||||
const ItemInst* _RangeWeapon = nullptr;
|
||||
const Item_Struct* ammo_lost = nullptr;
|
||||
const ItemData* ammo_lost = nullptr;
|
||||
|
||||
/*
|
||||
If LaunchProjectile is false this function will do archery damage on target,
|
||||
@@ -1582,7 +1583,7 @@ void Mob::DoThrowingAttackDmg(Mob* other, const ItemInst* RangeWeapon, const Ite
|
||||
}
|
||||
}
|
||||
|
||||
void Mob::SendItemAnimation(Mob *to, const Item_Struct *item, SkillUseTypes skillInUse, float velocity) {
|
||||
void Mob::SendItemAnimation(Mob *to, const ItemData *item, SkillUseTypes skillInUse, float velocity) {
|
||||
EQApplicationPacket *outapp = new EQApplicationPacket(OP_SomeItemPacketMaybe, sizeof(Arrow_Struct));
|
||||
Arrow_Struct *as = (Arrow_Struct *) outapp->pBuffer;
|
||||
as->type = 1;
|
||||
@@ -1632,7 +1633,7 @@ void Mob::ProjectileAnimation(Mob* to, int item_id, bool IsArrow, float speed, f
|
||||
if (!to)
|
||||
return;
|
||||
|
||||
const Item_Struct* item = nullptr;
|
||||
const ItemData* item = nullptr;
|
||||
uint8 item_type = 0;
|
||||
|
||||
if(!item_id) {
|
||||
@@ -1773,7 +1774,7 @@ void NPC::DoClassAttacks(Mob *target) {
|
||||
DoAnim(animKick);
|
||||
int32 dmg = 0;
|
||||
|
||||
if(GetWeaponDamage(target, (const Item_Struct*)nullptr) <= 0){
|
||||
if(GetWeaponDamage(target, (const ItemData*)nullptr) <= 0){
|
||||
dmg = -5;
|
||||
}
|
||||
else{
|
||||
@@ -1794,7 +1795,7 @@ void NPC::DoClassAttacks(Mob *target) {
|
||||
DoAnim(animTailRake);
|
||||
int32 dmg = 0;
|
||||
|
||||
if(GetWeaponDamage(target, (const Item_Struct*)nullptr) <= 0){
|
||||
if(GetWeaponDamage(target, (const ItemData*)nullptr) <= 0){
|
||||
dmg = -5;
|
||||
}
|
||||
else{
|
||||
@@ -1847,7 +1848,7 @@ void NPC::DoClassAttacks(Mob *target) {
|
||||
DoAnim(animKick);
|
||||
int32 dmg = 0;
|
||||
|
||||
if(GetWeaponDamage(target, (const Item_Struct*)nullptr) <= 0){
|
||||
if(GetWeaponDamage(target, (const ItemData*)nullptr) <= 0){
|
||||
dmg = -5;
|
||||
}
|
||||
else{
|
||||
@@ -1872,7 +1873,7 @@ void NPC::DoClassAttacks(Mob *target) {
|
||||
DoAnim(animTailRake);
|
||||
int32 dmg = 0;
|
||||
|
||||
if(GetWeaponDamage(target, (const Item_Struct*)nullptr) <= 0){
|
||||
if(GetWeaponDamage(target, (const ItemData*)nullptr) <= 0){
|
||||
dmg = -5;
|
||||
}
|
||||
else{
|
||||
@@ -2384,7 +2385,7 @@ void Mob::DoMeleeSkillAttackDmg(Mob* other, uint16 weapon_damage, SkillUseTypes
|
||||
int32 max_hit = (2 * weapon_damage*GetDamageTable(skillinuse)) / 100;
|
||||
|
||||
if(GetLevel() >= 28 && IsWarriorClass() ) {
|
||||
int ucDamageBonus = GetWeaponDamageBonus((const Item_Struct*) nullptr );
|
||||
int ucDamageBonus = GetWeaponDamageBonus((const ItemData*) nullptr );
|
||||
min_hit += (int) ucDamageBonus;
|
||||
max_hit += (int) ucDamageBonus;
|
||||
hate += ucDamageBonus;
|
||||
@@ -2397,7 +2398,7 @@ void Mob::DoMeleeSkillAttackDmg(Mob* other, uint16 weapon_damage, SkillUseTypes
|
||||
if(item->GetItem()->ItemType == ItemTypeShield) {
|
||||
hate += item->GetItem()->AC;
|
||||
}
|
||||
const Item_Struct *itm = item->GetItem();
|
||||
const ItemData *itm = item->GetItem();
|
||||
hate = hate * (100 + GetFuriousBash(itm->Focus.Effect)) / 100;
|
||||
}
|
||||
}
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user