mirror of
https://github.com/EQEmu/Server.git
synced 2025-12-13 06:21:28 +00:00
Merge branch 'master' of https://github.com/EQEmu/Server
Conflicts: common/eqemu_logsys.h
This commit is contained in:
commit
f9ba99e99f
@ -1,5 +1,8 @@
|
||||
EQEMu Changelog (Started on Sept 24, 2003 15:50)
|
||||
-------------------------------------------------------
|
||||
== 01/31/2015 ==
|
||||
Trevius: Fixed FindGroundZ() and GetGroundZ() to once again utilize the X and Y arguments that are passed to them.
|
||||
|
||||
== 01/30/2015 ==
|
||||
Akkadius: Implemented event type "EVENT_ENVIRONMENTAL_DAMAGE"
|
||||
- This event triggers when taking any sort of environmental damage. Example use:
|
||||
|
||||
@ -107,9 +107,9 @@ public:
|
||||
|
||||
/* General Information Queries */
|
||||
|
||||
bool AddBannedIP(char* bannedIP, const char* notes); //Lieka Edit: Add IP address to the Banned_IPs table.
|
||||
bool AddBannedIP(char* bannedIP, const char* notes); //Add IP address to the Banned_IPs table.
|
||||
bool AddGMIP(char* ip_address, char* name);
|
||||
bool CheckBannedIPs(const char* loginIP); //Lieka Edit: Check incoming connection against banned IP table.
|
||||
bool CheckBannedIPs(const char* loginIP); //Check incoming connection against banned IP table.
|
||||
bool CheckGMIPs(const char* loginIP, uint32 account_id);
|
||||
bool CheckNameFilter(const char* name, bool surname = false);
|
||||
bool CheckUsedName(const char* name);
|
||||
@ -118,7 +118,7 @@ public:
|
||||
uint32 GetAccountIDByChar(uint32 char_id);
|
||||
uint32 GetAccountIDByName(const char* accname, int16* status = 0, uint32* lsid = 0);
|
||||
uint32 GetCharacterID(const char *name);
|
||||
uint32 GetCharacterInfo(const char* iName, uint32* oAccID = 0, uint32* oZoneID = 0, uint32* oInstanceID = 0,float* oX = 0, float* oY = 0, float* oZ = 0);
|
||||
uint32 GetCharacterInfo(const char* iName, uint32* oAccID = 0, uint32* oZoneID = 0, uint32* oInstanceID = 0, float* oX = 0, float* oY = 0, float* oZ = 0);
|
||||
uint32 GetGuildIDByCharID(uint32 char_id);
|
||||
|
||||
void GetAccountName(uint32 accountid, char* name, uint32* oLSAccountID = 0);
|
||||
|
||||
@ -368,7 +368,7 @@ enum {
|
||||
#define AT_DamageState 44 // The damage state of a destructible object (0 through 4)
|
||||
//#define AT_Trader 300 // Bazzar Trader Mode
|
||||
|
||||
// solar: animations for AT_Anim
|
||||
// animations for AT_Anim
|
||||
#define ANIM_FREEZE 102
|
||||
#define ANIM_STAND 0x64
|
||||
#define ANIM_SIT 0x6e
|
||||
|
||||
@ -540,7 +540,7 @@ struct SpawnAppearance_Struct
|
||||
};
|
||||
|
||||
|
||||
// solar: this is used inside profile
|
||||
// this is used inside profile
|
||||
struct SpellBuff_Struct
|
||||
{
|
||||
/*000*/ uint8 slotid; //badly named... seems to be 2 for a real buff, 0 otherwise
|
||||
@ -1268,7 +1268,7 @@ struct Animation_Struct {
|
||||
/*04*/
|
||||
};
|
||||
|
||||
// solar: this is what causes the caster to animate and the target to
|
||||
// this is what causes the caster to animate and the target to
|
||||
// get the particle effects around them when a spell is cast
|
||||
// also causes a buff icon
|
||||
struct Action_Struct
|
||||
@ -1292,7 +1292,7 @@ struct Action_Struct
|
||||
/* 31 */
|
||||
};
|
||||
|
||||
// solar: this is what prints the You have been struck. and the regular
|
||||
// this is what prints the You have been struck. and the regular
|
||||
// melee messages like You try to pierce, etc. It's basically the melee
|
||||
// and spell damage message
|
||||
struct CombatDamage_Struct
|
||||
@ -1811,7 +1811,7 @@ struct RandomReq_Struct {
|
||||
uint32 high;
|
||||
};
|
||||
|
||||
/* solar: 9/23/03 reply to /random command; struct from Zaphod */
|
||||
/* 9/23/03 reply to /random command */
|
||||
struct RandomReply_Struct {
|
||||
/* 00 */ uint32 low;
|
||||
/* 04 */ uint32 high;
|
||||
|
||||
@ -72,7 +72,7 @@ namespace Console {
|
||||
LightRed = 12,
|
||||
LightMagenta = 13,
|
||||
Yellow = 14,
|
||||
White = 15,
|
||||
White = 15
|
||||
};
|
||||
}
|
||||
|
||||
@ -174,7 +174,7 @@ void EQEmuLogSys::ProcessLogWrite(uint16 debug_level, uint16 log_category, const
|
||||
process_log << time_stamp << " " << message << std::endl;
|
||||
}
|
||||
|
||||
uint16 EQEmuLogSys::GetWindowsConsoleColorFromCategory(uint16 log_category){
|
||||
uint16 EQEmuLogSys::GetWindowsConsoleColorFromCategory(uint16 log_category) {
|
||||
switch (log_category) {
|
||||
case Logs::Status:
|
||||
case Logs::Normal:
|
||||
@ -197,7 +197,7 @@ uint16 EQEmuLogSys::GetWindowsConsoleColorFromCategory(uint16 log_category){
|
||||
}
|
||||
}
|
||||
|
||||
std::string EQEmuLogSys::GetLinuxConsoleColorFromCategory(uint16 log_category){
|
||||
std::string EQEmuLogSys::GetLinuxConsoleColorFromCategory(uint16 log_category) {
|
||||
switch (log_category) {
|
||||
case Logs::Status:
|
||||
case Logs::Normal:
|
||||
@ -220,7 +220,7 @@ std::string EQEmuLogSys::GetLinuxConsoleColorFromCategory(uint16 log_category){
|
||||
}
|
||||
}
|
||||
|
||||
uint16 EQEmuLogSys::GetGMSayColorFromCategory(uint16 log_category){
|
||||
uint16 EQEmuLogSys::GetGMSayColorFromCategory(uint16 log_category) {
|
||||
switch (log_category) {
|
||||
case Logs::Status:
|
||||
case Logs::Normal:
|
||||
@ -317,7 +317,7 @@ void EQEmuLogSys::MakeDirectory(const std::string &directory_name)
|
||||
|
||||
void EQEmuLogSys::CloseFileLogs()
|
||||
{
|
||||
if (process_log.is_open()){
|
||||
if (process_log.is_open()) {
|
||||
process_log.close();
|
||||
}
|
||||
}
|
||||
|
||||
@ -26,11 +26,11 @@
|
||||
|
||||
#include "types.h"
|
||||
|
||||
namespace Logs{
|
||||
namespace Logs {
|
||||
enum DebugLevel {
|
||||
General = 1, /* 1 - Low-Level general debugging, useful info on single line */
|
||||
Moderate, /* 2 - Informational based, used in functions, when particular things load */
|
||||
Detail, /* 3 - Use this for extreme detail in logging, usually in extreme debugging in the stack or interprocess communication */
|
||||
Detail /* 3 - Use this for extreme detail in logging, usually in extreme debugging in the stack or interprocess communication */
|
||||
};
|
||||
|
||||
/*
|
||||
@ -124,6 +124,7 @@ namespace Logs{
|
||||
"MySQL Query",
|
||||
"Mercenaries",
|
||||
"Quest Debug",
|
||||
"Quest Debug"
|
||||
"Packet :: Server -> Client",
|
||||
"Packet :: Client -> Server Unhandled",
|
||||
};
|
||||
@ -160,7 +161,7 @@ public:
|
||||
log_to_gmsay[category_id] = [1-3] - Sets debug level for category to output to gmsay
|
||||
*/
|
||||
|
||||
struct LogSettings{
|
||||
struct LogSettings {
|
||||
uint8 log_to_file;
|
||||
uint8 log_to_console;
|
||||
uint8 log_to_gmsay;
|
||||
|
||||
@ -1441,6 +1441,7 @@ ItemInst::ItemInst(const Item_Struct* item, int16 charges) {
|
||||
m_ornamenticon = 0;
|
||||
m_ornamentidfile = 0;
|
||||
m_ornament_hero_model = 0;
|
||||
m_recast_timestamp = 0;
|
||||
}
|
||||
|
||||
ItemInst::ItemInst(SharedDatabase *db, uint32 item_id, int16 charges) {
|
||||
@ -1466,6 +1467,7 @@ ItemInst::ItemInst(SharedDatabase *db, uint32 item_id, int16 charges) {
|
||||
m_ornamenticon = 0;
|
||||
m_ornamentidfile = 0;
|
||||
m_ornament_hero_model = 0;
|
||||
m_recast_timestamp = 0;
|
||||
}
|
||||
|
||||
ItemInst::ItemInst(ItemInstTypes use_type) {
|
||||
@ -1486,6 +1488,7 @@ ItemInst::ItemInst(ItemInstTypes use_type) {
|
||||
m_ornamenticon = 0;
|
||||
m_ornamentidfile = 0;
|
||||
m_ornament_hero_model = 0;
|
||||
m_recast_timestamp = 0;
|
||||
}
|
||||
|
||||
// Make a copy of an ItemInst object
|
||||
@ -1539,6 +1542,7 @@ ItemInst::ItemInst(const ItemInst& copy)
|
||||
m_ornamenticon = copy.m_ornamenticon;
|
||||
m_ornamentidfile = copy.m_ornamentidfile;
|
||||
m_ornament_hero_model = copy.m_ornament_hero_model;
|
||||
m_recast_timestamp = copy.m_recast_timestamp;
|
||||
}
|
||||
|
||||
// Clean up container contents
|
||||
|
||||
@ -403,6 +403,8 @@ public:
|
||||
void SetOrnamentationIDFile(uint32 ornament_idfile) { m_ornamentidfile = ornament_idfile; }
|
||||
uint32 GetOrnamentHeroModel(int32 material_slot = -1) const;
|
||||
void SetOrnamentHeroModel(uint32 ornament_hero_model) { m_ornament_hero_model = ornament_hero_model; }
|
||||
uint32 GetRecastTimestamp() const { return m_recast_timestamp; }
|
||||
void SetRecastTimestamp(uint32 in) { m_recast_timestamp = in; }
|
||||
|
||||
void Initialize(SharedDatabase *db = nullptr);
|
||||
void ScaleItem();
|
||||
@ -450,6 +452,7 @@ protected:
|
||||
uint32 m_ornamenticon;
|
||||
uint32 m_ornamentidfile;
|
||||
uint32 m_ornament_hero_model;
|
||||
uint32 m_recast_timestamp;
|
||||
|
||||
//
|
||||
// Items inside of this item (augs or contents);
|
||||
|
||||
@ -5000,7 +5000,7 @@ namespace RoF
|
||||
hdr.scaled_value = inst->IsScaling() ? inst->GetExp() / 100 : 0;
|
||||
hdr.instance_id = (merchant_slot == 0) ? inst->GetSerialNumber() : merchant_slot;
|
||||
hdr.unknown028 = 0;
|
||||
hdr.last_cast_time = ((item->RecastDelay > 1) ? 1212693140 : 0);
|
||||
hdr.last_cast_time = inst->GetRecastTimestamp();
|
||||
hdr.charges = (stackable ? (item->MaxCharges ? 1 : 0) : charges);
|
||||
hdr.inst_nodrop = inst->IsAttuned() ? 1 : 0;
|
||||
hdr.unknown044 = 0;
|
||||
|
||||
@ -5069,7 +5069,7 @@ namespace RoF2
|
||||
hdr.scaled_value = inst->IsScaling() ? inst->GetExp() / 100 : 0;
|
||||
hdr.instance_id = (merchant_slot == 0) ? inst->GetSerialNumber() : merchant_slot;
|
||||
hdr.unknown028 = 0;
|
||||
hdr.last_cast_time = ((item->RecastDelay > 1) ? 1212693140 : 0);
|
||||
hdr.last_cast_time = inst->GetRecastTimestamp();
|
||||
hdr.charges = (stackable ? (item->MaxCharges ? 1 : 0) : charges);
|
||||
hdr.inst_nodrop = inst->IsAttuned() ? 1 : 0;
|
||||
hdr.unknown044 = 0;
|
||||
|
||||
@ -1394,7 +1394,7 @@ struct Animation_Struct {
|
||||
/*04*/
|
||||
};
|
||||
|
||||
// solar: this is what causes the caster to animate and the target to
|
||||
// this is what causes the caster to animate and the target to
|
||||
// get the particle effects around them when a spell is cast
|
||||
// also causes a buff icon
|
||||
struct Action_Struct
|
||||
@ -1445,7 +1445,7 @@ struct ActionAlt_Struct
|
||||
/*56*/
|
||||
};
|
||||
|
||||
// solar: this is what prints the You have been struck. and the regular
|
||||
// this is what prints the You have been struck. and the regular
|
||||
// melee messages like You try to pierce, etc. It's basically the melee
|
||||
// and spell damage message
|
||||
struct CombatDamage_Struct
|
||||
@ -1997,7 +1997,7 @@ struct RandomReq_Struct {
|
||||
uint32 high;
|
||||
};
|
||||
|
||||
/* solar: 9/23/03 reply to /random command; struct from Zaphod */
|
||||
/* 9/23/03 reply to /random command */
|
||||
struct RandomReply_Struct {
|
||||
/* 00 */ uint32 low;
|
||||
/* 04 */ uint32 high;
|
||||
|
||||
@ -1425,7 +1425,7 @@ struct Animation_Struct {
|
||||
/*04*/
|
||||
};
|
||||
|
||||
// solar: this is what causes the caster to animate and the target to
|
||||
// this is what causes the caster to animate and the target to
|
||||
// get the particle effects around them when a spell is cast
|
||||
// also causes a buff icon
|
||||
struct Action_Struct
|
||||
@ -1476,7 +1476,7 @@ struct ActionAlt_Struct
|
||||
/*56*/
|
||||
};
|
||||
|
||||
// solar: this is what prints the You have been struck. and the regular
|
||||
// this is what prints the You have been struck. and the regular
|
||||
// melee messages like You try to pierce, etc. It's basically the melee
|
||||
// and spell damage message
|
||||
struct CombatDamage_Struct
|
||||
@ -2028,7 +2028,7 @@ struct RandomReq_Struct {
|
||||
uint32 high;
|
||||
};
|
||||
|
||||
/* solar: 9/23/03 reply to /random command; struct from Zaphod */
|
||||
/* 9/23/03 reply to /random command */
|
||||
struct RandomReply_Struct {
|
||||
/* 00 */ uint32 low;
|
||||
/* 04 */ uint32 high;
|
||||
|
||||
@ -3548,7 +3548,7 @@ namespace SoD
|
||||
hdr.scaled_value = inst->IsScaling() ? inst->GetExp() / 100 : 0;
|
||||
hdr.instance_id = (merchant_slot == 0) ? inst->GetSerialNumber() : merchant_slot;
|
||||
hdr.unknown028 = 0;
|
||||
hdr.last_cast_time = ((item->RecastDelay > 1) ? 1212693140 : 0);
|
||||
hdr.last_cast_time = inst->GetRecastTimestamp();
|
||||
hdr.charges = (stackable ? (item->MaxCharges ? 1 : 0) : charges);
|
||||
hdr.inst_nodrop = inst->IsAttuned() ? 1 : 0;
|
||||
hdr.unknown044 = 0;
|
||||
|
||||
@ -538,7 +538,7 @@ struct SpawnAppearance_Struct
|
||||
};
|
||||
|
||||
|
||||
// solar: this is used inside profile
|
||||
// this is used inside profile
|
||||
struct SpellBuff_Struct
|
||||
{
|
||||
/*000*/ uint8 slotid; //badly named... seems to be 2 for a real buff, 0 otherwise
|
||||
@ -1196,7 +1196,7 @@ struct Animation_Struct {
|
||||
/*04*/
|
||||
};
|
||||
|
||||
// solar: this is what causes the caster to animate and the target to
|
||||
// this is what causes the caster to animate and the target to
|
||||
// get the particle effects around them when a spell is cast
|
||||
// also causes a buff icon
|
||||
struct Action_Struct
|
||||
@ -1248,7 +1248,7 @@ struct ActionAlt_Struct // ActionAlt_Struct - Size: 56 bytes
|
||||
/*0056*/
|
||||
};
|
||||
|
||||
// solar: this is what prints the You have been struck. and the regular
|
||||
// this is what prints the You have been struck. and the regular
|
||||
// melee messages like You try to pierce, etc. It's basically the melee
|
||||
// and spell damage message
|
||||
struct CombatDamage_Struct
|
||||
@ -1791,7 +1791,7 @@ struct RandomReq_Struct {
|
||||
uint32 high;
|
||||
};
|
||||
|
||||
/* solar: 9/23/03 reply to /random command; struct from Zaphod */
|
||||
/* 9/23/03 reply to /random command */
|
||||
struct RandomReply_Struct {
|
||||
/* 00 */ uint32 low;
|
||||
/* 04 */ uint32 high;
|
||||
|
||||
@ -2872,7 +2872,7 @@ namespace SoF
|
||||
hdr.scaled_value = inst->IsScaling() ? inst->GetExp() / 100 : 0;
|
||||
hdr.instance_id = (merchant_slot == 0) ? inst->GetSerialNumber() : merchant_slot;
|
||||
hdr.unknown028 = 0;
|
||||
hdr.last_cast_time = ((item->RecastDelay > 1) ? 1212693140 : 0);
|
||||
hdr.last_cast_time = inst->GetRecastTimestamp();
|
||||
hdr.charges = (stackable ? (item->MaxCharges ? 1 : 0) : charges);
|
||||
hdr.inst_nodrop = inst->IsAttuned() ? 1 : 0;
|
||||
hdr.unknown044 = 0;
|
||||
|
||||
@ -515,7 +515,7 @@ struct SpawnAppearance_Struct
|
||||
};
|
||||
|
||||
|
||||
// solar: this is used inside profile
|
||||
// this is used inside profile
|
||||
struct SpellBuff_Struct
|
||||
{
|
||||
/*000*/ uint8 slotid; //badly named... seems to be 2 for a real buff, 0 otherwise
|
||||
@ -1172,7 +1172,7 @@ struct Animation_Struct {
|
||||
/*04*/
|
||||
};
|
||||
|
||||
// solar: this is what causes the caster to animate and the target to
|
||||
// this is what causes the caster to animate and the target to
|
||||
// get the particle effects around them when a spell is cast
|
||||
// also causes a buff icon
|
||||
struct Action_Struct
|
||||
@ -1224,7 +1224,7 @@ struct ActionAlt_Struct // ActionAlt_Struct - Size: 56 bytes
|
||||
/*0056*/
|
||||
};
|
||||
|
||||
// solar: this is what prints the You have been struck. and the regular
|
||||
// this is what prints the You have been struck. and the regular
|
||||
// melee messages like You try to pierce, etc. It's basically the melee
|
||||
// and spell damage message
|
||||
struct CombatDamage_Struct
|
||||
@ -1768,7 +1768,7 @@ struct RandomReq_Struct {
|
||||
uint32 high;
|
||||
};
|
||||
|
||||
/* solar: 9/23/03 reply to /random command; struct from Zaphod */
|
||||
/* 9/23/03 reply to /random command */
|
||||
struct RandomReply_Struct {
|
||||
/* 00 */ uint32 low;
|
||||
/* 04 */ uint32 high;
|
||||
|
||||
@ -2004,7 +2004,7 @@ namespace Titanium
|
||||
inst->IsScaling() ? inst->GetExp() / 100 : 0,
|
||||
//merchant_slot, //instance ID, bullshit for now
|
||||
(merchant_slot == 0) ? inst->GetSerialNumber() : merchant_slot,
|
||||
0, // item recast timer timestamp field (aka..last_cast_time field in SoF+ clients)
|
||||
inst->GetRecastTimestamp(),
|
||||
(stackable ? ((inst->GetItem()->ItemType == ItemTypePotion) ? 1 : 0) : charges),
|
||||
inst->IsAttuned() ? 1 : 0,
|
||||
0
|
||||
|
||||
@ -438,7 +438,7 @@ struct SpawnAppearance_Struct
|
||||
};
|
||||
|
||||
|
||||
// solar: this is used inside profile
|
||||
// this is used inside profile
|
||||
struct SpellBuff_Struct
|
||||
{
|
||||
/*000*/ uint8 slotid; //badly named... seems to be 2 for a real buff, 0 otherwise
|
||||
@ -1054,7 +1054,7 @@ struct Animation_Struct {
|
||||
/*04*/
|
||||
};
|
||||
|
||||
// solar: this is what causes the caster to animate and the target to
|
||||
// this is what causes the caster to animate and the target to
|
||||
// get the particle effects around them when a spell is cast
|
||||
// also causes a buff icon
|
||||
struct Action_Struct
|
||||
@ -1078,7 +1078,7 @@ struct Action_Struct
|
||||
/* 31 */
|
||||
};
|
||||
|
||||
// solar: this is what prints the You have been struck. and the regular
|
||||
// this is what prints the You have been struck. and the regular
|
||||
// melee messages like You try to pierce, etc. It's basically the melee
|
||||
// and spell damage message
|
||||
struct CombatDamage_Struct
|
||||
@ -1516,7 +1516,7 @@ struct RandomReq_Struct {
|
||||
uint32 high;
|
||||
};
|
||||
|
||||
/* solar: 9/23/03 reply to /random command; struct from Zaphod */
|
||||
/* 9/23/03 reply to /random command */
|
||||
struct RandomReply_Struct {
|
||||
/* 00 */ uint32 low;
|
||||
/* 04 */ uint32 high;
|
||||
|
||||
@ -3793,7 +3793,7 @@ namespace UF
|
||||
hdr.scaled_value = inst->IsScaling() ? inst->GetExp() / 100 : 0;
|
||||
hdr.instance_id = (merchant_slot == 0) ? inst->GetSerialNumber() : merchant_slot;
|
||||
hdr.unknown028 = 0;
|
||||
hdr.last_cast_time = ((item->RecastDelay > 1) ? 1212693140 : 0);
|
||||
hdr.last_cast_time = inst->GetRecastTimestamp();
|
||||
hdr.charges = (stackable ? (item->MaxCharges ? 1 : 0) : charges);
|
||||
hdr.inst_nodrop = inst->IsAttuned() ? 1 : 0;
|
||||
hdr.unknown044 = 0;
|
||||
|
||||
@ -1250,7 +1250,7 @@ struct Animation_Struct {
|
||||
/*04*/
|
||||
};
|
||||
|
||||
// solar: this is what causes the caster to animate and the target to
|
||||
// this is what causes the caster to animate and the target to
|
||||
// get the particle effects around them when a spell is cast
|
||||
// also causes a buff icon
|
||||
struct Action_Struct
|
||||
@ -1305,7 +1305,7 @@ struct ActionAlt_Struct
|
||||
/*64*/
|
||||
};
|
||||
|
||||
// solar: this is what prints the You have been struck. and the regular
|
||||
// this is what prints the You have been struck. and the regular
|
||||
// melee messages like You try to pierce, etc. It's basically the melee
|
||||
// and spell damage message
|
||||
struct CombatDamage_Struct
|
||||
@ -1849,7 +1849,7 @@ struct RandomReq_Struct {
|
||||
uint32 high;
|
||||
};
|
||||
|
||||
/* solar: 9/23/03 reply to /random command; struct from Zaphod */
|
||||
/* 9/23/03 reply to /random command */
|
||||
struct RandomReply_Struct {
|
||||
/* 00 */ uint32 low;
|
||||
/* 04 */ uint32 high;
|
||||
|
||||
@ -79,6 +79,7 @@ public:
|
||||
inline const uint32 GetTimerTime() const { return timer_time; }
|
||||
inline const uint32 GetStartTime() const { return start_time; }
|
||||
inline const pTimerType GetType() const { return _type; }
|
||||
inline const uint32 GetReadyTimestamp() const { return start_time + timer_time; }
|
||||
|
||||
inline bool Enabled() { return enabled; }
|
||||
|
||||
|
||||
@ -438,30 +438,29 @@ bool SharedDatabase::GetSharedBank(uint32 id, Inventory *inv, bool is_charid)
|
||||
}
|
||||
}
|
||||
|
||||
if (!row[9])
|
||||
continue;
|
||||
if (row[9]) {
|
||||
std::string data_str(row[9]);
|
||||
std::string idAsString;
|
||||
std::string value;
|
||||
bool use_id = true;
|
||||
|
||||
std::string data_str(row[9]);
|
||||
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();
|
||||
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;
|
||||
}
|
||||
use_id = !use_id;
|
||||
continue;
|
||||
}
|
||||
|
||||
char v = data_str[i];
|
||||
if (use_id)
|
||||
idAsString.push_back(v);
|
||||
else
|
||||
value.push_back(v);
|
||||
char v = data_str[i];
|
||||
if (use_id)
|
||||
idAsString.push_back(v);
|
||||
else
|
||||
value.push_back(v);
|
||||
}
|
||||
}
|
||||
|
||||
put_slot_id = inv->PutItem(slot_id, *inst);
|
||||
@ -499,6 +498,8 @@ bool SharedDatabase::GetInventory(uint32 char_id, Inventory *inv)
|
||||
return false;
|
||||
}
|
||||
|
||||
auto timestamps = GetItemRecastTimestamps(char_id);
|
||||
|
||||
for (auto row = results.begin(); row != results.end(); ++row) {
|
||||
int16 slot_id = atoi(row[0]);
|
||||
uint32 item_id = atoi(row[1]);
|
||||
@ -583,6 +584,13 @@ bool SharedDatabase::GetInventory(uint32 char_id, Inventory *inv)
|
||||
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])
|
||||
@ -726,6 +734,39 @@ bool SharedDatabase::GetInventory(uint32 account_id, char *name, Inventory *inv)
|
||||
return GetSharedBank(account_id, inv, false);
|
||||
}
|
||||
|
||||
std::map<uint32, uint32> SharedDatabase::GetItemRecastTimestamps(uint32 char_id)
|
||||
{
|
||||
std::map<uint32, uint32> timers;
|
||||
std::string query = StringFormat("SELECT recast_type,timestamp FROM character_item_recast WHERE id=%u", char_id);
|
||||
auto results = QueryDatabase(query);
|
||||
if (!results.Success() || results.RowCount() == 0)
|
||||
return timers;
|
||||
|
||||
for (auto row = results.begin(); row != results.end(); ++row)
|
||||
timers[atoul(row[0])] = atoul(row[1]);
|
||||
return timers; // RVO or move assigned
|
||||
}
|
||||
|
||||
uint32 SharedDatabase::GetItemRecastTimestamp(uint32 char_id, uint32 recast_type)
|
||||
{
|
||||
std::string query = StringFormat("SELECT timestamp FROM character_item_recast WHERE id=%u AND recast_type=%u",
|
||||
char_id, recast_type);
|
||||
auto results = QueryDatabase(query);
|
||||
if (!results.Success() || results.RowCount() == 0)
|
||||
return 0;
|
||||
|
||||
auto row = results.begin();
|
||||
return static_cast<uint32>(atoul(row[0]));
|
||||
}
|
||||
|
||||
void SharedDatabase::ClearOldRecastTimestamps(uint32 char_id)
|
||||
{
|
||||
// This actually isn't strictly live-like. Live your recast timestamps are forever
|
||||
std::string query =
|
||||
StringFormat("DELETE FROM character_item_recast WHERE id = %u and timestamp < UNIX_TIMESTAMP()", char_id);
|
||||
QueryDatabase(query);
|
||||
}
|
||||
|
||||
void SharedDatabase::GetItemsCount(int32 &item_count, uint32 &max_id)
|
||||
{
|
||||
item_count = -1;
|
||||
|
||||
@ -11,6 +11,7 @@
|
||||
#include "fixed_memory_variable_hash_set.h"
|
||||
|
||||
#include <list>
|
||||
#include <map>
|
||||
|
||||
class EvolveInfo;
|
||||
class Inventory;
|
||||
@ -69,6 +70,9 @@ class SharedDatabase : public Database
|
||||
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);
|
||||
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);
|
||||
|
||||
|
||||
|
||||
@ -19,7 +19,7 @@
|
||||
|
||||
/*
|
||||
|
||||
solar: General outline of spell casting process
|
||||
General outline of spell casting process
|
||||
|
||||
1.
|
||||
a) Client clicks a spell bar gem, ability, or item. client_process.cpp
|
||||
|
||||
@ -618,7 +618,7 @@ typedef enum {
|
||||
|
||||
#define DF_Permanent 50
|
||||
|
||||
// solar: note this struct is historical, we don't actually need it to be
|
||||
// note this struct is historical, we don't actually need it to be
|
||||
// aligned to anything, but for maintaining it it is kept in the order that
|
||||
// the fields in the text file are. the numbering is not offset, but field
|
||||
// number. note that the id field is counted as 0, this way the numbers
|
||||
|
||||
@ -255,7 +255,7 @@ bool atobool(const char* iBool) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// solar: removes the crap and turns the underscores into spaces.
|
||||
// removes the crap and turns the underscores into spaces.
|
||||
char *CleanMobName(const char *in, char *out)
|
||||
{
|
||||
unsigned i, j;
|
||||
@ -414,4 +414,4 @@ void find_replace(std::string& string_subject, std::string& search_string, std::
|
||||
string_subject.replace(index, index + 1, replace_string);
|
||||
index = string_subject.find_first_of(search_string);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -30,7 +30,7 @@
|
||||
Manifest: https://github.com/EQEmu/Server/blob/master/utils/sql/db_update_manifest.txt
|
||||
*/
|
||||
|
||||
#define CURRENT_BINARY_DATABASE_VERSION 9072
|
||||
#define CURRENT_BINARY_DATABASE_VERSION 9073
|
||||
#define COMPILE_DATE __DATE__
|
||||
#define COMPILE_TIME __TIME__
|
||||
#ifndef WIN32
|
||||
|
||||
@ -326,6 +326,7 @@
|
||||
9070|2015_01_28_quest_debug_log_category.sql|SELECT * FROM `logsys_categories` WHERE `log_category_description` LIKE 'Quest Debug'|empty|
|
||||
9071|2015_01_29_merc_stats_table_update.sql|SHOW COLUMNS FROM `merc_stats` LIKE 'statscale'|empty|
|
||||
9072|2015_01_30_merc_attack_delay.sql|SHOW COLUMNS FROM `merc_stats` LIKE 'attack_delay'|empty|
|
||||
9073|2015_01_31_character_item_recast.sql|SHOW TABLES LIKE 'character_item_recast'|empty|
|
||||
|
||||
# Upgrade conditions:
|
||||
# This won't be needed after this system is implemented, but it is used database that are not
|
||||
|
||||
@ -1 +1 @@
|
||||
INSERT INTO `logsys_categories` (`log_category_id`, `log_category_description`, `log_to_gmsay`) VALUES ('38', 'Quest Debug', '1')
|
||||
INSERT INTO `logsys_categories` (`log_category_id`, `log_category_description`, `log_to_gmsay`) VALUES ('38', 'Quest Debug', '1');
|
||||
|
||||
@ -0,0 +1,7 @@
|
||||
CREATE TABLE `character_item_recast` (
|
||||
`id` int(11) UNSIGNED NOT NULL DEFAULT 0,
|
||||
`recast_type` smallint(11) UNSIGNED NOT NULL DEFAULT 0,
|
||||
`timestamp` int(11) UNSIGNED NOT NULL DEFAULT 0,
|
||||
PRIMARY KEY(`id`, `recast_type`),
|
||||
KEY `id` (`id`)
|
||||
) ENGINE = InnoDB DEFAULT CHARSET = latin1;
|
||||
@ -1616,7 +1616,7 @@ bool CheckCharCreateInfoTitanium(CharCreate_Struct *cc)
|
||||
int Charerrors = 0;
|
||||
|
||||
|
||||
// solar: if this is increased you'll have to add a column to the classrace
|
||||
// if this is increased you'll have to add a column to the classrace
|
||||
// table below
|
||||
#define _TABLE_RACES 16
|
||||
|
||||
@ -1678,7 +1678,7 @@ bool CheckCharCreateInfoTitanium(CharCreate_Struct *cc)
|
||||
{ /*Enchanter*/ true, false, true, false, true, true, false, false, false, false, false, true, false, false, false, true},
|
||||
{ /*Beastlord*/ false, true, false, false, false, false, false, false, true, true, false, false, true, true, false, false},
|
||||
{ /*Berserker*/ false, true, false, false, false, false, false, true, true, true, false, false, false, true, false, false}
|
||||
};//Initial table by kathgar, editted by Wiz for accuracy, solar too
|
||||
};
|
||||
|
||||
if (!cc)
|
||||
return false;
|
||||
@ -1711,7 +1711,7 @@ bool CheckCharCreateInfoTitanium(CharCreate_Struct *cc)
|
||||
return false;
|
||||
}
|
||||
|
||||
// solar: add up the base values for this class/race
|
||||
// add up the base values for this class/race
|
||||
// this is what they start with, and they have stat_points more
|
||||
// that can distributed
|
||||
bSTR = BaseClass[classtemp][0] + BaseRace[racetemp][0];
|
||||
@ -1725,7 +1725,7 @@ bool CheckCharCreateInfoTitanium(CharCreate_Struct *cc)
|
||||
bTOTAL = bSTR + bSTA + bAGI + bDEX + bWIS + bINT + bCHA;
|
||||
cTOTAL = cc->STR + cc->STA + cc->AGI + cc->DEX + cc->WIS + cc->INT + cc->CHA;
|
||||
|
||||
// solar: the first check makes sure the total is exactly what was expected.
|
||||
// the first check makes sure the total is exactly what was expected.
|
||||
// this will catch all the stat cheating, but there's still the issue
|
||||
// of reducing CHA or INT or something, to use for STR, so we check
|
||||
// that none are lower than the base or higher than base + stat_points
|
||||
|
||||
@ -32,7 +32,7 @@ extern std::vector<RaceClassAllocation> character_create_allocations;
|
||||
extern std::vector<RaceClassCombos> character_create_race_class_combos;
|
||||
|
||||
|
||||
// solar: the current stuff is at the bottom of this function
|
||||
// the current stuff is at the bottom of this function
|
||||
void WorldDatabase::GetCharSelectInfo(uint32 account_id, CharacterSelect_Struct* cs, uint32 ClientVersion) {
|
||||
Inventory *inv;
|
||||
uint8 has_home = 0;
|
||||
|
||||
@ -665,7 +665,7 @@ bool ZoneServer::Process() {
|
||||
}
|
||||
case ServerOP_ZoneToZoneRequest: {
|
||||
//
|
||||
// solar: ZoneChange is received by the zone the player is in, then the
|
||||
// ZoneChange is received by the zone the player is in, then the
|
||||
// zone sends a ZTZ which ends up here. This code then find the target
|
||||
// (ingress point) and boots it if needed, then sends the ZTZ to it.
|
||||
// The ingress server will decide wether the player can enter, then will
|
||||
|
||||
@ -481,7 +481,7 @@ void EntityList::AIYellForHelp(Mob* sender, Mob* attacker) {
|
||||
}
|
||||
|
||||
/*
|
||||
solar: returns false if attack should not be allowed
|
||||
returns false if attack should not be allowed
|
||||
I try to list every type of conflict that's possible here, so it's easy
|
||||
to see how the decision is made. Yea, it could be condensed and made
|
||||
faster, but I'm doing it this way to make it readable and easy to modify
|
||||
@ -550,7 +550,7 @@ bool Mob::IsAttackAllowed(Mob *target, bool isSpellAttack)
|
||||
}
|
||||
}
|
||||
|
||||
// solar: the format here is a matrix of mob type vs mob type.
|
||||
// the format here is a matrix of mob type vs mob type.
|
||||
// redundant ones are omitted and the reverse is tried if it falls through.
|
||||
|
||||
// first figure out if we're pets. we always look at the master's flags.
|
||||
@ -701,7 +701,7 @@ type', in which case, the answer is yes.
|
||||
}
|
||||
|
||||
|
||||
// solar: this is to check if non detrimental things are allowed to be done
|
||||
// this is to check if non detrimental things are allowed to be done
|
||||
// to the target. clients cannot affect npcs and vice versa, and clients
|
||||
// cannot affect other clients that are not of the same pvp flag as them.
|
||||
// also goes for their pets
|
||||
@ -717,7 +717,7 @@ bool Mob::IsBeneficialAllowed(Mob *target)
|
||||
if (target->GetAllowBeneficial())
|
||||
return true;
|
||||
|
||||
// solar: see IsAttackAllowed for notes
|
||||
// see IsAttackAllowed for notes
|
||||
|
||||
// first figure out if we're pets. we always look at the master's flags.
|
||||
// no need to compare pets to anything
|
||||
|
||||
@ -343,7 +343,7 @@ bool Mob::CheckHitChance(Mob* other, SkillUseTypes skillinuse, int Hand, int16 c
|
||||
|
||||
bool Mob::AvoidDamage(Mob* other, int32 &damage, bool CanRiposte)
|
||||
{
|
||||
/* solar: called when a mob is attacked, does the checks to see if it's a hit
|
||||
/* called when a mob is attacked, does the checks to see if it's a hit
|
||||
* and does other mitigation checks. 'this' is the mob being attacked.
|
||||
*
|
||||
* special return values:
|
||||
@ -1378,7 +1378,7 @@ void Client::Damage(Mob* other, int32 damage, uint16 spell_id, SkillUseTypes att
|
||||
if(spell_id==0)
|
||||
spell_id = SPELL_UNKNOWN;
|
||||
|
||||
// cut all PVP spell damage to 2/3 -solar
|
||||
// cut all PVP spell damage to 2/3
|
||||
// Blasting ourselfs is considered PvP
|
||||
//Don't do PvP mitigation if the caster is damaging himself
|
||||
if(other && other->IsClient() && (other != this) && damage > 0) {
|
||||
@ -2545,7 +2545,7 @@ void Mob::AddToHateList(Mob* other, uint32 hate /*= 0*/, int32 damage /*= 0*/, b
|
||||
}
|
||||
}
|
||||
|
||||
// solar: this is called from Damage() when 'this' is attacked by 'other.
|
||||
// this is called from Damage() when 'this' is attacked by 'other.
|
||||
// 'this' is the one being attacked
|
||||
// 'other' is the attacker
|
||||
// a damage shield causes damage (or healing) to whoever attacks the wearer
|
||||
|
||||
@ -18,7 +18,7 @@
|
||||
|
||||
/*
|
||||
|
||||
solar: Beacon class, extends Mob. Used for AE rain spells to have a mob
|
||||
Beacon class, extends Mob. Used for AE rain spells to have a mob
|
||||
target to center around.
|
||||
|
||||
*/
|
||||
@ -48,7 +48,7 @@ class Zone;
|
||||
extern EntityList entity_list;
|
||||
extern Zone* zone;
|
||||
|
||||
// solar: if lifetime is 0 this is a permanent beacon.. not sure if that'll be
|
||||
// if lifetime is 0 this is a permanent beacon.. not sure if that'll be
|
||||
// useful for anything
|
||||
Beacon::Beacon(Mob *at_mob, int lifetime)
|
||||
:Mob
|
||||
|
||||
@ -7406,7 +7406,7 @@ float Bot::GetProcChances(float ProcBonus, uint16 hand) {
|
||||
|
||||
bool Bot::AvoidDamage(Mob* other, int32 &damage, bool CanRiposte)
|
||||
{
|
||||
/* solar: called when a mob is attacked, does the checks to see if it's a hit
|
||||
/* called when a mob is attacked, does the checks to see if it's a hit
|
||||
* and does other mitigation checks. 'this' is the mob being attacked.
|
||||
*
|
||||
* special return values:
|
||||
@ -7781,7 +7781,7 @@ void Bot::TryBackstab(Mob *other, int ReuseTime) {
|
||||
|
||||
if (bIsBehind || bCanFrontalBS){ // Bot is behind other OR can do Frontal Backstab
|
||||
|
||||
// solar - chance to assassinate
|
||||
// chance to assassinate
|
||||
int chance = 10 + (GetDEX()/10) + (itembonuses.HeroicDEX/10); //18.5% chance at 85 dex 40% chance at 300 dex
|
||||
if(
|
||||
level >= 60 && // bot is 60 or higher
|
||||
|
||||
@ -416,15 +416,6 @@ int Client::HandlePacket(const EQApplicationPacket *app)
|
||||
std::cout << "Received 0x" << std::hex << std::setw(4) << std::setfill('0') << opcode << ", size=" << std::dec << app->size << std::endl;
|
||||
#endif
|
||||
|
||||
#ifdef SOLAR
|
||||
if(0 && opcode != OP_ClientUpdate)
|
||||
{
|
||||
Log.LogDebug(Logs::General,"HandlePacket() OPCODE debug enabled client %s", GetName());
|
||||
std::cerr << "OPCODE: " << std::hex << std::setw(4) << std::setfill('0') << opcode << std::dec << ", size: " << app->size << std::endl;
|
||||
DumpPacket(app);
|
||||
}
|
||||
#endif
|
||||
|
||||
switch(client_state) {
|
||||
case CLIENT_CONNECTING: {
|
||||
if(ConnectingOpcodes.count(opcode) != 1) {
|
||||
@ -1395,6 +1386,7 @@ void Client::Handle_Connect_OP_ZoneEntry(const EQApplicationPacket *app)
|
||||
if (RuleB(Character, SharedBankPlat))
|
||||
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 */
|
||||
|
||||
@ -960,6 +960,9 @@ void Client::BulkSendInventoryItems()
|
||||
void Client::BulkSendMerchantInventory(int merchant_id, int npcid) {
|
||||
const Item_Struct* handyitem = nullptr;
|
||||
uint32 numItemSlots = 80; //The max number of items passed in the transaction.
|
||||
if (ClientVersionBit & BIT_RoFAndLater) { // RoF+ can send 200 items
|
||||
numItemSlots = 200;
|
||||
}
|
||||
const Item_Struct *item;
|
||||
std::list<MerchantList> merlist = zone->merchanttable[merchant_id];
|
||||
std::list<MerchantList>::const_iterator itr;
|
||||
|
||||
@ -7,7 +7,7 @@
|
||||
#define HIGHEST_RESIST 9 //Max resist type value
|
||||
#define MAX_SPELL_PROJECTILE 10 //Max amount of spell projectiles that can be active by a single mob.
|
||||
|
||||
/* solar: macros for IsAttackAllowed, IsBeneficialAllowed */
|
||||
/* macros for IsAttackAllowed, IsBeneficialAllowed */
|
||||
#define _CLIENT(x) (x && x->IsClient() && !x->CastToClient()->IsBecomeNPC())
|
||||
#define _NPC(x) (x && x->IsNPC() && !x->CastToMob()->GetOwnerID())
|
||||
#define _BECOMENPC(x) (x && x->IsClient() && x->CastToClient()->IsBecomeNPC())
|
||||
|
||||
@ -318,7 +318,7 @@ Corpse::Corpse(Client* client, int32 in_rezexp) : Mob (
|
||||
// get their tints
|
||||
memcpy(item_tint, &client->GetPP().item_tint, sizeof(item_tint));
|
||||
|
||||
// solar: TODO soulbound items need not be added to corpse, but they need
|
||||
// TODO soulbound items need not be added to corpse, but they need
|
||||
// to go into the regular slots on the player, out of bags
|
||||
std::list<uint32> removed_list;
|
||||
|
||||
@ -965,6 +965,7 @@ void Corpse::MakeLootRequestPackets(Client* client, const EQApplicationPacket* a
|
||||
Save();
|
||||
}
|
||||
|
||||
auto timestamps = database.GetItemRecastTimestamps(client->CharacterID());
|
||||
outapp->priority = 6;
|
||||
client->QueuePacket(outapp);
|
||||
safe_delete(outapp);
|
||||
@ -973,6 +974,8 @@ void Corpse::MakeLootRequestPackets(Client* client, const EQApplicationPacket* a
|
||||
const Item_Struct* item = database.GetItem(pkitem);
|
||||
ItemInst* inst = database.CreateItem(item, item->MaxCharges);
|
||||
if(inst) {
|
||||
if (item->RecastDelay)
|
||||
inst->SetRecastTimestamp(timestamps.count(item->RecastType) ? timestamps.at(item->RecastType) : 0);
|
||||
client->SendItemPacket(EmuConstants::CORPSE_BEGIN, inst, ItemPacketLoot);
|
||||
safe_delete(inst);
|
||||
}
|
||||
@ -1004,6 +1007,8 @@ void Corpse::MakeLootRequestPackets(Client* client, const EQApplicationPacket* a
|
||||
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);
|
||||
if(inst) {
|
||||
if (item->RecastDelay)
|
||||
inst->SetRecastTimestamp(timestamps.count(item->RecastType) ? timestamps.at(item->RecastType) : 0);
|
||||
// MainGeneral1 is the corpse inventory start offset for Ti(EMu) - CORPSE_END = MainGeneral1 + MainCursor
|
||||
client->SendItemPacket(i + EmuConstants::CORPSE_BEGIN, inst, ItemPacketLoot);
|
||||
safe_delete(inst);
|
||||
@ -1460,4 +1465,4 @@ void Corpse::LoadPlayerCorpseDecayTime(uint32 corpse_db_id){
|
||||
else {
|
||||
corpse_graveyard_timer.SetTimer(3000);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -684,7 +684,7 @@ void EntityList::AETaunt(Client* taunter, float range)
|
||||
}
|
||||
}
|
||||
|
||||
// solar: causes caster to hit every mob within dist range of center with
|
||||
// causes caster to hit every mob within dist range of center with
|
||||
// spell_id.
|
||||
// NPC spells will only affect other NPCs with compatible faction
|
||||
void EntityList::AESpell(Mob *caster, Mob *center, uint16 spell_id, bool affect_caster, int16 resist_adjust)
|
||||
@ -820,7 +820,7 @@ void EntityList::MassGroupBuff(Mob *caster, Mob *center, uint16 spell_id, bool a
|
||||
}
|
||||
}
|
||||
|
||||
// solar: causes caster to hit every mob within dist range of center with
|
||||
// causes caster to hit every mob within dist range of center with
|
||||
// a bard pulse of spell_id.
|
||||
// NPC spells will only affect other NPCs with compatible faction
|
||||
void EntityList::AEBardPulse(Mob *caster, Mob *center, uint16 spell_id, bool affect_caster)
|
||||
|
||||
@ -879,7 +879,7 @@ void Client::PutLootInInventory(int16 slot_id, const ItemInst &inst, ServerLootI
|
||||
|
||||
if(bag_item_data) { // bag contents
|
||||
int16 interior_slot;
|
||||
// solar: our bag went into slot_id, now let's pack the contents in
|
||||
// our bag went into slot_id, now let's pack the contents in
|
||||
for(int i = SUB_BEGIN; i < EmuConstants::ITEM_CONTAINER_SIZE; i++) {
|
||||
if(bag_item_data[i] == nullptr)
|
||||
continue;
|
||||
@ -993,7 +993,7 @@ bool Client::AutoPutLootInInventory(ItemInst& inst, bool try_worn, bool try_curs
|
||||
return false;
|
||||
}
|
||||
|
||||
// solar: helper function for AutoPutLootInInventory
|
||||
// helper function for AutoPutLootInInventory
|
||||
void Client::MoveItemCharges(ItemInst &from, int16 to_slot, uint8 type)
|
||||
{
|
||||
ItemInst *tmp_inst = m_inv.GetItem(to_slot);
|
||||
|
||||
@ -35,14 +35,13 @@
|
||||
#include "zone.h"
|
||||
#include "lua_parser.h"
|
||||
|
||||
const char *LuaEvents[_LargestEventID] = {
|
||||
const char *LuaEvents[_LargestEventID] = {
|
||||
"event_say",
|
||||
"event_trade",
|
||||
"event_death",
|
||||
"event_spawn",
|
||||
"event_attack",
|
||||
"event_combat",
|
||||
"event_environmental_damage",
|
||||
"event_aggro",
|
||||
"event_slay",
|
||||
"event_npc_slay",
|
||||
@ -68,6 +67,7 @@ const char *LuaEvents[_LargestEventID] = {
|
||||
"event_aggro_say",
|
||||
"event_player_pickup",
|
||||
"event_popup_response",
|
||||
"event_environmental_damage",
|
||||
"event_proximity_say",
|
||||
"event_cast",
|
||||
"event_cast_begin",
|
||||
|
||||
10
zone/mob.cpp
10
zone/mob.cpp
@ -2792,7 +2792,7 @@ void Mob::Say(const char *format, ...)
|
||||
}
|
||||
|
||||
//
|
||||
// solar: this is like the above, but the first parameter is a string id
|
||||
// this is like the above, but the first parameter is a string id
|
||||
//
|
||||
void Mob::Say_StringID(uint32 string_id, const char *message3, const char *message4, const char *message5, const char *message6, const char *message7, const char *message8, const char *message9)
|
||||
{
|
||||
@ -3092,8 +3092,8 @@ float Mob::FindGroundZ(float new_x, float new_y, float z_offset)
|
||||
if (zone->zonemap != nullptr)
|
||||
{
|
||||
glm::vec3 me;
|
||||
me.x = m_Position.x;
|
||||
me.y = m_Position.y;
|
||||
me.x = new_x;
|
||||
me.y = new_y;
|
||||
me.z = m_Position.z + z_offset;
|
||||
glm::vec3 hit;
|
||||
float best_z = zone->zonemap->FindBestZ(me, &hit);
|
||||
@ -3112,8 +3112,8 @@ float Mob::GetGroundZ(float new_x, float new_y, float z_offset)
|
||||
if (zone->zonemap != 0)
|
||||
{
|
||||
glm::vec3 me;
|
||||
me.x = m_Position.x;
|
||||
me.y = m_Position.y;
|
||||
me.x = new_x;
|
||||
me.y = new_y;
|
||||
me.z = m_Position.z+z_offset;
|
||||
glm::vec3 hit;
|
||||
float best_z = zone->zonemap->FindBestZ(me, &hit);
|
||||
|
||||
@ -123,7 +123,7 @@ public:
|
||||
|
||||
//Attack
|
||||
virtual void RogueBackstab(Mob* other, bool min_damage = false, int ReuseTime = 10);
|
||||
virtual void RogueAssassinate(Mob* other); // solar
|
||||
virtual void RogueAssassinate(Mob* other);
|
||||
float MobAngle(Mob *other = 0, float ourx = 0.0f, float oury = 0.0f) const;
|
||||
// greater than 90 is behind
|
||||
inline bool BehindMob(Mob *other = 0, float ourx = 0.0f, float oury = 0.0f) const
|
||||
|
||||
337
zone/npc.cpp
337
zone/npc.cpp
@ -987,298 +987,267 @@ NPC* NPC::SpawnNPC(const char* spawncommand, const glm::vec4& position, Client*
|
||||
}
|
||||
}
|
||||
|
||||
uint32 ZoneDatabase::CreateNewNPCCommand(const char* zone, uint32 zone_version,Client *client, NPC* spawn, uint32 extra) {
|
||||
uint32 ZoneDatabase::CreateNewNPCCommand(const char *zone, uint32 zone_version, Client *client, NPC *spawn,
|
||||
uint32 extra)
|
||||
{
|
||||
uint32 npc_type_id = 0;
|
||||
|
||||
uint32 npc_type_id = 0;
|
||||
|
||||
if (extra && client && client->GetZoneID())
|
||||
{
|
||||
if (extra && client && client->GetZoneID()) {
|
||||
// Set an npc_type ID within the standard range for the current zone if possible (zone_id * 1000)
|
||||
int starting_npc_id = client->GetZoneID() * 1000;
|
||||
|
||||
std::string query = StringFormat("SELECT MAX(id) FROM npc_types WHERE id >= %i AND id < %i",
|
||||
starting_npc_id, starting_npc_id + 1000);
|
||||
auto results = QueryDatabase(query);
|
||||
starting_npc_id, starting_npc_id + 1000);
|
||||
auto results = QueryDatabase(query);
|
||||
if (results.Success()) {
|
||||
if (results.RowCount() != 0)
|
||||
{
|
||||
auto row = results.begin();
|
||||
npc_type_id = atoi(row[0]) + 1;
|
||||
// Prevent the npc_type id from exceeding the range for this zone
|
||||
if (npc_type_id >= (starting_npc_id + 1000))
|
||||
npc_type_id = 0;
|
||||
}
|
||||
else // No npc_type IDs set in this range yet
|
||||
npc_type_id = starting_npc_id;
|
||||
}
|
||||
}
|
||||
if (results.RowCount() != 0) {
|
||||
auto row = results.begin();
|
||||
npc_type_id = atoi(row[0]) + 1;
|
||||
// Prevent the npc_type id from exceeding the range for this zone
|
||||
if (npc_type_id >= (starting_npc_id + 1000))
|
||||
npc_type_id = 0;
|
||||
} else // No npc_type IDs set in this range yet
|
||||
npc_type_id = starting_npc_id;
|
||||
}
|
||||
}
|
||||
|
||||
char tmpstr[64];
|
||||
EntityList::RemoveNumbers(strn0cpy(tmpstr, spawn->GetName(), sizeof(tmpstr)));
|
||||
std::string query;
|
||||
if (npc_type_id)
|
||||
{
|
||||
query = StringFormat("INSERT INTO npc_types (id, name, level, race, class, hp, gender, "
|
||||
"texture, helmtexture, size, loottable_id, merchant_id, face, "
|
||||
"runspeed, prim_melee_type, sec_melee_type) "
|
||||
"VALUES(%i, \"%s\" , %i, %i, %i, %i, %i, %i, %i, %f, %i, %i, %i, %f, %i, %i)",
|
||||
npc_type_id, tmpstr, spawn->GetLevel(), spawn->GetRace(), spawn->GetClass(),
|
||||
spawn->GetMaxHP(), spawn->GetGender(), spawn->GetTexture(),
|
||||
spawn->GetHelmTexture(), spawn->GetSize(), spawn->GetLoottableID(),
|
||||
spawn->MerchantType, 0, spawn->GetRunspeed(), 28, 28);
|
||||
auto results = QueryDatabase(query);
|
||||
if (npc_type_id) {
|
||||
query = StringFormat("INSERT INTO npc_types (id, name, level, race, class, hp, gender, "
|
||||
"texture, helmtexture, size, loottable_id, merchant_id, face, "
|
||||
"runspeed, prim_melee_type, sec_melee_type) "
|
||||
"VALUES(%i, \"%s\" , %i, %i, %i, %i, %i, %i, %i, %f, %i, %i, %i, %f, %i, %i)",
|
||||
npc_type_id, tmpstr, spawn->GetLevel(), spawn->GetRace(), spawn->GetClass(),
|
||||
spawn->GetMaxHP(), spawn->GetGender(), spawn->GetTexture(),
|
||||
spawn->GetHelmTexture(), spawn->GetSize(), spawn->GetLoottableID(),
|
||||
spawn->MerchantType, 0, spawn->GetRunspeed(), 28, 28);
|
||||
auto results = QueryDatabase(query);
|
||||
if (!results.Success()) {
|
||||
return false;
|
||||
}
|
||||
npc_type_id = results.LastInsertedID();
|
||||
} else {
|
||||
query = StringFormat("INSERT INTO npc_types (name, level, race, class, hp, gender, "
|
||||
"texture, helmtexture, size, loottable_id, merchant_id, face, "
|
||||
"runspeed, prim_melee_type, sec_melee_type) "
|
||||
"VALUES(\"%s\", %i, %i, %i, %i, %i, %i, %i, %f, %i, %i, %i, %f, %i, %i)",
|
||||
tmpstr, spawn->GetLevel(), spawn->GetRace(), spawn->GetClass(), spawn->GetMaxHP(),
|
||||
spawn->GetGender(), spawn->GetTexture(), spawn->GetHelmTexture(), spawn->GetSize(),
|
||||
spawn->GetLoottableID(), spawn->MerchantType, 0, spawn->GetRunspeed(), 28, 28);
|
||||
auto results = QueryDatabase(query);
|
||||
if (!results.Success()) {
|
||||
return false;
|
||||
}
|
||||
npc_type_id = results.LastInsertedID();
|
||||
}
|
||||
else
|
||||
{
|
||||
query = StringFormat("INSERT INTO npc_types (name, level, race, class, hp, gender, "
|
||||
"texture, helmtexture, size, loottable_id, merchant_id, face, "
|
||||
"runspeed, prim_melee_type, sec_melee_type) "
|
||||
"VALUES(\"%s\", %i, %i, %i, %i, %i, %i, %i, %f, %i, %i, %i, %f, %i, %i)",
|
||||
tmpstr, spawn->GetLevel(), spawn->GetRace(), spawn->GetClass(),
|
||||
spawn->GetMaxHP(), spawn->GetGender(), spawn->GetTexture(),
|
||||
spawn->GetHelmTexture(), spawn->GetSize(), spawn->GetLoottableID(),
|
||||
spawn->MerchantType, 0, spawn->GetRunspeed(), 28, 28);
|
||||
auto results = QueryDatabase(query);
|
||||
if (!results.Success()) {
|
||||
return false;
|
||||
}
|
||||
npc_type_id = results.LastInsertedID();
|
||||
}
|
||||
|
||||
if(client)
|
||||
|
||||
query = StringFormat("INSERT INTO spawngroup (id, name) VALUES(%i, '%s-%s')", 0, zone, spawn->GetName());
|
||||
auto results = QueryDatabase(query);
|
||||
auto results = QueryDatabase(query);
|
||||
if (!results.Success()) {
|
||||
return false;
|
||||
}
|
||||
uint32 spawngroupid = results.LastInsertedID();
|
||||
uint32 spawngroupid = results.LastInsertedID();
|
||||
|
||||
if(client)
|
||||
|
||||
query = StringFormat("INSERT INTO spawn2 (zone, version, x, y, z, respawntime, heading, spawngroupID) "
|
||||
"VALUES('%s', %u, %f, %f, %f, %i, %f, %i)",
|
||||
zone, zone_version, spawn->GetX(), spawn->GetY(), spawn->GetZ(), 1200,
|
||||
spawn->GetHeading(), spawngroupid);
|
||||
results = QueryDatabase(query);
|
||||
query = StringFormat("INSERT INTO spawn2 (zone, version, x, y, z, respawntime, heading, spawngroupID) "
|
||||
"VALUES('%s', %u, %f, %f, %f, %i, %f, %i)",
|
||||
zone, zone_version, spawn->GetX(), spawn->GetY(), spawn->GetZ(), 1200, spawn->GetHeading(),
|
||||
spawngroupid);
|
||||
results = QueryDatabase(query);
|
||||
if (!results.Success()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if(client)
|
||||
|
||||
query = StringFormat("INSERT INTO spawnentry (spawngroupID, npcID, chance) VALUES(%i, %i, %i)",
|
||||
spawngroupid, npc_type_id, 100);
|
||||
results = QueryDatabase(query);
|
||||
query = StringFormat("INSERT INTO spawnentry (spawngroupID, npcID, chance) VALUES(%i, %i, %i)", spawngroupid,
|
||||
npc_type_id, 100);
|
||||
results = QueryDatabase(query);
|
||||
if (!results.Success()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if(client)
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
uint32 ZoneDatabase::AddNewNPCSpawnGroupCommand(const char* zone, uint32 zone_version, Client *client, NPC* spawn, uint32 respawnTime) {
|
||||
uint32 last_insert_id = 0;
|
||||
uint32 ZoneDatabase::AddNewNPCSpawnGroupCommand(const char *zone, uint32 zone_version, Client *client, NPC *spawn,
|
||||
uint32 respawnTime)
|
||||
{
|
||||
uint32 last_insert_id = 0;
|
||||
|
||||
std::string query = StringFormat("INSERT INTO spawngroup (name) VALUES('%s%s%i')",
|
||||
zone, spawn->GetName(), Timer::GetCurrentTime());
|
||||
auto results = QueryDatabase(query);
|
||||
std::string query = StringFormat("INSERT INTO spawngroup (name) VALUES('%s%s%i')", zone, spawn->GetName(),
|
||||
Timer::GetCurrentTime());
|
||||
auto results = QueryDatabase(query);
|
||||
if (!results.Success()) {
|
||||
return 0;
|
||||
}
|
||||
last_insert_id = results.LastInsertedID();
|
||||
last_insert_id = results.LastInsertedID();
|
||||
|
||||
uint32 respawntime = 0;
|
||||
uint32 spawnid = 0;
|
||||
if (respawnTime)
|
||||
respawntime = respawnTime;
|
||||
else if(spawn->respawn2 && spawn->respawn2->RespawnTimer() != 0)
|
||||
respawntime = spawn->respawn2->RespawnTimer();
|
||||
else
|
||||
respawntime = 1200;
|
||||
uint32 respawntime = 0;
|
||||
uint32 spawnid = 0;
|
||||
if (respawnTime)
|
||||
respawntime = respawnTime;
|
||||
else if (spawn->respawn2 && spawn->respawn2->RespawnTimer() != 0)
|
||||
respawntime = spawn->respawn2->RespawnTimer();
|
||||
else
|
||||
respawntime = 1200;
|
||||
|
||||
query = StringFormat("INSERT INTO spawn2 (zone, version, x, y, z, respawntime, heading, spawngroupID) "
|
||||
"VALUES('%s', %u, %f, %f, %f, %i, %f, %i)",
|
||||
zone, zone_version, spawn->GetX(), spawn->GetY(), spawn->GetZ(), respawntime,
|
||||
spawn->GetHeading(), last_insert_id);
|
||||
results = QueryDatabase(query);
|
||||
if (!results.Success()) {
|
||||
return 0;
|
||||
}
|
||||
spawnid = results.LastInsertedID();
|
||||
query = StringFormat("INSERT INTO spawn2 (zone, version, x, y, z, respawntime, heading, spawngroupID) "
|
||||
"VALUES('%s', %u, %f, %f, %f, %i, %f, %i)",
|
||||
zone, zone_version, spawn->GetX(), spawn->GetY(), spawn->GetZ(), respawntime,
|
||||
spawn->GetHeading(), last_insert_id);
|
||||
results = QueryDatabase(query);
|
||||
if (!results.Success()) {
|
||||
return 0;
|
||||
}
|
||||
spawnid = results.LastInsertedID();
|
||||
|
||||
if(client)
|
||||
query = StringFormat("INSERT INTO spawnentry (spawngroupID, npcID, chance) VALUES(%i, %i, %i)", last_insert_id,
|
||||
spawn->GetNPCTypeID(), 100);
|
||||
results = QueryDatabase(query);
|
||||
if (!results.Success()) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
query = StringFormat("INSERT INTO spawnentry (spawngroupID, npcID, chance) VALUES(%i, %i, %i)",
|
||||
last_insert_id, spawn->GetNPCTypeID(), 100);
|
||||
results = QueryDatabase(query);
|
||||
if (!results.Success()) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
if(client)
|
||||
|
||||
return spawnid;
|
||||
return spawnid;
|
||||
}
|
||||
|
||||
uint32 ZoneDatabase::UpdateNPCTypeAppearance(Client *client, NPC* spawn) {
|
||||
|
||||
std::string query = StringFormat("UPDATE npc_types SET name = \"%s\", level = %i, race = %i, class = %i, "
|
||||
"hp = %i, gender = %i, texture = %i, helmtexture = %i, size = %i, "
|
||||
"loottable_id = %i, merchant_id = %i, face = %i, WHERE id = %i",
|
||||
spawn->GetName(), spawn->GetLevel(), spawn->GetRace(), spawn->GetClass(),
|
||||
spawn->GetMaxHP(), spawn->GetGender(), spawn->GetTexture(),
|
||||
spawn->GetHelmTexture(), spawn->GetSize(), spawn->GetLoottableID(),
|
||||
spawn->MerchantType, spawn->GetNPCTypeID());
|
||||
auto results = QueryDatabase(query);
|
||||
if (!results.Success() && client)
|
||||
|
||||
return results.Success() == true? 1: 0;
|
||||
uint32 ZoneDatabase::UpdateNPCTypeAppearance(Client *client, NPC *spawn)
|
||||
{
|
||||
std::string query =
|
||||
StringFormat("UPDATE npc_types SET name = \"%s\", level = %i, race = %i, class = %i, "
|
||||
"hp = %i, gender = %i, texture = %i, helmtexture = %i, size = %i, "
|
||||
"loottable_id = %i, merchant_id = %i, face = %i, WHERE id = %i",
|
||||
spawn->GetName(), spawn->GetLevel(), spawn->GetRace(), spawn->GetClass(), spawn->GetMaxHP(),
|
||||
spawn->GetGender(), spawn->GetTexture(), spawn->GetHelmTexture(), spawn->GetSize(),
|
||||
spawn->GetLoottableID(), spawn->MerchantType, spawn->GetNPCTypeID());
|
||||
auto results = QueryDatabase(query);
|
||||
return results.Success() == true ? 1 : 0;
|
||||
}
|
||||
|
||||
uint32 ZoneDatabase::DeleteSpawnLeaveInNPCTypeTable(const char* zone, Client *client, NPC* spawn) {
|
||||
uint32 ZoneDatabase::DeleteSpawnLeaveInNPCTypeTable(const char *zone, Client *client, NPC *spawn)
|
||||
{
|
||||
uint32 id = 0;
|
||||
uint32 spawngroupID = 0;
|
||||
|
||||
std::string query = StringFormat("SELECT id, spawngroupID FROM spawn2 WHERE "
|
||||
"zone='%s' AND spawngroupID=%i", zone, spawn->GetSp2());
|
||||
auto results = QueryDatabase(query);
|
||||
if (!results.Success())
|
||||
"zone='%s' AND spawngroupID=%i",
|
||||
zone, spawn->GetSp2());
|
||||
auto results = QueryDatabase(query);
|
||||
if (!results.Success())
|
||||
return 0;
|
||||
|
||||
if (results.RowCount() == 0)
|
||||
return 0;
|
||||
if (results.RowCount() == 0)
|
||||
return 0;
|
||||
|
||||
auto row = results.begin();
|
||||
if (row[0])
|
||||
id = atoi(row[0]);
|
||||
id = atoi(row[0]);
|
||||
|
||||
if (row[1])
|
||||
spawngroupID = atoi(row[1]);
|
||||
spawngroupID = atoi(row[1]);
|
||||
|
||||
query = StringFormat("DELETE FROM spawn2 WHERE id = '%i'", id);
|
||||
results = QueryDatabase(query);
|
||||
query = StringFormat("DELETE FROM spawn2 WHERE id = '%i'", id);
|
||||
results = QueryDatabase(query);
|
||||
if (!results.Success())
|
||||
return 0;
|
||||
|
||||
if(client)
|
||||
|
||||
query = StringFormat("DELETE FROM spawngroup WHERE id = '%i'", spawngroupID);
|
||||
results = QueryDatabase(query);
|
||||
query = StringFormat("DELETE FROM spawngroup WHERE id = '%i'", spawngroupID);
|
||||
results = QueryDatabase(query);
|
||||
if (!results.Success())
|
||||
return 0;
|
||||
|
||||
if(client)
|
||||
|
||||
query = StringFormat("DELETE FROM spawnentry WHERE spawngroupID = '%i'", spawngroupID);
|
||||
results = QueryDatabase(query);
|
||||
query = StringFormat("DELETE FROM spawnentry WHERE spawngroupID = '%i'", spawngroupID);
|
||||
results = QueryDatabase(query);
|
||||
if (!results.Success())
|
||||
return 0;
|
||||
|
||||
if(client)
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
uint32 ZoneDatabase::DeleteSpawnRemoveFromNPCTypeTable(const char* zone, uint32 zone_version, Client *client, NPC* spawn) {
|
||||
|
||||
uint32 ZoneDatabase::DeleteSpawnRemoveFromNPCTypeTable(const char *zone, uint32 zone_version, Client *client,
|
||||
NPC *spawn)
|
||||
{
|
||||
uint32 id = 0;
|
||||
uint32 spawngroupID = 0;
|
||||
|
||||
std::string query = StringFormat("SELECT id, spawngroupID FROM spawn2 WHERE zone = '%s' "
|
||||
"AND version = %u AND spawngroupID = %i",
|
||||
zone, zone_version, spawn->GetSp2());
|
||||
auto results = QueryDatabase(query);
|
||||
if (!results.Success())
|
||||
"AND version = %u AND spawngroupID = %i",
|
||||
zone, zone_version, spawn->GetSp2());
|
||||
auto results = QueryDatabase(query);
|
||||
if (!results.Success())
|
||||
return 0;
|
||||
|
||||
if (results.RowCount() == 0)
|
||||
return 0;
|
||||
if (results.RowCount() == 0)
|
||||
return 0;
|
||||
|
||||
auto row = results.begin();
|
||||
|
||||
if (row[0])
|
||||
id = atoi(row[0]);
|
||||
id = atoi(row[0]);
|
||||
|
||||
if (row[1])
|
||||
spawngroupID = atoi(row[1]);
|
||||
spawngroupID = atoi(row[1]);
|
||||
|
||||
query = StringFormat("DELETE FROM spawn2 WHERE id = '%i'", id);
|
||||
results = QueryDatabase(query);
|
||||
if (!results.Success())
|
||||
return 0;
|
||||
|
||||
if(client)
|
||||
|
||||
query = StringFormat("DELETE FROM spawngroup WHERE id = '%i'", spawngroupID);
|
||||
query = StringFormat("DELETE FROM spawn2 WHERE id = '%i'", id);
|
||||
results = QueryDatabase(query);
|
||||
if (!results.Success())
|
||||
return 0;
|
||||
|
||||
if(client)
|
||||
|
||||
query = StringFormat("DELETE FROM spawnentry WHERE spawngroupID = '%i'", spawngroupID);
|
||||
query = StringFormat("DELETE FROM spawngroup WHERE id = '%i'", spawngroupID);
|
||||
results = QueryDatabase(query);
|
||||
if (!results.Success())
|
||||
return 0;
|
||||
|
||||
if(client)
|
||||
|
||||
query = StringFormat("DELETE FROM npc_types WHERE id = '%i'", spawn->GetNPCTypeID());
|
||||
query = StringFormat("DELETE FROM spawnentry WHERE spawngroupID = '%i'", spawngroupID);
|
||||
results = QueryDatabase(query);
|
||||
if (!results.Success())
|
||||
return 0;
|
||||
|
||||
if(client)
|
||||
query = StringFormat("DELETE FROM npc_types WHERE id = '%i'", spawn->GetNPCTypeID());
|
||||
results = QueryDatabase(query);
|
||||
if (!results.Success())
|
||||
return 0;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
uint32 ZoneDatabase::AddSpawnFromSpawnGroup(const char* zone, uint32 zone_version, Client *client, NPC* spawn, uint32 spawnGroupID) {
|
||||
|
||||
uint32 ZoneDatabase::AddSpawnFromSpawnGroup(const char *zone, uint32 zone_version, Client *client, NPC *spawn,
|
||||
uint32 spawnGroupID)
|
||||
{
|
||||
uint32 last_insert_id = 0;
|
||||
std::string query = StringFormat("INSERT INTO spawn2 (zone, version, x, y, z, respawntime, heading, spawngroupID) "
|
||||
"VALUES('%s', %u, %f, %f, %f, %i, %f, %i)",
|
||||
zone, zone_version, client->GetX(), client->GetY(), client->GetZ(),
|
||||
120, client->GetHeading(), spawnGroupID);
|
||||
auto results = QueryDatabase(query);
|
||||
if (!results.Success())
|
||||
std::string query =
|
||||
StringFormat("INSERT INTO spawn2 (zone, version, x, y, z, respawntime, heading, spawngroupID) "
|
||||
"VALUES('%s', %u, %f, %f, %f, %i, %f, %i)",
|
||||
zone, zone_version, client->GetX(), client->GetY(), client->GetZ(), 120, client->GetHeading(),
|
||||
spawnGroupID);
|
||||
auto results = QueryDatabase(query);
|
||||
if (!results.Success())
|
||||
return 0;
|
||||
|
||||
if(client)
|
||||
|
||||
return 1;
|
||||
return 1;
|
||||
}
|
||||
|
||||
uint32 ZoneDatabase::AddNPCTypes(const char* zone, uint32 zone_version, Client *client, NPC* spawn, uint32 spawnGroupID) {
|
||||
|
||||
uint32 npc_type_id;
|
||||
uint32 ZoneDatabase::AddNPCTypes(const char *zone, uint32 zone_version, Client *client, NPC *spawn, uint32 spawnGroupID)
|
||||
{
|
||||
uint32 npc_type_id;
|
||||
char numberlessName[64];
|
||||
|
||||
EntityList::RemoveNumbers(strn0cpy(numberlessName, spawn->GetName(), sizeof(numberlessName)));
|
||||
std::string query = StringFormat("INSERT INTO npc_types (name, level, race, class, hp, gender, "
|
||||
"texture, helmtexture, size, loottable_id, merchant_id, face, "
|
||||
"runspeed, prim_melee_type, sec_melee_type) "
|
||||
"VALUES(\"%s\", %i, %i, %i, %i, %i, %i, %i, %f, %i, %i, %i, %f, %i, %i)",
|
||||
numberlessName, spawn->GetLevel(), spawn->GetRace(), spawn->GetClass(),
|
||||
spawn->GetMaxHP(), spawn->GetGender(), spawn->GetTexture(),
|
||||
spawn->GetHelmTexture(), spawn->GetSize(), spawn->GetLoottableID(),
|
||||
spawn->MerchantType, 0, spawn->GetRunspeed(), 28, 28);
|
||||
auto results = QueryDatabase(query);
|
||||
std::string query =
|
||||
StringFormat("INSERT INTO npc_types (name, level, race, class, hp, gender, "
|
||||
"texture, helmtexture, size, loottable_id, merchant_id, face, "
|
||||
"runspeed, prim_melee_type, sec_melee_type) "
|
||||
"VALUES(\"%s\", %i, %i, %i, %i, %i, %i, %i, %f, %i, %i, %i, %f, %i, %i)",
|
||||
numberlessName, spawn->GetLevel(), spawn->GetRace(), spawn->GetClass(), spawn->GetMaxHP(),
|
||||
spawn->GetGender(), spawn->GetTexture(), spawn->GetHelmTexture(), spawn->GetSize(),
|
||||
spawn->GetLoottableID(), spawn->MerchantType, 0, spawn->GetRunspeed(), 28, 28);
|
||||
auto results = QueryDatabase(query);
|
||||
if (!results.Success())
|
||||
return 0;
|
||||
npc_type_id = results.LastInsertedID();
|
||||
npc_type_id = results.LastInsertedID();
|
||||
|
||||
if(client)
|
||||
|
||||
if(client)
|
||||
client->Message(0, "%s npc_type ID %i created successfully!", numberlessName, npc_type_id);
|
||||
if (client)
|
||||
client->Message(0, "%s npc_type ID %i created successfully!", numberlessName, npc_type_id);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
@ -467,16 +467,21 @@ bool Object::HandleClick(Client* sender, const ClickObject_Struct* click_object)
|
||||
if (m_inst && sender) {
|
||||
// if there is a lore conflict, delete the offending item from the server inventory
|
||||
// the client updates itself and takes care of sending "duplicate lore item" messages
|
||||
if(sender->CheckLoreConflict(m_inst->GetItem())) {
|
||||
int16 loreslot = sender->GetInv().HasItem(m_inst->GetItem()->ID, 0, invWhereBank);
|
||||
auto item = m_inst->GetItem();
|
||||
if(sender->CheckLoreConflict(item)) {
|
||||
int16 loreslot = sender->GetInv().HasItem(item->ID, 0, invWhereBank);
|
||||
if (loreslot != INVALID_INDEX) // if the duplicate is in the bank, delete it.
|
||||
sender->DeleteItemInInventory(loreslot);
|
||||
else
|
||||
cursordelete = true; // otherwise, we delete the new one
|
||||
}
|
||||
|
||||
if (item->RecastDelay)
|
||||
m_inst->SetRecastTimestamp(
|
||||
database.GetItemRecastTimestamp(sender->CharacterID(), item->RecastType));
|
||||
|
||||
char buf[10];
|
||||
snprintf(buf, 9, "%u", m_inst->GetItem()->ID);
|
||||
snprintf(buf, 9, "%u", item->ID);
|
||||
buf[9] = '\0';
|
||||
std::vector<EQEmu::Any> args;
|
||||
args.push_back(m_inst);
|
||||
|
||||
@ -663,7 +663,7 @@ void Mob::RogueBackstab(Mob* other, bool min_damage, int ReuseTime)
|
||||
DoAnim(animPiercing);
|
||||
}
|
||||
|
||||
// solar - assassinate [Kayen: No longer used for regular assassinate 6-29-14]
|
||||
// assassinate [No longer used for regular assassinate 6-29-14]
|
||||
void Mob::RogueAssassinate(Mob* other)
|
||||
{
|
||||
//can you dodge, parry, etc.. an assassinate??
|
||||
|
||||
@ -1242,6 +1242,8 @@ void Mob::CastedSpellFinished(uint16 spell_id, uint32 target_id, uint16 slot,
|
||||
{
|
||||
//Can we start the timer here? I don't see why not.
|
||||
CastToClient()->GetPTimers().Start((pTimerItemStart + recasttype), recastdelay);
|
||||
database.UpdateItemRecastTimestamps(CastToClient()->CharacterID(), recasttype,
|
||||
CastToClient()->GetPTimers().Get(pTimerItemStart + recasttype)->GetReadyTimestamp());
|
||||
}
|
||||
}
|
||||
|
||||
@ -2023,6 +2025,7 @@ bool Mob::SpellFinished(uint16 spell_id, Mob *spell_target, uint16 slot, uint16
|
||||
//
|
||||
// Switch #2 - execute the spell
|
||||
//
|
||||
|
||||
switch(CastAction)
|
||||
{
|
||||
default:
|
||||
@ -2146,6 +2149,15 @@ bool Mob::SpellFinished(uint16 spell_id, Mob *spell_target, uint16 slot, uint16
|
||||
// caster if they're not using TGB
|
||||
// NOTE: this will always hit the caster, plus the target's group so
|
||||
// it can affect up to 7 people if the targeted group is not our own
|
||||
|
||||
// Allow pets who cast group spells to affect the group.
|
||||
if (spell_target->IsPetOwnerClient()){
|
||||
Mob* owner = spell_target->GetOwner();
|
||||
|
||||
if (owner)
|
||||
spell_target = owner;
|
||||
}
|
||||
|
||||
if(spell_target->IsGrouped())
|
||||
{
|
||||
Group *target_group = entity_list.GetGroupByMob(spell_target);
|
||||
@ -2270,11 +2282,15 @@ bool Mob::SpellFinished(uint16 spell_id, Mob *spell_target, uint16 slot, uint16
|
||||
{
|
||||
ItemInst *itm = CastToClient()->GetInv().GetItem(inventory_slot);
|
||||
if(itm && itm->GetItem()->RecastDelay > 0){
|
||||
CastToClient()->GetPTimers().Start((pTimerItemStart + itm->GetItem()->RecastType), itm->GetItem()->RecastDelay);
|
||||
auto recast_type = itm->GetItem()->RecastType;
|
||||
CastToClient()->GetPTimers().Start((pTimerItemStart + recast_type), itm->GetItem()->RecastDelay);
|
||||
database.UpdateItemRecastTimestamps(
|
||||
CastToClient()->CharacterID(), recast_type,
|
||||
CastToClient()->GetPTimers().Get(pTimerItemStart + recast_type)->GetReadyTimestamp());
|
||||
EQApplicationPacket *outapp = new EQApplicationPacket(OP_ItemRecastDelay, sizeof(ItemRecastDelay_Struct));
|
||||
ItemRecastDelay_Struct *ird = (ItemRecastDelay_Struct *)outapp->pBuffer;
|
||||
ird->recast_delay = itm->GetItem()->RecastDelay;
|
||||
ird->recast_type = itm->GetItem()->RecastType;
|
||||
ird->recast_type = recast_type;
|
||||
CastToClient()->QueuePacket(outapp);
|
||||
safe_delete(outapp);
|
||||
}
|
||||
|
||||
@ -647,7 +647,7 @@ void WorldServer::Process() {
|
||||
case ServerOP_Petition: {
|
||||
std::cout << "Got Server Requested Petition List Refresh" << std::endl;
|
||||
ServerPetitionUpdate_Struct* sus = (ServerPetitionUpdate_Struct*) pack->pBuffer;
|
||||
// solar: this was typoed to = instead of ==, not that it acts any different now though..
|
||||
// this was typoed to = instead of ==, not that it acts any different now though..
|
||||
if (sus->status == 0) petition_list.ReadDatabase();
|
||||
else if (sus->status == 1) petition_list.ReadDatabase(); // Until I fix this to be better....
|
||||
break;
|
||||
|
||||
@ -2999,6 +2999,14 @@ void ZoneDatabase::RemoveTempFactions(Client *client) {
|
||||
QueryDatabase(query);
|
||||
}
|
||||
|
||||
void ZoneDatabase::UpdateItemRecastTimestamps(uint32 char_id, uint32 recast_type, uint32 timestamp)
|
||||
{
|
||||
std::string query =
|
||||
StringFormat("REPLACE INTO character_item_recast (id, recast_type, timestamp) VALUES (%u, %u, %u)", char_id,
|
||||
recast_type, timestamp);
|
||||
QueryDatabase(query);
|
||||
}
|
||||
|
||||
void ZoneDatabase::LoadPetInfo(Client *client) {
|
||||
|
||||
// Load current pet and suspended pet
|
||||
|
||||
@ -256,6 +256,7 @@ public:
|
||||
void LoadPetInfo(Client *c);
|
||||
void SavePetInfo(Client *c);
|
||||
void RemoveTempFactions(Client *c);
|
||||
void UpdateItemRecastTimestamps(uint32 char_id, uint32 recast_type, uint32 timestamp);
|
||||
|
||||
/* Character Data Loaders */
|
||||
bool LoadCharacterFactionValues(uint32 character_id, faction_map & val_list);
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user