Compare commits

...

36 Commits

Author SHA1 Message Date
KimLS 46cb96a026 Merchant buying in flux but it works better now 2015-06-22 23:50:39 -07:00
KimLS bbc3733c3a Compiles again, had to disable a new piece of code though 2015-06-21 01:45:42 -07:00
KimLS 5995afa1b8 Merge from master, probably wont compile but will fix that soon 2015-06-21 01:38:19 -07:00
KimLS ff3cb9fc54 Merge branch 'master' into inv2 2015-04-07 16:29:07 -07:00
KimLS 56e7d1b0dc Okay finally merchant buying works -.- 2015-04-07 16:28:28 -07:00
KimLS 7341ecc185 Some work on implementing slot selection 2015-04-06 16:53:12 -07:00
KimLS 279ed8d86c Merge branch 'master' into inv2 2015-03-25 15:55:16 -07:00
KimLS 21ce5c6daa Merge plus some work on fixing stacking for merchants. 2015-03-15 14:02:13 -07:00
KimLS 00af95502e Wip merchant stuff, summoning should work now. 2015-03-06 15:53:15 -08:00
KimLS dda8ae4803 Basic item summoning, fix for saving not working 100 pct, deletion works, cursor queue should work too. 2015-03-05 18:03:37 -08:00
KimLS 316aa5ef73 Added current table to utils sql, though not formatted correctly yet since it's heavily wip 2015-03-04 19:35:10 -08:00
KimLS 9fcdf5367e Swap saving now works correctly except for cursor items which wont be reloaded correctly as we don't send cursor on login yet. Also added check for bag into another bag src bag needs to have nothing in it first. 2015-03-04 19:33:01 -08:00
KimLS 972d3d8874 Fix for swapping a stack with another item that is not of the same stack size. Added some console visualization for testing and added basics of data modeling for inventory, saving soon. 2015-03-02 19:38:57 -08:00
KimLS abc5ddc5f8 Inventory Swap implemented and passes tests, though still want to verify it a bit more also does not yet save but that's next. Fixed a crash in memory buffer too. 2015-03-02 00:44:28 -08:00
KimLS 14b5a8d817 Merge from master 2015-02-28 17:59:32 -08:00
KimLS 20cbe4af44 More work on swapping, almost there just need to write code for stack split/move/combining 2015-02-28 17:56:01 -08:00
KimLS 7870bf103a Working on can equip, putting it in the general inventory class. 2015-02-27 02:40:44 -08:00
KimLS 18b4d068ea Early stages of swapping requirements in, should check for basic validity and equipable status 2015-02-26 22:09:29 -08:00
KimLS 568938d003 Merge from master 2015-02-25 19:39:48 -08:00
KimLS 215861dd86 Added serialization differentiation 2015-02-25 19:36:10 -08:00
KimLS c62cff1ce7 Fixed test again. 2015-02-24 00:38:49 -08:00
KimLS 69612b44d4 OP_MoveItem encode/decode for RoF2, disabled other patches for now (until i get rof2 packets and mechanics working well enough to go back and fix those) 2015-02-23 22:45:50 -08:00
KimLS 8bce7893ed BulkSendItems now works on RoF2 2015-02-23 17:33:21 -08:00
KimLS 4e4168852b Going to start work on SerializingItems for bulk inv sends 2015-02-23 01:50:50 -08:00
KimLS ca278d029e Fix for Memory Buffer stuff, have yet to compile so not sure if that's enough. Partial work on RoF inventory bulk send 2015-02-22 19:38:44 -08:00
KimLS 273574d4db Added memory buffer plus tests to project, going to use it for item serialization 2015-02-22 15:37:11 -08:00
KimLS c71a5888ff Merge branch 'master' into inv2 2015-02-22 14:27:49 -08:00
KimLS b3c53e5907 Merge master, fix conflicts 2015-02-21 15:30:15 -08:00
KimLS f511862004 Working working working on getting the basics setup 2015-02-21 15:21:45 -08:00
KimLS a90e9cf4c6 Refactoring 2015-02-20 20:15:58 -08:00
KimLS 2d617f0ea7 Get/Put item implementation + tests 2015-02-20 16:24:32 -08:00
KimLS 551c0ef368 Basic arch work, doesn't make a ton of sense yet but it will 2015-02-19 23:34:43 -08:00
KimLS a5274b9b6e InventoryOld in client has been unhooked from loading/saving 2015-02-18 20:29:58 -08:00
KimLS fc2492a859 Merge from master, fixed conflicts 2015-02-18 13:18:21 -08:00
KimLS 701e194ece Renamed Item_Struct to ItemData 2015-02-17 18:06:22 -08:00
KimLS b75e6308dd Renamed Inventory to InventoryOld 2015-02-17 13:42:21 -08:00
112 changed files with 6386 additions and 4027 deletions
+18 -1
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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 */
+1 -1
View File
@@ -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
View File
@@ -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];
};*/
+782
View File
@@ -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;
}
+165
View File
@@ -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
+40
View File
@@ -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
+212
View File
@@ -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);
}
+45
View File
@@ -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
+40
View File
@@ -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
View File
@@ -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
View File
@@ -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;
+135
View File
@@ -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);
}
}
+70
View File
@@ -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
+19 -22
View File
@@ -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];
};
+389
View File
@@ -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);
}
+126
View File
@@ -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
+212
View File
@@ -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;
}
+124
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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)
+2 -2
View File
@@ -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 = ?
+1 -1
View File
@@ -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
View File
@@ -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);
+1 -1
View File
@@ -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
View File
@@ -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);
+1 -1
View File
@@ -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
View File
@@ -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;
+1 -1
View File
@@ -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
View File
@@ -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);
+1 -1
View File
@@ -2032,7 +2032,7 @@ struct AdventureLeaderboard_Struct
/*struct Item_Shop_Struct {
uint16 merchantid;
uint8 itemtype;
Item_Struct item;
ItemData item;
uint8 iss_unknown001[6];
};*/
-21
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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;
-223
View File
@@ -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
-6
View File
@@ -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);
-35
View File
@@ -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
+2 -2
View File
@@ -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();
+3 -1
View File
@@ -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
View File
@@ -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);
+337
View File
@@ -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
View File
@@ -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;
}
+605
View File
@@ -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
+21
View File
@@ -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
View File
@@ -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
View File
@@ -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; }
-7
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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.
+1 -1
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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,
-1
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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);
}
+3 -2
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
File diff suppressed because it is too large Load Diff
+9 -9
View File
@@ -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
View File
@@ -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) {
+1 -1
View File
@@ -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)
+6 -6
View File
@@ -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
View File
@@ -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
View File
@@ -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();
+2 -2
View File
@@ -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;
}
+1 -1
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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;
+4 -4
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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..?
-7
View File
@@ -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);
}
-1
View File
@@ -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
View File
@@ -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
View File
@@ -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