mirror of
https://github.com/EQEmu/Server.git
synced 2026-03-28 15:42:26 +00:00
Merge branch 'master' into feature/eqemu-api-data-service-netstats-ws
This commit is contained in:
commit
09b633e374
@ -26,24 +26,26 @@
|
|||||||
std::string EQEmuConfig::ConfigFile = "eqemu_config.json";
|
std::string EQEmuConfig::ConfigFile = "eqemu_config.json";
|
||||||
EQEmuConfig *EQEmuConfig::_config = nullptr;
|
EQEmuConfig *EQEmuConfig::_config = nullptr;
|
||||||
|
|
||||||
void EQEmuConfig::parse_config() {
|
void EQEmuConfig::parse_config()
|
||||||
|
{
|
||||||
ShortName = _root["server"]["world"].get("shortname", "").asString();
|
|
||||||
LongName = _root["server"]["world"].get("longname", "").asString();
|
ShortName = _root["server"]["world"].get("shortname", "").asString();
|
||||||
|
LongName = _root["server"]["world"].get("longname", "").asString();
|
||||||
WorldAddress = _root["server"]["world"].get("address", "").asString();
|
WorldAddress = _root["server"]["world"].get("address", "").asString();
|
||||||
LocalAddress = _root["server"]["world"].get("localaddress", "").asString();
|
LocalAddress = _root["server"]["world"].get("localaddress", "").asString();
|
||||||
MaxClients = atoi(_root["server"]["world"].get("maxclients", "-1").asString().c_str());
|
MaxClients = atoi(_root["server"]["world"].get("maxclients", "-1").asString().c_str());
|
||||||
SharedKey = _root["server"]["world"].get("key", "").asString();
|
SharedKey = _root["server"]["world"].get("key", "").asString();
|
||||||
LoginCount = 0;
|
LoginCount = 0;
|
||||||
|
|
||||||
if (_root["server"]["world"]["loginserver"].isObject()) {
|
if (_root["server"]["world"]["loginserver"].isObject()) {
|
||||||
LoginHost = _root["server"]["world"]["loginserver"].get("host", "login.eqemulator.net").asString();
|
LoginHost = _root["server"]["world"]["loginserver"].get("host", "login.eqemulator.net").asString();
|
||||||
LoginPort = atoi(_root["server"]["world"]["loginserver"].get("port", "5998").asString().c_str());
|
LoginPort = atoi(_root["server"]["world"]["loginserver"].get("port", "5998").asString().c_str());
|
||||||
LoginLegacy = false;
|
LoginLegacy = false;
|
||||||
if (_root["server"]["world"]["loginserver"].get("legacy", "0").asString() == "1") LoginLegacy = true;
|
if (_root["server"]["world"]["loginserver"].get("legacy", "0").asString() == "1") { LoginLegacy = true; }
|
||||||
LoginAccount = _root["server"]["world"]["loginserver"].get("account", "").asString();
|
LoginAccount = _root["server"]["world"]["loginserver"].get("account", "").asString();
|
||||||
LoginPassword = _root["server"]["world"]["loginserver"].get("password", "").asString();
|
LoginPassword = _root["server"]["world"]["loginserver"].get("password", "").asString();
|
||||||
} else {
|
}
|
||||||
|
else {
|
||||||
char str[32];
|
char str[32];
|
||||||
loginlist.Clear();
|
loginlist.Clear();
|
||||||
do {
|
do {
|
||||||
@ -53,74 +55,102 @@ void EQEmuConfig::parse_config() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
auto loginconfig = new LoginConfig;
|
auto loginconfig = new LoginConfig;
|
||||||
loginconfig->LoginHost = _root["server"]["world"][str].get("host", "login.eqemulator.net").asString();
|
loginconfig->LoginHost = _root["server"]["world"][str].get("host", "login.eqemulator.net").asString();
|
||||||
loginconfig->LoginPort = atoi(_root["server"]["world"][str].get("port", "5998").asString().c_str());
|
loginconfig->LoginPort = atoi(_root["server"]["world"][str].get("port", "5998").asString().c_str());
|
||||||
loginconfig->LoginAccount = _root["server"]["world"][str].get("account", "").asString();
|
loginconfig->LoginAccount = _root["server"]["world"][str].get("account", "").asString();
|
||||||
loginconfig->LoginPassword = _root["server"]["world"][str].get("password", "").asString();
|
loginconfig->LoginPassword = _root["server"]["world"][str].get("password", "").asString();
|
||||||
|
|
||||||
loginconfig->LoginLegacy = false;
|
loginconfig->LoginLegacy = false;
|
||||||
if (_root["server"]["world"][str].get("legacy", "0").asString() == "1") loginconfig->LoginLegacy = true;
|
if (_root["server"]["world"][str].get("legacy", "0").asString() == "1") { loginconfig->LoginLegacy = true; }
|
||||||
loginlist.Insert(loginconfig);
|
loginlist.Insert(loginconfig);
|
||||||
} while (LoginCount < 100);
|
} while (LoginCount < 100);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
//<locked> from xml converts to json as locked: "", so i default to "false".
|
//<locked> from xml converts to json as locked: "", so i default to "false".
|
||||||
//The only way to enable locked is by switching to true, meaning this value is always false until manually set true
|
//The only way to enable locked is by switching to true, meaning this value is always false until manually set true
|
||||||
Locked = false;
|
Locked = false;
|
||||||
if (_root["server"]["world"].get("locked", "false").asString() == "true") Locked = true;
|
if (_root["server"]["world"].get("locked", "false").asString() == "true") { Locked = true; }
|
||||||
WorldIP = _root["server"]["world"]["tcp"].get("host", "127.0.0.1").asString();
|
WorldIP = _root["server"]["world"]["tcp"].get("host", "127.0.0.1").asString();
|
||||||
WorldTCPPort = atoi(_root["server"]["world"]["tcp"].get("port", "9000").asString().c_str());
|
WorldTCPPort = atoi(_root["server"]["world"]["tcp"].get("port", "9000").asString().c_str());
|
||||||
|
|
||||||
TelnetIP = _root["server"]["world"]["telnet"].get("ip", "127.0.0.1").asString();
|
TelnetIP = _root["server"]["world"]["telnet"].get("ip", "127.0.0.1").asString();
|
||||||
TelnetTCPPort = atoi(_root["server"]["world"]["telnet"].get("port", "9001").asString().c_str());
|
TelnetTCPPort = atoi(_root["server"]["world"]["telnet"].get("port", "9001").asString().c_str());
|
||||||
TelnetEnabled = false;
|
TelnetEnabled = false;
|
||||||
if (_root["server"]["world"]["telnet"].get("enabled", "false").asString() == "true") TelnetEnabled = true;
|
if (_root["server"]["world"]["telnet"].get("enabled", "false").asString() == "true") { TelnetEnabled = true; }
|
||||||
|
|
||||||
WorldHTTPMimeFile = _root["server"]["world"]["http"].get("mimefile", "mime.types").asString();
|
WorldHTTPMimeFile = _root["server"]["world"]["http"].get("mimefile", "mime.types").asString();
|
||||||
WorldHTTPPort = atoi(_root["server"]["world"]["http"].get("port", "9080").asString().c_str());
|
WorldHTTPPort = atoi(_root["server"]["world"]["http"].get("port", "9080").asString().c_str());
|
||||||
WorldHTTPEnabled = false;
|
WorldHTTPEnabled = false;
|
||||||
if (_root["server"]["world"]["http"].get("enabled", "false").asString() == "true") WorldHTTPEnabled = true;
|
|
||||||
|
|
||||||
|
if (_root["server"]["world"]["http"].get("enabled", "false").asString() == "true") {
|
||||||
|
WorldHTTPEnabled = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* UCS
|
||||||
|
*/
|
||||||
ChatHost = _root["server"]["chatserver"].get("host", "eqchat.eqemulator.net").asString();
|
ChatHost = _root["server"]["chatserver"].get("host", "eqchat.eqemulator.net").asString();
|
||||||
ChatPort = atoi(_root["server"]["chatserver"].get("port", "7778").asString().c_str());
|
ChatPort = atoi(_root["server"]["chatserver"].get("port", "7778").asString().c_str());
|
||||||
|
|
||||||
MailHost = _root["server"]["mailserver"].get("host", "eqmail.eqemulator.net").asString();
|
MailHost = _root["server"]["mailserver"].get("host", "eqmail.eqemulator.net").asString();
|
||||||
MailPort = atoi(_root["server"]["mailserver"].get("port", "7778").asString().c_str());
|
MailPort = atoi(_root["server"]["mailserver"].get("port", "7778").asString().c_str());
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Database
|
||||||
|
*/
|
||||||
DatabaseUsername = _root["server"]["database"].get("username", "eq").asString();
|
DatabaseUsername = _root["server"]["database"].get("username", "eq").asString();
|
||||||
DatabasePassword = _root["server"]["database"].get("password", "eq").asString();
|
DatabasePassword = _root["server"]["database"].get("password", "eq").asString();
|
||||||
DatabaseHost = _root["server"]["database"].get("host", "localhost").asString();
|
DatabaseHost = _root["server"]["database"].get("host", "localhost").asString();
|
||||||
DatabasePort = atoi(_root["server"]["database"].get("port", "3306").asString().c_str());
|
DatabasePort = atoi(_root["server"]["database"].get("port", "3306").asString().c_str());
|
||||||
DatabaseDB = _root["server"]["database"].get("db", "eq").asString();
|
DatabaseDB = _root["server"]["database"].get("db", "eq").asString();
|
||||||
|
|
||||||
QSDatabaseHost = _root["server"]["qsdatabase"].get("host", "localhost").asString();
|
/**
|
||||||
QSDatabasePort = atoi(_root["server"]["qsdatabase"].get("port", "3306").asString().c_str());
|
* QS
|
||||||
|
*/
|
||||||
|
QSDatabaseHost = _root["server"]["qsdatabase"].get("host", "localhost").asString();
|
||||||
|
QSDatabasePort = atoi(_root["server"]["qsdatabase"].get("port", "3306").asString().c_str());
|
||||||
QSDatabaseUsername = _root["server"]["qsdatabase"].get("username", "eq").asString();
|
QSDatabaseUsername = _root["server"]["qsdatabase"].get("username", "eq").asString();
|
||||||
QSDatabasePassword = _root["server"]["qsdatabase"].get("password", "eq").asString();
|
QSDatabasePassword = _root["server"]["qsdatabase"].get("password", "eq").asString();
|
||||||
QSDatabaseDB = _root["server"]["qsdatabase"].get("db", "eq").asString();
|
QSDatabaseDB = _root["server"]["qsdatabase"].get("db", "eq").asString();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Zones
|
||||||
|
*/
|
||||||
DefaultStatus = atoi(_root["server"]["zones"].get("defaultstatus", 0).asString().c_str());
|
DefaultStatus = atoi(_root["server"]["zones"].get("defaultstatus", 0).asString().c_str());
|
||||||
ZonePortLow = atoi(_root["server"]["zones"]["ports"].get("low", "7000").asString().c_str());
|
ZonePortLow = atoi(_root["server"]["zones"]["ports"].get("low", "7000").asString().c_str());
|
||||||
ZonePortHigh = atoi(_root["server"]["zones"]["ports"].get("high", "7999").asString().c_str());
|
ZonePortHigh = atoi(_root["server"]["zones"]["ports"].get("high", "7999").asString().c_str());
|
||||||
|
|
||||||
SpellsFile = _root["server"]["files"].get("spells", "spells_us.txt").asString();
|
/**
|
||||||
OpCodesFile = _root["server"]["files"].get("opcodes", "opcodes.conf").asString();
|
* Files
|
||||||
PluginPlFile = _root["server"]["files"].get("plugin.pl", "plugin.pl").asString();
|
*/
|
||||||
|
SpellsFile = _root["server"]["files"].get("spells", "spells_us.txt").asString();
|
||||||
|
OpCodesFile = _root["server"]["files"].get("opcodes", "opcodes.conf").asString();
|
||||||
|
MailOpCodesFile = _root["server"]["files"].get("mail_opcodes", "mail_opcodes.conf").asString();
|
||||||
|
PluginPlFile = _root["server"]["files"].get("plugin.pl", "plugin.pl").asString();
|
||||||
|
|
||||||
MapDir = _root["server"]["directories"].get("maps", "Maps/").asString();
|
/**
|
||||||
QuestDir = _root["server"]["directories"].get("quests", "quests/").asString();
|
* Directories
|
||||||
PluginDir = _root["server"]["directories"].get("plugins", "plugins/").asString();
|
*/
|
||||||
|
MapDir = _root["server"]["directories"].get("maps", "Maps/").asString();
|
||||||
|
QuestDir = _root["server"]["directories"].get("quests", "quests/").asString();
|
||||||
|
PluginDir = _root["server"]["directories"].get("plugins", "plugins/").asString();
|
||||||
LuaModuleDir = _root["server"]["directories"].get("lua_modules", "lua_modules/").asString();
|
LuaModuleDir = _root["server"]["directories"].get("lua_modules", "lua_modules/").asString();
|
||||||
PatchDir = _root["server"]["directories"].get("patches", "./").asString();
|
PatchDir = _root["server"]["directories"].get("patches", "./").asString();
|
||||||
SharedMemDir = _root["server"]["directories"].get("shared_memory", "shared/").asString();
|
SharedMemDir = _root["server"]["directories"].get("shared_memory", "shared/").asString();
|
||||||
LogDir = _root["server"]["directories"].get("logs", "logs/").asString();
|
LogDir = _root["server"]["directories"].get("logs", "logs/").asString();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Logs
|
||||||
|
*/
|
||||||
LogPrefix = _root["server"]["launcher"].get("logprefix", "logs/zone-").asString();
|
LogPrefix = _root["server"]["launcher"].get("logprefix", "logs/zone-").asString();
|
||||||
LogSuffix = _root["server"]["launcher"].get("logsuffix", ".log").asString();
|
LogSuffix = _root["server"]["launcher"].get("logsuffix", ".log").asString();
|
||||||
RestartWait = atoi(_root["server"]["launcher"]["timers"].get("restart", "10000").asString().c_str());
|
|
||||||
TerminateWait = atoi(_root["server"]["launcher"]["timers"].get("reterminate", "10000").asString().c_str());
|
/**
|
||||||
InitialBootWait = atoi(_root["server"]["launcher"]["timers"].get("initial", "20000").asString().c_str());
|
* Launcher
|
||||||
|
*/
|
||||||
|
RestartWait = atoi(_root["server"]["launcher"]["timers"].get("restart", "10000").asString().c_str());
|
||||||
|
TerminateWait = atoi(_root["server"]["launcher"]["timers"].get("reterminate", "10000").asString().c_str());
|
||||||
|
InitialBootWait = atoi(_root["server"]["launcher"]["timers"].get("initial", "20000").asString().c_str());
|
||||||
ZoneBootInterval = atoi(_root["server"]["launcher"]["timers"].get("interval", "2000").asString().c_str());
|
ZoneBootInterval = atoi(_root["server"]["launcher"]["timers"].get("interval", "2000").asString().c_str());
|
||||||
#ifdef WIN32
|
#ifdef WIN32
|
||||||
ZoneExe = _root["server"]["launcher"].get("exe", "zone.exe").asString();
|
ZoneExe = _root["server"]["launcher"].get("exe", "zone.exe").asString();
|
||||||
@ -230,6 +260,9 @@ std::string EQEmuConfig::GetByName(const std::string &var_name) const
|
|||||||
if (var_name == "OpCodesFile") {
|
if (var_name == "OpCodesFile") {
|
||||||
return (OpCodesFile);
|
return (OpCodesFile);
|
||||||
}
|
}
|
||||||
|
if (var_name == "MailOpCodesFile") {
|
||||||
|
return (MailOpCodesFile);
|
||||||
|
}
|
||||||
if (var_name == "PluginPlFile") {
|
if (var_name == "PluginPlFile") {
|
||||||
return (PluginPlFile);
|
return (PluginPlFile);
|
||||||
}
|
}
|
||||||
@ -312,6 +345,7 @@ void EQEmuConfig::Dump() const
|
|||||||
std::cout << "QSDatabasePort = " << QSDatabasePort << std::endl;
|
std::cout << "QSDatabasePort = " << QSDatabasePort << std::endl;
|
||||||
std::cout << "SpellsFile = " << SpellsFile << std::endl;
|
std::cout << "SpellsFile = " << SpellsFile << std::endl;
|
||||||
std::cout << "OpCodesFile = " << OpCodesFile << std::endl;
|
std::cout << "OpCodesFile = " << OpCodesFile << std::endl;
|
||||||
|
std::cout << "MailOpcodesFile = " << MailOpCodesFile << std::endl;
|
||||||
std::cout << "PluginPlFile = " << PluginPlFile << std::endl;
|
std::cout << "PluginPlFile = " << PluginPlFile << std::endl;
|
||||||
std::cout << "MapDir = " << MapDir << std::endl;
|
std::cout << "MapDir = " << MapDir << std::endl;
|
||||||
std::cout << "QuestDir = " << QuestDir << std::endl;
|
std::cout << "QuestDir = " << QuestDir << std::endl;
|
||||||
@ -322,6 +356,6 @@ void EQEmuConfig::Dump() const
|
|||||||
std::cout << "LogDir = " << LogDir << std::endl;
|
std::cout << "LogDir = " << LogDir << std::endl;
|
||||||
std::cout << "ZonePortLow = " << ZonePortLow << std::endl;
|
std::cout << "ZonePortLow = " << ZonePortLow << std::endl;
|
||||||
std::cout << "ZonePortHigh = " << ZonePortHigh << std::endl;
|
std::cout << "ZonePortHigh = " << ZonePortHigh << std::endl;
|
||||||
std::cout << "DefaultStatus = " << (int)DefaultStatus << std::endl;
|
std::cout << "DefaultStatus = " << (int) DefaultStatus << std::endl;
|
||||||
// std::cout << "DynamicCount = " << DynamicCount << std::endl;
|
// std::cout << "DynamicCount = " << DynamicCount << std::endl;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -84,6 +84,7 @@ class EQEmuConfig
|
|||||||
// From <files/>
|
// From <files/>
|
||||||
std::string SpellsFile;
|
std::string SpellsFile;
|
||||||
std::string OpCodesFile;
|
std::string OpCodesFile;
|
||||||
|
std::string MailOpCodesFile;
|
||||||
std::string PluginPlFile;
|
std::string PluginPlFile;
|
||||||
|
|
||||||
// From <directories/>
|
// From <directories/>
|
||||||
|
|||||||
@ -16,6 +16,7 @@
|
|||||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#include "eqemu_logsys.h"
|
||||||
#include "emu_opcodes.h"
|
#include "emu_opcodes.h"
|
||||||
#include "opcodemgr.h"
|
#include "opcodemgr.h"
|
||||||
|
|
||||||
@ -31,7 +32,7 @@ OpcodeManager::OpcodeManager() {
|
|||||||
bool OpcodeManager::LoadOpcodesFile(const char *filename, OpcodeSetStrategy *s, bool report_errors) {
|
bool OpcodeManager::LoadOpcodesFile(const char *filename, OpcodeSetStrategy *s, bool report_errors) {
|
||||||
FILE *opf = fopen(filename, "r");
|
FILE *opf = fopen(filename, "r");
|
||||||
if(opf == nullptr) {
|
if(opf == nullptr) {
|
||||||
fprintf(stderr, "Unable to open opcodes file '%s'. Thats bad.\n", filename);
|
Log(Logs::General, Logs::Error, "Unable to open opcodes file '%s'", filename);
|
||||||
return(false);
|
return(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -34,7 +34,7 @@
|
|||||||
#define CURRENT_BINARY_DATABASE_VERSION 9139
|
#define CURRENT_BINARY_DATABASE_VERSION 9139
|
||||||
|
|
||||||
#ifdef BOTS
|
#ifdef BOTS
|
||||||
#define CURRENT_BINARY_BOTS_DATABASE_VERSION 9022
|
#define CURRENT_BINARY_BOTS_DATABASE_VERSION 9023
|
||||||
#else
|
#else
|
||||||
#define CURRENT_BINARY_BOTS_DATABASE_VERSION 0 // must be 0
|
#define CURRENT_BINARY_BOTS_DATABASE_VERSION 0 // must be 0
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@ -23,6 +23,7 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
|||||||
#include "../common/eqemu_logsys_fmt.h"
|
#include "../common/eqemu_logsys_fmt.h"
|
||||||
#include "../common/misc_functions.h"
|
#include "../common/misc_functions.h"
|
||||||
|
|
||||||
|
#include "ucsconfig.h"
|
||||||
#include "clientlist.h"
|
#include "clientlist.h"
|
||||||
#include "database.h"
|
#include "database.h"
|
||||||
#include "chatchannel.h"
|
#include "chatchannel.h"
|
||||||
@ -466,6 +467,7 @@ static void ProcessCommandIgnore(Client *c, std::string Ignoree) {
|
|||||||
safe_delete(outapp);
|
safe_delete(outapp);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Clientlist::Clientlist(int ChatPort) {
|
Clientlist::Clientlist(int ChatPort) {
|
||||||
EQStreamManagerInterfaceOptions chat_opts(ChatPort, false, false);
|
EQStreamManagerInterfaceOptions chat_opts(ChatPort, false, false);
|
||||||
chat_opts.opcode_size = 1;
|
chat_opts.opcode_size = 1;
|
||||||
@ -479,7 +481,10 @@ Clientlist::Clientlist(int ChatPort) {
|
|||||||
|
|
||||||
ChatOpMgr = new RegularOpcodeManager;
|
ChatOpMgr = new RegularOpcodeManager;
|
||||||
|
|
||||||
if (!ChatOpMgr->LoadOpcodes("mail_opcodes.conf"))
|
const ucsconfig *Config = ucsconfig::get();
|
||||||
|
|
||||||
|
Log(Logs::General, Logs::UCS_Server, "Loading '%s'", Config->MailOpCodesFile.c_str());
|
||||||
|
if (!ChatOpMgr->LoadOpcodes(Config->MailOpCodesFile.c_str()))
|
||||||
exit(1);
|
exit(1);
|
||||||
|
|
||||||
chatsf->OnNewConnection([this](std::shared_ptr<EQ::Net::EQStream> stream) {
|
chatsf->OnNewConnection([this](std::shared_ptr<EQ::Net::EQStream> stream) {
|
||||||
|
|||||||
@ -72,14 +72,6 @@ if (-e "eqemu_update.pl") {
|
|||||||
unlink("eqemu_update.pl");
|
unlink("eqemu_update.pl");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (-e "db_update") {
|
|
||||||
unlink("db_update");
|
|
||||||
}
|
|
||||||
|
|
||||||
if (-e "updates_staged") {
|
|
||||||
unlink("updates_staged");
|
|
||||||
}
|
|
||||||
|
|
||||||
print "[Info] For EQEmu Server management utilities - run eqemu_server.pl\n" if $ARGV[0] eq "ran_from_world";
|
print "[Info] For EQEmu Server management utilities - run eqemu_server.pl\n" if $ARGV[0] eq "ran_from_world";
|
||||||
|
|
||||||
check_db_version_table();
|
check_db_version_table();
|
||||||
@ -652,6 +644,14 @@ sub do_self_update_check_routine {
|
|||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
print "[Update] No script update necessary...\n";
|
print "[Update] No script update necessary...\n";
|
||||||
|
|
||||||
|
if (-e "db_update") {
|
||||||
|
unlink("db_update");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (-e "updates_staged") {
|
||||||
|
unlink("updates_staged");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
unlink("updates_staged/eqemu_server.pl");
|
unlink("updates_staged/eqemu_server.pl");
|
||||||
|
|||||||
@ -21,6 +21,7 @@
|
|||||||
9020|2018_08_13_bots_inventory_update.sql|SELECT * FROM `inventory_versions` WHERE `version` = 2 and `bot_step` = 0|not_empty|
|
9020|2018_08_13_bots_inventory_update.sql|SELECT * FROM `inventory_versions` WHERE `version` = 2 and `bot_step` = 0|not_empty|
|
||||||
9021|2018_10_09_bots_owner_options.sql|SHOW TABLES LIKE 'bot_owner_options'|empty|
|
9021|2018_10_09_bots_owner_options.sql|SHOW TABLES LIKE 'bot_owner_options'|empty|
|
||||||
9022|2019_02_07_bots_stance_type_update.sql|SELECT * FROM `bot_spell_casting_chances` WHERE `spell_type_index` = '255' AND `class_id` = '255' AND `stance_index` = '0'|not_empty|
|
9022|2019_02_07_bots_stance_type_update.sql|SELECT * FROM `bot_spell_casting_chances` WHERE `spell_type_index` = '255' AND `class_id` = '255' AND `stance_index` = '0'|not_empty|
|
||||||
|
9023|2019_06_22_bots_owner_option_stats_update.sql|SHOW COLUMNS FROM `bot_owner_options` LIKE 'stats_update'|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
|
||||||
|
|||||||
@ -0,0 +1 @@
|
|||||||
|
ALTER TABLE `bot_owner_options` ADD COLUMN `stats_update` SMALLINT(3) UNSIGNED NULL DEFAULT '0' AFTER `death_marquee`;
|
||||||
@ -251,9 +251,17 @@ bool Mob::CheckWillAggro(Mob *mob) {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
Mob *ownr = mob->GetOwner();
|
/**
|
||||||
if(ownr && ownr->IsClient() && !ownr->CastToClient()->ClientFinishedLoading())
|
* Pets shouldn't scan for aggro
|
||||||
|
*/
|
||||||
|
if (this->GetOwner()) {
|
||||||
return false;
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
Mob *pet_owner = mob->GetOwner();
|
||||||
|
if (pet_owner && pet_owner->IsClient()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
float iAggroRange = GetAggroRange();
|
float iAggroRange = GetAggroRange();
|
||||||
|
|
||||||
@ -727,6 +735,7 @@ type', in which case, the answer is yes.
|
|||||||
}
|
}
|
||||||
|
|
||||||
#ifdef BOTS
|
#ifdef BOTS
|
||||||
|
// this is HIGHLY inefficient
|
||||||
bool HasRuleDefined = false;
|
bool HasRuleDefined = false;
|
||||||
bool IsBotAttackAllowed = false;
|
bool IsBotAttackAllowed = false;
|
||||||
IsBotAttackAllowed = Bot::IsBotAttackAllowed(mob1, mob2, HasRuleDefined);
|
IsBotAttackAllowed = Bot::IsBotAttackAllowed(mob1, mob2, HasRuleDefined);
|
||||||
|
|||||||
@ -439,6 +439,7 @@ NPCType *Bot::FillNPCTypeStruct(uint32 botSpellsID, std::string botName, std::st
|
|||||||
bot_npc_type->skip_global_loot = true;
|
bot_npc_type->skip_global_loot = true;
|
||||||
//bot_npc_type->rare_spawn = false;
|
//bot_npc_type->rare_spawn = false;
|
||||||
bot_npc_type->stuck_behavior = Ground;
|
bot_npc_type->stuck_behavior = Ground;
|
||||||
|
bot_npc_type->skip_auto_scale = true;
|
||||||
|
|
||||||
return bot_npc_type;
|
return bot_npc_type;
|
||||||
}
|
}
|
||||||
@ -3498,7 +3499,7 @@ void Bot::LevelBotWithClient(Client* client, uint8 level, bool sendlvlapp) {
|
|||||||
Bot* bot = *biter;
|
Bot* bot = *biter;
|
||||||
if(bot && (bot->GetLevel() != client->GetLevel())) {
|
if(bot && (bot->GetLevel() != client->GetLevel())) {
|
||||||
bot->SetPetChooser(false); // not sure what this does, but was in bot 'update' code
|
bot->SetPetChooser(false); // not sure what this does, but was in bot 'update' code
|
||||||
bot->CalcBotStats(false); // TODO: look at this and see if 'true' should be passed...
|
bot->CalcBotStats(client->GetBotOptionStatsUpdate());
|
||||||
if(sendlvlapp)
|
if(sendlvlapp)
|
||||||
bot->SendLevelAppearance();
|
bot->SendLevelAppearance();
|
||||||
// modified from Client::SetLevel()
|
// modified from Client::SetLevel()
|
||||||
@ -4175,6 +4176,9 @@ void Bot::PerformTradeWithClient(int16 beginSlotID, int16 endSlotID, Client* cli
|
|||||||
size_t returned_count = client_return.size();
|
size_t returned_count = client_return.size();
|
||||||
|
|
||||||
client->Message(CC_Lime, "Trade with '%s' resulted in %i accepted item%s, %i returned item%s.", GetCleanName(), accepted_count, ((accepted_count == 1) ? "" : "s"), returned_count, ((returned_count == 1) ? "" : "s"));
|
client->Message(CC_Lime, "Trade with '%s' resulted in %i accepted item%s, %i returned item%s.", GetCleanName(), accepted_count, ((accepted_count == 1) ? "" : "s"), returned_count, ((returned_count == 1) ? "" : "s"));
|
||||||
|
|
||||||
|
if (accepted_count)
|
||||||
|
CalcBotStats(client->GetBotOptionStatsUpdate());
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Bot::Death(Mob *killerMob, int32 damage, uint16 spell_id, EQEmu::skills::SkillType attack_skill) {
|
bool Bot::Death(Mob *killerMob, int32 damage, uint16 spell_id, EQEmu::skills::SkillType attack_skill) {
|
||||||
|
|||||||
@ -3441,16 +3441,34 @@ void bot_command_movement_speed(Client *c, const Seperator *sep)
|
|||||||
void bot_command_owner_option(Client *c, const Seperator *sep)
|
void bot_command_owner_option(Client *c, const Seperator *sep)
|
||||||
{
|
{
|
||||||
if (helper_is_help_or_usage(sep->arg[1])) {
|
if (helper_is_help_or_usage(sep->arg[1])) {
|
||||||
c->Message(m_usage, "usage: %s [deathmarquee]", sep->arg[0]);
|
c->Message(m_usage, "usage: %s [deathmarquee | statsupdate] (argument: enable | disable | null (toggles))", sep->arg[0]);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string owner_option = sep->arg[1];
|
std::string owner_option = sep->arg[1];
|
||||||
|
std::string flag = sep->arg[2];
|
||||||
|
|
||||||
if (!owner_option.compare("deathmarquee")) {
|
if (!owner_option.compare("deathmarquee")) {
|
||||||
c->SetBotOptionDeathMarquee(!c->GetBotOptionDeathMarquee());
|
if (!flag.compare("enable"))
|
||||||
c->Message(m_action, "Bot death marquee is now %s.", (c->GetBotOptionDeathMarquee() == true ? "enabled" : "disabled"));
|
c->SetBotOptionDeathMarquee(true);
|
||||||
|
else if (!flag.compare("disable"))
|
||||||
|
c->SetBotOptionDeathMarquee(false);
|
||||||
|
else
|
||||||
|
c->SetBotOptionDeathMarquee(!c->GetBotOptionDeathMarquee());
|
||||||
|
|
||||||
botdb.SaveOwnerOptionDeathMarquee(c->CharacterID(), c->GetBotOptionDeathMarquee());
|
botdb.SaveOwnerOptionDeathMarquee(c->CharacterID(), c->GetBotOptionDeathMarquee());
|
||||||
|
c->Message(m_action, "Bot 'death marquee' is now %s.", (c->GetBotOptionDeathMarquee() == true ? "enabled" : "disabled"));
|
||||||
|
}
|
||||||
|
else if (!owner_option.compare("statsupdate")) {
|
||||||
|
if (!flag.compare("enable"))
|
||||||
|
c->SetBotOptionStatsUpdate(true);
|
||||||
|
else if (!flag.compare("disable"))
|
||||||
|
c->SetBotOptionStatsUpdate(false);
|
||||||
|
else
|
||||||
|
c->SetBotOptionStatsUpdate(!c->GetBotOptionStatsUpdate());
|
||||||
|
|
||||||
|
botdb.SaveOwnerOptionStatsUpdate(c->CharacterID(), c->GetBotOptionStatsUpdate());
|
||||||
|
c->Message(m_action, "Bot 'stats update' is now %s.", (c->GetBotOptionStatsUpdate() == true ? "enabled" : "disabled"));
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
c->Message(m_fail, "Owner option '%s' is not recognized.", owner_option.c_str());
|
c->Message(m_fail, "Owner option '%s' is not recognized.", owner_option.c_str());
|
||||||
@ -5532,7 +5550,7 @@ void bot_subcommand_bot_update(Client *c, const Seperator *sep)
|
|||||||
continue;
|
continue;
|
||||||
|
|
||||||
bot_iter->SetPetChooser(false);
|
bot_iter->SetPetChooser(false);
|
||||||
bot_iter->CalcBotStats((sbl.size() == 1));
|
bot_iter->CalcBotStats(c->GetBotOptionStatsUpdate());
|
||||||
bot_iter->SendAppearancePacket(AT_WhoLevel, bot_iter->GetLevel(), true, true);
|
bot_iter->SendAppearancePacket(AT_WhoLevel, bot_iter->GetLevel(), true, true);
|
||||||
++bot_count;
|
++bot_count;
|
||||||
}
|
}
|
||||||
@ -7321,7 +7339,7 @@ void bot_subcommand_inventory_remove(Client *c, const Seperator *sep)
|
|||||||
}
|
}
|
||||||
|
|
||||||
my_bot->BotRemoveEquipItem(slotId);
|
my_bot->BotRemoveEquipItem(slotId);
|
||||||
my_bot->CalcBotStats();
|
my_bot->CalcBotStats(c->GetBotOptionStatsUpdate());
|
||||||
}
|
}
|
||||||
|
|
||||||
switch (slotId) {
|
switch (slotId) {
|
||||||
|
|||||||
@ -2188,7 +2188,7 @@ bool BotDatabase::LoadOwnerOptions(Client *owner)
|
|||||||
return false;
|
return false;
|
||||||
|
|
||||||
query = StringFormat(
|
query = StringFormat(
|
||||||
"SELECT `death_marquee` FROM `bot_owner_options`"
|
"SELECT `death_marquee`, `stats_update` FROM `bot_owner_options`"
|
||||||
" WHERE `owner_id` = '%u'",
|
" WHERE `owner_id` = '%u'",
|
||||||
owner->CharacterID()
|
owner->CharacterID()
|
||||||
);
|
);
|
||||||
@ -2204,6 +2204,7 @@ bool BotDatabase::LoadOwnerOptions(Client *owner)
|
|||||||
|
|
||||||
auto row = results.begin();
|
auto row = results.begin();
|
||||||
owner->SetBotOptionDeathMarquee((atoi(row[0]) != 0));
|
owner->SetBotOptionDeathMarquee((atoi(row[0]) != 0));
|
||||||
|
owner->SetBotOptionStatsUpdate((atoi(row[1]) != 0));
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -2227,6 +2228,25 @@ bool BotDatabase::SaveOwnerOptionDeathMarquee(const uint32 owner_id, const bool
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool BotDatabase::SaveOwnerOptionStatsUpdate(const uint32 owner_id, const bool flag)
|
||||||
|
{
|
||||||
|
if (!owner_id)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
query = StringFormat(
|
||||||
|
"UPDATE `bot_owner_options`"
|
||||||
|
" SET `stats_update` = '%u'"
|
||||||
|
" WHERE `owner_id` = '%u'",
|
||||||
|
(flag == true ? 1 : 0),
|
||||||
|
owner_id
|
||||||
|
);
|
||||||
|
auto results = QueryDatabase(query);
|
||||||
|
if (!results.Success())
|
||||||
|
return false;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/* Bot bot-group functions */
|
/* Bot bot-group functions */
|
||||||
bool BotDatabase::QueryBotGroupExistence(const std::string& group_name, bool& extant_flag)
|
bool BotDatabase::QueryBotGroupExistence(const std::string& group_name, bool& extant_flag)
|
||||||
|
|||||||
@ -148,6 +148,7 @@ public:
|
|||||||
|
|
||||||
bool LoadOwnerOptions(Client *owner);
|
bool LoadOwnerOptions(Client *owner);
|
||||||
bool SaveOwnerOptionDeathMarquee(const uint32 owner_id, const bool flag);
|
bool SaveOwnerOptionDeathMarquee(const uint32 owner_id, const bool flag);
|
||||||
|
bool SaveOwnerOptionStatsUpdate(const uint32 owner_id, const bool flag);
|
||||||
|
|
||||||
/* Bot bot-group functions */
|
/* Bot bot-group functions */
|
||||||
bool QueryBotGroupExistence(const std::string& botgroup_name, bool& extant_flag);
|
bool QueryBotGroupExistence(const std::string& botgroup_name, bool& extant_flag);
|
||||||
|
|||||||
@ -781,6 +781,8 @@ public:
|
|||||||
void UnmemSpell(int slot, bool update_client = true);
|
void UnmemSpell(int slot, bool update_client = true);
|
||||||
void UnmemSpellBySpellID(int32 spell_id);
|
void UnmemSpellBySpellID(int32 spell_id);
|
||||||
void UnmemSpellAll(bool update_client = true);
|
void UnmemSpellAll(bool update_client = true);
|
||||||
|
uint16 FindMemmedSpellBySlot(int slot);
|
||||||
|
int MemmedCount();
|
||||||
void ScribeSpell(uint16 spell_id, int slot, bool update_client = true);
|
void ScribeSpell(uint16 spell_id, int slot, bool update_client = true);
|
||||||
void UnscribeSpell(int slot, bool update_client = true);
|
void UnscribeSpell(int slot, bool update_client = true);
|
||||||
void UnscribeSpellAll(bool update_client = true);
|
void UnscribeSpellAll(bool update_client = true);
|
||||||
@ -1640,18 +1642,22 @@ private:
|
|||||||
#ifdef BOTS
|
#ifdef BOTS
|
||||||
struct BotOwnerOptions {
|
struct BotOwnerOptions {
|
||||||
bool death_marquee;
|
bool death_marquee;
|
||||||
|
bool stats_update;
|
||||||
};
|
};
|
||||||
|
|
||||||
BotOwnerOptions bot_owner_options;
|
BotOwnerOptions bot_owner_options;
|
||||||
|
|
||||||
const BotOwnerOptions DefaultBotOwnerOptions = {
|
const BotOwnerOptions DefaultBotOwnerOptions = {
|
||||||
false // death_marquee
|
false, // death_marquee
|
||||||
|
false // stats_update
|
||||||
};
|
};
|
||||||
|
|
||||||
public:
|
public:
|
||||||
void SetBotOptionDeathMarquee(bool flag) { bot_owner_options.death_marquee = flag; }
|
void SetBotOptionDeathMarquee(bool flag) { bot_owner_options.death_marquee = flag; }
|
||||||
|
void SetBotOptionStatsUpdate(bool flag) { bot_owner_options.stats_update = flag; }
|
||||||
|
|
||||||
bool GetBotOptionDeathMarquee() const { return bot_owner_options.death_marquee; }
|
bool GetBotOptionDeathMarquee() const { return bot_owner_options.death_marquee; }
|
||||||
|
bool GetBotOptionStatsUpdate() const { return bot_owner_options.stats_update; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@ -286,6 +286,17 @@ Bot *Entity::CastToBot()
|
|||||||
#endif
|
#endif
|
||||||
return static_cast<Bot *>(this);
|
return static_cast<Bot *>(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const Bot *Entity::CastToBot() const
|
||||||
|
{
|
||||||
|
#ifdef _EQDEBUG
|
||||||
|
if (!IsBot()) {
|
||||||
|
std::cout << "CastToBot error" << std::endl;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
return static_cast<const Bot *>(this);
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
EntityList::EntityList()
|
EntityList::EntityList()
|
||||||
@ -509,16 +520,16 @@ void EntityList::MobProcess()
|
|||||||
}
|
}
|
||||||
|
|
||||||
if(mob_dead) {
|
if(mob_dead) {
|
||||||
if(mob->IsNPC()) {
|
if(mob->IsMerc()) {
|
||||||
entity_list.RemoveNPC(id);
|
|
||||||
}
|
|
||||||
else if(mob->IsMerc()) {
|
|
||||||
entity_list.RemoveMerc(id);
|
entity_list.RemoveMerc(id);
|
||||||
#ifdef BOTS
|
|
||||||
}
|
}
|
||||||
|
#ifdef BOTS
|
||||||
else if(mob->IsBot()) {
|
else if(mob->IsBot()) {
|
||||||
entity_list.RemoveBot(id);
|
entity_list.RemoveBot(id);
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
|
else if(mob->IsNPC()) {
|
||||||
|
entity_list.RemoveNPC(id);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
#ifdef _WINDOWS
|
#ifdef _WINDOWS
|
||||||
|
|||||||
@ -116,6 +116,7 @@ public:
|
|||||||
|
|
||||||
#ifdef BOTS
|
#ifdef BOTS
|
||||||
Bot* CastToBot();
|
Bot* CastToBot();
|
||||||
|
const Bot* CastToBot() const;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|||||||
@ -180,7 +180,7 @@ bool Client::CanFish() {
|
|||||||
const float LineLength = RuleR(Watermap, FishingLineLength);
|
const float LineLength = RuleR(Watermap, FishingLineLength);
|
||||||
int HeadingDegrees;
|
int HeadingDegrees;
|
||||||
|
|
||||||
HeadingDegrees = (int) ((GetHeading()*360)/256);
|
HeadingDegrees = (int) ((GetHeading()*360)/512);
|
||||||
HeadingDegrees = HeadingDegrees % 360;
|
HeadingDegrees = HeadingDegrees % 360;
|
||||||
|
|
||||||
rodPosition.x = m_Position.x + RodLength * sin(HeadingDegrees * M_PI/180.0f);
|
rodPosition.x = m_Position.x + RodLength * sin(HeadingDegrees * M_PI/180.0f);
|
||||||
|
|||||||
@ -98,7 +98,7 @@ uint32 Client::NukeItem(uint32 itemnum, uint8 where_to_check) {
|
|||||||
x++;
|
x++;
|
||||||
}
|
}
|
||||||
|
|
||||||
DeleteItemInInventory(i, 0, ((((uint64)1 << (EQEmu::invslot::GENERAL_BEGIN + ((i - EQEmu::invbag::GENERAL_BAGS_BEGIN) / EQEmu::invbag::SLOT_COUNT))) & GetInv().GetLookup()->PossessionsBitmask) == 0));
|
DeleteItemInInventory(i, 0, ((((uint64)1 << (EQEmu::invslot::GENERAL_BEGIN + ((i - EQEmu::invbag::GENERAL_BAGS_BEGIN) / EQEmu::invbag::SLOT_COUNT))) & GetInv().GetLookup()->PossessionsBitmask) != 0));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -972,8 +972,8 @@ void Client::DeleteItemInInventory(int16 slot_id, int8 quantity, bool client_upd
|
|||||||
safe_delete(outapp);
|
safe_delete(outapp);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
outapp = new EQApplicationPacket(OP_DeleteItem, sizeof(DeleteItem_Struct));
|
outapp = new EQApplicationPacket(OP_MoveItem, sizeof(MoveItem_Struct));
|
||||||
DeleteItem_Struct* delitem = (DeleteItem_Struct*)outapp->pBuffer;
|
MoveItem_Struct* delitem = (MoveItem_Struct*)outapp->pBuffer;
|
||||||
delitem->from_slot = slot_id;
|
delitem->from_slot = slot_id;
|
||||||
delitem->to_slot = 0xFFFFFFFF;
|
delitem->to_slot = 0xFFFFFFFF;
|
||||||
delitem->number_in_stack = 0xFFFFFFFF;
|
delitem->number_in_stack = 0xFFFFFFFF;
|
||||||
|
|||||||
@ -550,6 +550,16 @@ void Lua_Client::UnmemSpellAll(bool update_client) {
|
|||||||
self->UnmemSpellAll(update_client);
|
self->UnmemSpellAll(update_client);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
uint16 Lua_Client::FindMemmedSpellBySlot(int slot) {
|
||||||
|
Lua_Safe_Call_Int();
|
||||||
|
return self->FindMemmedSpellBySlot(slot);
|
||||||
|
}
|
||||||
|
|
||||||
|
int Lua_Client::MemmedCount() {
|
||||||
|
Lua_Safe_Call_Int();
|
||||||
|
return self->MemmedCount();
|
||||||
|
}
|
||||||
|
|
||||||
void Lua_Client::ScribeSpell(int spell_id, int slot) {
|
void Lua_Client::ScribeSpell(int spell_id, int slot) {
|
||||||
Lua_Safe_Call_Void();
|
Lua_Safe_Call_Void();
|
||||||
self->ScribeSpell(spell_id, slot);
|
self->ScribeSpell(spell_id, slot);
|
||||||
@ -1618,6 +1628,8 @@ luabind::scope lua_register_client() {
|
|||||||
.def("UnmemSpellBySpellID", (void(Lua_Client::*)(int32))&Lua_Client::UnmemSpellBySpellID)
|
.def("UnmemSpellBySpellID", (void(Lua_Client::*)(int32))&Lua_Client::UnmemSpellBySpellID)
|
||||||
.def("UnmemSpellAll", (void(Lua_Client::*)(void))&Lua_Client::UnmemSpellAll)
|
.def("UnmemSpellAll", (void(Lua_Client::*)(void))&Lua_Client::UnmemSpellAll)
|
||||||
.def("UnmemSpellAll", (void(Lua_Client::*)(bool))&Lua_Client::UnmemSpellAll)
|
.def("UnmemSpellAll", (void(Lua_Client::*)(bool))&Lua_Client::UnmemSpellAll)
|
||||||
|
.def("FindMemmedSpellBySlot", (uint16(Lua_Client::*)(int))&Lua_Client::FindMemmedSpellBySlot)
|
||||||
|
.def("MemmedCount", (int(Lua_Client::*)(void))&Lua_Client::MemmedCount)
|
||||||
.def("ScribeSpell", (void(Lua_Client::*)(int,int))&Lua_Client::ScribeSpell)
|
.def("ScribeSpell", (void(Lua_Client::*)(int,int))&Lua_Client::ScribeSpell)
|
||||||
.def("ScribeSpell", (void(Lua_Client::*)(int,int,bool))&Lua_Client::ScribeSpell)
|
.def("ScribeSpell", (void(Lua_Client::*)(int,int,bool))&Lua_Client::ScribeSpell)
|
||||||
.def("UnscribeSpell", (void(Lua_Client::*)(int))&Lua_Client::UnscribeSpell)
|
.def("UnscribeSpell", (void(Lua_Client::*)(int))&Lua_Client::UnscribeSpell)
|
||||||
|
|||||||
@ -135,6 +135,8 @@ public:
|
|||||||
void UnmemSpellBySpellID(int32 spell_id);
|
void UnmemSpellBySpellID(int32 spell_id);
|
||||||
void UnmemSpellAll();
|
void UnmemSpellAll();
|
||||||
void UnmemSpellAll(bool update_client);
|
void UnmemSpellAll(bool update_client);
|
||||||
|
uint16 FindMemmedSpellBySlot(int slot);
|
||||||
|
int MemmedCount();
|
||||||
void ScribeSpell(int spell_id, int slot);
|
void ScribeSpell(int spell_id, int slot);
|
||||||
void ScribeSpell(int spell_id, int slot, bool update_client);
|
void ScribeSpell(int spell_id, int slot, bool update_client);
|
||||||
void UnscribeSpell(int slot);
|
void UnscribeSpell(int slot);
|
||||||
|
|||||||
@ -322,6 +322,16 @@ bool Lua_Mob::FindBuff(int spell_id) {
|
|||||||
return self->FindBuff(spell_id);
|
return self->FindBuff(spell_id);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
uint16 Lua_Mob::FindBuffBySlot(int slot) {
|
||||||
|
Lua_Safe_Call_Int();
|
||||||
|
return self->FindBuffBySlot(slot);
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32 Lua_Mob::BuffCount() {
|
||||||
|
Lua_Safe_Call_Int();
|
||||||
|
return self->BuffCount();
|
||||||
|
}
|
||||||
|
|
||||||
bool Lua_Mob::FindType(int type) {
|
bool Lua_Mob::FindType(int type) {
|
||||||
Lua_Safe_Call_Bool();
|
Lua_Safe_Call_Bool();
|
||||||
return self->FindType(type);
|
return self->FindType(type);
|
||||||
@ -2091,6 +2101,11 @@ int Lua_Mob::GetWeaponDamageBonus(Lua_Item weapon, bool offhand) {
|
|||||||
return self->GetWeaponDamageBonus(weapon, offhand);
|
return self->GetWeaponDamageBonus(weapon, offhand);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int Lua_Mob::GetItemStat(uint32 itemid, const char* identifier) {
|
||||||
|
Lua_Safe_Call_Int();
|
||||||
|
return self->GetItemStat(itemid, identifier);
|
||||||
|
}
|
||||||
|
|
||||||
Lua_StatBonuses Lua_Mob::GetItemBonuses()
|
Lua_StatBonuses Lua_Mob::GetItemBonuses()
|
||||||
{
|
{
|
||||||
Lua_Safe_Call_Class(Lua_StatBonuses);
|
Lua_Safe_Call_Class(Lua_StatBonuses);
|
||||||
@ -2218,6 +2233,8 @@ luabind::scope lua_register_mob() {
|
|||||||
.def("IsInvisible", (bool(Lua_Mob::*)(Lua_Mob))&Lua_Mob::IsInvisible)
|
.def("IsInvisible", (bool(Lua_Mob::*)(Lua_Mob))&Lua_Mob::IsInvisible)
|
||||||
.def("SetInvisible", &Lua_Mob::SetInvisible)
|
.def("SetInvisible", &Lua_Mob::SetInvisible)
|
||||||
.def("FindBuff", &Lua_Mob::FindBuff)
|
.def("FindBuff", &Lua_Mob::FindBuff)
|
||||||
|
.def("FindBuffBySlot", (uint16(Lua_Mob::*)(int))&Lua_Mob::FindBuffBySlot)
|
||||||
|
.def("BuffCount", &Lua_Mob::BuffCount)
|
||||||
.def("FindType", (bool(Lua_Mob::*)(int))&Lua_Mob::FindType)
|
.def("FindType", (bool(Lua_Mob::*)(int))&Lua_Mob::FindType)
|
||||||
.def("FindType", (bool(Lua_Mob::*)(int,bool))&Lua_Mob::FindType)
|
.def("FindType", (bool(Lua_Mob::*)(int,bool))&Lua_Mob::FindType)
|
||||||
.def("FindType", (bool(Lua_Mob::*)(int,bool,int))&Lua_Mob::FindType)
|
.def("FindType", (bool(Lua_Mob::*)(int,bool,int))&Lua_Mob::FindType)
|
||||||
@ -2248,6 +2265,7 @@ luabind::scope lua_register_mob() {
|
|||||||
.def("IsWarriorClass", &Lua_Mob::IsWarriorClass)
|
.def("IsWarriorClass", &Lua_Mob::IsWarriorClass)
|
||||||
.def("GetHP", &Lua_Mob::GetHP)
|
.def("GetHP", &Lua_Mob::GetHP)
|
||||||
.def("GetMaxHP", &Lua_Mob::GetMaxHP)
|
.def("GetMaxHP", &Lua_Mob::GetMaxHP)
|
||||||
|
.def("GetItemStat", (int(Lua_Mob::*)(uint32,const char*))&Lua_Mob::GetItemStat)
|
||||||
.def("GetItemHPBonuses", &Lua_Mob::GetItemHPBonuses)
|
.def("GetItemHPBonuses", &Lua_Mob::GetItemHPBonuses)
|
||||||
.def("GetSpellHPBonuses", &Lua_Mob::GetSpellHPBonuses)
|
.def("GetSpellHPBonuses", &Lua_Mob::GetSpellHPBonuses)
|
||||||
.def("GetWalkspeed", &Lua_Mob::GetWalkspeed)
|
.def("GetWalkspeed", &Lua_Mob::GetWalkspeed)
|
||||||
|
|||||||
@ -82,6 +82,8 @@ public:
|
|||||||
bool IsInvisible(Lua_Mob other);
|
bool IsInvisible(Lua_Mob other);
|
||||||
void SetInvisible(int state);
|
void SetInvisible(int state);
|
||||||
bool FindBuff(int spell_id);
|
bool FindBuff(int spell_id);
|
||||||
|
uint16 FindBuffBySlot(int slot);
|
||||||
|
uint32 BuffCount();
|
||||||
bool FindType(int type);
|
bool FindType(int type);
|
||||||
bool FindType(int type, bool offensive);
|
bool FindType(int type, bool offensive);
|
||||||
bool FindType(int type, bool offensive, int threshold);
|
bool FindType(int type, bool offensive, int threshold);
|
||||||
@ -402,6 +404,7 @@ public:
|
|||||||
bool IsAmnesiad();
|
bool IsAmnesiad();
|
||||||
int32 GetMeleeMitigation();
|
int32 GetMeleeMitigation();
|
||||||
int GetWeaponDamageBonus(Lua_Item weapon, bool offhand);
|
int GetWeaponDamageBonus(Lua_Item weapon, bool offhand);
|
||||||
|
int GetItemStat(uint32 itemid, const char* identifier);
|
||||||
Lua_StatBonuses GetItemBonuses();
|
Lua_StatBonuses GetItemBonuses();
|
||||||
Lua_StatBonuses GetSpellBonuses();
|
Lua_StatBonuses GetSpellBonuses();
|
||||||
Lua_StatBonuses GetAABonuses();
|
Lua_StatBonuses GetAABonuses();
|
||||||
|
|||||||
@ -385,6 +385,8 @@ public:
|
|||||||
void DamageShield(Mob* other, bool spell_ds = false);
|
void DamageShield(Mob* other, bool spell_ds = false);
|
||||||
int32 RuneAbsorb(int32 damage, uint16 type);
|
int32 RuneAbsorb(int32 damage, uint16 type);
|
||||||
bool FindBuff(uint16 spellid);
|
bool FindBuff(uint16 spellid);
|
||||||
|
uint16 FindBuffBySlot(int slot);
|
||||||
|
uint32 BuffCount();
|
||||||
bool FindType(uint16 type, bool bOffensive = false, uint16 threshold = 100);
|
bool FindType(uint16 type, bool bOffensive = false, uint16 threshold = 100);
|
||||||
int16 GetBuffSlotFromType(uint16 type);
|
int16 GetBuffSlotFromType(uint16 type);
|
||||||
uint16 GetSpellIDFromSlot(uint8 slot);
|
uint16 GetSpellIDFromSlot(uint8 slot);
|
||||||
|
|||||||
@ -2436,7 +2436,7 @@ bool NPC::AI_AddNPCSpells(uint32 iDBSpellsID) {
|
|||||||
}
|
}
|
||||||
DBnpcspells_Struct* parentlist = database.GetNPCSpells(spell_list->parent_list);
|
DBnpcspells_Struct* parentlist = database.GetNPCSpells(spell_list->parent_list);
|
||||||
#if MobAI_DEBUG_Spells >= 10
|
#if MobAI_DEBUG_Spells >= 10
|
||||||
std::string debug_msg = StringFormat("Loading NPCSpells onto %s: dbspellsid=%u", this->GetName(), iDBSpellsID);
|
std::string debug_msg = StringFormat("Loading NPCSpells onto %s: dbspellsid=%u, level=%u", this->GetName(), iDBSpellsID, this->GetLevel());
|
||||||
if (spell_list) {
|
if (spell_list) {
|
||||||
debug_msg.append(StringFormat(" (found, %u), parentlist=%u", spell_list->entries.size(), spell_list->parent_list));
|
debug_msg.append(StringFormat(" (found, %u), parentlist=%u", spell_list->entries.size(), spell_list->parent_list));
|
||||||
if (spell_list->parent_list) {
|
if (spell_list->parent_list) {
|
||||||
@ -2450,6 +2450,22 @@ bool NPC::AI_AddNPCSpells(uint32 iDBSpellsID) {
|
|||||||
debug_msg.append(" (not found)");
|
debug_msg.append(" (not found)");
|
||||||
}
|
}
|
||||||
Log(Logs::Detail, Logs::AI, "%s", debug_msg.c_str());
|
Log(Logs::Detail, Logs::AI, "%s", debug_msg.c_str());
|
||||||
|
|
||||||
|
#ifdef MobAI_DEBUG_Spells >= 25
|
||||||
|
if (parentlist) {
|
||||||
|
for (const auto &iter : parentlist->entries) {
|
||||||
|
Log(Logs::Detail, Logs::AI, "(%i) %s", iter.spellid, spells[iter.spellid].name);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Log(Logs::Detail, Logs::AI, "fin (parent list)");
|
||||||
|
if (spell_list) {
|
||||||
|
for (const auto &iter : spell_list->entries) {
|
||||||
|
Log(Logs::Detail, Logs::AI, "(%i) %s", iter.spellid, spells[iter.spellid].name);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Log(Logs::Detail, Logs::AI, "fin (spell list)");
|
||||||
|
#endif
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
uint16 attack_proc_spell = -1;
|
uint16 attack_proc_spell = -1;
|
||||||
int8 proc_chance = 3;
|
int8 proc_chance = 3;
|
||||||
|
|||||||
@ -189,11 +189,11 @@ inline std::string GetMobAttributeByString(Mob *mob, const std::string &attribut
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (attribute == "cor") {
|
if (attribute == "cor") {
|
||||||
return std::to_string(mob->GetCorrup());
|
return commify(std::to_string(mob->GetCorrup())) + scaling_modified;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (attribute == "phy") {
|
if (attribute == "phy") {
|
||||||
return std::to_string(mob->GetPhR());
|
return commify(std::to_string(mob->GetPhR())) + scaling_modified;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (attribute == "name") {
|
if (attribute == "name") {
|
||||||
|
|||||||
@ -574,6 +574,9 @@ int main(int argc, char** argv) {
|
|||||||
if (InterserverTimer.Check()) {
|
if (InterserverTimer.Check()) {
|
||||||
InterserverTimer.Start();
|
InterserverTimer.Start();
|
||||||
database.ping();
|
database.ping();
|
||||||
|
#ifdef BOTS
|
||||||
|
botdb.ping();
|
||||||
|
#endif
|
||||||
entity_list.UpdateWho();
|
entity_list.UpdateWho();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|||||||
@ -239,6 +239,7 @@ NPC::NPC(const NPCType *npc_type_data, Spawn2 *in_respawn, const glm::vec4 &posi
|
|||||||
p_depop = false;
|
p_depop = false;
|
||||||
loottable_id = npc_type_data->loottable_id;
|
loottable_id = npc_type_data->loottable_id;
|
||||||
skip_global_loot = npc_type_data->skip_global_loot;
|
skip_global_loot = npc_type_data->skip_global_loot;
|
||||||
|
skip_auto_scale = npc_type_data->skip_auto_scale;
|
||||||
rare_spawn = npc_type_data->rare_spawn;
|
rare_spawn = npc_type_data->rare_spawn;
|
||||||
no_target_hotkey = npc_type_data->no_target_hotkey;
|
no_target_hotkey = npc_type_data->no_target_hotkey;
|
||||||
primary_faction = 0;
|
primary_faction = 0;
|
||||||
@ -2214,6 +2215,14 @@ void NPC::ModifyNPCStat(const char *identifier, const char *new_value)
|
|||||||
CR = atoi(val.c_str());
|
CR = atoi(val.c_str());
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
else if (id == "cor") {
|
||||||
|
Corrup = atoi(val.c_str());
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
else if (id == "phr") {
|
||||||
|
PhR = atoi(val.c_str());
|
||||||
|
return;
|
||||||
|
}
|
||||||
else if (id == "pr") {
|
else if (id == "pr") {
|
||||||
PR = atoi(val.c_str());
|
PR = atoi(val.c_str());
|
||||||
return;
|
return;
|
||||||
|
|||||||
@ -468,6 +468,7 @@ public:
|
|||||||
|
|
||||||
virtual int GetStuckBehavior() const { return NPCTypedata_ours ? NPCTypedata_ours->stuck_behavior : NPCTypedata->stuck_behavior; }
|
virtual int GetStuckBehavior() const { return NPCTypedata_ours ? NPCTypedata_ours->stuck_behavior : NPCTypedata->stuck_behavior; }
|
||||||
|
|
||||||
|
inline bool IsSkipAutoScale() const { return skip_auto_scale; }
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|
||||||
@ -612,6 +613,7 @@ protected:
|
|||||||
private:
|
private:
|
||||||
uint32 loottable_id;
|
uint32 loottable_id;
|
||||||
bool skip_global_loot;
|
bool skip_global_loot;
|
||||||
|
bool skip_auto_scale;
|
||||||
bool p_depop;
|
bool p_depop;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@ -26,6 +26,9 @@
|
|||||||
*/
|
*/
|
||||||
void NpcScaleManager::ScaleNPC(NPC * npc)
|
void NpcScaleManager::ScaleNPC(NPC * npc)
|
||||||
{
|
{
|
||||||
|
if (npc->IsSkipAutoScale())
|
||||||
|
return;
|
||||||
|
|
||||||
int8 npc_type = GetNPCScalingType(npc);
|
int8 npc_type = GetNPCScalingType(npc);
|
||||||
int npc_level = npc->GetLevel();
|
int npc_level = npc->GetLevel();
|
||||||
bool is_auto_scaled = IsAutoScaled(npc);
|
bool is_auto_scaled = IsAutoScaled(npc);
|
||||||
@ -42,7 +45,7 @@ void NpcScaleManager::ScaleNPC(NPC * npc)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (npc->GetAC() == 0) {
|
if (npc->GetAC() == 0 && is_auto_scaled) {
|
||||||
npc->ModifyNPCStat("ac", std::to_string(scale_data.ac).c_str());
|
npc->ModifyNPCStat("ac", std::to_string(scale_data.ac).c_str());
|
||||||
}
|
}
|
||||||
if (npc->GetMaxHP() == 0) {
|
if (npc->GetMaxHP() == 0) {
|
||||||
@ -94,11 +97,11 @@ void NpcScaleManager::ScaleNPC(NPC * npc)
|
|||||||
if (npc->GetDR() == 0) {
|
if (npc->GetDR() == 0) {
|
||||||
npc->ModifyNPCStat("dr", std::to_string(scale_data.disease_resist).c_str());
|
npc->ModifyNPCStat("dr", std::to_string(scale_data.disease_resist).c_str());
|
||||||
}
|
}
|
||||||
if (npc->GetCorrup() == 0) {
|
if (npc->GetCorrup() == 0 && is_auto_scaled) {
|
||||||
npc->ModifyNPCStat("cr", std::to_string(scale_data.corruption_resist).c_str());
|
npc->ModifyNPCStat("cor", std::to_string(scale_data.corruption_resist).c_str());
|
||||||
}
|
}
|
||||||
if (npc->GetPhR() == 0) {
|
if (npc->GetPhR() == 0 && is_auto_scaled) {
|
||||||
npc->ModifyNPCStat("pr", std::to_string(scale_data.physical_resist).c_str());
|
npc->ModifyNPCStat("phr", std::to_string(scale_data.physical_resist).c_str());
|
||||||
}
|
}
|
||||||
if (npc->GetMinDMG() == 0 && npc->GetMaxDMG() == 0) {
|
if (npc->GetMinDMG() == 0 && npc->GetMaxDMG() == 0) {
|
||||||
int min_dmg = scale_data.min_dmg;
|
int min_dmg = scale_data.min_dmg;
|
||||||
@ -621,4 +624,4 @@ bool NpcScaleManager::ApplyGlobalBaseScalingToNPCDynamically(NPC *&npc)
|
|||||||
auto results = database.QueryDatabase(query);
|
auto results = database.QueryDatabase(query);
|
||||||
|
|
||||||
return results.Success();
|
return results.Success();
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1233,15 +1233,17 @@ XS(XS_Client_MovePC) {
|
|||||||
if (THIS->IsMerc()) {
|
if (THIS->IsMerc()) {
|
||||||
Log(Logs::Detail, Logs::None,
|
Log(Logs::Detail, Logs::None,
|
||||||
"[CLIENT] Perl(XS_Client_MovePC) attempted to process a type Merc reference");
|
"[CLIENT] Perl(XS_Client_MovePC) attempted to process a type Merc reference");
|
||||||
} else if (THIS->IsNPC()) {
|
}
|
||||||
|
#ifdef BOTS
|
||||||
|
else if (THIS->IsBot()) {
|
||||||
|
Log(Logs::Detail, Logs::None,
|
||||||
|
"[CLIENT] Perl(XS_Client_MovePC) attempted to process a type Bot reference");
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
else if (THIS->IsNPC()) {
|
||||||
Log(Logs::Detail, Logs::None,
|
Log(Logs::Detail, Logs::None,
|
||||||
"[CLIENT] Perl(XS_Client_MovePC) attempted to process a type NPC reference");
|
"[CLIENT] Perl(XS_Client_MovePC) attempted to process a type NPC reference");
|
||||||
}
|
}
|
||||||
#ifdef BOTS
|
|
||||||
else if (THIS->IsBot()) {
|
|
||||||
Log(Logs::Detail, Logs::None, "[CLIENT] Perl(XS_Client_MovePC) attempted to process a type Bot reference");
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
else {
|
else {
|
||||||
Log(Logs::Detail, Logs::None,
|
Log(Logs::Detail, Logs::None,
|
||||||
"[CLIENT] Perl(XS_Client_MovePC) attempted to process an Unknown type reference");
|
"[CLIENT] Perl(XS_Client_MovePC) attempted to process an Unknown type reference");
|
||||||
@ -1283,15 +1285,17 @@ XS(XS_Client_MovePCInstance) {
|
|||||||
if (THIS->IsMerc()) {
|
if (THIS->IsMerc()) {
|
||||||
Log(Logs::Detail, Logs::None,
|
Log(Logs::Detail, Logs::None,
|
||||||
"[CLIENT] Perl(XS_Client_MovePCInstance) attempted to process a type Merc reference");
|
"[CLIENT] Perl(XS_Client_MovePCInstance) attempted to process a type Merc reference");
|
||||||
} else if (THIS->IsNPC()) {
|
}
|
||||||
|
#ifdef BOTS
|
||||||
|
else if (THIS->IsBot()) {
|
||||||
|
Log(Logs::Detail, Logs::None,
|
||||||
|
"[CLIENT] Perl(XS_Client_MovePCInstance) attempted to process a type Bot reference");
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
else if (THIS->IsNPC()) {
|
||||||
Log(Logs::Detail, Logs::None,
|
Log(Logs::Detail, Logs::None,
|
||||||
"[CLIENT] Perl(XS_Client_MovePCInstance) attempted to process a type NPC reference");
|
"[CLIENT] Perl(XS_Client_MovePCInstance) attempted to process a type NPC reference");
|
||||||
}
|
}
|
||||||
#ifdef BOTS
|
|
||||||
else if (THIS->IsBot()) {
|
|
||||||
Log(Logs::Detail, Logs::None, "[CLIENT] Perl(XS_Client_MovePCInstance) attempted to process a type Bot reference");
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
else {
|
else {
|
||||||
Log(Logs::Detail, Logs::None,
|
Log(Logs::Detail, Logs::None,
|
||||||
"[CLIENT] Perl(XS_Client_MovePCInstance) attempted to process an Unknown type reference");
|
"[CLIENT] Perl(XS_Client_MovePCInstance) attempted to process an Unknown type reference");
|
||||||
@ -2404,6 +2408,57 @@ XS(XS_Client_UnmemSpellAll) {
|
|||||||
XSRETURN_EMPTY;
|
XSRETURN_EMPTY;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
XS(XS_Client_FindMemmedSpellBySlot); /* prototype to pass -Wmissing-prototypes */
|
||||||
|
XS(XS_Client_FindMemmedSpellBySlot) {
|
||||||
|
dXSARGS;
|
||||||
|
if (items != 2)
|
||||||
|
Perl_croak(aTHX_ "Usage: Client::FindMemmedSpellBySlot(THIS, int slot)");
|
||||||
|
{
|
||||||
|
Client *THIS;
|
||||||
|
uint16 RETVAL;
|
||||||
|
dXSTARG;
|
||||||
|
int slot = SvIV(ST(1));
|
||||||
|
|
||||||
|
if (sv_derived_from(ST(0), "Client")) {
|
||||||
|
IV tmp = SvIV((SV *) SvRV(ST(0)));
|
||||||
|
THIS = INT2PTR(Client *, tmp);
|
||||||
|
} else
|
||||||
|
Perl_croak(aTHX_ "THIS is not of type Client");
|
||||||
|
if (THIS == nullptr)
|
||||||
|
Perl_croak(aTHX_ "THIS is nullptr, avoiding crash.");
|
||||||
|
|
||||||
|
RETVAL = THIS->FindMemmedSpellBySlot(slot);
|
||||||
|
XSprePUSH;
|
||||||
|
PUSHu((UV) RETVAL);
|
||||||
|
}
|
||||||
|
XSRETURN(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
XS(XS_Client_MemmedCount); /* prototype to pass -Wmissing-prototypes */
|
||||||
|
XS(XS_Client_MemmedCount) {
|
||||||
|
dXSARGS;
|
||||||
|
if (items != 1)
|
||||||
|
Perl_croak(aTHX_ "Usage: Client::MemmedCount(THIS)");
|
||||||
|
{
|
||||||
|
Client *THIS;
|
||||||
|
uint32 RETVAL;
|
||||||
|
dXSTARG;
|
||||||
|
|
||||||
|
if (sv_derived_from(ST(0), "Client")) {
|
||||||
|
IV tmp = SvIV((SV *) SvRV(ST(0)));
|
||||||
|
THIS = INT2PTR(Client *, tmp);
|
||||||
|
} else
|
||||||
|
Perl_croak(aTHX_ "THIS is not of type Client");
|
||||||
|
if (THIS == nullptr)
|
||||||
|
Perl_croak(aTHX_ "THIS is nullptr, avoiding crash.");
|
||||||
|
|
||||||
|
RETVAL = THIS->MemmedCount();
|
||||||
|
XSprePUSH;
|
||||||
|
PUSHu((UV) RETVAL);
|
||||||
|
}
|
||||||
|
XSRETURN(1);
|
||||||
|
}
|
||||||
|
|
||||||
XS(XS_Client_ScribeSpell); /* prototype to pass -Wmissing-prototypes */
|
XS(XS_Client_ScribeSpell); /* prototype to pass -Wmissing-prototypes */
|
||||||
XS(XS_Client_ScribeSpell) {
|
XS(XS_Client_ScribeSpell) {
|
||||||
dXSARGS;
|
dXSARGS;
|
||||||
@ -6478,6 +6533,8 @@ XS(boot_Client) {
|
|||||||
newXSproto(strcpy(buf, "UnmemSpell"), XS_Client_UnmemSpell, file, "$$;$");
|
newXSproto(strcpy(buf, "UnmemSpell"), XS_Client_UnmemSpell, file, "$$;$");
|
||||||
newXSproto(strcpy(buf, "UnmemSpellAll"), XS_Client_UnmemSpellAll, file, "$;$");
|
newXSproto(strcpy(buf, "UnmemSpellAll"), XS_Client_UnmemSpellAll, file, "$;$");
|
||||||
newXSproto(strcpy(buf, "UnmemSpellBySpellID"), XS_Client_UnmemSpellBySpellID, file, "$$");
|
newXSproto(strcpy(buf, "UnmemSpellBySpellID"), XS_Client_UnmemSpellBySpellID, file, "$$");
|
||||||
|
newXSproto(strcpy(buf, "FindMemmedSpellBySlot"), XS_Client_FindMemmedSpellBySlot, file, "$$");
|
||||||
|
newXSproto(strcpy(buf, "MemmedCount"), XS_Client_MemmedCount, file, "$");
|
||||||
newXSproto(strcpy(buf, "UnscribeSpell"), XS_Client_UnscribeSpell, file, "$$;$");
|
newXSproto(strcpy(buf, "UnscribeSpell"), XS_Client_UnscribeSpell, file, "$$;$");
|
||||||
newXSproto(strcpy(buf, "UnscribeSpellAll"), XS_Client_UnscribeSpellAll, file, "$;$");
|
newXSproto(strcpy(buf, "UnscribeSpellAll"), XS_Client_UnscribeSpellAll, file, "$;$");
|
||||||
newXSproto(strcpy(buf, "UntrainDisc"), XS_Client_UntrainDisc, file, "$$;$");
|
newXSproto(strcpy(buf, "UntrainDisc"), XS_Client_UntrainDisc, file, "$$;$");
|
||||||
|
|||||||
@ -1297,6 +1297,57 @@ XS(XS_Mob_FindBuff) {
|
|||||||
XSRETURN(1);
|
XSRETURN(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
XS(XS_Mob_FindBuffBySlot); /* prototype to pass -Wmissing-prototypes */
|
||||||
|
XS(XS_Mob_FindBuffBySlot) {
|
||||||
|
dXSARGS;
|
||||||
|
if (items != 2)
|
||||||
|
Perl_croak(aTHX_ "Usage: Mob::FindBuffBySlot(THIS, int slot)");
|
||||||
|
{
|
||||||
|
Mob *THIS;
|
||||||
|
uint16 RETVAL;
|
||||||
|
dXSTARG;
|
||||||
|
int slot = SvIV(ST(1));
|
||||||
|
|
||||||
|
if (sv_derived_from(ST(0), "Mob")) {
|
||||||
|
IV tmp = SvIV((SV *) SvRV(ST(0)));
|
||||||
|
THIS = INT2PTR(Mob *, tmp);
|
||||||
|
} else
|
||||||
|
Perl_croak(aTHX_ "THIS is not of type Mob");
|
||||||
|
if (THIS == nullptr)
|
||||||
|
Perl_croak(aTHX_ "THIS is nullptr, avoiding crash.");
|
||||||
|
|
||||||
|
RETVAL = THIS->FindBuffBySlot(slot);
|
||||||
|
XSprePUSH;
|
||||||
|
PUSHu((UV) RETVAL);
|
||||||
|
}
|
||||||
|
XSRETURN(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
XS(XS_Mob_BuffCount); /* prototype to pass -Wmissing-prototypes */
|
||||||
|
XS(XS_Mob_BuffCount) {
|
||||||
|
dXSARGS;
|
||||||
|
if (items != 1)
|
||||||
|
Perl_croak(aTHX_ "Usage: Mob::BuffCount(THIS)");
|
||||||
|
{
|
||||||
|
Mob *THIS;
|
||||||
|
uint32 RETVAL;
|
||||||
|
dXSTARG;
|
||||||
|
|
||||||
|
if (sv_derived_from(ST(0), "Mob")) {
|
||||||
|
IV tmp = SvIV((SV *) SvRV(ST(0)));
|
||||||
|
THIS = INT2PTR(Mob *, tmp);
|
||||||
|
} else
|
||||||
|
Perl_croak(aTHX_ "THIS is not of type Mob");
|
||||||
|
if (THIS == nullptr)
|
||||||
|
Perl_croak(aTHX_ "THIS is nullptr, avoiding crash.");
|
||||||
|
|
||||||
|
RETVAL = THIS->BuffCount();
|
||||||
|
XSprePUSH;
|
||||||
|
PUSHu((UV) RETVAL);
|
||||||
|
}
|
||||||
|
XSRETURN(1);
|
||||||
|
}
|
||||||
|
|
||||||
XS(XS_Mob_FindType); /* prototype to pass -Wmissing-prototypes */
|
XS(XS_Mob_FindType); /* prototype to pass -Wmissing-prototypes */
|
||||||
XS(XS_Mob_FindType) {
|
XS(XS_Mob_FindType) {
|
||||||
dXSARGS;
|
dXSARGS;
|
||||||
@ -8581,6 +8632,8 @@ XS(boot_Mob) {
|
|||||||
newXSproto(strcpy(buf, "IsInvisible"), XS_Mob_IsInvisible, file, "$;$");
|
newXSproto(strcpy(buf, "IsInvisible"), XS_Mob_IsInvisible, file, "$;$");
|
||||||
newXSproto(strcpy(buf, "SetInvisible"), XS_Mob_SetInvisible, file, "$$");
|
newXSproto(strcpy(buf, "SetInvisible"), XS_Mob_SetInvisible, file, "$$");
|
||||||
newXSproto(strcpy(buf, "FindBuff"), XS_Mob_FindBuff, file, "$$");
|
newXSproto(strcpy(buf, "FindBuff"), XS_Mob_FindBuff, file, "$$");
|
||||||
|
newXSproto(strcpy(buf, "FindBuffBySlot"), XS_Mob_FindBuffBySlot, file, "$$");
|
||||||
|
newXSproto(strcpy(buf, "BuffCount"), XS_Mob_BuffCount, file, "$");
|
||||||
newXSproto(strcpy(buf, "FindType"), XS_Mob_FindType, file, "$$;$$");
|
newXSproto(strcpy(buf, "FindType"), XS_Mob_FindType, file, "$$;$$");
|
||||||
newXSproto(strcpy(buf, "GetBuffSlotFromType"), XS_Mob_GetBuffSlotFromType, file, "$$");
|
newXSproto(strcpy(buf, "GetBuffSlotFromType"), XS_Mob_GetBuffSlotFromType, file, "$$");
|
||||||
newXSproto(strcpy(buf, "MakePet"), XS_Mob_MakePet, file, "$$$;$");
|
newXSproto(strcpy(buf, "MakePet"), XS_Mob_MakePet, file, "$$$;$");
|
||||||
|
|||||||
@ -1278,6 +1278,7 @@ void Client::ThrowingAttack(Mob* other, bool CanDoubleAttack) { //old was 51
|
|||||||
}
|
}
|
||||||
else if(dist < (RuleI(Combat, MinRangedAttackDist)*RuleI(Combat, MinRangedAttackDist))){
|
else if(dist < (RuleI(Combat, MinRangedAttackDist)*RuleI(Combat, MinRangedAttackDist))){
|
||||||
Message_StringID(15,RANGED_TOO_CLOSE);//Client enforces range and sends the message, this is a backup just incase.
|
Message_StringID(15,RANGED_TOO_CLOSE);//Client enforces range and sends the message, this is a backup just incase.
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(!IsAttackAllowed(other) ||
|
if(!IsAttackAllowed(other) ||
|
||||||
|
|||||||
@ -455,7 +455,7 @@ bool Mob::DoCastSpell(uint16 spell_id, uint16 target_id, CastingSlot slot,
|
|||||||
{
|
{
|
||||||
mana_cost = 0;
|
mana_cost = 0;
|
||||||
} else {
|
} else {
|
||||||
Log(Logs::Detail, Logs::Spells, "Spell Error not enough mana spell=%d mymana=%d cost=%d\n", GetName(), spell_id, my_curmana, mana_cost);
|
Log(Logs::Detail, Logs::Spells, "Spell Error not enough mana spell=%d mymana=%d cost=%d\n", spell_id, my_curmana, mana_cost);
|
||||||
if(IsClient()) {
|
if(IsClient()) {
|
||||||
//clients produce messages... npcs should not for this case
|
//clients produce messages... npcs should not for this case
|
||||||
Message_StringID(13, INSUFFICIENT_MANA);
|
Message_StringID(13, INSUFFICIENT_MANA);
|
||||||
@ -4032,6 +4032,23 @@ bool Mob::FindBuff(uint16 spellid)
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
uint16 Mob::FindBuffBySlot(int slot) {
|
||||||
|
if (buffs[slot].spellid != SPELL_UNKNOWN)
|
||||||
|
return buffs[slot].spellid;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32 Mob::BuffCount() {
|
||||||
|
uint32 active_buff_count = 0;
|
||||||
|
int buff_count = GetMaxTotalSlots();
|
||||||
|
for (int i = 0; i < buff_count; i++)
|
||||||
|
if (buffs[i].spellid != SPELL_UNKNOWN)
|
||||||
|
active_buff_count++;
|
||||||
|
|
||||||
|
return active_buff_count;
|
||||||
|
}
|
||||||
|
|
||||||
// removes all buffs
|
// removes all buffs
|
||||||
void Mob::BuffFadeAll()
|
void Mob::BuffFadeAll()
|
||||||
{
|
{
|
||||||
@ -5039,6 +5056,23 @@ void Client::UnmemSpellAll(bool update_client)
|
|||||||
UnmemSpell(i, update_client);
|
UnmemSpell(i, update_client);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
uint16 Client::FindMemmedSpellBySlot(int slot) {
|
||||||
|
if (m_pp.mem_spells[slot] != 0xFFFFFFFF)
|
||||||
|
return m_pp.mem_spells[slot];
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int Client::MemmedCount() {
|
||||||
|
int memmed_count = 0;
|
||||||
|
for (int i = 0; i < EQEmu::spells::SPELL_GEM_COUNT; i++)
|
||||||
|
if (m_pp.mem_spells[i] != 0xFFFFFFFF)
|
||||||
|
memmed_count++;
|
||||||
|
|
||||||
|
return memmed_count;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void Client::ScribeSpell(uint16 spell_id, int slot, bool update_client)
|
void Client::ScribeSpell(uint16 spell_id, int slot, bool update_client)
|
||||||
{
|
{
|
||||||
if(slot >= EQEmu::spells::SPELLBOOK_SIZE || slot < 0)
|
if(slot >= EQEmu::spells::SPELLBOOK_SIZE || slot < 0)
|
||||||
|
|||||||
@ -2690,6 +2690,7 @@ const NPCType* ZoneDatabase::LoadNPCTypesData(uint32 npc_type_id, bool bulk_load
|
|||||||
temp_npctype_data->rare_spawn = atoi(row[108]) != 0;
|
temp_npctype_data->rare_spawn = atoi(row[108]) != 0;
|
||||||
temp_npctype_data->stuck_behavior = atoi(row[109]);
|
temp_npctype_data->stuck_behavior = atoi(row[109]);
|
||||||
temp_npctype_data->use_model = atoi(row[110]);
|
temp_npctype_data->use_model = atoi(row[110]);
|
||||||
|
temp_npctype_data->skip_auto_scale = false; // hardcoded here for now
|
||||||
|
|
||||||
// If NPC with duplicate NPC id already in table,
|
// If NPC with duplicate NPC id already in table,
|
||||||
// free item we attempted to add.
|
// free item we attempted to add.
|
||||||
@ -2892,6 +2893,8 @@ const NPCType* ZoneDatabase::GetMercType(uint32 id, uint16 raceid, uint32 client
|
|||||||
tmpNPCType->scalerate = atoi(row[43]);
|
tmpNPCType->scalerate = atoi(row[43]);
|
||||||
tmpNPCType->spellscale = atoi(row[44]);
|
tmpNPCType->spellscale = atoi(row[44]);
|
||||||
tmpNPCType->healscale = atoi(row[45]);
|
tmpNPCType->healscale = atoi(row[45]);
|
||||||
|
tmpNPCType->skip_global_loot = true;
|
||||||
|
tmpNPCType->skip_auto_scale = true;
|
||||||
|
|
||||||
// If Merc with duplicate NPC id already in table,
|
// If Merc with duplicate NPC id already in table,
|
||||||
// free item we attempted to add.
|
// free item we attempted to add.
|
||||||
|
|||||||
@ -143,6 +143,7 @@ struct NPCType
|
|||||||
bool untargetable;
|
bool untargetable;
|
||||||
bool skip_global_loot;
|
bool skip_global_loot;
|
||||||
bool rare_spawn;
|
bool rare_spawn;
|
||||||
|
bool skip_auto_scale; // just so it doesn't mess up bots or mercs, probably should add to DB too just in case
|
||||||
int8 stuck_behavior;
|
int8 stuck_behavior;
|
||||||
uint16 use_model;
|
uint16 use_model;
|
||||||
};
|
};
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user