mirror of
https://github.com/EQEmu/Server.git
synced 2025-12-17 22:51:30 +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)
|
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 ==
|
== 01/30/2015 ==
|
||||||
Akkadius: Implemented event type "EVENT_ENVIRONMENTAL_DAMAGE"
|
Akkadius: Implemented event type "EVENT_ENVIRONMENTAL_DAMAGE"
|
||||||
- This event triggers when taking any sort of environmental damage. Example use:
|
- This event triggers when taking any sort of environmental damage. Example use:
|
||||||
|
|||||||
@ -107,9 +107,9 @@ public:
|
|||||||
|
|
||||||
/* General Information Queries */
|
/* 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 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 CheckGMIPs(const char* loginIP, uint32 account_id);
|
||||||
bool CheckNameFilter(const char* name, bool surname = false);
|
bool CheckNameFilter(const char* name, bool surname = false);
|
||||||
bool CheckUsedName(const char* name);
|
bool CheckUsedName(const char* name);
|
||||||
@ -118,7 +118,7 @@ public:
|
|||||||
uint32 GetAccountIDByChar(uint32 char_id);
|
uint32 GetAccountIDByChar(uint32 char_id);
|
||||||
uint32 GetAccountIDByName(const char* accname, int16* status = 0, uint32* lsid = 0);
|
uint32 GetAccountIDByName(const char* accname, int16* status = 0, uint32* lsid = 0);
|
||||||
uint32 GetCharacterID(const char *name);
|
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);
|
uint32 GetGuildIDByCharID(uint32 char_id);
|
||||||
|
|
||||||
void GetAccountName(uint32 accountid, char* name, uint32* oLSAccountID = 0);
|
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_DamageState 44 // The damage state of a destructible object (0 through 4)
|
||||||
//#define AT_Trader 300 // Bazzar Trader Mode
|
//#define AT_Trader 300 // Bazzar Trader Mode
|
||||||
|
|
||||||
// solar: animations for AT_Anim
|
// animations for AT_Anim
|
||||||
#define ANIM_FREEZE 102
|
#define ANIM_FREEZE 102
|
||||||
#define ANIM_STAND 0x64
|
#define ANIM_STAND 0x64
|
||||||
#define ANIM_SIT 0x6e
|
#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
|
struct SpellBuff_Struct
|
||||||
{
|
{
|
||||||
/*000*/ uint8 slotid; //badly named... seems to be 2 for a real buff, 0 otherwise
|
/*000*/ uint8 slotid; //badly named... seems to be 2 for a real buff, 0 otherwise
|
||||||
@ -1268,7 +1268,7 @@ struct Animation_Struct {
|
|||||||
/*04*/
|
/*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
|
// get the particle effects around them when a spell is cast
|
||||||
// also causes a buff icon
|
// also causes a buff icon
|
||||||
struct Action_Struct
|
struct Action_Struct
|
||||||
@ -1292,7 +1292,7 @@ struct Action_Struct
|
|||||||
/* 31 */
|
/* 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
|
// melee messages like You try to pierce, etc. It's basically the melee
|
||||||
// and spell damage message
|
// and spell damage message
|
||||||
struct CombatDamage_Struct
|
struct CombatDamage_Struct
|
||||||
@ -1811,7 +1811,7 @@ struct RandomReq_Struct {
|
|||||||
uint32 high;
|
uint32 high;
|
||||||
};
|
};
|
||||||
|
|
||||||
/* solar: 9/23/03 reply to /random command; struct from Zaphod */
|
/* 9/23/03 reply to /random command */
|
||||||
struct RandomReply_Struct {
|
struct RandomReply_Struct {
|
||||||
/* 00 */ uint32 low;
|
/* 00 */ uint32 low;
|
||||||
/* 04 */ uint32 high;
|
/* 04 */ uint32 high;
|
||||||
|
|||||||
@ -72,7 +72,7 @@ namespace Console {
|
|||||||
LightRed = 12,
|
LightRed = 12,
|
||||||
LightMagenta = 13,
|
LightMagenta = 13,
|
||||||
Yellow = 14,
|
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;
|
process_log << time_stamp << " " << message << std::endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint16 EQEmuLogSys::GetWindowsConsoleColorFromCategory(uint16 log_category){
|
uint16 EQEmuLogSys::GetWindowsConsoleColorFromCategory(uint16 log_category) {
|
||||||
switch (log_category) {
|
switch (log_category) {
|
||||||
case Logs::Status:
|
case Logs::Status:
|
||||||
case Logs::Normal:
|
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) {
|
switch (log_category) {
|
||||||
case Logs::Status:
|
case Logs::Status:
|
||||||
case Logs::Normal:
|
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) {
|
switch (log_category) {
|
||||||
case Logs::Status:
|
case Logs::Status:
|
||||||
case Logs::Normal:
|
case Logs::Normal:
|
||||||
@ -317,7 +317,7 @@ void EQEmuLogSys::MakeDirectory(const std::string &directory_name)
|
|||||||
|
|
||||||
void EQEmuLogSys::CloseFileLogs()
|
void EQEmuLogSys::CloseFileLogs()
|
||||||
{
|
{
|
||||||
if (process_log.is_open()){
|
if (process_log.is_open()) {
|
||||||
process_log.close();
|
process_log.close();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -26,11 +26,11 @@
|
|||||||
|
|
||||||
#include "types.h"
|
#include "types.h"
|
||||||
|
|
||||||
namespace Logs{
|
namespace Logs {
|
||||||
enum DebugLevel {
|
enum DebugLevel {
|
||||||
General = 1, /* 1 - Low-Level general debugging, useful info on single line */
|
General = 1, /* 1 - Low-Level general debugging, useful info on single line */
|
||||||
Moderate, /* 2 - Informational based, used in functions, when particular things load */
|
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",
|
"MySQL Query",
|
||||||
"Mercenaries",
|
"Mercenaries",
|
||||||
"Quest Debug",
|
"Quest Debug",
|
||||||
|
"Quest Debug"
|
||||||
"Packet :: Server -> Client",
|
"Packet :: Server -> Client",
|
||||||
"Packet :: Client -> Server Unhandled",
|
"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
|
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_file;
|
||||||
uint8 log_to_console;
|
uint8 log_to_console;
|
||||||
uint8 log_to_gmsay;
|
uint8 log_to_gmsay;
|
||||||
|
|||||||
@ -1441,6 +1441,7 @@ ItemInst::ItemInst(const Item_Struct* item, int16 charges) {
|
|||||||
m_ornamenticon = 0;
|
m_ornamenticon = 0;
|
||||||
m_ornamentidfile = 0;
|
m_ornamentidfile = 0;
|
||||||
m_ornament_hero_model = 0;
|
m_ornament_hero_model = 0;
|
||||||
|
m_recast_timestamp = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
ItemInst::ItemInst(SharedDatabase *db, uint32 item_id, int16 charges) {
|
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_ornamenticon = 0;
|
||||||
m_ornamentidfile = 0;
|
m_ornamentidfile = 0;
|
||||||
m_ornament_hero_model = 0;
|
m_ornament_hero_model = 0;
|
||||||
|
m_recast_timestamp = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
ItemInst::ItemInst(ItemInstTypes use_type) {
|
ItemInst::ItemInst(ItemInstTypes use_type) {
|
||||||
@ -1486,6 +1488,7 @@ ItemInst::ItemInst(ItemInstTypes use_type) {
|
|||||||
m_ornamenticon = 0;
|
m_ornamenticon = 0;
|
||||||
m_ornamentidfile = 0;
|
m_ornamentidfile = 0;
|
||||||
m_ornament_hero_model = 0;
|
m_ornament_hero_model = 0;
|
||||||
|
m_recast_timestamp = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Make a copy of an ItemInst object
|
// Make a copy of an ItemInst object
|
||||||
@ -1539,6 +1542,7 @@ ItemInst::ItemInst(const ItemInst& copy)
|
|||||||
m_ornamenticon = copy.m_ornamenticon;
|
m_ornamenticon = copy.m_ornamenticon;
|
||||||
m_ornamentidfile = copy.m_ornamentidfile;
|
m_ornamentidfile = copy.m_ornamentidfile;
|
||||||
m_ornament_hero_model = copy.m_ornament_hero_model;
|
m_ornament_hero_model = copy.m_ornament_hero_model;
|
||||||
|
m_recast_timestamp = copy.m_recast_timestamp;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Clean up container contents
|
// Clean up container contents
|
||||||
|
|||||||
@ -403,6 +403,8 @@ public:
|
|||||||
void SetOrnamentationIDFile(uint32 ornament_idfile) { m_ornamentidfile = ornament_idfile; }
|
void SetOrnamentationIDFile(uint32 ornament_idfile) { m_ornamentidfile = ornament_idfile; }
|
||||||
uint32 GetOrnamentHeroModel(int32 material_slot = -1) const;
|
uint32 GetOrnamentHeroModel(int32 material_slot = -1) const;
|
||||||
void SetOrnamentHeroModel(uint32 ornament_hero_model) { m_ornament_hero_model = ornament_hero_model; }
|
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 Initialize(SharedDatabase *db = nullptr);
|
||||||
void ScaleItem();
|
void ScaleItem();
|
||||||
@ -450,6 +452,7 @@ protected:
|
|||||||
uint32 m_ornamenticon;
|
uint32 m_ornamenticon;
|
||||||
uint32 m_ornamentidfile;
|
uint32 m_ornamentidfile;
|
||||||
uint32 m_ornament_hero_model;
|
uint32 m_ornament_hero_model;
|
||||||
|
uint32 m_recast_timestamp;
|
||||||
|
|
||||||
//
|
//
|
||||||
// Items inside of this item (augs or contents);
|
// Items inside of this item (augs or contents);
|
||||||
|
|||||||
@ -5000,7 +5000,7 @@ namespace RoF
|
|||||||
hdr.scaled_value = inst->IsScaling() ? inst->GetExp() / 100 : 0;
|
hdr.scaled_value = inst->IsScaling() ? inst->GetExp() / 100 : 0;
|
||||||
hdr.instance_id = (merchant_slot == 0) ? inst->GetSerialNumber() : merchant_slot;
|
hdr.instance_id = (merchant_slot == 0) ? inst->GetSerialNumber() : merchant_slot;
|
||||||
hdr.unknown028 = 0;
|
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.charges = (stackable ? (item->MaxCharges ? 1 : 0) : charges);
|
||||||
hdr.inst_nodrop = inst->IsAttuned() ? 1 : 0;
|
hdr.inst_nodrop = inst->IsAttuned() ? 1 : 0;
|
||||||
hdr.unknown044 = 0;
|
hdr.unknown044 = 0;
|
||||||
|
|||||||
@ -5069,7 +5069,7 @@ namespace RoF2
|
|||||||
hdr.scaled_value = inst->IsScaling() ? inst->GetExp() / 100 : 0;
|
hdr.scaled_value = inst->IsScaling() ? inst->GetExp() / 100 : 0;
|
||||||
hdr.instance_id = (merchant_slot == 0) ? inst->GetSerialNumber() : merchant_slot;
|
hdr.instance_id = (merchant_slot == 0) ? inst->GetSerialNumber() : merchant_slot;
|
||||||
hdr.unknown028 = 0;
|
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.charges = (stackable ? (item->MaxCharges ? 1 : 0) : charges);
|
||||||
hdr.inst_nodrop = inst->IsAttuned() ? 1 : 0;
|
hdr.inst_nodrop = inst->IsAttuned() ? 1 : 0;
|
||||||
hdr.unknown044 = 0;
|
hdr.unknown044 = 0;
|
||||||
|
|||||||
@ -1394,7 +1394,7 @@ struct Animation_Struct {
|
|||||||
/*04*/
|
/*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
|
// get the particle effects around them when a spell is cast
|
||||||
// also causes a buff icon
|
// also causes a buff icon
|
||||||
struct Action_Struct
|
struct Action_Struct
|
||||||
@ -1445,7 +1445,7 @@ struct ActionAlt_Struct
|
|||||||
/*56*/
|
/*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
|
// melee messages like You try to pierce, etc. It's basically the melee
|
||||||
// and spell damage message
|
// and spell damage message
|
||||||
struct CombatDamage_Struct
|
struct CombatDamage_Struct
|
||||||
@ -1997,7 +1997,7 @@ struct RandomReq_Struct {
|
|||||||
uint32 high;
|
uint32 high;
|
||||||
};
|
};
|
||||||
|
|
||||||
/* solar: 9/23/03 reply to /random command; struct from Zaphod */
|
/* 9/23/03 reply to /random command */
|
||||||
struct RandomReply_Struct {
|
struct RandomReply_Struct {
|
||||||
/* 00 */ uint32 low;
|
/* 00 */ uint32 low;
|
||||||
/* 04 */ uint32 high;
|
/* 04 */ uint32 high;
|
||||||
|
|||||||
@ -1425,7 +1425,7 @@ struct Animation_Struct {
|
|||||||
/*04*/
|
/*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
|
// get the particle effects around them when a spell is cast
|
||||||
// also causes a buff icon
|
// also causes a buff icon
|
||||||
struct Action_Struct
|
struct Action_Struct
|
||||||
@ -1476,7 +1476,7 @@ struct ActionAlt_Struct
|
|||||||
/*56*/
|
/*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
|
// melee messages like You try to pierce, etc. It's basically the melee
|
||||||
// and spell damage message
|
// and spell damage message
|
||||||
struct CombatDamage_Struct
|
struct CombatDamage_Struct
|
||||||
@ -2028,7 +2028,7 @@ struct RandomReq_Struct {
|
|||||||
uint32 high;
|
uint32 high;
|
||||||
};
|
};
|
||||||
|
|
||||||
/* solar: 9/23/03 reply to /random command; struct from Zaphod */
|
/* 9/23/03 reply to /random command */
|
||||||
struct RandomReply_Struct {
|
struct RandomReply_Struct {
|
||||||
/* 00 */ uint32 low;
|
/* 00 */ uint32 low;
|
||||||
/* 04 */ uint32 high;
|
/* 04 */ uint32 high;
|
||||||
|
|||||||
@ -3548,7 +3548,7 @@ namespace SoD
|
|||||||
hdr.scaled_value = inst->IsScaling() ? inst->GetExp() / 100 : 0;
|
hdr.scaled_value = inst->IsScaling() ? inst->GetExp() / 100 : 0;
|
||||||
hdr.instance_id = (merchant_slot == 0) ? inst->GetSerialNumber() : merchant_slot;
|
hdr.instance_id = (merchant_slot == 0) ? inst->GetSerialNumber() : merchant_slot;
|
||||||
hdr.unknown028 = 0;
|
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.charges = (stackable ? (item->MaxCharges ? 1 : 0) : charges);
|
||||||
hdr.inst_nodrop = inst->IsAttuned() ? 1 : 0;
|
hdr.inst_nodrop = inst->IsAttuned() ? 1 : 0;
|
||||||
hdr.unknown044 = 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
|
struct SpellBuff_Struct
|
||||||
{
|
{
|
||||||
/*000*/ uint8 slotid; //badly named... seems to be 2 for a real buff, 0 otherwise
|
/*000*/ uint8 slotid; //badly named... seems to be 2 for a real buff, 0 otherwise
|
||||||
@ -1196,7 +1196,7 @@ struct Animation_Struct {
|
|||||||
/*04*/
|
/*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
|
// get the particle effects around them when a spell is cast
|
||||||
// also causes a buff icon
|
// also causes a buff icon
|
||||||
struct Action_Struct
|
struct Action_Struct
|
||||||
@ -1248,7 +1248,7 @@ struct ActionAlt_Struct // ActionAlt_Struct - Size: 56 bytes
|
|||||||
/*0056*/
|
/*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
|
// melee messages like You try to pierce, etc. It's basically the melee
|
||||||
// and spell damage message
|
// and spell damage message
|
||||||
struct CombatDamage_Struct
|
struct CombatDamage_Struct
|
||||||
@ -1791,7 +1791,7 @@ struct RandomReq_Struct {
|
|||||||
uint32 high;
|
uint32 high;
|
||||||
};
|
};
|
||||||
|
|
||||||
/* solar: 9/23/03 reply to /random command; struct from Zaphod */
|
/* 9/23/03 reply to /random command */
|
||||||
struct RandomReply_Struct {
|
struct RandomReply_Struct {
|
||||||
/* 00 */ uint32 low;
|
/* 00 */ uint32 low;
|
||||||
/* 04 */ uint32 high;
|
/* 04 */ uint32 high;
|
||||||
|
|||||||
@ -2872,7 +2872,7 @@ namespace SoF
|
|||||||
hdr.scaled_value = inst->IsScaling() ? inst->GetExp() / 100 : 0;
|
hdr.scaled_value = inst->IsScaling() ? inst->GetExp() / 100 : 0;
|
||||||
hdr.instance_id = (merchant_slot == 0) ? inst->GetSerialNumber() : merchant_slot;
|
hdr.instance_id = (merchant_slot == 0) ? inst->GetSerialNumber() : merchant_slot;
|
||||||
hdr.unknown028 = 0;
|
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.charges = (stackable ? (item->MaxCharges ? 1 : 0) : charges);
|
||||||
hdr.inst_nodrop = inst->IsAttuned() ? 1 : 0;
|
hdr.inst_nodrop = inst->IsAttuned() ? 1 : 0;
|
||||||
hdr.unknown044 = 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
|
struct SpellBuff_Struct
|
||||||
{
|
{
|
||||||
/*000*/ uint8 slotid; //badly named... seems to be 2 for a real buff, 0 otherwise
|
/*000*/ uint8 slotid; //badly named... seems to be 2 for a real buff, 0 otherwise
|
||||||
@ -1172,7 +1172,7 @@ struct Animation_Struct {
|
|||||||
/*04*/
|
/*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
|
// get the particle effects around them when a spell is cast
|
||||||
// also causes a buff icon
|
// also causes a buff icon
|
||||||
struct Action_Struct
|
struct Action_Struct
|
||||||
@ -1224,7 +1224,7 @@ struct ActionAlt_Struct // ActionAlt_Struct - Size: 56 bytes
|
|||||||
/*0056*/
|
/*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
|
// melee messages like You try to pierce, etc. It's basically the melee
|
||||||
// and spell damage message
|
// and spell damage message
|
||||||
struct CombatDamage_Struct
|
struct CombatDamage_Struct
|
||||||
@ -1768,7 +1768,7 @@ struct RandomReq_Struct {
|
|||||||
uint32 high;
|
uint32 high;
|
||||||
};
|
};
|
||||||
|
|
||||||
/* solar: 9/23/03 reply to /random command; struct from Zaphod */
|
/* 9/23/03 reply to /random command */
|
||||||
struct RandomReply_Struct {
|
struct RandomReply_Struct {
|
||||||
/* 00 */ uint32 low;
|
/* 00 */ uint32 low;
|
||||||
/* 04 */ uint32 high;
|
/* 04 */ uint32 high;
|
||||||
|
|||||||
@ -2004,7 +2004,7 @@ namespace Titanium
|
|||||||
inst->IsScaling() ? inst->GetExp() / 100 : 0,
|
inst->IsScaling() ? inst->GetExp() / 100 : 0,
|
||||||
//merchant_slot, //instance ID, bullshit for now
|
//merchant_slot, //instance ID, bullshit for now
|
||||||
(merchant_slot == 0) ? inst->GetSerialNumber() : merchant_slot,
|
(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),
|
(stackable ? ((inst->GetItem()->ItemType == ItemTypePotion) ? 1 : 0) : charges),
|
||||||
inst->IsAttuned() ? 1 : 0,
|
inst->IsAttuned() ? 1 : 0,
|
||||||
0
|
0
|
||||||
|
|||||||
@ -438,7 +438,7 @@ struct SpawnAppearance_Struct
|
|||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
// solar: this is used inside profile
|
// this is used inside profile
|
||||||
struct SpellBuff_Struct
|
struct SpellBuff_Struct
|
||||||
{
|
{
|
||||||
/*000*/ uint8 slotid; //badly named... seems to be 2 for a real buff, 0 otherwise
|
/*000*/ uint8 slotid; //badly named... seems to be 2 for a real buff, 0 otherwise
|
||||||
@ -1054,7 +1054,7 @@ struct Animation_Struct {
|
|||||||
/*04*/
|
/*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
|
// get the particle effects around them when a spell is cast
|
||||||
// also causes a buff icon
|
// also causes a buff icon
|
||||||
struct Action_Struct
|
struct Action_Struct
|
||||||
@ -1078,7 +1078,7 @@ struct Action_Struct
|
|||||||
/* 31 */
|
/* 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
|
// melee messages like You try to pierce, etc. It's basically the melee
|
||||||
// and spell damage message
|
// and spell damage message
|
||||||
struct CombatDamage_Struct
|
struct CombatDamage_Struct
|
||||||
@ -1516,7 +1516,7 @@ struct RandomReq_Struct {
|
|||||||
uint32 high;
|
uint32 high;
|
||||||
};
|
};
|
||||||
|
|
||||||
/* solar: 9/23/03 reply to /random command; struct from Zaphod */
|
/* 9/23/03 reply to /random command */
|
||||||
struct RandomReply_Struct {
|
struct RandomReply_Struct {
|
||||||
/* 00 */ uint32 low;
|
/* 00 */ uint32 low;
|
||||||
/* 04 */ uint32 high;
|
/* 04 */ uint32 high;
|
||||||
|
|||||||
@ -3793,7 +3793,7 @@ namespace UF
|
|||||||
hdr.scaled_value = inst->IsScaling() ? inst->GetExp() / 100 : 0;
|
hdr.scaled_value = inst->IsScaling() ? inst->GetExp() / 100 : 0;
|
||||||
hdr.instance_id = (merchant_slot == 0) ? inst->GetSerialNumber() : merchant_slot;
|
hdr.instance_id = (merchant_slot == 0) ? inst->GetSerialNumber() : merchant_slot;
|
||||||
hdr.unknown028 = 0;
|
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.charges = (stackable ? (item->MaxCharges ? 1 : 0) : charges);
|
||||||
hdr.inst_nodrop = inst->IsAttuned() ? 1 : 0;
|
hdr.inst_nodrop = inst->IsAttuned() ? 1 : 0;
|
||||||
hdr.unknown044 = 0;
|
hdr.unknown044 = 0;
|
||||||
|
|||||||
@ -1250,7 +1250,7 @@ struct Animation_Struct {
|
|||||||
/*04*/
|
/*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
|
// get the particle effects around them when a spell is cast
|
||||||
// also causes a buff icon
|
// also causes a buff icon
|
||||||
struct Action_Struct
|
struct Action_Struct
|
||||||
@ -1305,7 +1305,7 @@ struct ActionAlt_Struct
|
|||||||
/*64*/
|
/*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
|
// melee messages like You try to pierce, etc. It's basically the melee
|
||||||
// and spell damage message
|
// and spell damage message
|
||||||
struct CombatDamage_Struct
|
struct CombatDamage_Struct
|
||||||
@ -1849,7 +1849,7 @@ struct RandomReq_Struct {
|
|||||||
uint32 high;
|
uint32 high;
|
||||||
};
|
};
|
||||||
|
|
||||||
/* solar: 9/23/03 reply to /random command; struct from Zaphod */
|
/* 9/23/03 reply to /random command */
|
||||||
struct RandomReply_Struct {
|
struct RandomReply_Struct {
|
||||||
/* 00 */ uint32 low;
|
/* 00 */ uint32 low;
|
||||||
/* 04 */ uint32 high;
|
/* 04 */ uint32 high;
|
||||||
|
|||||||
@ -79,6 +79,7 @@ public:
|
|||||||
inline const uint32 GetTimerTime() const { return timer_time; }
|
inline const uint32 GetTimerTime() const { return timer_time; }
|
||||||
inline const uint32 GetStartTime() const { return start_time; }
|
inline const uint32 GetStartTime() const { return start_time; }
|
||||||
inline const pTimerType GetType() const { return _type; }
|
inline const pTimerType GetType() const { return _type; }
|
||||||
|
inline const uint32 GetReadyTimestamp() const { return start_time + timer_time; }
|
||||||
|
|
||||||
inline bool Enabled() { return enabled; }
|
inline bool Enabled() { return enabled; }
|
||||||
|
|
||||||
|
|||||||
@ -438,30 +438,29 @@ bool SharedDatabase::GetSharedBank(uint32 id, Inventory *inv, bool is_charid)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!row[9])
|
if (row[9]) {
|
||||||
continue;
|
std::string data_str(row[9]);
|
||||||
|
std::string idAsString;
|
||||||
|
std::string value;
|
||||||
|
bool use_id = true;
|
||||||
|
|
||||||
std::string data_str(row[9]);
|
for (int i = 0; i < data_str.length(); ++i) {
|
||||||
std::string idAsString;
|
if (data_str[i] == '^') {
|
||||||
std::string value;
|
if (!use_id) {
|
||||||
bool use_id = true;
|
inst->SetCustomData(idAsString, value);
|
||||||
|
idAsString.clear();
|
||||||
for (int i = 0; i < data_str.length(); ++i) {
|
value.clear();
|
||||||
if (data_str[i] == '^') {
|
}
|
||||||
if (!use_id) {
|
use_id = !use_id;
|
||||||
inst->SetCustomData(idAsString, value);
|
continue;
|
||||||
idAsString.clear();
|
|
||||||
value.clear();
|
|
||||||
}
|
}
|
||||||
use_id = !use_id;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
char v = data_str[i];
|
char v = data_str[i];
|
||||||
if (use_id)
|
if (use_id)
|
||||||
idAsString.push_back(v);
|
idAsString.push_back(v);
|
||||||
else
|
else
|
||||||
value.push_back(v);
|
value.push_back(v);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
put_slot_id = inv->PutItem(slot_id, *inst);
|
put_slot_id = inv->PutItem(slot_id, *inst);
|
||||||
@ -499,6 +498,8 @@ bool SharedDatabase::GetInventory(uint32 char_id, Inventory *inv)
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
auto timestamps = GetItemRecastTimestamps(char_id);
|
||||||
|
|
||||||
for (auto row = results.begin(); row != results.end(); ++row) {
|
for (auto row = results.begin(); row != results.end(); ++row) {
|
||||||
int16 slot_id = atoi(row[0]);
|
int16 slot_id = atoi(row[0]);
|
||||||
uint32 item_id = atoi(row[1]);
|
uint32 item_id = atoi(row[1]);
|
||||||
@ -583,6 +584,13 @@ bool SharedDatabase::GetInventory(uint32 char_id, Inventory *inv)
|
|||||||
else
|
else
|
||||||
inst->SetCharges(charges);
|
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) {
|
if (item->ItemClass == ItemClassCommon) {
|
||||||
for (int i = AUG_BEGIN; i < EmuConstants::ITEM_COMMON_SIZE; i++) {
|
for (int i = AUG_BEGIN; i < EmuConstants::ITEM_COMMON_SIZE; i++) {
|
||||||
if (aug[i])
|
if (aug[i])
|
||||||
@ -726,6 +734,39 @@ bool SharedDatabase::GetInventory(uint32 account_id, char *name, Inventory *inv)
|
|||||||
return GetSharedBank(account_id, inv, false);
|
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)
|
void SharedDatabase::GetItemsCount(int32 &item_count, uint32 &max_id)
|
||||||
{
|
{
|
||||||
item_count = -1;
|
item_count = -1;
|
||||||
|
|||||||
@ -11,6 +11,7 @@
|
|||||||
#include "fixed_memory_variable_hash_set.h"
|
#include "fixed_memory_variable_hash_set.h"
|
||||||
|
|
||||||
#include <list>
|
#include <list>
|
||||||
|
#include <map>
|
||||||
|
|
||||||
class EvolveInfo;
|
class EvolveInfo;
|
||||||
class Inventory;
|
class Inventory;
|
||||||
@ -69,6 +70,9 @@ class SharedDatabase : public Database
|
|||||||
bool SetSharedPlatinum(uint32 account_id, int32 amount_to_add);
|
bool SetSharedPlatinum(uint32 account_id, int32 amount_to_add);
|
||||||
bool GetInventory(uint32 char_id, Inventory* inv);
|
bool GetInventory(uint32 char_id, Inventory* inv);
|
||||||
bool GetInventory(uint32 account_id, char* name, 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);
|
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.
|
1.
|
||||||
a) Client clicks a spell bar gem, ability, or item. client_process.cpp
|
a) Client clicks a spell bar gem, ability, or item. client_process.cpp
|
||||||
|
|||||||
@ -618,7 +618,7 @@ typedef enum {
|
|||||||
|
|
||||||
#define DF_Permanent 50
|
#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
|
// 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
|
// 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
|
// 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;
|
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)
|
char *CleanMobName(const char *in, char *out)
|
||||||
{
|
{
|
||||||
unsigned i, j;
|
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);
|
string_subject.replace(index, index + 1, replace_string);
|
||||||
index = string_subject.find_first_of(search_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
|
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_DATE __DATE__
|
||||||
#define COMPILE_TIME __TIME__
|
#define COMPILE_TIME __TIME__
|
||||||
#ifndef WIN32
|
#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|
|
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|
|
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|
|
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:
|
# Upgrade conditions:
|
||||||
# This won't be needed after this system is implemented, but it is used database that are not
|
# 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;
|
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
|
// table below
|
||||||
#define _TABLE_RACES 16
|
#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},
|
{ /*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},
|
{ /*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}
|
{ /*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)
|
if (!cc)
|
||||||
return false;
|
return false;
|
||||||
@ -1711,7 +1711,7 @@ bool CheckCharCreateInfoTitanium(CharCreate_Struct *cc)
|
|||||||
return false;
|
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
|
// this is what they start with, and they have stat_points more
|
||||||
// that can distributed
|
// that can distributed
|
||||||
bSTR = BaseClass[classtemp][0] + BaseRace[racetemp][0];
|
bSTR = BaseClass[classtemp][0] + BaseRace[racetemp][0];
|
||||||
@ -1725,7 +1725,7 @@ bool CheckCharCreateInfoTitanium(CharCreate_Struct *cc)
|
|||||||
bTOTAL = bSTR + bSTA + bAGI + bDEX + bWIS + bINT + bCHA;
|
bTOTAL = bSTR + bSTA + bAGI + bDEX + bWIS + bINT + bCHA;
|
||||||
cTOTAL = cc->STR + cc->STA + cc->AGI + cc->DEX + cc->WIS + cc->INT + cc->CHA;
|
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
|
// 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
|
// 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
|
// 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;
|
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) {
|
void WorldDatabase::GetCharSelectInfo(uint32 account_id, CharacterSelect_Struct* cs, uint32 ClientVersion) {
|
||||||
Inventory *inv;
|
Inventory *inv;
|
||||||
uint8 has_home = 0;
|
uint8 has_home = 0;
|
||||||
|
|||||||
@ -665,7 +665,7 @@ bool ZoneServer::Process() {
|
|||||||
}
|
}
|
||||||
case ServerOP_ZoneToZoneRequest: {
|
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
|
// 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.
|
// (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
|
// 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
|
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
|
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
|
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.
|
// 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.
|
// 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
|
// 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.
|
// cannot affect other clients that are not of the same pvp flag as them.
|
||||||
// also goes for their pets
|
// also goes for their pets
|
||||||
@ -717,7 +717,7 @@ bool Mob::IsBeneficialAllowed(Mob *target)
|
|||||||
if (target->GetAllowBeneficial())
|
if (target->GetAllowBeneficial())
|
||||||
return true;
|
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.
|
// first figure out if we're pets. we always look at the master's flags.
|
||||||
// no need to compare pets to anything
|
// 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)
|
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.
|
* and does other mitigation checks. 'this' is the mob being attacked.
|
||||||
*
|
*
|
||||||
* special return values:
|
* special return values:
|
||||||
@ -1378,7 +1378,7 @@ void Client::Damage(Mob* other, int32 damage, uint16 spell_id, SkillUseTypes att
|
|||||||
if(spell_id==0)
|
if(spell_id==0)
|
||||||
spell_id = SPELL_UNKNOWN;
|
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
|
// Blasting ourselfs is considered PvP
|
||||||
//Don't do PvP mitigation if the caster is damaging himself
|
//Don't do PvP mitigation if the caster is damaging himself
|
||||||
if(other && other->IsClient() && (other != this) && damage > 0) {
|
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
|
// 'this' is the one being attacked
|
||||||
// 'other' is the attacker
|
// 'other' is the attacker
|
||||||
// a damage shield causes damage (or healing) to whoever attacks the wearer
|
// 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.
|
target to center around.
|
||||||
|
|
||||||
*/
|
*/
|
||||||
@ -48,7 +48,7 @@ class Zone;
|
|||||||
extern EntityList entity_list;
|
extern EntityList entity_list;
|
||||||
extern Zone* zone;
|
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
|
// useful for anything
|
||||||
Beacon::Beacon(Mob *at_mob, int lifetime)
|
Beacon::Beacon(Mob *at_mob, int lifetime)
|
||||||
:Mob
|
:Mob
|
||||||
|
|||||||
@ -7406,7 +7406,7 @@ float Bot::GetProcChances(float ProcBonus, uint16 hand) {
|
|||||||
|
|
||||||
bool Bot::AvoidDamage(Mob* other, int32 &damage, bool CanRiposte)
|
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.
|
* and does other mitigation checks. 'this' is the mob being attacked.
|
||||||
*
|
*
|
||||||
* special return values:
|
* 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
|
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
|
int chance = 10 + (GetDEX()/10) + (itembonuses.HeroicDEX/10); //18.5% chance at 85 dex 40% chance at 300 dex
|
||||||
if(
|
if(
|
||||||
level >= 60 && // bot is 60 or higher
|
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;
|
std::cout << "Received 0x" << std::hex << std::setw(4) << std::setfill('0') << opcode << ", size=" << std::dec << app->size << std::endl;
|
||||||
#endif
|
#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) {
|
switch(client_state) {
|
||||||
case CLIENT_CONNECTING: {
|
case CLIENT_CONNECTING: {
|
||||||
if(ConnectingOpcodes.count(opcode) != 1) {
|
if(ConnectingOpcodes.count(opcode) != 1) {
|
||||||
@ -1395,6 +1386,7 @@ void Client::Handle_Connect_OP_ZoneEntry(const EQApplicationPacket *app)
|
|||||||
if (RuleB(Character, SharedBankPlat))
|
if (RuleB(Character, SharedBankPlat))
|
||||||
m_pp.platinum_shared = database.GetSharedPlatinum(this->AccountID());
|
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 */
|
loaditems = database.GetInventory(cid, &m_inv); /* Load Character Inventory */
|
||||||
database.LoadCharacterBandolier(cid, &m_pp); /* Load Character Bandolier */
|
database.LoadCharacterBandolier(cid, &m_pp); /* Load Character Bandolier */
|
||||||
database.LoadCharacterBindPoint(cid, &m_pp); /* Load Character Bind */
|
database.LoadCharacterBindPoint(cid, &m_pp); /* Load Character Bind */
|
||||||
|
|||||||
@ -960,6 +960,9 @@ void Client::BulkSendInventoryItems()
|
|||||||
void Client::BulkSendMerchantInventory(int merchant_id, int npcid) {
|
void Client::BulkSendMerchantInventory(int merchant_id, int npcid) {
|
||||||
const Item_Struct* handyitem = nullptr;
|
const Item_Struct* handyitem = nullptr;
|
||||||
uint32 numItemSlots = 80; //The max number of items passed in the transaction.
|
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;
|
const Item_Struct *item;
|
||||||
std::list<MerchantList> merlist = zone->merchanttable[merchant_id];
|
std::list<MerchantList> merlist = zone->merchanttable[merchant_id];
|
||||||
std::list<MerchantList>::const_iterator itr;
|
std::list<MerchantList>::const_iterator itr;
|
||||||
|
|||||||
@ -7,7 +7,7 @@
|
|||||||
#define HIGHEST_RESIST 9 //Max resist type value
|
#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.
|
#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 _CLIENT(x) (x && x->IsClient() && !x->CastToClient()->IsBecomeNPC())
|
||||||
#define _NPC(x) (x && x->IsNPC() && !x->CastToMob()->GetOwnerID())
|
#define _NPC(x) (x && x->IsNPC() && !x->CastToMob()->GetOwnerID())
|
||||||
#define _BECOMENPC(x) (x && x->IsClient() && x->CastToClient()->IsBecomeNPC())
|
#define _BECOMENPC(x) (x && x->IsClient() && x->CastToClient()->IsBecomeNPC())
|
||||||
|
|||||||
@ -318,7 +318,7 @@ Corpse::Corpse(Client* client, int32 in_rezexp) : Mob (
|
|||||||
// get their tints
|
// get their tints
|
||||||
memcpy(item_tint, &client->GetPP().item_tint, sizeof(item_tint));
|
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
|
// to go into the regular slots on the player, out of bags
|
||||||
std::list<uint32> removed_list;
|
std::list<uint32> removed_list;
|
||||||
|
|
||||||
@ -965,6 +965,7 @@ void Corpse::MakeLootRequestPackets(Client* client, const EQApplicationPacket* a
|
|||||||
Save();
|
Save();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
auto timestamps = database.GetItemRecastTimestamps(client->CharacterID());
|
||||||
outapp->priority = 6;
|
outapp->priority = 6;
|
||||||
client->QueuePacket(outapp);
|
client->QueuePacket(outapp);
|
||||||
safe_delete(outapp);
|
safe_delete(outapp);
|
||||||
@ -973,6 +974,8 @@ void Corpse::MakeLootRequestPackets(Client* client, const EQApplicationPacket* a
|
|||||||
const Item_Struct* item = database.GetItem(pkitem);
|
const Item_Struct* item = database.GetItem(pkitem);
|
||||||
ItemInst* inst = database.CreateItem(item, item->MaxCharges);
|
ItemInst* inst = database.CreateItem(item, item->MaxCharges);
|
||||||
if(inst) {
|
if(inst) {
|
||||||
|
if (item->RecastDelay)
|
||||||
|
inst->SetRecastTimestamp(timestamps.count(item->RecastType) ? timestamps.at(item->RecastType) : 0);
|
||||||
client->SendItemPacket(EmuConstants::CORPSE_BEGIN, inst, ItemPacketLoot);
|
client->SendItemPacket(EmuConstants::CORPSE_BEGIN, inst, ItemPacketLoot);
|
||||||
safe_delete(inst);
|
safe_delete(inst);
|
||||||
}
|
}
|
||||||
@ -1004,6 +1007,8 @@ void Corpse::MakeLootRequestPackets(Client* client, const EQApplicationPacket* a
|
|||||||
if(client && item) {
|
if(client && item) {
|
||||||
ItemInst* inst = database.CreateItem(item, item_data->charges, item_data->aug_1, item_data->aug_2, item_data->aug_3, item_data->aug_4, item_data->aug_5, item_data->aug_6, item_data->attuned);
|
ItemInst* inst = database.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(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
|
// MainGeneral1 is the corpse inventory start offset for Ti(EMu) - CORPSE_END = MainGeneral1 + MainCursor
|
||||||
client->SendItemPacket(i + EmuConstants::CORPSE_BEGIN, inst, ItemPacketLoot);
|
client->SendItemPacket(i + EmuConstants::CORPSE_BEGIN, inst, ItemPacketLoot);
|
||||||
safe_delete(inst);
|
safe_delete(inst);
|
||||||
@ -1460,4 +1465,4 @@ void Corpse::LoadPlayerCorpseDecayTime(uint32 corpse_db_id){
|
|||||||
else {
|
else {
|
||||||
corpse_graveyard_timer.SetTimer(3000);
|
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.
|
// spell_id.
|
||||||
// NPC spells will only affect other NPCs with compatible faction
|
// 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)
|
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.
|
// a bard pulse of spell_id.
|
||||||
// NPC spells will only affect other NPCs with compatible faction
|
// NPC spells will only affect other NPCs with compatible faction
|
||||||
void EntityList::AEBardPulse(Mob *caster, Mob *center, uint16 spell_id, bool affect_caster)
|
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
|
if(bag_item_data) { // bag contents
|
||||||
int16 interior_slot;
|
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++) {
|
for(int i = SUB_BEGIN; i < EmuConstants::ITEM_CONTAINER_SIZE; i++) {
|
||||||
if(bag_item_data[i] == nullptr)
|
if(bag_item_data[i] == nullptr)
|
||||||
continue;
|
continue;
|
||||||
@ -993,7 +993,7 @@ bool Client::AutoPutLootInInventory(ItemInst& inst, bool try_worn, bool try_curs
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// solar: helper function for AutoPutLootInInventory
|
// helper function for AutoPutLootInInventory
|
||||||
void Client::MoveItemCharges(ItemInst &from, int16 to_slot, uint8 type)
|
void Client::MoveItemCharges(ItemInst &from, int16 to_slot, uint8 type)
|
||||||
{
|
{
|
||||||
ItemInst *tmp_inst = m_inv.GetItem(to_slot);
|
ItemInst *tmp_inst = m_inv.GetItem(to_slot);
|
||||||
|
|||||||
@ -35,14 +35,13 @@
|
|||||||
#include "zone.h"
|
#include "zone.h"
|
||||||
#include "lua_parser.h"
|
#include "lua_parser.h"
|
||||||
|
|
||||||
const char *LuaEvents[_LargestEventID] = {
|
const char *LuaEvents[_LargestEventID] = {
|
||||||
"event_say",
|
"event_say",
|
||||||
"event_trade",
|
"event_trade",
|
||||||
"event_death",
|
"event_death",
|
||||||
"event_spawn",
|
"event_spawn",
|
||||||
"event_attack",
|
"event_attack",
|
||||||
"event_combat",
|
"event_combat",
|
||||||
"event_environmental_damage",
|
|
||||||
"event_aggro",
|
"event_aggro",
|
||||||
"event_slay",
|
"event_slay",
|
||||||
"event_npc_slay",
|
"event_npc_slay",
|
||||||
@ -68,6 +67,7 @@ const char *LuaEvents[_LargestEventID] = {
|
|||||||
"event_aggro_say",
|
"event_aggro_say",
|
||||||
"event_player_pickup",
|
"event_player_pickup",
|
||||||
"event_popup_response",
|
"event_popup_response",
|
||||||
|
"event_environmental_damage",
|
||||||
"event_proximity_say",
|
"event_proximity_say",
|
||||||
"event_cast",
|
"event_cast",
|
||||||
"event_cast_begin",
|
"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)
|
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)
|
if (zone->zonemap != nullptr)
|
||||||
{
|
{
|
||||||
glm::vec3 me;
|
glm::vec3 me;
|
||||||
me.x = m_Position.x;
|
me.x = new_x;
|
||||||
me.y = m_Position.y;
|
me.y = new_y;
|
||||||
me.z = m_Position.z + z_offset;
|
me.z = m_Position.z + z_offset;
|
||||||
glm::vec3 hit;
|
glm::vec3 hit;
|
||||||
float best_z = zone->zonemap->FindBestZ(me, &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)
|
if (zone->zonemap != 0)
|
||||||
{
|
{
|
||||||
glm::vec3 me;
|
glm::vec3 me;
|
||||||
me.x = m_Position.x;
|
me.x = new_x;
|
||||||
me.y = m_Position.y;
|
me.y = new_y;
|
||||||
me.z = m_Position.z+z_offset;
|
me.z = m_Position.z+z_offset;
|
||||||
glm::vec3 hit;
|
glm::vec3 hit;
|
||||||
float best_z = zone->zonemap->FindBestZ(me, &hit);
|
float best_z = zone->zonemap->FindBestZ(me, &hit);
|
||||||
|
|||||||
@ -123,7 +123,7 @@ public:
|
|||||||
|
|
||||||
//Attack
|
//Attack
|
||||||
virtual void RogueBackstab(Mob* other, bool min_damage = false, int ReuseTime = 10);
|
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;
|
float MobAngle(Mob *other = 0, float ourx = 0.0f, float oury = 0.0f) const;
|
||||||
// greater than 90 is behind
|
// greater than 90 is behind
|
||||||
inline bool BehindMob(Mob *other = 0, float ourx = 0.0f, float oury = 0.0f) const
|
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)
|
// 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;
|
int starting_npc_id = client->GetZoneID() * 1000;
|
||||||
|
|
||||||
std::string query = StringFormat("SELECT MAX(id) FROM npc_types WHERE id >= %i AND id < %i",
|
std::string query = StringFormat("SELECT MAX(id) FROM npc_types WHERE id >= %i AND id < %i",
|
||||||
starting_npc_id, starting_npc_id + 1000);
|
starting_npc_id, starting_npc_id + 1000);
|
||||||
auto results = QueryDatabase(query);
|
auto results = QueryDatabase(query);
|
||||||
if (results.Success()) {
|
if (results.Success()) {
|
||||||
if (results.RowCount() != 0)
|
if (results.RowCount() != 0) {
|
||||||
{
|
auto row = results.begin();
|
||||||
auto row = results.begin();
|
npc_type_id = atoi(row[0]) + 1;
|
||||||
npc_type_id = atoi(row[0]) + 1;
|
// Prevent the npc_type id from exceeding the range for this zone
|
||||||
// Prevent the npc_type id from exceeding the range for this zone
|
if (npc_type_id >= (starting_npc_id + 1000))
|
||||||
if (npc_type_id >= (starting_npc_id + 1000))
|
npc_type_id = 0;
|
||||||
npc_type_id = 0;
|
} else // No npc_type IDs set in this range yet
|
||||||
}
|
npc_type_id = starting_npc_id;
|
||||||
else // No npc_type IDs set in this range yet
|
}
|
||||||
npc_type_id = starting_npc_id;
|
}
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
char tmpstr[64];
|
char tmpstr[64];
|
||||||
EntityList::RemoveNumbers(strn0cpy(tmpstr, spawn->GetName(), sizeof(tmpstr)));
|
EntityList::RemoveNumbers(strn0cpy(tmpstr, spawn->GetName(), sizeof(tmpstr)));
|
||||||
std::string query;
|
std::string query;
|
||||||
if (npc_type_id)
|
if (npc_type_id) {
|
||||||
{
|
query = StringFormat("INSERT INTO npc_types (id, name, level, race, class, hp, gender, "
|
||||||
query = StringFormat("INSERT INTO npc_types (id, name, level, race, class, hp, gender, "
|
"texture, helmtexture, size, loottable_id, merchant_id, face, "
|
||||||
"texture, helmtexture, size, loottable_id, merchant_id, face, "
|
"runspeed, prim_melee_type, sec_melee_type) "
|
||||||
"runspeed, prim_melee_type, sec_melee_type) "
|
"VALUES(%i, \"%s\" , %i, %i, %i, %i, %i, %i, %i, %f, %i, %i, %i, %f, %i, %i)",
|
||||||
"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(),
|
||||||
npc_type_id, tmpstr, spawn->GetLevel(), spawn->GetRace(), spawn->GetClass(),
|
spawn->GetMaxHP(), spawn->GetGender(), spawn->GetTexture(),
|
||||||
spawn->GetMaxHP(), spawn->GetGender(), spawn->GetTexture(),
|
spawn->GetHelmTexture(), spawn->GetSize(), spawn->GetLoottableID(),
|
||||||
spawn->GetHelmTexture(), spawn->GetSize(), spawn->GetLoottableID(),
|
spawn->MerchantType, 0, spawn->GetRunspeed(), 28, 28);
|
||||||
spawn->MerchantType, 0, spawn->GetRunspeed(), 28, 28);
|
auto results = QueryDatabase(query);
|
||||||
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()) {
|
if (!results.Success()) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
npc_type_id = results.LastInsertedID();
|
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());
|
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()) {
|
if (!results.Success()) {
|
||||||
return false;
|
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)",
|
||||||
query = StringFormat("INSERT INTO spawn2 (zone, version, x, y, z, respawntime, heading, spawngroupID) "
|
zone, zone_version, spawn->GetX(), spawn->GetY(), spawn->GetZ(), 1200, spawn->GetHeading(),
|
||||||
"VALUES('%s', %u, %f, %f, %f, %i, %f, %i)",
|
spawngroupid);
|
||||||
zone, zone_version, spawn->GetX(), spawn->GetY(), spawn->GetZ(), 1200,
|
results = QueryDatabase(query);
|
||||||
spawn->GetHeading(), spawngroupid);
|
|
||||||
results = QueryDatabase(query);
|
|
||||||
if (!results.Success()) {
|
if (!results.Success()) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(client)
|
query = StringFormat("INSERT INTO spawnentry (spawngroupID, npcID, chance) VALUES(%i, %i, %i)", spawngroupid,
|
||||||
|
npc_type_id, 100);
|
||||||
query = StringFormat("INSERT INTO spawnentry (spawngroupID, npcID, chance) VALUES(%i, %i, %i)",
|
results = QueryDatabase(query);
|
||||||
spawngroupid, npc_type_id, 100);
|
|
||||||
results = QueryDatabase(query);
|
|
||||||
if (!results.Success()) {
|
if (!results.Success()) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(client)
|
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32 ZoneDatabase::AddNewNPCSpawnGroupCommand(const char* zone, uint32 zone_version, Client *client, NPC* spawn, uint32 respawnTime) {
|
uint32 ZoneDatabase::AddNewNPCSpawnGroupCommand(const char *zone, uint32 zone_version, Client *client, NPC *spawn,
|
||||||
uint32 last_insert_id = 0;
|
uint32 respawnTime)
|
||||||
|
{
|
||||||
|
uint32 last_insert_id = 0;
|
||||||
|
|
||||||
std::string query = StringFormat("INSERT INTO spawngroup (name) VALUES('%s%s%i')",
|
std::string query = StringFormat("INSERT INTO spawngroup (name) VALUES('%s%s%i')", zone, spawn->GetName(),
|
||||||
zone, spawn->GetName(), Timer::GetCurrentTime());
|
Timer::GetCurrentTime());
|
||||||
auto results = QueryDatabase(query);
|
auto results = QueryDatabase(query);
|
||||||
if (!results.Success()) {
|
if (!results.Success()) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
last_insert_id = results.LastInsertedID();
|
last_insert_id = results.LastInsertedID();
|
||||||
|
|
||||||
uint32 respawntime = 0;
|
uint32 respawntime = 0;
|
||||||
uint32 spawnid = 0;
|
uint32 spawnid = 0;
|
||||||
if (respawnTime)
|
if (respawnTime)
|
||||||
respawntime = respawnTime;
|
respawntime = respawnTime;
|
||||||
else if(spawn->respawn2 && spawn->respawn2->RespawnTimer() != 0)
|
else if (spawn->respawn2 && spawn->respawn2->RespawnTimer() != 0)
|
||||||
respawntime = spawn->respawn2->RespawnTimer();
|
respawntime = spawn->respawn2->RespawnTimer();
|
||||||
else
|
else
|
||||||
respawntime = 1200;
|
respawntime = 1200;
|
||||||
|
|
||||||
query = StringFormat("INSERT INTO spawn2 (zone, version, x, y, z, respawntime, heading, spawngroupID) "
|
query = StringFormat("INSERT INTO spawn2 (zone, version, x, y, z, respawntime, heading, spawngroupID) "
|
||||||
"VALUES('%s', %u, %f, %f, %f, %i, %f, %i)",
|
"VALUES('%s', %u, %f, %f, %f, %i, %f, %i)",
|
||||||
zone, zone_version, spawn->GetX(), spawn->GetY(), spawn->GetZ(), respawntime,
|
zone, zone_version, spawn->GetX(), spawn->GetY(), spawn->GetZ(), respawntime,
|
||||||
spawn->GetHeading(), last_insert_id);
|
spawn->GetHeading(), last_insert_id);
|
||||||
results = QueryDatabase(query);
|
results = QueryDatabase(query);
|
||||||
if (!results.Success()) {
|
if (!results.Success()) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
spawnid = results.LastInsertedID();
|
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)",
|
return spawnid;
|
||||||
last_insert_id, spawn->GetNPCTypeID(), 100);
|
|
||||||
results = QueryDatabase(query);
|
|
||||||
if (!results.Success()) {
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(client)
|
|
||||||
|
|
||||||
return spawnid;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32 ZoneDatabase::UpdateNPCTypeAppearance(Client *client, NPC* spawn) {
|
uint32 ZoneDatabase::UpdateNPCTypeAppearance(Client *client, NPC *spawn)
|
||||||
|
{
|
||||||
std::string query = StringFormat("UPDATE npc_types SET name = \"%s\", level = %i, race = %i, class = %i, "
|
std::string query =
|
||||||
"hp = %i, gender = %i, texture = %i, helmtexture = %i, size = %i, "
|
StringFormat("UPDATE npc_types SET name = \"%s\", level = %i, race = %i, class = %i, "
|
||||||
"loottable_id = %i, merchant_id = %i, face = %i, WHERE id = %i",
|
"hp = %i, gender = %i, texture = %i, helmtexture = %i, size = %i, "
|
||||||
spawn->GetName(), spawn->GetLevel(), spawn->GetRace(), spawn->GetClass(),
|
"loottable_id = %i, merchant_id = %i, face = %i, WHERE id = %i",
|
||||||
spawn->GetMaxHP(), spawn->GetGender(), spawn->GetTexture(),
|
spawn->GetName(), spawn->GetLevel(), spawn->GetRace(), spawn->GetClass(), spawn->GetMaxHP(),
|
||||||
spawn->GetHelmTexture(), spawn->GetSize(), spawn->GetLoottableID(),
|
spawn->GetGender(), spawn->GetTexture(), spawn->GetHelmTexture(), spawn->GetSize(),
|
||||||
spawn->MerchantType, spawn->GetNPCTypeID());
|
spawn->GetLoottableID(), spawn->MerchantType, spawn->GetNPCTypeID());
|
||||||
auto results = QueryDatabase(query);
|
auto results = QueryDatabase(query);
|
||||||
if (!results.Success() && client)
|
return results.Success() == true ? 1 : 0;
|
||||||
|
|
||||||
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 id = 0;
|
||||||
uint32 spawngroupID = 0;
|
uint32 spawngroupID = 0;
|
||||||
|
|
||||||
std::string query = StringFormat("SELECT id, spawngroupID FROM spawn2 WHERE "
|
std::string query = StringFormat("SELECT id, spawngroupID FROM spawn2 WHERE "
|
||||||
"zone='%s' AND spawngroupID=%i", zone, spawn->GetSp2());
|
"zone='%s' AND spawngroupID=%i",
|
||||||
auto results = QueryDatabase(query);
|
zone, spawn->GetSp2());
|
||||||
if (!results.Success())
|
auto results = QueryDatabase(query);
|
||||||
|
if (!results.Success())
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
if (results.RowCount() == 0)
|
if (results.RowCount() == 0)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
auto row = results.begin();
|
auto row = results.begin();
|
||||||
if (row[0])
|
if (row[0])
|
||||||
id = atoi(row[0]);
|
id = atoi(row[0]);
|
||||||
|
|
||||||
if (row[1])
|
if (row[1])
|
||||||
spawngroupID = atoi(row[1]);
|
spawngroupID = atoi(row[1]);
|
||||||
|
|
||||||
query = StringFormat("DELETE FROM spawn2 WHERE id = '%i'", id);
|
query = StringFormat("DELETE FROM spawn2 WHERE id = '%i'", id);
|
||||||
results = QueryDatabase(query);
|
results = QueryDatabase(query);
|
||||||
if (!results.Success())
|
if (!results.Success())
|
||||||
return 0;
|
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())
|
if (!results.Success())
|
||||||
return 0;
|
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())
|
if (!results.Success())
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
if(client)
|
|
||||||
|
|
||||||
return 1;
|
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 id = 0;
|
||||||
uint32 spawngroupID = 0;
|
uint32 spawngroupID = 0;
|
||||||
|
|
||||||
std::string query = StringFormat("SELECT id, spawngroupID FROM spawn2 WHERE zone = '%s' "
|
std::string query = StringFormat("SELECT id, spawngroupID FROM spawn2 WHERE zone = '%s' "
|
||||||
"AND version = %u AND spawngroupID = %i",
|
"AND version = %u AND spawngroupID = %i",
|
||||||
zone, zone_version, spawn->GetSp2());
|
zone, zone_version, spawn->GetSp2());
|
||||||
auto results = QueryDatabase(query);
|
auto results = QueryDatabase(query);
|
||||||
if (!results.Success())
|
if (!results.Success())
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
if (results.RowCount() == 0)
|
if (results.RowCount() == 0)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
auto row = results.begin();
|
auto row = results.begin();
|
||||||
|
|
||||||
if (row[0])
|
if (row[0])
|
||||||
id = atoi(row[0]);
|
id = atoi(row[0]);
|
||||||
|
|
||||||
if (row[1])
|
if (row[1])
|
||||||
spawngroupID = atoi(row[1]);
|
spawngroupID = atoi(row[1]);
|
||||||
|
|
||||||
query = StringFormat("DELETE FROM spawn2 WHERE id = '%i'", id);
|
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);
|
results = QueryDatabase(query);
|
||||||
if (!results.Success())
|
if (!results.Success())
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
if(client)
|
query = StringFormat("DELETE FROM spawngroup WHERE id = '%i'", spawngroupID);
|
||||||
|
|
||||||
query = StringFormat("DELETE FROM spawnentry WHERE spawngroupID = '%i'", spawngroupID);
|
|
||||||
results = QueryDatabase(query);
|
results = QueryDatabase(query);
|
||||||
if (!results.Success())
|
if (!results.Success())
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
if(client)
|
query = StringFormat("DELETE FROM spawnentry WHERE spawngroupID = '%i'", spawngroupID);
|
||||||
|
|
||||||
query = StringFormat("DELETE FROM npc_types WHERE id = '%i'", spawn->GetNPCTypeID());
|
|
||||||
results = QueryDatabase(query);
|
results = QueryDatabase(query);
|
||||||
if (!results.Success())
|
if (!results.Success())
|
||||||
return 0;
|
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;
|
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;
|
uint32 last_insert_id = 0;
|
||||||
std::string query = StringFormat("INSERT INTO spawn2 (zone, version, x, y, z, respawntime, heading, spawngroupID) "
|
std::string query =
|
||||||
"VALUES('%s', %u, %f, %f, %f, %i, %f, %i)",
|
StringFormat("INSERT INTO spawn2 (zone, version, x, y, z, respawntime, heading, spawngroupID) "
|
||||||
zone, zone_version, client->GetX(), client->GetY(), client->GetZ(),
|
"VALUES('%s', %u, %f, %f, %f, %i, %f, %i)",
|
||||||
120, client->GetHeading(), spawnGroupID);
|
zone, zone_version, client->GetX(), client->GetY(), client->GetZ(), 120, client->GetHeading(),
|
||||||
auto results = QueryDatabase(query);
|
spawnGroupID);
|
||||||
if (!results.Success())
|
auto results = QueryDatabase(query);
|
||||||
|
if (!results.Success())
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
if(client)
|
return 1;
|
||||||
|
|
||||||
return 1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32 ZoneDatabase::AddNPCTypes(const char* zone, uint32 zone_version, Client *client, NPC* spawn, uint32 spawnGroupID) {
|
uint32 ZoneDatabase::AddNPCTypes(const char *zone, uint32 zone_version, Client *client, NPC *spawn, uint32 spawnGroupID)
|
||||||
|
{
|
||||||
uint32 npc_type_id;
|
uint32 npc_type_id;
|
||||||
char numberlessName[64];
|
char numberlessName[64];
|
||||||
|
|
||||||
EntityList::RemoveNumbers(strn0cpy(numberlessName, spawn->GetName(), sizeof(numberlessName)));
|
EntityList::RemoveNumbers(strn0cpy(numberlessName, spawn->GetName(), sizeof(numberlessName)));
|
||||||
std::string query = StringFormat("INSERT INTO npc_types (name, level, race, class, hp, gender, "
|
std::string query =
|
||||||
"texture, helmtexture, size, loottable_id, merchant_id, face, "
|
StringFormat("INSERT INTO npc_types (name, level, race, class, hp, gender, "
|
||||||
"runspeed, prim_melee_type, sec_melee_type) "
|
"texture, helmtexture, size, loottable_id, merchant_id, face, "
|
||||||
"VALUES(\"%s\", %i, %i, %i, %i, %i, %i, %i, %f, %i, %i, %i, %f, %i, %i)",
|
"runspeed, prim_melee_type, sec_melee_type) "
|
||||||
numberlessName, spawn->GetLevel(), spawn->GetRace(), spawn->GetClass(),
|
"VALUES(\"%s\", %i, %i, %i, %i, %i, %i, %i, %f, %i, %i, %i, %f, %i, %i)",
|
||||||
spawn->GetMaxHP(), spawn->GetGender(), spawn->GetTexture(),
|
numberlessName, spawn->GetLevel(), spawn->GetRace(), spawn->GetClass(), spawn->GetMaxHP(),
|
||||||
spawn->GetHelmTexture(), spawn->GetSize(), spawn->GetLoottableID(),
|
spawn->GetGender(), spawn->GetTexture(), spawn->GetHelmTexture(), spawn->GetSize(),
|
||||||
spawn->MerchantType, 0, spawn->GetRunspeed(), 28, 28);
|
spawn->GetLoottableID(), spawn->MerchantType, 0, spawn->GetRunspeed(), 28, 28);
|
||||||
auto results = QueryDatabase(query);
|
auto results = QueryDatabase(query);
|
||||||
if (!results.Success())
|
if (!results.Success())
|
||||||
return 0;
|
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;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -467,16 +467,21 @@ bool Object::HandleClick(Client* sender, const ClickObject_Struct* click_object)
|
|||||||
if (m_inst && sender) {
|
if (m_inst && sender) {
|
||||||
// if there is a lore conflict, delete the offending item from the server inventory
|
// 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
|
// the client updates itself and takes care of sending "duplicate lore item" messages
|
||||||
if(sender->CheckLoreConflict(m_inst->GetItem())) {
|
auto item = m_inst->GetItem();
|
||||||
int16 loreslot = sender->GetInv().HasItem(m_inst->GetItem()->ID, 0, invWhereBank);
|
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.
|
if (loreslot != INVALID_INDEX) // if the duplicate is in the bank, delete it.
|
||||||
sender->DeleteItemInInventory(loreslot);
|
sender->DeleteItemInInventory(loreslot);
|
||||||
else
|
else
|
||||||
cursordelete = true; // otherwise, we delete the new one
|
cursordelete = true; // otherwise, we delete the new one
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (item->RecastDelay)
|
||||||
|
m_inst->SetRecastTimestamp(
|
||||||
|
database.GetItemRecastTimestamp(sender->CharacterID(), item->RecastType));
|
||||||
|
|
||||||
char buf[10];
|
char buf[10];
|
||||||
snprintf(buf, 9, "%u", m_inst->GetItem()->ID);
|
snprintf(buf, 9, "%u", item->ID);
|
||||||
buf[9] = '\0';
|
buf[9] = '\0';
|
||||||
std::vector<EQEmu::Any> args;
|
std::vector<EQEmu::Any> args;
|
||||||
args.push_back(m_inst);
|
args.push_back(m_inst);
|
||||||
|
|||||||
@ -663,7 +663,7 @@ void Mob::RogueBackstab(Mob* other, bool min_damage, int ReuseTime)
|
|||||||
DoAnim(animPiercing);
|
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)
|
void Mob::RogueAssassinate(Mob* other)
|
||||||
{
|
{
|
||||||
//can you dodge, parry, etc.. an assassinate??
|
//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.
|
//Can we start the timer here? I don't see why not.
|
||||||
CastToClient()->GetPTimers().Start((pTimerItemStart + recasttype), recastdelay);
|
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 #2 - execute the spell
|
||||||
//
|
//
|
||||||
|
|
||||||
switch(CastAction)
|
switch(CastAction)
|
||||||
{
|
{
|
||||||
default:
|
default:
|
||||||
@ -2146,6 +2149,15 @@ bool Mob::SpellFinished(uint16 spell_id, Mob *spell_target, uint16 slot, uint16
|
|||||||
// caster if they're not using TGB
|
// caster if they're not using TGB
|
||||||
// NOTE: this will always hit the caster, plus the target's group so
|
// 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
|
// 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())
|
if(spell_target->IsGrouped())
|
||||||
{
|
{
|
||||||
Group *target_group = entity_list.GetGroupByMob(spell_target);
|
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);
|
ItemInst *itm = CastToClient()->GetInv().GetItem(inventory_slot);
|
||||||
if(itm && itm->GetItem()->RecastDelay > 0){
|
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));
|
EQApplicationPacket *outapp = new EQApplicationPacket(OP_ItemRecastDelay, sizeof(ItemRecastDelay_Struct));
|
||||||
ItemRecastDelay_Struct *ird = (ItemRecastDelay_Struct *)outapp->pBuffer;
|
ItemRecastDelay_Struct *ird = (ItemRecastDelay_Struct *)outapp->pBuffer;
|
||||||
ird->recast_delay = itm->GetItem()->RecastDelay;
|
ird->recast_delay = itm->GetItem()->RecastDelay;
|
||||||
ird->recast_type = itm->GetItem()->RecastType;
|
ird->recast_type = recast_type;
|
||||||
CastToClient()->QueuePacket(outapp);
|
CastToClient()->QueuePacket(outapp);
|
||||||
safe_delete(outapp);
|
safe_delete(outapp);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -647,7 +647,7 @@ void WorldServer::Process() {
|
|||||||
case ServerOP_Petition: {
|
case ServerOP_Petition: {
|
||||||
std::cout << "Got Server Requested Petition List Refresh" << std::endl;
|
std::cout << "Got Server Requested Petition List Refresh" << std::endl;
|
||||||
ServerPetitionUpdate_Struct* sus = (ServerPetitionUpdate_Struct*) pack->pBuffer;
|
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();
|
if (sus->status == 0) petition_list.ReadDatabase();
|
||||||
else if (sus->status == 1) petition_list.ReadDatabase(); // Until I fix this to be better....
|
else if (sus->status == 1) petition_list.ReadDatabase(); // Until I fix this to be better....
|
||||||
break;
|
break;
|
||||||
|
|||||||
@ -2999,6 +2999,14 @@ void ZoneDatabase::RemoveTempFactions(Client *client) {
|
|||||||
QueryDatabase(query);
|
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) {
|
void ZoneDatabase::LoadPetInfo(Client *client) {
|
||||||
|
|
||||||
// Load current pet and suspended pet
|
// Load current pet and suspended pet
|
||||||
|
|||||||
@ -256,6 +256,7 @@ public:
|
|||||||
void LoadPetInfo(Client *c);
|
void LoadPetInfo(Client *c);
|
||||||
void SavePetInfo(Client *c);
|
void SavePetInfo(Client *c);
|
||||||
void RemoveTempFactions(Client *c);
|
void RemoveTempFactions(Client *c);
|
||||||
|
void UpdateItemRecastTimestamps(uint32 char_id, uint32 recast_type, uint32 timestamp);
|
||||||
|
|
||||||
/* Character Data Loaders */
|
/* Character Data Loaders */
|
||||||
bool LoadCharacterFactionValues(uint32 character_id, faction_map & val_list);
|
bool LoadCharacterFactionValues(uint32 character_id, faction_map & val_list);
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user