mirror of
https://github.com/EQEmu/Server.git
synced 2025-12-11 21:01:29 +00:00
[Pets] Convert Load/Save of Pet Info to Repositories (#3853)
* [Pets] Convert Save/Load of Pet Info to Repositories - Convert `LoadPetInfo` to repositories. - `SavePetInfo` already used repositories, cleanup logic. * Update repositories. * Update zonedb.cpp
This commit is contained in:
parent
1227f35382
commit
f3de3e8c31
@ -716,6 +716,16 @@ namespace Language {
|
||||
|
||||
constexpr uint8 MaxValue = 100;
|
||||
}
|
||||
namespace PetInfoType {
|
||||
constexpr int Current = 0;
|
||||
constexpr int Suspended = 1;
|
||||
}
|
||||
|
||||
namespace BuffEffectType {
|
||||
constexpr uint8 None = 0;
|
||||
constexpr uint8 Buff = 2;
|
||||
constexpr uint8 InverseBuff = 4;
|
||||
}
|
||||
|
||||
typedef enum {
|
||||
FilterNone = 0,
|
||||
|
||||
@ -6,7 +6,7 @@
|
||||
* Any modifications to base repositories are to be made by the generator only
|
||||
*
|
||||
* @generator ./utils/scripts/generators/repository-generator.pl
|
||||
* @docs https://eqemu.gitbook.io/server/in-development/developer-area/repositories
|
||||
* @docs https://docs.eqemu.io/developer/repositories
|
||||
*/
|
||||
|
||||
#ifndef EQEMU_BASE_CHARACTER_PET_BUFFS_REPOSITORY_H
|
||||
@ -16,6 +16,7 @@
|
||||
#include "../../strings.h"
|
||||
#include <ctime>
|
||||
|
||||
|
||||
class BaseCharacterPetBuffsRepository {
|
||||
public:
|
||||
struct CharacterPetBuffs {
|
||||
@ -144,8 +145,9 @@ public:
|
||||
{
|
||||
auto results = db.QueryDatabase(
|
||||
fmt::format(
|
||||
"{} WHERE id = {} LIMIT 1",
|
||||
"{} WHERE {} = {} LIMIT 1",
|
||||
BaseSelect(),
|
||||
PrimaryKey(),
|
||||
character_pet_buffs_id
|
||||
)
|
||||
);
|
||||
@ -418,6 +420,82 @@ public:
|
||||
return (results.Success() && results.begin()[0] ? strtoll(results.begin()[0], nullptr, 10) : 0);
|
||||
}
|
||||
|
||||
static std::string BaseReplace()
|
||||
{
|
||||
return fmt::format(
|
||||
"REPLACE INTO {} ({}) ",
|
||||
TableName(),
|
||||
ColumnsRaw()
|
||||
);
|
||||
}
|
||||
|
||||
static int ReplaceOne(
|
||||
Database& db,
|
||||
const CharacterPetBuffs &e
|
||||
)
|
||||
{
|
||||
std::vector<std::string> v;
|
||||
|
||||
v.push_back(std::to_string(e.char_id));
|
||||
v.push_back(std::to_string(e.pet));
|
||||
v.push_back(std::to_string(e.slot));
|
||||
v.push_back(std::to_string(e.spell_id));
|
||||
v.push_back(std::to_string(e.caster_level));
|
||||
v.push_back("'" + Strings::Escape(e.castername) + "'");
|
||||
v.push_back(std::to_string(e.ticsremaining));
|
||||
v.push_back(std::to_string(e.counters));
|
||||
v.push_back(std::to_string(e.numhits));
|
||||
v.push_back(std::to_string(e.rune));
|
||||
v.push_back(std::to_string(e.instrument_mod));
|
||||
|
||||
auto results = db.QueryDatabase(
|
||||
fmt::format(
|
||||
"{} VALUES ({})",
|
||||
BaseReplace(),
|
||||
Strings::Implode(",", v)
|
||||
)
|
||||
);
|
||||
|
||||
return (results.Success() ? results.RowsAffected() : 0);
|
||||
}
|
||||
|
||||
static int ReplaceMany(
|
||||
Database& db,
|
||||
const std::vector<CharacterPetBuffs> &entries
|
||||
)
|
||||
{
|
||||
std::vector<std::string> insert_chunks;
|
||||
|
||||
for (auto &e: entries) {
|
||||
std::vector<std::string> v;
|
||||
|
||||
v.push_back(std::to_string(e.char_id));
|
||||
v.push_back(std::to_string(e.pet));
|
||||
v.push_back(std::to_string(e.slot));
|
||||
v.push_back(std::to_string(e.spell_id));
|
||||
v.push_back(std::to_string(e.caster_level));
|
||||
v.push_back("'" + Strings::Escape(e.castername) + "'");
|
||||
v.push_back(std::to_string(e.ticsremaining));
|
||||
v.push_back(std::to_string(e.counters));
|
||||
v.push_back(std::to_string(e.numhits));
|
||||
v.push_back(std::to_string(e.rune));
|
||||
v.push_back(std::to_string(e.instrument_mod));
|
||||
|
||||
insert_chunks.push_back("(" + Strings::Implode(",", v) + ")");
|
||||
}
|
||||
|
||||
std::vector<std::string> v;
|
||||
|
||||
auto results = db.QueryDatabase(
|
||||
fmt::format(
|
||||
"{} VALUES {}",
|
||||
BaseReplace(),
|
||||
Strings::Implode(",", insert_chunks)
|
||||
)
|
||||
);
|
||||
|
||||
return (results.Success() ? results.RowsAffected() : 0);
|
||||
}
|
||||
};
|
||||
|
||||
#endif //EQEMU_BASE_CHARACTER_PET_BUFFS_REPOSITORY_H
|
||||
|
||||
@ -6,7 +6,7 @@
|
||||
* Any modifications to base repositories are to be made by the generator only
|
||||
*
|
||||
* @generator ./utils/scripts/generators/repository-generator.pl
|
||||
* @docs https://eqemu.gitbook.io/server/in-development/developer-area/repositories
|
||||
* @docs https://docs.eqemu.io/developer/repositories
|
||||
*/
|
||||
|
||||
#ifndef EQEMU_BASE_CHARACTER_PET_INFO_REPOSITORY_H
|
||||
@ -16,6 +16,7 @@
|
||||
#include "../../strings.h"
|
||||
#include <ctime>
|
||||
|
||||
|
||||
class BaseCharacterPetInfoRepository {
|
||||
public:
|
||||
struct CharacterPetInfo {
|
||||
@ -136,8 +137,9 @@ public:
|
||||
{
|
||||
auto results = db.QueryDatabase(
|
||||
fmt::format(
|
||||
"{} WHERE id = {} LIMIT 1",
|
||||
"{} WHERE {} = {} LIMIT 1",
|
||||
BaseSelect(),
|
||||
PrimaryKey(),
|
||||
character_pet_info_id
|
||||
)
|
||||
);
|
||||
@ -398,6 +400,78 @@ public:
|
||||
return (results.Success() && results.begin()[0] ? strtoll(results.begin()[0], nullptr, 10) : 0);
|
||||
}
|
||||
|
||||
static std::string BaseReplace()
|
||||
{
|
||||
return fmt::format(
|
||||
"REPLACE INTO {} ({}) ",
|
||||
TableName(),
|
||||
ColumnsRaw()
|
||||
);
|
||||
}
|
||||
|
||||
static int ReplaceOne(
|
||||
Database& db,
|
||||
const CharacterPetInfo &e
|
||||
)
|
||||
{
|
||||
std::vector<std::string> v;
|
||||
|
||||
v.push_back(std::to_string(e.char_id));
|
||||
v.push_back(std::to_string(e.pet));
|
||||
v.push_back("'" + Strings::Escape(e.petname) + "'");
|
||||
v.push_back(std::to_string(e.petpower));
|
||||
v.push_back(std::to_string(e.spell_id));
|
||||
v.push_back(std::to_string(e.hp));
|
||||
v.push_back(std::to_string(e.mana));
|
||||
v.push_back(std::to_string(e.size));
|
||||
v.push_back(std::to_string(e.taunting));
|
||||
|
||||
auto results = db.QueryDatabase(
|
||||
fmt::format(
|
||||
"{} VALUES ({})",
|
||||
BaseReplace(),
|
||||
Strings::Implode(",", v)
|
||||
)
|
||||
);
|
||||
|
||||
return (results.Success() ? results.RowsAffected() : 0);
|
||||
}
|
||||
|
||||
static int ReplaceMany(
|
||||
Database& db,
|
||||
const std::vector<CharacterPetInfo> &entries
|
||||
)
|
||||
{
|
||||
std::vector<std::string> insert_chunks;
|
||||
|
||||
for (auto &e: entries) {
|
||||
std::vector<std::string> v;
|
||||
|
||||
v.push_back(std::to_string(e.char_id));
|
||||
v.push_back(std::to_string(e.pet));
|
||||
v.push_back("'" + Strings::Escape(e.petname) + "'");
|
||||
v.push_back(std::to_string(e.petpower));
|
||||
v.push_back(std::to_string(e.spell_id));
|
||||
v.push_back(std::to_string(e.hp));
|
||||
v.push_back(std::to_string(e.mana));
|
||||
v.push_back(std::to_string(e.size));
|
||||
v.push_back(std::to_string(e.taunting));
|
||||
|
||||
insert_chunks.push_back("(" + Strings::Implode(",", v) + ")");
|
||||
}
|
||||
|
||||
std::vector<std::string> v;
|
||||
|
||||
auto results = db.QueryDatabase(
|
||||
fmt::format(
|
||||
"{} VALUES {}",
|
||||
BaseReplace(),
|
||||
Strings::Implode(",", insert_chunks)
|
||||
)
|
||||
);
|
||||
|
||||
return (results.Success() ? results.RowsAffected() : 0);
|
||||
}
|
||||
};
|
||||
|
||||
#endif //EQEMU_BASE_CHARACTER_PET_INFO_REPOSITORY_H
|
||||
|
||||
@ -6,7 +6,7 @@
|
||||
* Any modifications to base repositories are to be made by the generator only
|
||||
*
|
||||
* @generator ./utils/scripts/generators/repository-generator.pl
|
||||
* @docs https://eqemu.gitbook.io/server/in-development/developer-area/repositories
|
||||
* @docs https://docs.eqemu.io/developer/repositories
|
||||
*/
|
||||
|
||||
#ifndef EQEMU_BASE_CHARACTER_PET_INVENTORY_REPOSITORY_H
|
||||
@ -16,6 +16,7 @@
|
||||
#include "../../strings.h"
|
||||
#include <ctime>
|
||||
|
||||
|
||||
class BaseCharacterPetInventoryRepository {
|
||||
public:
|
||||
struct CharacterPetInventory {
|
||||
@ -116,8 +117,9 @@ public:
|
||||
{
|
||||
auto results = db.QueryDatabase(
|
||||
fmt::format(
|
||||
"{} WHERE id = {} LIMIT 1",
|
||||
"{} WHERE {} = {} LIMIT 1",
|
||||
BaseSelect(),
|
||||
PrimaryKey(),
|
||||
character_pet_inventory_id
|
||||
)
|
||||
);
|
||||
@ -348,6 +350,68 @@ public:
|
||||
return (results.Success() && results.begin()[0] ? strtoll(results.begin()[0], nullptr, 10) : 0);
|
||||
}
|
||||
|
||||
static std::string BaseReplace()
|
||||
{
|
||||
return fmt::format(
|
||||
"REPLACE INTO {} ({}) ",
|
||||
TableName(),
|
||||
ColumnsRaw()
|
||||
);
|
||||
}
|
||||
|
||||
static int ReplaceOne(
|
||||
Database& db,
|
||||
const CharacterPetInventory &e
|
||||
)
|
||||
{
|
||||
std::vector<std::string> v;
|
||||
|
||||
v.push_back(std::to_string(e.char_id));
|
||||
v.push_back(std::to_string(e.pet));
|
||||
v.push_back(std::to_string(e.slot));
|
||||
v.push_back(std::to_string(e.item_id));
|
||||
|
||||
auto results = db.QueryDatabase(
|
||||
fmt::format(
|
||||
"{} VALUES ({})",
|
||||
BaseReplace(),
|
||||
Strings::Implode(",", v)
|
||||
)
|
||||
);
|
||||
|
||||
return (results.Success() ? results.RowsAffected() : 0);
|
||||
}
|
||||
|
||||
static int ReplaceMany(
|
||||
Database& db,
|
||||
const std::vector<CharacterPetInventory> &entries
|
||||
)
|
||||
{
|
||||
std::vector<std::string> insert_chunks;
|
||||
|
||||
for (auto &e: entries) {
|
||||
std::vector<std::string> v;
|
||||
|
||||
v.push_back(std::to_string(e.char_id));
|
||||
v.push_back(std::to_string(e.pet));
|
||||
v.push_back(std::to_string(e.slot));
|
||||
v.push_back(std::to_string(e.item_id));
|
||||
|
||||
insert_chunks.push_back("(" + Strings::Implode(",", v) + ")");
|
||||
}
|
||||
|
||||
std::vector<std::string> v;
|
||||
|
||||
auto results = db.QueryDatabase(
|
||||
fmt::format(
|
||||
"{} VALUES {}",
|
||||
BaseReplace(),
|
||||
Strings::Implode(",", insert_chunks)
|
||||
)
|
||||
);
|
||||
|
||||
return (results.Success() ? results.RowsAffected() : 0);
|
||||
}
|
||||
};
|
||||
|
||||
#endif //EQEMU_BASE_CHARACTER_PET_INVENTORY_REPOSITORY_H
|
||||
|
||||
@ -382,7 +382,7 @@ public:
|
||||
inline ExtendedProfile_Struct& GetEPP() { return m_epp; }
|
||||
inline EQ::InventoryProfile& GetInv() { return m_inv; }
|
||||
inline const EQ::InventoryProfile& GetInv() const { return m_inv; }
|
||||
inline PetInfo* GetPetInfo(uint16 pet) { return (pet==1)?&m_suspendedminion:&m_petinfo; }
|
||||
inline PetInfo* GetPetInfo(int pet_info_type) { return pet_info_type == PetInfoType::Suspended ? &m_suspendedminion : &m_petinfo; }
|
||||
inline InspectMessage_Struct& GetInspectMessage() { return m_inspect_message; }
|
||||
inline const InspectMessage_Struct& GetInspectMessage() const { return m_inspect_message; }
|
||||
void ReloadExpansionProfileSetting();
|
||||
|
||||
311
zone/zonedb.cpp
311
zone/zonedb.cpp
@ -3121,124 +3121,136 @@ void ZoneDatabase::LoadAuras(Client *c)
|
||||
|
||||
void ZoneDatabase::SavePetInfo(Client *client)
|
||||
{
|
||||
PetInfo *petinfo = nullptr;
|
||||
PetInfo* p = nullptr;
|
||||
|
||||
// Pet Info
|
||||
std::vector<CharacterPetInfoRepository::CharacterPetInfo> pet_infos = {};
|
||||
CharacterPetInfoRepository::CharacterPetInfo pet_info = {};
|
||||
std::vector<CharacterPetInfoRepository::CharacterPetInfo> pet_infos;
|
||||
auto pet_info = CharacterPetInfoRepository::NewEntity();
|
||||
|
||||
// Pet buffs
|
||||
std::vector<CharacterPetBuffsRepository::CharacterPetBuffs> pet_buffs = {};
|
||||
CharacterPetBuffsRepository::CharacterPetBuffs pet_buff = {};
|
||||
std::vector<CharacterPetBuffsRepository::CharacterPetBuffs> pet_buffs;
|
||||
auto pet_buff = CharacterPetBuffsRepository::NewEntity();
|
||||
|
||||
// Pet inventory
|
||||
std::vector<CharacterPetInventoryRepository::CharacterPetInventory> inventory = {};
|
||||
CharacterPetInventoryRepository::CharacterPetInventory item = {};
|
||||
std::vector<CharacterPetInventoryRepository::CharacterPetInventory> inventory;
|
||||
auto item = CharacterPetInventoryRepository::NewEntity();
|
||||
|
||||
// Loop through pet types
|
||||
for (int pet = 0; pet < 2; pet++) {
|
||||
petinfo = client->GetPetInfo(pet);
|
||||
if (!petinfo) {
|
||||
for (int pet_info_type = PetInfoType::Current; pet_info_type <= PetInfoType::Suspended; pet_info_type++) {
|
||||
p = client->GetPetInfo(pet_info_type);
|
||||
if (!p) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// build pet info into struct
|
||||
pet_info.char_id = client->CharacterID();
|
||||
pet_info.pet = pet;
|
||||
pet_info.petname = petinfo->Name;
|
||||
pet_info.petpower = petinfo->petpower;
|
||||
pet_info.spell_id = petinfo->SpellID;
|
||||
pet_info.hp = petinfo->HP;
|
||||
pet_info.mana = petinfo->Mana;
|
||||
pet_info.size = petinfo->size;
|
||||
pet_info.taunting = (petinfo->taunting) ? 1 : 0;
|
||||
pet_info.pet = pet_info_type;
|
||||
pet_info.petname = p->Name;
|
||||
pet_info.petpower = p->petpower;
|
||||
pet_info.spell_id = p->SpellID;
|
||||
pet_info.hp = p->HP;
|
||||
pet_info.mana = p->Mana;
|
||||
pet_info.size = p->size;
|
||||
pet_info.taunting = p->taunting ? 1 : 0;
|
||||
|
||||
// add pet info to vector
|
||||
pet_infos.push_back(pet_info);
|
||||
|
||||
// build pet buffs into struct
|
||||
int pet_buff_count = 0;
|
||||
// Guard against setting the maximum pet slots above the client allowed maximum.
|
||||
int max_slots = RuleI(Spells, MaxTotalSlotsPET) > PET_BUFF_COUNT ? PET_BUFF_COUNT : RuleI(Spells, MaxTotalSlotsPET);
|
||||
uint32 pet_buff_count = 0;
|
||||
|
||||
// count pet buffs
|
||||
for (int index = 0; index < max_slots; index++) {
|
||||
if (!IsValidSpell(petinfo->Buffs[index].spellid)) {
|
||||
const uint32 max_slots = (
|
||||
RuleI(Spells, MaxTotalSlotsPET) > PET_BUFF_COUNT ?
|
||||
PET_BUFF_COUNT :
|
||||
RuleI(Spells, MaxTotalSlotsPET)
|
||||
);
|
||||
|
||||
for (int slot_id = 0; slot_id < max_slots; slot_id++) {
|
||||
if (!IsValidSpell(p->Buffs[slot_id].spellid)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
pet_buff_count++;
|
||||
}
|
||||
|
||||
// reserve space for pet buffs
|
||||
pet_buffs.reserve(pet_buff_count);
|
||||
|
||||
// loop through pet buffs
|
||||
for (int index = 0; index < max_slots; index++) {
|
||||
if (!IsValidSpell(petinfo->Buffs[index].spellid)) {
|
||||
for (int slot_id = 0; slot_id < max_slots; slot_id++) {
|
||||
if (!IsValidSpell(p->Buffs[slot_id].spellid)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
pet_buff.char_id = client->CharacterID();
|
||||
pet_buff.pet = pet;
|
||||
pet_buff.slot = index;
|
||||
pet_buff.spell_id = petinfo->Buffs[index].spellid;
|
||||
pet_buff.caster_level = petinfo->Buffs[index].level;
|
||||
pet_buff.ticsremaining = petinfo->Buffs[index].duration;
|
||||
pet_buff.counters = petinfo->Buffs[index].counters;
|
||||
pet_buff.instrument_mod = petinfo->Buffs[index].bard_modifier;
|
||||
pet_buff.pet = pet_info_type;
|
||||
pet_buff.slot = slot_id;
|
||||
pet_buff.spell_id = p->Buffs[slot_id].spellid;
|
||||
pet_buff.caster_level = p->Buffs[slot_id].level;
|
||||
pet_buff.ticsremaining = p->Buffs[slot_id].duration;
|
||||
pet_buff.counters = p->Buffs[slot_id].counters;
|
||||
pet_buff.instrument_mod = p->Buffs[slot_id].bard_modifier;
|
||||
|
||||
// add pet buffs to vector
|
||||
pet_buffs.push_back(pet_buff);
|
||||
}
|
||||
|
||||
// build pet inventory into struct
|
||||
int pet_inventory_count = 0;
|
||||
for (int index = EQ::invslot::EQUIPMENT_BEGIN; index <= EQ::invslot::EQUIPMENT_END; index++) {
|
||||
if (!petinfo->Items[index]) {
|
||||
uint32 pet_inventory_count = 0;
|
||||
|
||||
for (
|
||||
int slot_id = EQ::invslot::EQUIPMENT_BEGIN;
|
||||
slot_id <= EQ::invslot::EQUIPMENT_END;
|
||||
slot_id++
|
||||
) {
|
||||
if (!p->Items[slot_id]) {
|
||||
continue;
|
||||
}
|
||||
|
||||
pet_inventory_count++;
|
||||
}
|
||||
|
||||
// reserve space for pet inventory
|
||||
inventory.reserve(pet_inventory_count);
|
||||
|
||||
// loop through pet inventory
|
||||
for (int index = EQ::invslot::EQUIPMENT_BEGIN; index <= EQ::invslot::EQUIPMENT_END; index++) {
|
||||
if (!petinfo->Items[index]) {
|
||||
for (
|
||||
int slot_id = EQ::invslot::EQUIPMENT_BEGIN;
|
||||
slot_id <= EQ::invslot::EQUIPMENT_END;
|
||||
slot_id++
|
||||
) {
|
||||
if (!p->Items[slot_id]) {
|
||||
continue;
|
||||
}
|
||||
|
||||
item.char_id = client->CharacterID();
|
||||
item.pet = pet;
|
||||
item.slot = index;
|
||||
item.item_id = petinfo->Items[index];
|
||||
item.pet = pet_info_type;
|
||||
item.slot = slot_id;
|
||||
item.item_id = p->Items[slot_id];
|
||||
|
||||
// add pet inventory to vector
|
||||
inventory.push_back(item);
|
||||
}
|
||||
}
|
||||
|
||||
// Delete existing pet info
|
||||
CharacterPetInfoRepository::DeleteWhere(database, fmt::format("char_id = {}", client->CharacterID()));
|
||||
CharacterPetInfoRepository::DeleteWhere(
|
||||
database,
|
||||
fmt::format(
|
||||
"`char_id` = {}",
|
||||
client->CharacterID()
|
||||
)
|
||||
);
|
||||
|
||||
// insert pet info into database
|
||||
if (!pet_infos.empty()) {
|
||||
CharacterPetInfoRepository::InsertMany(database, pet_infos);
|
||||
}
|
||||
|
||||
// Delete existing pet buffs
|
||||
CharacterPetBuffsRepository::DeleteWhere(database, fmt::format("char_id = {}", client->CharacterID()));
|
||||
CharacterPetBuffsRepository::DeleteWhere(
|
||||
database,
|
||||
fmt::format(
|
||||
"`char_id` = {}",
|
||||
client->CharacterID()
|
||||
)
|
||||
);
|
||||
|
||||
// insert pet buffs into database
|
||||
if (!pet_buffs.empty()) {
|
||||
CharacterPetBuffsRepository::InsertMany(database, pet_buffs);
|
||||
}
|
||||
|
||||
// Delete existing pet inventory
|
||||
CharacterPetInventoryRepository::DeleteWhere(database, fmt::format("char_id = {}", client->CharacterID()));
|
||||
CharacterPetInventoryRepository::DeleteWhere(
|
||||
database,
|
||||
fmt::format(
|
||||
"`char_id` = {}",
|
||||
client->CharacterID()
|
||||
)
|
||||
);
|
||||
|
||||
// insert pet inventory into database
|
||||
if (!inventory.empty()) {
|
||||
CharacterPetInventoryRepository::InsertMany(database, inventory);
|
||||
}
|
||||
@ -3275,109 +3287,106 @@ void ZoneDatabase::DeleteItemRecast(uint32 character_id, uint32 recast_type)
|
||||
|
||||
void ZoneDatabase::LoadPetInfo(Client *client)
|
||||
{
|
||||
|
||||
// Load current pet and suspended pet
|
||||
PetInfo *petinfo = client->GetPetInfo(0);
|
||||
PetInfo *suspended = client->GetPetInfo(1);
|
||||
auto pet_info = client->GetPetInfo(PetInfoType::Current);
|
||||
auto suspended_pet_info = client->GetPetInfo(PetInfoType::Suspended);
|
||||
|
||||
memset(petinfo, 0, sizeof(PetInfo));
|
||||
memset(suspended, 0, sizeof(PetInfo));
|
||||
memset(pet_info, 0, sizeof(PetInfo));
|
||||
memset(suspended_pet_info, 0, sizeof(PetInfo));
|
||||
|
||||
std::string query = StringFormat("SELECT `pet`, `petname`, `petpower`, `spell_id`, "
|
||||
"`hp`, `mana`, `size` , `taunting` FROM `character_pet_info` "
|
||||
"WHERE `char_id` = %u",
|
||||
client->CharacterID());
|
||||
auto results = database.QueryDatabase(query);
|
||||
if (!results.Success()) {
|
||||
const auto& info = CharacterPetInfoRepository::GetWhere(
|
||||
database,
|
||||
fmt::format(
|
||||
"`char_id` = {}",
|
||||
client->CharacterID()
|
||||
)
|
||||
);
|
||||
|
||||
if (info.empty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
PetInfo *pi;
|
||||
for (auto& row = results.begin(); row != results.end(); ++row) {
|
||||
uint16 pet = Strings::ToInt(row[0]);
|
||||
PetInfo* p;
|
||||
|
||||
if (pet == 0)
|
||||
pi = petinfo;
|
||||
else if (pet == 1)
|
||||
pi = suspended;
|
||||
else
|
||||
for (const auto& e : info) {
|
||||
if (e.pet == PetInfoType::Current) {
|
||||
p = pet_info;
|
||||
} else if (e.pet == PetInfoType::Suspended) {
|
||||
p = suspended_pet_info;
|
||||
} else {
|
||||
continue;
|
||||
}
|
||||
|
||||
strncpy(pi->Name, row[1], 64);
|
||||
pi->petpower = Strings::ToInt(row[2]);
|
||||
pi->SpellID = Strings::ToInt(row[3]);
|
||||
pi->HP = Strings::ToUnsignedInt(row[4]);
|
||||
pi->Mana = Strings::ToUnsignedInt(row[5]);
|
||||
pi->size = Strings::ToFloat(row[6]);
|
||||
pi->taunting = (bool) Strings::ToInt(row[7]);
|
||||
strn0cpy(p->Name, e.petname.c_str(), sizeof(c->Name));
|
||||
|
||||
p->petpower = e.petpower;
|
||||
p->SpellID = e.spell_id;
|
||||
p->HP = e.hp;
|
||||
p->Mana = e.mana;
|
||||
p->size = e.size;
|
||||
p->taunting = e.taunting;
|
||||
}
|
||||
|
||||
query = StringFormat("SELECT `pet`, `slot`, `spell_id`, `caster_level`, `castername`, "
|
||||
"`ticsremaining`, `counters`, `instrument_mod` FROM `character_pet_buffs` "
|
||||
"WHERE `char_id` = %u",
|
||||
client->CharacterID());
|
||||
results = QueryDatabase(query);
|
||||
if (!results.Success()) {
|
||||
return;
|
||||
const auto& buffs = CharacterPetBuffsRepository::GetWhere(
|
||||
database,
|
||||
fmt::format(
|
||||
"`char_id` = {}",
|
||||
client->CharacterID()
|
||||
)
|
||||
);
|
||||
|
||||
if (!buffs.empty()) {
|
||||
for (const auto& e : buffs) {
|
||||
if (e.pet == PetInfoType::Current) {
|
||||
p = pet_info;
|
||||
} else if (e.pet == PetInfoType::Suspended) {
|
||||
p = suspended_pet_info;
|
||||
} else {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (e.slot >= RuleI(Spells, MaxTotalSlotsPET)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!IsValidSpell(e.spell_id)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
p->Buffs[e.slot].spellid = e.spell_id;
|
||||
p->Buffs[e.slot].level = e.caster_level;
|
||||
p->Buffs[e.slot].player_id = 0;
|
||||
p->Buffs[e.slot].effect_type = BuffEffectType::Buff;
|
||||
p->Buffs[e.slot].duration = e.ticsremaining;
|
||||
p->Buffs[e.slot].counters = e.counters;
|
||||
p->Buffs[e.slot].bard_modifier = e.instrument_mod;
|
||||
}
|
||||
}
|
||||
|
||||
for (auto& row = results.begin(); row != results.end(); ++row) {
|
||||
uint16 pet = Strings::ToInt(row[0]);
|
||||
if (pet == 0)
|
||||
pi = petinfo;
|
||||
else if (pet == 1)
|
||||
pi = suspended;
|
||||
else
|
||||
continue;
|
||||
const auto& inventory = CharacterPetInventoryRepository::GetWhere(
|
||||
database,
|
||||
fmt::format(
|
||||
"`char_id` = {}",
|
||||
client->CharacterID()
|
||||
)
|
||||
);
|
||||
|
||||
uint32 slot_id = Strings::ToUnsignedInt(row[1]);
|
||||
if (slot_id >= RuleI(Spells, MaxTotalSlotsPET))
|
||||
continue;
|
||||
if (!inventory.empty()) {
|
||||
for (const auto& e : inventory) {
|
||||
if (e.pet == PetInfoType::Current) {
|
||||
p = pet_info;
|
||||
} else if (e.pet == PetInfoType::Suspended) {
|
||||
p = suspended_pet_info;
|
||||
} else {
|
||||
continue;
|
||||
}
|
||||
|
||||
uint32 spell_id = Strings::ToUnsignedInt(row[2]);
|
||||
if (!IsValidSpell(spell_id))
|
||||
continue;
|
||||
if (!EQ::ValueWithin(e.slot, EQ::invslot::EQUIPMENT_BEGIN, EQ::invslot::EQUIPMENT_END)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
uint32 caster_level = Strings::ToInt(row[3]);
|
||||
int caster_id = 0;
|
||||
// The castername field is currently unused
|
||||
int32 ticsremaining = Strings::ToInt(row[5]);
|
||||
uint32 counters = Strings::ToUnsignedInt(row[6]);
|
||||
uint8 bard_mod = Strings::ToUnsignedInt(row[7]);
|
||||
|
||||
pi->Buffs[slot_id].spellid = spell_id;
|
||||
pi->Buffs[slot_id].level = caster_level;
|
||||
pi->Buffs[slot_id].player_id = caster_id;
|
||||
pi->Buffs[slot_id].effect_type = 2; // Always 2 in buffs struct for real buffs
|
||||
|
||||
pi->Buffs[slot_id].duration = ticsremaining;
|
||||
pi->Buffs[slot_id].counters = counters;
|
||||
pi->Buffs[slot_id].bard_modifier = bard_mod;
|
||||
}
|
||||
|
||||
query = StringFormat("SELECT `pet`, `slot`, `item_id` "
|
||||
"FROM `character_pet_inventory` "
|
||||
"WHERE `char_id`=%u",
|
||||
client->CharacterID());
|
||||
results = database.QueryDatabase(query);
|
||||
if (!results.Success()) {
|
||||
return;
|
||||
}
|
||||
|
||||
for (auto& row = results.begin(); row != results.end(); ++row) {
|
||||
uint16 pet = Strings::ToInt(row[0]);
|
||||
if (pet == 0)
|
||||
pi = petinfo;
|
||||
else if (pet == 1)
|
||||
pi = suspended;
|
||||
else
|
||||
continue;
|
||||
|
||||
int slot = Strings::ToInt(row[1]);
|
||||
if (slot < EQ::invslot::EQUIPMENT_BEGIN || slot > EQ::invslot::EQUIPMENT_END)
|
||||
continue;
|
||||
|
||||
pi->Items[slot] = Strings::ToUnsignedInt(row[2]);
|
||||
p->Items[e.slot] = e.item_id;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user