mirror of
https://github.com/EQEmu/Server.git
synced 2026-06-25 18:47:35 +00:00
Compare commits
23 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 090086f50c | |||
| 407b003f7d | |||
| b6d315d803 | |||
| 6927177291 | |||
| 31ede355a8 | |||
| 0df84e1ee6 | |||
| 0d509a7f3a | |||
| 4c2271ff69 | |||
| ca2072e7bf | |||
| e1eb1ff738 | |||
| 25f5898bae | |||
| 934ff3dadf | |||
| e4ff76dceb | |||
| 6960a1a682 | |||
| d4174ca236 | |||
| 7854130a93 | |||
| e9c63c7d94 | |||
| 27e0665aae | |||
| ea2f431fce | |||
| 8bdcf7cb94 | |||
| 87cb74b851 | |||
| 26c267db1b | |||
| 99f8e6cef5 |
@@ -1,3 +1,57 @@
|
|||||||
|
## [22.9.0] - 04/01/2023
|
||||||
|
|
||||||
|
### Bots
|
||||||
|
|
||||||
|
* Remove Bot Groups Functionality ([#3165](https://github.com/EQEmu/Server/pull/3165)) @Aeadoin 2023-04-01
|
||||||
|
|
||||||
|
### Code
|
||||||
|
|
||||||
|
* Cleanup excessive type casting: string -> char * -> string ([#3169](https://github.com/EQEmu/Server/pull/3169)) @Aeadoin 2023-04-01
|
||||||
|
|
||||||
|
### Crash
|
||||||
|
|
||||||
|
* Add Checks for valid pointers or fix existing. ([#3164](https://github.com/EQEmu/Server/pull/3164)) @Aeadoin 2023-04-01
|
||||||
|
* Fix out of bound arrays, other potential crashes ([#3166](https://github.com/EQEmu/Server/pull/3166)) @Aeadoin 2023-04-01
|
||||||
|
|
||||||
|
### Fixes
|
||||||
|
|
||||||
|
* Correct SE_SlayUndead & SE_HeadShotLevel limit Value when applied. ([#3171](https://github.com/EQEmu/Server/pull/3171)) @Aeadoin 2023-04-01
|
||||||
|
* Prevent VerifyGroup from setting OOZ membername to Null character. ([#3168](https://github.com/EQEmu/Server/pull/3168)) @Aeadoin 2023-04-01
|
||||||
|
|
||||||
|
### Quest API
|
||||||
|
|
||||||
|
* Add missing Luabind definitions to lua_general.cpp ([#3167](https://github.com/EQEmu/Server/pull/3167)) @Kinglykrab 2023-04-01
|
||||||
|
|
||||||
|
## [22.8.2] - 03/30/2023
|
||||||
|
|
||||||
|
### Code
|
||||||
|
|
||||||
|
* "equipped" not "equiped", "dual" not "duel". ([#3149](https://github.com/EQEmu/Server/pull/3149)) @Kinglykrab 2023-03-27
|
||||||
|
|
||||||
|
### Crash
|
||||||
|
|
||||||
|
* Add Checks for out of bounds & dereferencing nullptrs ([#3151](https://github.com/EQEmu/Server/pull/3151)) @Aeadoin 2023-03-28
|
||||||
|
|
||||||
|
### Fixes
|
||||||
|
|
||||||
|
* Check Rule "Bots Enabled" to prevent bot database calls on connect ([#3154](https://github.com/EQEmu/Server/pull/3154)) @Aeadoin 2023-03-29
|
||||||
|
* Correct logic checks for Bot rule AllowOwnerOptionAltCombat ([#3158](https://github.com/EQEmu/Server/pull/3158)) @Aeadoin 2023-03-30
|
||||||
|
* Fix an issue with EVENT_DISCONNECT not firing on regular /camp ([#3153](https://github.com/EQEmu/Server/pull/3153)) @Kinglykrab 2023-03-28
|
||||||
|
* Fix bot_raid_members.sql for MYSQL. ([#3155](https://github.com/EQEmu/Server/pull/3155)) @Aeadoin 2023-03-28
|
||||||
|
* Fix for OOZ Group updates when removing/inviting Bots ([#3159](https://github.com/EQEmu/Server/pull/3159)) @Aeadoin 2023-03-30
|
||||||
|
* Fix issues with Lua tables not starting at index 1 ([#3160](https://github.com/EQEmu/Server/pull/3160)) @Kinglykrab 2023-03-30
|
||||||
|
* Fix strcpy-param-overlap ([#3157](https://github.com/EQEmu/Server/pull/3157)) @Aeadoin 2023-03-29
|
||||||
|
|
||||||
|
### Rules
|
||||||
|
|
||||||
|
* Remove Guild Bank Zone ID Rule ([#3156](https://github.com/EQEmu/Server/pull/3156)) @Kinglykrab 2023-03-29
|
||||||
|
|
||||||
|
## [22.8.1] - 03/27/2023
|
||||||
|
|
||||||
|
### Fixes
|
||||||
|
|
||||||
|
* Fix for NPCs having spells interrupted. ([#3150](https://github.com/EQEmu/Server/pull/3150)) @Aeadoin 2023-03-27
|
||||||
|
|
||||||
## [22.8.0] - 03/25/2023
|
## [22.8.0] - 03/25/2023
|
||||||
|
|
||||||
### Code
|
### Code
|
||||||
|
|||||||
+1
-1
@@ -2345,7 +2345,7 @@ void Database::SourceDatabaseTableFromUrl(std::string table_name, std::string ur
|
|||||||
|
|
||||||
int sourced_queries = 0;
|
int sourced_queries = 0;
|
||||||
|
|
||||||
if (auto res = cli.Get(request_uri.get_path().c_str())) {
|
if (auto res = cli.Get(request_uri.get_path())) {
|
||||||
if (res->status == 200) {
|
if (res->status == 200) {
|
||||||
for (auto &s: Strings::Split(res->body, ';')) {
|
for (auto &s: Strings::Split(res->body, ';')) {
|
||||||
if (!Strings::Trim(s).empty()) {
|
if (!Strings::Trim(s).empty()) {
|
||||||
|
|||||||
@@ -6690,7 +6690,7 @@ static WSInit wsinit_;
|
|||||||
if (params.empty()) { return Get(path, headers); }
|
if (params.empty()) { return Get(path, headers); }
|
||||||
|
|
||||||
std::string path_with_query = append_query_params(path, params);
|
std::string path_with_query = append_query_params(path, params);
|
||||||
return Get(path_with_query.c_str(), headers, progress);
|
return Get(path_with_query, headers, progress);
|
||||||
}
|
}
|
||||||
|
|
||||||
inline Result ClientImpl::Get(const std::string &path, const Params ¶ms,
|
inline Result ClientImpl::Get(const std::string &path, const Params ¶ms,
|
||||||
@@ -6710,7 +6710,7 @@ static WSInit wsinit_;
|
|||||||
}
|
}
|
||||||
|
|
||||||
std::string path_with_query = append_query_params(path, params);
|
std::string path_with_query = append_query_params(path, params);
|
||||||
return Get(path_with_query.c_str(), headers, response_handler,
|
return Get(path_with_query, headers, response_handler,
|
||||||
content_receiver, progress);
|
content_receiver, progress);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -6807,7 +6807,7 @@ static WSInit wsinit_;
|
|||||||
std::string content_type;
|
std::string content_type;
|
||||||
const auto &body = detail::serialize_multipart_formdata(
|
const auto &body = detail::serialize_multipart_formdata(
|
||||||
items, detail::make_multipart_data_boundary(), content_type);
|
items, detail::make_multipart_data_boundary(), content_type);
|
||||||
return Post(path, headers, body, content_type.c_str());
|
return Post(path, headers, body, content_type);
|
||||||
}
|
}
|
||||||
|
|
||||||
inline Result ClientImpl::Post(const std::string &path, const Headers &headers,
|
inline Result ClientImpl::Post(const std::string &path, const Headers &headers,
|
||||||
@@ -6820,7 +6820,7 @@ static WSInit wsinit_;
|
|||||||
std::string content_type;
|
std::string content_type;
|
||||||
const auto &body =
|
const auto &body =
|
||||||
detail::serialize_multipart_formdata(items, boundary, content_type);
|
detail::serialize_multipart_formdata(items, boundary, content_type);
|
||||||
return Post(path, headers, body, content_type.c_str());
|
return Post(path, headers, body, content_type);
|
||||||
}
|
}
|
||||||
|
|
||||||
inline Result ClientImpl::Put(const std::string &path) {
|
inline Result ClientImpl::Put(const std::string &path) {
|
||||||
|
|||||||
+1
-1
@@ -151,7 +151,7 @@ static char *temp=nullptr;
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
ptr++;
|
ptr++;
|
||||||
uint32 id = Strings::ToUnsignedInt(field[id_pos].c_str());
|
uint32 id = Strings::ToUnsignedInt(field[id_pos]);
|
||||||
items[id]=field;
|
items[id]=field;
|
||||||
|
|
||||||
for(i=0;i<10;i++) {
|
for(i=0;i<10;i++) {
|
||||||
|
|||||||
+2
-2
@@ -141,11 +141,11 @@ bool RuleManager::SetRule(const std::string &rule_name, const std::string &rule_
|
|||||||
|
|
||||||
switch (type) {
|
switch (type) {
|
||||||
case IntRule:
|
case IntRule:
|
||||||
m_RuleIntValues[index] = Strings::ToInt(rule_value.c_str());
|
m_RuleIntValues[index] = Strings::ToInt(rule_value);
|
||||||
LogRules("Set rule [{}] to value [{}]", rule_name, m_RuleIntValues[index]);
|
LogRules("Set rule [{}] to value [{}]", rule_name, m_RuleIntValues[index]);
|
||||||
break;
|
break;
|
||||||
case RealRule:
|
case RealRule:
|
||||||
m_RuleRealValues[index] = Strings::ToFloat(rule_value.c_str());
|
m_RuleRealValues[index] = Strings::ToFloat(rule_value);
|
||||||
LogRules("Set rule [{}] to value [{:.2f}]", rule_name, m_RuleRealValues[index]);
|
LogRules("Set rule [{}] to value [{:.2f}]", rule_name, m_RuleRealValues[index]);
|
||||||
break;
|
break;
|
||||||
case BoolRule:
|
case BoolRule:
|
||||||
|
|||||||
@@ -274,7 +274,6 @@ RULE_BOOL(World, EnableTutorialButton, true, "Setting whether the Tutorial butto
|
|||||||
RULE_BOOL(World, EnableReturnHomeButton, true, "Setting whether the Return Home button should be active")
|
RULE_BOOL(World, EnableReturnHomeButton, true, "Setting whether the Return Home button should be active")
|
||||||
RULE_INT(World, MaxLevelForTutorial, 10, "The highest level with which you can enter the tutorial")
|
RULE_INT(World, MaxLevelForTutorial, 10, "The highest level with which you can enter the tutorial")
|
||||||
RULE_INT(World, TutorialZoneID, 189, "Zone ID of the tutorial")
|
RULE_INT(World, TutorialZoneID, 189, "Zone ID of the tutorial")
|
||||||
RULE_INT(World, GuildBankZoneID, 345, "Zone ID of the guild bank")
|
|
||||||
RULE_INT(World, MinOfflineTimeToReturnHome, 21600, "Minimum offline time to activate the Return Home button. 21600 seconds is 6 Hours")
|
RULE_INT(World, MinOfflineTimeToReturnHome, 21600, "Minimum offline time to activate the Return Home button. 21600 seconds is 6 Hours")
|
||||||
RULE_INT(World, MaxClientsPerIP, -1, "Maximum number of clients allowed to connect per IP address if account status is < AddMaxClientsStatus. Default value: -1 (feature disabled)")
|
RULE_INT(World, MaxClientsPerIP, -1, "Maximum number of clients allowed to connect per IP address if account status is < AddMaxClientsStatus. Default value: -1 (feature disabled)")
|
||||||
RULE_INT(World, ExemptMaxClientsStatus, -1, "Exempt accounts from the MaxClientsPerIP and AddMaxClientsStatus rules, if their status is >= this value. Default value: -1 (feature disabled)")
|
RULE_INT(World, ExemptMaxClientsStatus, -1, "Exempt accounts from the MaxClientsPerIP and AddMaxClientsStatus rules, if their status is >= this value. Default value: -1 (feature disabled)")
|
||||||
|
|||||||
+2
-2
@@ -504,7 +504,7 @@ enum SpellRestriction
|
|||||||
HAS_NO_ILLUSIONS_OF_GRANDEUR_BUFF = 12519, //
|
HAS_NO_ILLUSIONS_OF_GRANDEUR_BUFF = 12519, //
|
||||||
IS_HP_ABOVE_50_PCT = 16010, //
|
IS_HP_ABOVE_50_PCT = 16010, //
|
||||||
IS_HP_UNDER_50_PCT = 16031, //
|
IS_HP_UNDER_50_PCT = 16031, //
|
||||||
IS_OFF_HAND_EQUIPED = 27672, // You must be wielding a weapon or shield in your offhand to use this ability.
|
IS_OFF_HAND_EQUIPPED = 27672, // You must be wielding a weapon or shield in your offhand to use this ability.
|
||||||
HAS_NO_PACT_OF_FATE_RECOURSE_BUFF = 29556, // This spell will not work while Pact of Fate Recourse is active. | caster restriction |
|
HAS_NO_PACT_OF_FATE_RECOURSE_BUFF = 29556, // This spell will not work while Pact of Fate Recourse is active. | caster restriction |
|
||||||
HAS_NO_SHROUD_OF_PRAYER_BUFF = 32339, // Your target cannot receive another Quiet Prayer this soon.
|
HAS_NO_SHROUD_OF_PRAYER_BUFF = 32339, // Your target cannot receive another Quiet Prayer this soon.
|
||||||
IS_MANA_BELOW_20_PCT = 38311, // This ability requires you to be at or below 20% of your maximum mana.
|
IS_MANA_BELOW_20_PCT = 38311, // This ability requires you to be at or below 20% of your maximum mana.
|
||||||
@@ -1211,7 +1211,7 @@ typedef enum {
|
|||||||
#define SE_Double_Backstab_Front 473 // implemented - Chance to double backstab from front
|
#define SE_Double_Backstab_Front 473 // implemented - Chance to double backstab from front
|
||||||
#define SE_Pet_Crit_Melee_Damage_Pct_Owner 474 // implemenetd - Critical damage mod applied to pets from owner
|
#define SE_Pet_Crit_Melee_Damage_Pct_Owner 474 // implemenetd - Critical damage mod applied to pets from owner
|
||||||
#define SE_Trigger_Spell_Non_Item 475 // implemented - Trigger spell on cast only if not from item click.
|
#define SE_Trigger_Spell_Non_Item 475 // implemented - Trigger spell on cast only if not from item click.
|
||||||
#define SE_Weapon_Stance 476 // implemented, @Misc, Apply a specific spell buffs automatically depending 2Hander, Shield or Duel Wield is equiped, base: spellid, base: 0=2H 1=Shield 2=DW, max: none
|
#define SE_Weapon_Stance 476 // implemented, @Misc, Apply a specific spell buffs automatically depending 2Hander, Shield or Dual Wield is equipped, base: spellid, base: 0=2H 1=Shield 2=DW, max: none
|
||||||
#define SE_Hatelist_To_Top_Index 477 // Implemented - Chance to be set to top of rampage list
|
#define SE_Hatelist_To_Top_Index 477 // Implemented - Chance to be set to top of rampage list
|
||||||
#define SE_Hatelist_To_Tail_Index 478 // Implemented - Chance to be set to bottom of rampage list
|
#define SE_Hatelist_To_Tail_Index 478 // Implemented - Chance to be set to bottom of rampage list
|
||||||
#define SE_Ff_Value_Min 479 // implemented, @Ff, Minimum base value of a spell that can be focused, base: spells to be focused base1 value
|
#define SE_Ff_Value_Min 479 // implemented, @Ff, Minimum base value of a spell that can be focused, base: spells to be focused base1 value
|
||||||
|
|||||||
+2
-2
@@ -25,7 +25,7 @@
|
|||||||
|
|
||||||
// Build variables
|
// Build variables
|
||||||
// these get injected during the build pipeline
|
// these get injected during the build pipeline
|
||||||
#define CURRENT_VERSION "22.8.0-dev" // always append -dev to the current version for custom-builds
|
#define CURRENT_VERSION "22.9.0-dev" // always append -dev to the current version for custom-builds
|
||||||
#define LOGIN_VERSION "0.8.0"
|
#define LOGIN_VERSION "0.8.0"
|
||||||
#define COMPILE_DATE __DATE__
|
#define COMPILE_DATE __DATE__
|
||||||
#define COMPILE_TIME __TIME__
|
#define COMPILE_TIME __TIME__
|
||||||
@@ -44,7 +44,7 @@
|
|||||||
|
|
||||||
#define CURRENT_BINARY_DATABASE_VERSION 9227
|
#define CURRENT_BINARY_DATABASE_VERSION 9227
|
||||||
|
|
||||||
#define CURRENT_BINARY_BOTS_DATABASE_VERSION 9038
|
#define CURRENT_BINARY_BOTS_DATABASE_VERSION 9039
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|||||||
+1
-1
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "eqemu-server",
|
"name": "eqemu-server",
|
||||||
"version": "22.8.0",
|
"version": "22.9.0",
|
||||||
"repository": {
|
"repository": {
|
||||||
"type": "git",
|
"type": "git",
|
||||||
"url": "https://github.com/EQEmu/Server.git"
|
"url": "https://github.com/EQEmu/Server.git"
|
||||||
|
|||||||
+1
-1
@@ -659,7 +659,7 @@ ChatChannel *ChatChannelList::RemoveClientFromChannel(const std::string& in_chan
|
|||||||
std::string channel_name = in_channel_name;
|
std::string channel_name = in_channel_name;
|
||||||
|
|
||||||
if (in_channel_name.length() > 0 && isdigit(channel_name[0])) {
|
if (in_channel_name.length() > 0 && isdigit(channel_name[0])) {
|
||||||
channel_name = c->ChannelSlotName(Strings::ToInt(in_channel_name.c_str()));
|
channel_name = c->ChannelSlotName(Strings::ToInt(in_channel_name));
|
||||||
}
|
}
|
||||||
|
|
||||||
auto *required_channel = FindChannel(channel_name);
|
auto *required_channel = FindChannel(channel_name);
|
||||||
|
|||||||
+14
-14
@@ -379,14 +379,14 @@ static void ProcessSetMessageStatus(std::string SetMessageCommand) {
|
|||||||
|
|
||||||
if (NumEnd == std::string::npos) {
|
if (NumEnd == std::string::npos) {
|
||||||
|
|
||||||
MessageNumber = Strings::ToInt(SetMessageCommand.substr(NumStart).c_str());
|
MessageNumber = Strings::ToInt(SetMessageCommand.substr(NumStart));
|
||||||
|
|
||||||
database.SetMessageStatus(MessageNumber, Status);
|
database.SetMessageStatus(MessageNumber, Status);
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
MessageNumber = Strings::ToInt(SetMessageCommand.substr(NumStart, NumEnd - NumStart).c_str());
|
MessageNumber = Strings::ToInt(SetMessageCommand.substr(NumStart, NumEnd - NumStart));
|
||||||
|
|
||||||
database.SetMessageStatus(MessageNumber, Status);
|
database.SetMessageStatus(MessageNumber, Status);
|
||||||
|
|
||||||
@@ -878,7 +878,7 @@ void Clientlist::ProcessOPMailCommand(Client *c, std::string command_string, boo
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case CommandGetBody:
|
case CommandGetBody:
|
||||||
database.SendBody(c, Strings::ToInt(parameters.c_str()));
|
database.SendBody(c, Strings::ToInt(parameters));
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case CommandMailTo:
|
case CommandMailTo:
|
||||||
@@ -893,7 +893,7 @@ void Clientlist::ProcessOPMailCommand(Client *c, std::string command_string, boo
|
|||||||
case CommandSelectMailBox:
|
case CommandSelectMailBox:
|
||||||
{
|
{
|
||||||
std::string::size_type NumStart = parameters.find_first_of("0123456789");
|
std::string::size_type NumStart = parameters.find_first_of("0123456789");
|
||||||
c->ChangeMailBox(Strings::ToInt(parameters.substr(NumStart).c_str()));
|
c->ChangeMailBox(Strings::ToInt(parameters.substr(NumStart)));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case CommandSetMailForwarding:
|
case CommandSetMailForwarding:
|
||||||
@@ -1255,7 +1255,7 @@ void Client::ProcessChannelList(std::string Input) {
|
|||||||
std::string ChannelName = Input;
|
std::string ChannelName = Input;
|
||||||
|
|
||||||
if (isdigit(ChannelName[0]))
|
if (isdigit(ChannelName[0]))
|
||||||
ChannelName = ChannelSlotName(Strings::ToInt(ChannelName.c_str()));
|
ChannelName = ChannelSlotName(Strings::ToInt(ChannelName));
|
||||||
|
|
||||||
ChatChannel *RequiredChannel = ChannelList->FindChannel(ChannelName);
|
ChatChannel *RequiredChannel = ChannelList->FindChannel(ChannelName);
|
||||||
|
|
||||||
@@ -1416,7 +1416,7 @@ void Client::SendChannelMessageByNumber(std::string Message) {
|
|||||||
if (MessageStart == std::string::npos)
|
if (MessageStart == std::string::npos)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
int ChannelNumber = Strings::ToInt(Message.substr(0, MessageStart).c_str());
|
int ChannelNumber = Strings::ToInt(Message.substr(0, MessageStart));
|
||||||
|
|
||||||
if ((ChannelNumber < 1) || (ChannelNumber > MAX_JOINED_CHANNELS)) {
|
if ((ChannelNumber < 1) || (ChannelNumber > MAX_JOINED_CHANNELS)) {
|
||||||
|
|
||||||
@@ -1659,7 +1659,7 @@ void Client::SetChannelPassword(std::string ChannelPassword) {
|
|||||||
std::string ChannelName = ChannelPassword.substr(ChannelStart);
|
std::string ChannelName = ChannelPassword.substr(ChannelStart);
|
||||||
|
|
||||||
if ((ChannelName.length() > 0) && isdigit(ChannelName[0]))
|
if ((ChannelName.length() > 0) && isdigit(ChannelName[0]))
|
||||||
ChannelName = ChannelSlotName(Strings::ToInt(ChannelName.c_str()));
|
ChannelName = ChannelSlotName(Strings::ToInt(ChannelName));
|
||||||
|
|
||||||
std::string Message;
|
std::string Message;
|
||||||
|
|
||||||
@@ -1724,7 +1724,7 @@ void Client::SetChannelOwner(std::string CommandString) {
|
|||||||
std::string ChannelName = CapitaliseName(CommandString.substr(ChannelStart));
|
std::string ChannelName = CapitaliseName(CommandString.substr(ChannelStart));
|
||||||
|
|
||||||
if ((ChannelName.length() > 0) && isdigit(ChannelName[0]))
|
if ((ChannelName.length() > 0) && isdigit(ChannelName[0]))
|
||||||
ChannelName = ChannelSlotName(Strings::ToInt(ChannelName.c_str()));
|
ChannelName = ChannelSlotName(Strings::ToInt(ChannelName));
|
||||||
|
|
||||||
LogInfo("Set owner of channel [[{}]] to [[{}]]", ChannelName.c_str(), NewOwner.c_str());
|
LogInfo("Set owner of channel [[{}]] to [[{}]]", ChannelName.c_str(), NewOwner.c_str());
|
||||||
|
|
||||||
@@ -1770,7 +1770,7 @@ void Client::OPList(std::string CommandString) {
|
|||||||
std::string ChannelName = CapitaliseName(CommandString.substr(ChannelStart));
|
std::string ChannelName = CapitaliseName(CommandString.substr(ChannelStart));
|
||||||
|
|
||||||
if ((ChannelName.length() > 0) && isdigit(ChannelName[0]))
|
if ((ChannelName.length() > 0) && isdigit(ChannelName[0]))
|
||||||
ChannelName = ChannelSlotName(Strings::ToInt(ChannelName.c_str()));
|
ChannelName = ChannelSlotName(Strings::ToInt(ChannelName));
|
||||||
|
|
||||||
ChatChannel *RequiredChannel = ChannelList->FindChannel(ChannelName);
|
ChatChannel *RequiredChannel = ChannelList->FindChannel(ChannelName);
|
||||||
|
|
||||||
@@ -1813,7 +1813,7 @@ void Client::ChannelInvite(std::string CommandString) {
|
|||||||
std::string ChannelName = CapitaliseName(CommandString.substr(ChannelStart));
|
std::string ChannelName = CapitaliseName(CommandString.substr(ChannelStart));
|
||||||
|
|
||||||
if ((ChannelName.length() > 0) && isdigit(ChannelName[0]))
|
if ((ChannelName.length() > 0) && isdigit(ChannelName[0]))
|
||||||
ChannelName = ChannelSlotName(Strings::ToInt(ChannelName.c_str()));
|
ChannelName = ChannelSlotName(Strings::ToInt(ChannelName));
|
||||||
|
|
||||||
LogInfo("[[{}]] invites [[{}]] to channel [[{}]]", GetName().c_str(), Invitee.c_str(), ChannelName.c_str());
|
LogInfo("[[{}]] invites [[{}]] to channel [[{}]]", GetName().c_str(), Invitee.c_str(), ChannelName.c_str());
|
||||||
|
|
||||||
@@ -1883,7 +1883,7 @@ void Client::ChannelModerate(std::string CommandString) {
|
|||||||
std::string ChannelName = CapitaliseName(CommandString.substr(ChannelStart));
|
std::string ChannelName = CapitaliseName(CommandString.substr(ChannelStart));
|
||||||
|
|
||||||
if ((ChannelName.length() > 0) && isdigit(ChannelName[0]))
|
if ((ChannelName.length() > 0) && isdigit(ChannelName[0]))
|
||||||
ChannelName = ChannelSlotName(Strings::ToInt(ChannelName.c_str()));
|
ChannelName = ChannelSlotName(Strings::ToInt(ChannelName));
|
||||||
|
|
||||||
ChatChannel *RequiredChannel = ChannelList->FindChannel(ChannelName);
|
ChatChannel *RequiredChannel = ChannelList->FindChannel(ChannelName);
|
||||||
|
|
||||||
@@ -1941,7 +1941,7 @@ void Client::ChannelGrantModerator(std::string CommandString) {
|
|||||||
std::string ChannelName = CapitaliseName(CommandString.substr(ChannelStart));
|
std::string ChannelName = CapitaliseName(CommandString.substr(ChannelStart));
|
||||||
|
|
||||||
if ((ChannelName.length() > 0) && isdigit(ChannelName[0]))
|
if ((ChannelName.length() > 0) && isdigit(ChannelName[0]))
|
||||||
ChannelName = ChannelSlotName(Strings::ToInt(ChannelName.c_str()));
|
ChannelName = ChannelSlotName(Strings::ToInt(ChannelName));
|
||||||
|
|
||||||
LogInfo("[[{}]] gives [[{}]] moderator rights to channel [[{}]]", GetName().c_str(), Moderator.c_str(), ChannelName.c_str());
|
LogInfo("[[{}]] gives [[{}]] moderator rights to channel [[{}]]", GetName().c_str(), Moderator.c_str(), ChannelName.c_str());
|
||||||
|
|
||||||
@@ -2022,7 +2022,7 @@ void Client::ChannelGrantVoice(std::string CommandString) {
|
|||||||
std::string ChannelName = CapitaliseName(CommandString.substr(ChannelStart));
|
std::string ChannelName = CapitaliseName(CommandString.substr(ChannelStart));
|
||||||
|
|
||||||
if ((ChannelName.length() > 0) && isdigit(ChannelName[0]))
|
if ((ChannelName.length() > 0) && isdigit(ChannelName[0]))
|
||||||
ChannelName = ChannelSlotName(Strings::ToInt(ChannelName.c_str()));
|
ChannelName = ChannelSlotName(Strings::ToInt(ChannelName));
|
||||||
|
|
||||||
LogInfo("[[{}]] gives [[{}]] voice to channel [[{}]]", GetName().c_str(), Voicee.c_str(), ChannelName.c_str());
|
LogInfo("[[{}]] gives [[{}]] voice to channel [[{}]]", GetName().c_str(), Voicee.c_str(), ChannelName.c_str());
|
||||||
|
|
||||||
@@ -2110,7 +2110,7 @@ void Client::ChannelKick(std::string CommandString) {
|
|||||||
std::string ChannelName = CapitaliseName(CommandString.substr(ChannelStart));
|
std::string ChannelName = CapitaliseName(CommandString.substr(ChannelStart));
|
||||||
|
|
||||||
if ((ChannelName.length() > 0) && isdigit(ChannelName[0]))
|
if ((ChannelName.length() > 0) && isdigit(ChannelName[0]))
|
||||||
ChannelName = ChannelSlotName(Strings::ToInt(ChannelName.c_str()));
|
ChannelName = ChannelSlotName(Strings::ToInt(ChannelName));
|
||||||
|
|
||||||
LogInfo("[[{}]] kicks [[{}]] from channel [[{}]]", GetName().c_str(), Kickee.c_str(), ChannelName.c_str());
|
LogInfo("[[{}]] kicks [[{}]] from channel [[{}]]", GetName().c_str(), Kickee.c_str(), ChannelName.c_str());
|
||||||
|
|
||||||
|
|||||||
@@ -37,6 +37,7 @@
|
|||||||
9036|2023_01_19_drop_bot_views.sql|SHOW TABLES LIKE 'vw_groups'|not_empty|
|
9036|2023_01_19_drop_bot_views.sql|SHOW TABLES LIKE 'vw_groups'|not_empty|
|
||||||
9037|2023_01_22_add_name_index.sql||show index from bot_data WHERE key_name = 'name`|empty|
|
9037|2023_01_22_add_name_index.sql||show index from bot_data WHERE key_name = 'name`|empty|
|
||||||
9038|2023_02_16_add_caster_range.sql|SHOW COLUMNS FROM `bot_data` LIKE 'caster_range'|empty|
|
9038|2023_02_16_add_caster_range.sql|SHOW COLUMNS FROM `bot_data` LIKE 'caster_range'|empty|
|
||||||
|
9039|2023_03_31_remove_bot_groups.sql|SHOW TABLES LIKE 'bot_groups'|not_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,4 @@
|
|||||||
|
SET FOREIGN_KEY_CHECKS = 0;
|
||||||
|
DROP TABLE IF EXISTS `bot_groups`;
|
||||||
|
DROP TABLE IF EXISTS `bot_group_members`;
|
||||||
|
SET FOREIGN_KEY_CHECKS = 1;
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
DROP INDEX IF EXISTS `PRIMARY` ON `raid_members`;
|
DROP INDEX `PRIMARY` ON `raid_members`;
|
||||||
CREATE UNIQUE INDEX IF NOT EXISTS `UNIQUE` ON `raid_members`(`name`);
|
CREATE UNIQUE INDEX `UNIQUE` ON `raid_members`(`name`);
|
||||||
ALTER TABLE `raid_members` ADD COLUMN `bot_id` int(4) NOT NULL DEFAULT 0 AFTER `charid`;
|
ALTER TABLE `raid_members` ADD COLUMN `bot_id` int(4) NOT NULL DEFAULT 0 AFTER `charid`;
|
||||||
ALTER TABLE `raid_members` ADD COLUMN `id` BIGINT UNSIGNED NOT NULL PRIMARY KEY AUTO_INCREMENT FIRST;
|
ALTER TABLE `raid_members` ADD COLUMN `id` BIGINT UNSIGNED NOT NULL PRIMARY KEY AUTO_INCREMENT FIRST;
|
||||||
+3
-3
@@ -1258,7 +1258,7 @@ bool Client::ChecksumVerificationCRCEQGame(uint64 checksum)
|
|||||||
std::string checksumvar;
|
std::string checksumvar;
|
||||||
uint64_t checksumint;
|
uint64_t checksumint;
|
||||||
if (database.GetVariable("crc_eqgame", checksumvar)) {
|
if (database.GetVariable("crc_eqgame", checksumvar)) {
|
||||||
checksumint = Strings::ToBigInt(checksumvar.c_str());
|
checksumint = Strings::ToBigInt(checksumvar);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
LogChecksumVerification("variable not set in variables table.");
|
LogChecksumVerification("variable not set in variables table.");
|
||||||
@@ -1281,7 +1281,7 @@ bool Client::ChecksumVerificationCRCSkillCaps(uint64 checksum)
|
|||||||
std::string checksumvar;
|
std::string checksumvar;
|
||||||
uint64_t checksumint;
|
uint64_t checksumint;
|
||||||
if (database.GetVariable("crc_skillcaps", checksumvar)) {
|
if (database.GetVariable("crc_skillcaps", checksumvar)) {
|
||||||
checksumint = Strings::ToBigInt(checksumvar.c_str());
|
checksumint = Strings::ToBigInt(checksumvar);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
LogChecksumVerification("[checksum_crc2_skillcaps] variable not set in variables table.");
|
LogChecksumVerification("[checksum_crc2_skillcaps] variable not set in variables table.");
|
||||||
@@ -1304,7 +1304,7 @@ bool Client::ChecksumVerificationCRCBaseData(uint64 checksum)
|
|||||||
std::string checksumvar;
|
std::string checksumvar;
|
||||||
uint64_t checksumint;
|
uint64_t checksumint;
|
||||||
if (database.GetVariable("crc_basedata", checksumvar)) {
|
if (database.GetVariable("crc_basedata", checksumvar)) {
|
||||||
checksumint = Strings::ToBigInt(checksumvar.c_str());
|
checksumint = Strings::ToBigInt(checksumvar);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
LogChecksumVerification("variable not set in variables table.");
|
LogChecksumVerification("variable not set in variables table.");
|
||||||
|
|||||||
@@ -360,7 +360,7 @@ bool ClientListEntry::CheckAuth(uint32 loginserver_account_id, const char *key_p
|
|||||||
}
|
}
|
||||||
std::string lsworldadmin;
|
std::string lsworldadmin;
|
||||||
if (database.GetVariable("honorlsworldadmin", lsworldadmin)) {
|
if (database.GetVariable("honorlsworldadmin", lsworldadmin)) {
|
||||||
if (Strings::ToInt(lsworldadmin.c_str()) == 1 && pworldadmin != 0 && (padmin < pworldadmin || padmin == AccountStatus::Player)) {
|
if (Strings::ToInt(lsworldadmin) == 1 && pworldadmin != 0 && (padmin < pworldadmin || padmin == AccountStatus::Player)) {
|
||||||
padmin = pworldadmin;
|
padmin = pworldadmin;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+18
-18
@@ -166,14 +166,14 @@ void ConsoleWho(
|
|||||||
}
|
}
|
||||||
else if (Strings::IsNumber(arg)) {
|
else if (Strings::IsNumber(arg)) {
|
||||||
if (whom.lvllow == 0xFFFF) {
|
if (whom.lvllow == 0xFFFF) {
|
||||||
whom.lvllow = Strings::ToInt(arg.c_str());
|
whom.lvllow = Strings::ToInt(arg);
|
||||||
whom.lvlhigh = whom.lvllow;
|
whom.lvlhigh = whom.lvllow;
|
||||||
}
|
}
|
||||||
else if (Strings::ToInt(arg.c_str()) > int(whom.lvllow)) {
|
else if (Strings::ToInt(arg) > int(whom.lvllow)) {
|
||||||
whom.lvlhigh = Strings::ToInt(arg.c_str());
|
whom.lvlhigh = Strings::ToInt(arg);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
whom.lvllow = Strings::ToInt(arg.c_str());
|
whom.lvllow = Strings::ToInt(arg);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
@@ -200,11 +200,11 @@ void ConsoleUptime(
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Strings::IsNumber(args[0]) && Strings::ToInt(args[0].c_str()) > 0) {
|
if (Strings::IsNumber(args[0]) && Strings::ToInt(args[0]) > 0) {
|
||||||
auto pack = new ServerPacket(ServerOP_Uptime, sizeof(ServerUptime_Struct));
|
auto pack = new ServerPacket(ServerOP_Uptime, sizeof(ServerUptime_Struct));
|
||||||
ServerUptime_Struct *sus = (ServerUptime_Struct *) pack->pBuffer;
|
ServerUptime_Struct *sus = (ServerUptime_Struct *) pack->pBuffer;
|
||||||
snprintf(sus->adminname, sizeof(sus->adminname), "*%s", connection->UserName().c_str());
|
snprintf(sus->adminname, sizeof(sus->adminname), "*%s", connection->UserName().c_str());
|
||||||
sus->zoneserverid = Strings::ToInt(args[0].c_str());
|
sus->zoneserverid = Strings::ToInt(args[0]);
|
||||||
ZoneServer *zs = zoneserver_list.FindByID(sus->zoneserverid);
|
ZoneServer *zs = zoneserver_list.FindByID(sus->zoneserverid);
|
||||||
if (zs) {
|
if (zs) {
|
||||||
zs->SendPacket(pack);
|
zs->SendPacket(pack);
|
||||||
@@ -284,7 +284,7 @@ void ConsoleEmote(
|
|||||||
0,
|
0,
|
||||||
0,
|
0,
|
||||||
AccountStatus::Player,
|
AccountStatus::Player,
|
||||||
Strings::ToInt(args[1].c_str()),
|
Strings::ToInt(args[1]),
|
||||||
Strings::Join(join_args, " ").c_str()
|
Strings::Join(join_args, " ").c_str()
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@@ -295,7 +295,7 @@ void ConsoleEmote(
|
|||||||
0,
|
0,
|
||||||
0,
|
0,
|
||||||
AccountStatus::Player,
|
AccountStatus::Player,
|
||||||
Strings::ToInt(args[1].c_str()),
|
Strings::ToInt(args[1]),
|
||||||
Strings::Join(join_args, " ").c_str()
|
Strings::Join(join_args, " ").c_str()
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@@ -304,7 +304,7 @@ void ConsoleEmote(
|
|||||||
args[0].c_str(),
|
args[0].c_str(),
|
||||||
0,
|
0,
|
||||||
AccountStatus::Player,
|
AccountStatus::Player,
|
||||||
Strings::ToInt(args[1].c_str()),
|
Strings::ToInt(args[1]),
|
||||||
Strings::Join(join_args, " ").c_str()
|
Strings::Join(join_args, " ").c_str()
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@@ -585,7 +585,7 @@ void ConsoleZoneShutdown(
|
|||||||
pack->opcode = ServerOP_ZoneShutdown;
|
pack->opcode = ServerOP_ZoneShutdown;
|
||||||
strcpy(s->adminname, tmpname);
|
strcpy(s->adminname, tmpname);
|
||||||
if (Strings::IsNumber(args[0])) {
|
if (Strings::IsNumber(args[0])) {
|
||||||
s->ZoneServerID = Strings::ToInt(args[0].c_str());
|
s->ZoneServerID = Strings::ToInt(args[0]);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
s->zoneid = ZoneID(args[0].c_str());
|
s->zoneid = ZoneID(args[0].c_str());
|
||||||
@@ -639,12 +639,12 @@ void ConsoleZoneBootup(
|
|||||||
if (args.size() > 2) {
|
if (args.size() > 2) {
|
||||||
zoneserver_list.SOPZoneBootup(
|
zoneserver_list.SOPZoneBootup(
|
||||||
tmpname,
|
tmpname,
|
||||||
Strings::ToInt(args[0].c_str()),
|
Strings::ToInt(args[0]),
|
||||||
args[1].c_str(),
|
args[1].c_str(),
|
||||||
(bool) (strcasecmp(args[1].c_str(), "static") == 0));
|
(bool) (strcasecmp(args[1].c_str(), "static") == 0));
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
zoneserver_list.SOPZoneBootup(tmpname, Strings::ToInt(args[0].c_str()), args[1].c_str(), false);
|
zoneserver_list.SOPZoneBootup(tmpname, Strings::ToInt(args[0]), args[1].c_str(), false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -751,10 +751,10 @@ void ConsoleFlag(
|
|||||||
connection->SendLine("Usage: flag [status] [accountname]");
|
connection->SendLine("Usage: flag [status] [accountname]");
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
if (Strings::ToInt(args[0].c_str()) > connection->Admin()) {
|
if (Strings::ToInt(args[0]) > connection->Admin()) {
|
||||||
connection->SendLine("You cannot set people's status to higher than your own");
|
connection->SendLine("You cannot set people's status to higher than your own");
|
||||||
}
|
}
|
||||||
else if (!database.SetAccountStatus(args[1].c_str(), Strings::ToInt(args[0].c_str()))) {
|
else if (!database.SetAccountStatus(args[1].c_str(), Strings::ToInt(args[0]))) {
|
||||||
connection->SendLine("Unable to flag account!");
|
connection->SendLine("Unable to flag account!");
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
@@ -821,8 +821,8 @@ void ConsoleWorldShutdown(
|
|||||||
{
|
{
|
||||||
if (args.size() == 2) {
|
if (args.size() == 2) {
|
||||||
int32 time, interval;
|
int32 time, interval;
|
||||||
if (Strings::IsNumber(args[0]) && Strings::IsNumber(args[1]) && ((time = Strings::ToInt(args[0].c_str())) > 0) &&
|
if (Strings::IsNumber(args[0]) && Strings::IsNumber(args[1]) && ((time = Strings::ToInt(args[0])) > 0) &&
|
||||||
((interval = Strings::ToInt(args[1].c_str())) > 0)) {
|
((interval = Strings::ToInt(args[1])) > 0)) {
|
||||||
zoneserver_list.WorldShutDown(time, interval);
|
zoneserver_list.WorldShutDown(time, interval);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
@@ -886,7 +886,7 @@ void ConsoleSignalCharByName(
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
connection->SendLine(StringFormat("Signal Sent to %s with ID %i", (char *) args[0].c_str(), Strings::ToInt(args[1].c_str())));
|
connection->SendLine(StringFormat("Signal Sent to %s with ID %i", (char *) args[0].c_str(), Strings::ToInt(args[1])));
|
||||||
uint32 message_len = strlen((char *) args[0].c_str()) + 1;
|
uint32 message_len = strlen((char *) args[0].c_str()) + 1;
|
||||||
auto pack = new ServerPacket(ServerOP_CZSignal, sizeof(CZSignal_Struct) + message_len);
|
auto pack = new ServerPacket(ServerOP_CZSignal, sizeof(CZSignal_Struct) + message_len);
|
||||||
CZSignal_Struct* CZS = (CZSignal_Struct*) pack->pBuffer;
|
CZSignal_Struct* CZS = (CZSignal_Struct*) pack->pBuffer;
|
||||||
@@ -894,7 +894,7 @@ void ConsoleSignalCharByName(
|
|||||||
int update_identifier = 0;
|
int update_identifier = 0;
|
||||||
CZS->update_type = update_type;
|
CZS->update_type = update_type;
|
||||||
CZS->update_identifier = update_identifier;
|
CZS->update_identifier = update_identifier;
|
||||||
CZS->signal_id = Strings::ToInt(args[1].c_str());
|
CZS->signal_id = Strings::ToInt(args[1]);
|
||||||
strn0cpy(CZS->client_name, (char *) args[0].c_str(), 64);
|
strn0cpy(CZS->client_name, (char *) args[0].c_str(), 64);
|
||||||
zoneserver_list.SendPacket(pack);
|
zoneserver_list.SendPacket(pack);
|
||||||
safe_delete(pack);
|
safe_delete(pack);
|
||||||
|
|||||||
@@ -204,7 +204,7 @@ void WorldBoot::CheckForServerScript(bool force_download)
|
|||||||
r.set_read_timeout(1, 0);
|
r.set_read_timeout(1, 0);
|
||||||
r.set_write_timeout(1, 0);
|
r.set_write_timeout(1, 0);
|
||||||
|
|
||||||
if (auto res = r.Get(u.get_path().c_str())) {
|
if (auto res = r.Get(u.get_path())) {
|
||||||
if (res->status == 200) {
|
if (res->status == 200) {
|
||||||
// write file
|
// write file
|
||||||
|
|
||||||
@@ -369,7 +369,7 @@ bool WorldBoot::DatabaseLoadRoutines(int argc, char **argv)
|
|||||||
if (database.GetVariable("RuleSet", tmp)) {
|
if (database.GetVariable("RuleSet", tmp)) {
|
||||||
LogInfo("Loading rule set [{}]", tmp.c_str());
|
LogInfo("Loading rule set [{}]", tmp.c_str());
|
||||||
|
|
||||||
if (!RuleManager::Instance()->LoadRules(&database, tmp.c_str(), false)) {
|
if (!RuleManager::Instance()->LoadRules(&database, tmp, false)) {
|
||||||
LogInfo("Failed to load ruleset [{}], falling back to defaults", tmp.c_str());
|
LogInfo("Failed to load ruleset [{}], falling back to defaults", tmp.c_str());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+2
-2
@@ -1963,7 +1963,7 @@ void Client::TogglePassiveAlternativeAdvancement(const AA::Rank &rank, uint32 ab
|
|||||||
AA::Rank *rank_next = zone->GetAlternateAdvancementRank(rank.next_id);
|
AA::Rank *rank_next = zone->GetAlternateAdvancementRank(rank.next_id);
|
||||||
|
|
||||||
//Add checks for any special cases for toggle.
|
//Add checks for any special cases for toggle.
|
||||||
if (IsEffectinAlternateAdvancementRankEffects(*rank_next, SE_Weapon_Stance)) {
|
if (rank_next && IsEffectinAlternateAdvancementRankEffects(*rank_next, SE_Weapon_Stance)) {
|
||||||
weaponstance.aabonus_enabled = true;
|
weaponstance.aabonus_enabled = true;
|
||||||
ApplyWeaponsStance();
|
ApplyWeaponsStance();
|
||||||
}
|
}
|
||||||
@@ -2003,7 +2003,7 @@ bool Client::UseTogglePassiveHotkey(const AA::Rank &rank) {
|
|||||||
else if (rank.prev_id != -1) {//Check when effect is Enabled.
|
else if (rank.prev_id != -1) {//Check when effect is Enabled.
|
||||||
AA::Rank *rank_prev = zone->GetAlternateAdvancementRank(rank.prev_id);
|
AA::Rank *rank_prev = zone->GetAlternateAdvancementRank(rank.prev_id);
|
||||||
|
|
||||||
if (IsEffectInSpell(rank_prev->spell, SE_Buy_AA_Rank)) {
|
if (rank_prev && IsEffectInSpell(rank_prev->spell, SE_Buy_AA_Rank)) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+3
-2
@@ -904,9 +904,10 @@ bool Mob::IsBeneficialAllowed(Mob *target)
|
|||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
else if(mob2->IsBot())
|
else if (mob2 && mob2->IsBot()) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
else if(_NPC(mob1))
|
else if(_NPC(mob1))
|
||||||
{
|
{
|
||||||
if(_CLIENT(mob2))
|
if(_CLIENT(mob2))
|
||||||
@@ -1436,7 +1437,7 @@ void Mob::ClearFeignMemory() {
|
|||||||
while (remembered_feigned_mobid != feign_memory_list.end())
|
while (remembered_feigned_mobid != feign_memory_list.end())
|
||||||
{
|
{
|
||||||
Mob* remembered_mob = entity_list.GetMob(*remembered_feigned_mobid);
|
Mob* remembered_mob = entity_list.GetMob(*remembered_feigned_mobid);
|
||||||
if (remembered_mob->IsClient() && remembered_mob != nullptr) { //Still in zone
|
if (remembered_mob && remembered_mob->IsClient()) { //Still in zone
|
||||||
remembered_mob->CastToClient()->RemoveXTarget(this, false);
|
remembered_mob->CastToClient()->RemoveXTarget(this, false);
|
||||||
}
|
}
|
||||||
++remembered_feigned_mobid;
|
++remembered_feigned_mobid;
|
||||||
|
|||||||
@@ -471,11 +471,11 @@ Json::Value ApiGetMobListDetail(EQ::Net::WebsocketServerConnection *connection,
|
|||||||
row["has_primary_aggro"] = mob->HasPrimaryAggro();
|
row["has_primary_aggro"] = mob->HasPrimaryAggro();
|
||||||
row["has_project_illusion"] = mob->HasProjectIllusion();
|
row["has_project_illusion"] = mob->HasProjectIllusion();
|
||||||
row["has_projectile_attack"] = mob->HasProjectileAttack();
|
row["has_projectile_attack"] = mob->HasProjectileAttack();
|
||||||
row["has_shield_equiped"] = mob->HasShieldEquiped();
|
row["has_shield_equipped"] = mob->HasShieldEquipped();
|
||||||
row["has_special_abilities"] = mob->HasSpecialAbilities();
|
row["has_special_abilities"] = mob->HasSpecialAbilities();
|
||||||
row["has_tar_reflection"] = mob->HasTargetReflection();
|
row["has_tar_reflection"] = mob->HasTargetReflection();
|
||||||
row["has_temp_pets_active"] = mob->HasTempPetsActive();
|
row["has_temp_pets_active"] = mob->HasTempPetsActive();
|
||||||
row["has_two_hand_blunt_equiped"] = mob->HasTwoHandBluntEquiped();
|
row["has_two_hand_blunt_equipped"] = mob->HasTwoHandBluntEquipped();
|
||||||
row["has_two_hander_equipped"] = mob->HasTwoHanderEquipped();
|
row["has_two_hander_equipped"] = mob->HasTwoHanderEquipped();
|
||||||
row["hate_summon"] = mob->HateSummon();
|
row["hate_summon"] = mob->HateSummon();
|
||||||
row["helm_texture"] = mob->GetHelmTexture();
|
row["helm_texture"] = mob->GetHelmTexture();
|
||||||
|
|||||||
+9
-9
@@ -592,7 +592,7 @@ bool Mob::AvoidDamage(Mob *other, DamageHitInfo &hit)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Try Shield Block OR TwoHandBluntBlockCheck
|
// Try Shield Block OR TwoHandBluntBlockCheck
|
||||||
if (HasShieldEquiped() && (aabonuses.ShieldBlock || spellbonuses.ShieldBlock || itembonuses.ShieldBlock) && (InFront || bBlockFromRear)) {
|
if (HasShieldEquipped() && (aabonuses.ShieldBlock || spellbonuses.ShieldBlock || itembonuses.ShieldBlock) && (InFront || bBlockFromRear)) {
|
||||||
int chance = aabonuses.ShieldBlock + spellbonuses.ShieldBlock + itembonuses.ShieldBlock;
|
int chance = aabonuses.ShieldBlock + spellbonuses.ShieldBlock + itembonuses.ShieldBlock;
|
||||||
if (counter_block || counter_all) {
|
if (counter_block || counter_all) {
|
||||||
float counter = (counter_block + counter_all) / 100.0f;
|
float counter = (counter_block + counter_all) / 100.0f;
|
||||||
@@ -604,7 +604,7 @@ bool Mob::AvoidDamage(Mob *other, DamageHitInfo &hit)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (HasTwoHandBluntEquiped() && (aabonuses.TwoHandBluntBlock || spellbonuses.TwoHandBluntBlock || itembonuses.TwoHandBluntBlock) && (InFront || bBlockFromRear)) {
|
if (HasTwoHandBluntEquipped() && (aabonuses.TwoHandBluntBlock || spellbonuses.TwoHandBluntBlock || itembonuses.TwoHandBluntBlock) && (InFront || bBlockFromRear)) {
|
||||||
int chance = aabonuses.TwoHandBluntBlock + itembonuses.TwoHandBluntBlock + spellbonuses.TwoHandBluntBlock;
|
int chance = aabonuses.TwoHandBluntBlock + itembonuses.TwoHandBluntBlock + spellbonuses.TwoHandBluntBlock;
|
||||||
if (counter_block || counter_all) {
|
if (counter_block || counter_all) {
|
||||||
float counter = (counter_block + counter_all) / 100.0f;
|
float counter = (counter_block + counter_all) / 100.0f;
|
||||||
@@ -874,7 +874,7 @@ int Mob::ACSum(bool skip_caps)
|
|||||||
int ac = 0; // this should be base AC whenever shrouds come around
|
int ac = 0; // this should be base AC whenever shrouds come around
|
||||||
ac += itembonuses.AC; // items + food + tribute
|
ac += itembonuses.AC; // items + food + tribute
|
||||||
int shield_ac = 0;
|
int shield_ac = 0;
|
||||||
if (HasShieldEquiped() && IsOfClientBot()) {
|
if (HasShieldEquipped() && IsOfClientBot()) {
|
||||||
auto inst = (IsClient()) ? GetInv().GetItem(EQ::invslot::slotSecondary) : CastToBot()->GetBotItem(EQ::invslot::slotSecondary);
|
auto inst = (IsClient()) ? GetInv().GetItem(EQ::invslot::slotSecondary) : CastToBot()->GetBotItem(EQ::invslot::slotSecondary);
|
||||||
if (inst) {
|
if (inst) {
|
||||||
if (inst->GetItemRecommendedLevel(true) <= GetLevel()) {
|
if (inst->GetItemRecommendedLevel(true) <= GetLevel()) {
|
||||||
@@ -1484,7 +1484,6 @@ bool Mob::Attack(Mob* other, int Hand, bool bRiposte, bool IsStrikethrough, bool
|
|||||||
|
|
||||||
if (
|
if (
|
||||||
(IsCasting() && GetClass() != BARD && !IsFromSpell)
|
(IsCasting() && GetClass() != BARD && !IsFromSpell)
|
||||||
|| other == nullptr
|
|
||||||
|| ((IsClient() && CastToClient()->dead) || (other->IsClient() && other->CastToClient()->dead))
|
|| ((IsClient() && CastToClient()->dead) || (other->IsClient() && other->CastToClient()->dead))
|
||||||
|| (GetHP() < 0)
|
|| (GetHP() < 0)
|
||||||
|| (!IsAttackAllowed(other))
|
|| (!IsAttackAllowed(other))
|
||||||
@@ -1555,7 +1554,7 @@ bool Mob::Attack(Mob* other, int Hand, bool bRiposte, bool IsStrikethrough, bool
|
|||||||
if (Hand == EQ::invslot::slotPrimary || Hand == EQ::invslot::slotSecondary)
|
if (Hand == EQ::invslot::slotPrimary || Hand == EQ::invslot::slotSecondary)
|
||||||
my_hit.base_damage = DoDamageCaps(my_hit.base_damage);
|
my_hit.base_damage = DoDamageCaps(my_hit.base_damage);
|
||||||
auto shield_inc = spellbonuses.ShieldEquipDmgMod + itembonuses.ShieldEquipDmgMod + aabonuses.ShieldEquipDmgMod;
|
auto shield_inc = spellbonuses.ShieldEquipDmgMod + itembonuses.ShieldEquipDmgMod + aabonuses.ShieldEquipDmgMod;
|
||||||
if (shield_inc > 0 && HasShieldEquiped() && Hand == EQ::invslot::slotPrimary) {
|
if (shield_inc > 0 && HasShieldEquipped() && Hand == EQ::invslot::slotPrimary) {
|
||||||
my_hit.base_damage = my_hit.base_damage * (100 + shield_inc) / 100;
|
my_hit.base_damage = my_hit.base_damage * (100 + shield_inc) / 100;
|
||||||
hate = hate * (100 + shield_inc) / 100;
|
hate = hate * (100 + shield_inc) / 100;
|
||||||
}
|
}
|
||||||
@@ -1979,10 +1978,10 @@ bool Client::Death(Mob* killerMob, int64 damage, uint16 spell, EQ::skills::Skill
|
|||||||
database.GetVariable("ServerType", tmp);
|
database.GetVariable("ServerType", tmp);
|
||||||
if (tmp[0] == '1' && tmp[1] == '\0' && killerMob && killerMob->IsClient()) {
|
if (tmp[0] == '1' && tmp[1] == '\0' && killerMob && killerMob->IsClient()) {
|
||||||
database.GetVariable("PvPreward", tmp);
|
database.GetVariable("PvPreward", tmp);
|
||||||
auto reward = Strings::ToInt(tmp.c_str());
|
auto reward = Strings::ToInt(tmp);
|
||||||
if (reward == 3) {
|
if (reward == 3) {
|
||||||
database.GetVariable("PvPitem", tmp);
|
database.GetVariable("PvPitem", tmp);
|
||||||
auto pvp_item_id = Strings::ToInt(tmp.c_str());
|
auto pvp_item_id = Strings::ToInt(tmp);
|
||||||
const auto* item = database.GetItem(pvp_item_id);
|
const auto* item = database.GetItem(pvp_item_id);
|
||||||
if (item) {
|
if (item) {
|
||||||
new_corpse->SetPlayerKillItemID(pvp_item_id);
|
new_corpse->SetPlayerKillItemID(pvp_item_id);
|
||||||
@@ -2835,10 +2834,11 @@ bool NPC::Death(Mob* killer_mob, int64 damage, uint16 spell, EQ::skills::SkillTy
|
|||||||
if (emote_id) {
|
if (emote_id) {
|
||||||
oos->CastToNPC()->DoNPCEmote(EQ::constants::EmoteEventTypes::KilledNPC, emote_id);
|
oos->CastToNPC()->DoNPCEmote(EQ::constants::EmoteEventTypes::KilledNPC, emote_id);
|
||||||
}
|
}
|
||||||
|
if (killer_mob) {
|
||||||
killer_mob->TrySpellOnKill(killed_level, spell);
|
killer_mob->TrySpellOnKill(killed_level, spell);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (killer_mob && killer_mob->IsBot()) {
|
if (killer_mob && killer_mob->IsBot()) {
|
||||||
if (parse->BotHasQuestSub(EVENT_NPC_SLAY)) {
|
if (parse->BotHasQuestSub(EVENT_NPC_SLAY)) {
|
||||||
@@ -5995,7 +5995,7 @@ void Mob::DoShieldDamageOnShielder(Mob *shield_target, int64 hit_damage_done, EQ
|
|||||||
}
|
}
|
||||||
|
|
||||||
int mitigation = shielder->GetShielderMitigation(); //Default shielder mitigates 25 pct of damage taken, this can be increased up to max 50 by equipping a shield item
|
int mitigation = shielder->GetShielderMitigation(); //Default shielder mitigates 25 pct of damage taken, this can be increased up to max 50 by equipping a shield item
|
||||||
if (shielder->IsClient() && shielder->HasShieldEquiped()) {
|
if (shielder->IsClient() && shielder->HasShieldEquipped()) {
|
||||||
EQ::ItemInstance* inst = shielder->CastToClient()->GetInv().GetItem(EQ::invslot::slotSecondary);
|
EQ::ItemInstance* inst = shielder->CastToClient()->GetInv().GetItem(EQ::invslot::slotSecondary);
|
||||||
if (inst) {
|
if (inst) {
|
||||||
const EQ::ItemData* shield = inst->GetItem();
|
const EQ::ItemData* shield = inst->GetItem();
|
||||||
|
|||||||
+8
-2
@@ -963,6 +963,10 @@ bool ZoneDatabase::GetAuraEntry(uint16 spell_id, AuraRecord &record)
|
|||||||
|
|
||||||
void Mob::AddAura(Aura *aura, AuraRecord &record)
|
void Mob::AddAura(Aura *aura, AuraRecord &record)
|
||||||
{
|
{
|
||||||
|
if (!aura) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
LogAura(
|
LogAura(
|
||||||
"aura owner [{}] spawn_id [{}] aura_name [{}]",
|
"aura owner [{}] spawn_id [{}] aura_name [{}]",
|
||||||
GetCleanName(),
|
GetCleanName(),
|
||||||
@@ -971,7 +975,6 @@ void Mob::AddAura(Aura *aura, AuraRecord &record)
|
|||||||
);
|
);
|
||||||
|
|
||||||
// this is called only when it's safe
|
// this is called only when it's safe
|
||||||
assert(aura != nullptr);
|
|
||||||
strn0cpy(aura_mgr.auras[aura_mgr.count].name, aura->GetCleanName(), 64);
|
strn0cpy(aura_mgr.auras[aura_mgr.count].name, aura->GetCleanName(), 64);
|
||||||
aura_mgr.auras[aura_mgr.count].spawn_id = aura->GetID();
|
aura_mgr.auras[aura_mgr.count].spawn_id = aura->GetID();
|
||||||
aura_mgr.auras[aura_mgr.count].aura = aura;
|
aura_mgr.auras[aura_mgr.count].aura = aura;
|
||||||
@@ -998,6 +1001,10 @@ void Mob::AddAura(Aura *aura, AuraRecord &record)
|
|||||||
|
|
||||||
void Mob::AddTrap(Aura *aura, AuraRecord &record)
|
void Mob::AddTrap(Aura *aura, AuraRecord &record)
|
||||||
{
|
{
|
||||||
|
if (!aura) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
LogAura(
|
LogAura(
|
||||||
"aura owner [{}] spawn_id [{}] aura_name [{}]",
|
"aura owner [{}] spawn_id [{}] aura_name [{}]",
|
||||||
GetCleanName(),
|
GetCleanName(),
|
||||||
@@ -1006,7 +1013,6 @@ void Mob::AddTrap(Aura *aura, AuraRecord &record)
|
|||||||
);
|
);
|
||||||
|
|
||||||
// this is called only when it's safe
|
// this is called only when it's safe
|
||||||
assert(aura != nullptr);
|
|
||||||
strn0cpy(trap_mgr.auras[trap_mgr.count].name, aura->GetCleanName(), 64);
|
strn0cpy(trap_mgr.auras[trap_mgr.count].name, aura->GetCleanName(), 64);
|
||||||
trap_mgr.auras[trap_mgr.count].spawn_id = aura->GetID();
|
trap_mgr.auras[trap_mgr.count].spawn_id = aura->GetID();
|
||||||
trap_mgr.auras[trap_mgr.count].aura = aura;
|
trap_mgr.auras[trap_mgr.count].aura = aura;
|
||||||
|
|||||||
+32
-23
@@ -145,10 +145,10 @@ int Mob::CalcRecommendedLevelBonus(uint8 current_level, uint8 recommended_level,
|
|||||||
|
|
||||||
void Mob::CalcItemBonuses(StatBonuses* b) {
|
void Mob::CalcItemBonuses(StatBonuses* b) {
|
||||||
ClearItemFactionBonuses();
|
ClearItemFactionBonuses();
|
||||||
SetShieldEquiped(false);
|
SetShieldEquipped(false);
|
||||||
SetTwoHandBluntEquiped(false);
|
SetTwoHandBluntEquipped(false);
|
||||||
SetTwoHanderEquipped(false);
|
SetTwoHanderEquipped(false);
|
||||||
SetDuelWeaponsEquiped(false);
|
SetDualWeaponsEquipped(false);
|
||||||
|
|
||||||
int16 i;
|
int16 i;
|
||||||
|
|
||||||
@@ -178,13 +178,13 @@ void Mob::CalcItemBonuses(StatBonuses* b) {
|
|||||||
item->ItemType == EQ::item::ItemTypeShield &&
|
item->ItemType == EQ::item::ItemTypeShield &&
|
||||||
i == EQ::invslot::slotSecondary
|
i == EQ::invslot::slotSecondary
|
||||||
) {
|
) {
|
||||||
SetShieldEquiped(true);
|
SetShieldEquipped(true);
|
||||||
} else if (
|
} else if (
|
||||||
item &&
|
item &&
|
||||||
item->ItemType == EQ::item::ItemType2HBlunt &&
|
item->ItemType == EQ::item::ItemType2HBlunt &&
|
||||||
i == EQ::invslot::slotPrimary
|
i == EQ::invslot::slotPrimary
|
||||||
) {
|
) {
|
||||||
SetTwoHandBluntEquiped(true);
|
SetTwoHandBluntEquipped(true);
|
||||||
SetTwoHanderEquipped(true);
|
SetTwoHanderEquipped(true);
|
||||||
} else if (
|
} else if (
|
||||||
item &&
|
item &&
|
||||||
@@ -196,7 +196,7 @@ void Mob::CalcItemBonuses(StatBonuses* b) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (CanThisClassDualWield()) {
|
if (CanThisClassDualWield()) {
|
||||||
SetDuelWeaponsEquiped(true);
|
SetDualWeaponsEquipped(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (IsOfClientBot()) {
|
if (IsOfClientBot()) {
|
||||||
@@ -1442,9 +1442,10 @@ void Mob::ApplyAABonuses(const AA::Rank &rank, StatBonuses *newbon)
|
|||||||
}
|
}
|
||||||
|
|
||||||
case SE_SlayUndead: {
|
case SE_SlayUndead: {
|
||||||
if (newbon->SlayUndead[SBIndex::SLAYUNDEAD_DMG_MOD] < base_value)
|
if (newbon->SlayUndead[SBIndex::SLAYUNDEAD_DMG_MOD] < base_value) {
|
||||||
newbon->SlayUndead[SBIndex::SLAYUNDEAD_RATE_MOD] = base_value; // Rate
|
newbon->SlayUndead[SBIndex::SLAYUNDEAD_RATE_MOD] = base_value; // Rate
|
||||||
newbon->SlayUndead[SBIndex::SLAYUNDEAD_DMG_MOD] = limit_value; // Damage Modifier
|
newbon->SlayUndead[SBIndex::SLAYUNDEAD_DMG_MOD] = limit_value; // Damage Modifier
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1612,9 +1613,10 @@ void Mob::ApplyAABonuses(const AA::Rank &rank, StatBonuses *newbon)
|
|||||||
}
|
}
|
||||||
|
|
||||||
case SE_HeadShotLevel: {
|
case SE_HeadShotLevel: {
|
||||||
if (newbon->HSLevel[SBIndex::FINISHING_EFFECT_LEVEL_MAX] < base_value)
|
if (newbon->HSLevel[SBIndex::FINISHING_EFFECT_LEVEL_MAX] < base_value) {
|
||||||
newbon->HSLevel[SBIndex::FINISHING_EFFECT_LEVEL_MAX] = base_value;
|
newbon->HSLevel[SBIndex::FINISHING_EFFECT_LEVEL_MAX] = base_value;
|
||||||
newbon->HSLevel[SBIndex::FINISHING_EFFECT_LEVEL_CHANCE_BONUS] = limit_value;
|
newbon->HSLevel[SBIndex::FINISHING_EFFECT_LEVEL_CHANCE_BONUS] = limit_value;
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1802,8 +1804,9 @@ void Mob::ApplyAABonuses(const AA::Rank &rank, StatBonuses *newbon)
|
|||||||
case SE_Damage_Taken_Position_Mod:
|
case SE_Damage_Taken_Position_Mod:
|
||||||
{
|
{
|
||||||
//Mitigate if damage taken from behind base2 = 0, from front base2 = 1
|
//Mitigate if damage taken from behind base2 = 0, from front base2 = 1
|
||||||
if (limit_value < 0 || limit_value > 2)
|
if (limit_value < 0 || limit_value >= 2) {
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
else if (base_value < 0 && newbon->Damage_Taken_Position_Mod[limit_value] > base_value)
|
else if (base_value < 0 && newbon->Damage_Taken_Position_Mod[limit_value] > base_value)
|
||||||
newbon->Damage_Taken_Position_Mod[limit_value] = base_value;
|
newbon->Damage_Taken_Position_Mod[limit_value] = base_value;
|
||||||
else if (base_value > 0 && newbon->Damage_Taken_Position_Mod[limit_value] < base_value)
|
else if (base_value > 0 && newbon->Damage_Taken_Position_Mod[limit_value] < base_value)
|
||||||
@@ -1813,8 +1816,9 @@ void Mob::ApplyAABonuses(const AA::Rank &rank, StatBonuses *newbon)
|
|||||||
|
|
||||||
case SE_Melee_Damage_Position_Mod:
|
case SE_Melee_Damage_Position_Mod:
|
||||||
{
|
{
|
||||||
if (limit_value < 0 || limit_value > 2)
|
if (limit_value < 0 || limit_value >= 2) {
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
else if (base_value < 0 && newbon->Melee_Damage_Position_Mod[limit_value] > base_value)
|
else if (base_value < 0 && newbon->Melee_Damage_Position_Mod[limit_value] > base_value)
|
||||||
newbon->Melee_Damage_Position_Mod[limit_value] = base_value;
|
newbon->Melee_Damage_Position_Mod[limit_value] = base_value;
|
||||||
else if (base_value > 0 && newbon->Melee_Damage_Position_Mod[limit_value] < base_value)
|
else if (base_value > 0 && newbon->Melee_Damage_Position_Mod[limit_value] < base_value)
|
||||||
@@ -1825,9 +1829,9 @@ void Mob::ApplyAABonuses(const AA::Rank &rank, StatBonuses *newbon)
|
|||||||
case SE_Damage_Taken_Position_Amt:
|
case SE_Damage_Taken_Position_Amt:
|
||||||
{
|
{
|
||||||
//Mitigate if damage taken from behind base2 = 0, from front base2 = 1
|
//Mitigate if damage taken from behind base2 = 0, from front base2 = 1
|
||||||
if (limit_value < 0 || limit_value > 2)
|
if (limit_value < 0 || limit_value >= 2) {
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
newbon->Damage_Taken_Position_Amt[limit_value] += base_value;
|
newbon->Damage_Taken_Position_Amt[limit_value] += base_value;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -1835,8 +1839,9 @@ void Mob::ApplyAABonuses(const AA::Rank &rank, StatBonuses *newbon)
|
|||||||
case SE_Melee_Damage_Position_Amt:
|
case SE_Melee_Damage_Position_Amt:
|
||||||
{
|
{
|
||||||
//Mitigate if damage taken from behind base2 = 0, from front base2 = 1
|
//Mitigate if damage taken from behind base2 = 0, from front base2 = 1
|
||||||
if (limit_value < 0 || limit_value > 2)
|
if (limit_value < 0 || limit_value >= 2) {
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
newbon->Melee_Damage_Position_Amt[limit_value] += base_value;
|
newbon->Melee_Damage_Position_Amt[limit_value] += base_value;
|
||||||
break;
|
break;
|
||||||
@@ -3175,8 +3180,9 @@ void Mob::ApplySpellsBonuses(uint16 spell_id, uint8 casterlevel, StatBonuses *ne
|
|||||||
case SE_HPToMana:
|
case SE_HPToMana:
|
||||||
{
|
{
|
||||||
//Lower the ratio the more favorable
|
//Lower the ratio the more favorable
|
||||||
if((!new_bonus->HPToManaConvert) || (new_bonus->HPToManaConvert >= effect_value))
|
if ((!new_bonus->HPToManaConvert) || (new_bonus->HPToManaConvert >= effect_value)) {
|
||||||
new_bonus->HPToManaConvert = spells[spell_id].base_value[i];
|
new_bonus->HPToManaConvert = spells[spell_id].base_value[i];
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -3523,11 +3529,11 @@ void Mob::ApplySpellsBonuses(uint16 spell_id, uint8 casterlevel, StatBonuses *ne
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
case SE_SlayUndead:
|
case SE_SlayUndead: {
|
||||||
{
|
if (new_bonus->SlayUndead[SBIndex::SLAYUNDEAD_DMG_MOD] < effect_value) {
|
||||||
if(new_bonus->SlayUndead[SBIndex::SLAYUNDEAD_DMG_MOD] < effect_value)
|
|
||||||
new_bonus->SlayUndead[SBIndex::SLAYUNDEAD_RATE_MOD] = effect_value; // Rate
|
new_bonus->SlayUndead[SBIndex::SLAYUNDEAD_RATE_MOD] = effect_value; // Rate
|
||||||
new_bonus->SlayUndead[SBIndex::SLAYUNDEAD_DMG_MOD] = limit_value; // Damage Modifier
|
new_bonus->SlayUndead[SBIndex::SLAYUNDEAD_DMG_MOD] = limit_value; // Damage Modifier
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -3669,8 +3675,7 @@ void Mob::ApplySpellsBonuses(uint16 spell_id, uint8 casterlevel, StatBonuses *ne
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
case SE_HeadShotLevel:
|
case SE_HeadShotLevel: {
|
||||||
{
|
|
||||||
if (new_bonus->HSLevel[SBIndex::FINISHING_EFFECT_LEVEL_MAX] < effect_value) {
|
if (new_bonus->HSLevel[SBIndex::FINISHING_EFFECT_LEVEL_MAX] < effect_value) {
|
||||||
new_bonus->HSLevel[SBIndex::FINISHING_EFFECT_LEVEL_MAX] = effect_value;
|
new_bonus->HSLevel[SBIndex::FINISHING_EFFECT_LEVEL_MAX] = effect_value;
|
||||||
new_bonus->HSLevel[SBIndex::FINISHING_EFFECT_LEVEL_CHANCE_BONUS] = limit_value;
|
new_bonus->HSLevel[SBIndex::FINISHING_EFFECT_LEVEL_CHANCE_BONUS] = limit_value;
|
||||||
@@ -3884,8 +3889,9 @@ void Mob::ApplySpellsBonuses(uint16 spell_id, uint8 casterlevel, StatBonuses *ne
|
|||||||
case SE_Damage_Taken_Position_Mod:
|
case SE_Damage_Taken_Position_Mod:
|
||||||
{
|
{
|
||||||
//Mitigate if damage taken from behind base2 = 0, from front base2 = 1
|
//Mitigate if damage taken from behind base2 = 0, from front base2 = 1
|
||||||
if (limit_value < 0 || limit_value > 2)
|
if (limit_value < 0 || limit_value >= 2) {
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
if (AdditiveWornBonus)
|
if (AdditiveWornBonus)
|
||||||
new_bonus->Damage_Taken_Position_Mod[limit_value] += effect_value;
|
new_bonus->Damage_Taken_Position_Mod[limit_value] += effect_value;
|
||||||
else if (effect_value < 0 && new_bonus->Damage_Taken_Position_Mod[limit_value] > effect_value)
|
else if (effect_value < 0 && new_bonus->Damage_Taken_Position_Mod[limit_value] > effect_value)
|
||||||
@@ -3898,8 +3904,9 @@ void Mob::ApplySpellsBonuses(uint16 spell_id, uint8 casterlevel, StatBonuses *ne
|
|||||||
case SE_Melee_Damage_Position_Mod:
|
case SE_Melee_Damage_Position_Mod:
|
||||||
{
|
{
|
||||||
//Increase damage by percent from behind base2 = 0, from front base2 = 1
|
//Increase damage by percent from behind base2 = 0, from front base2 = 1
|
||||||
if (limit_value < 0 || limit_value > 2)
|
if (limit_value < 0 || limit_value >= 2) {
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
if (AdditiveWornBonus)
|
if (AdditiveWornBonus)
|
||||||
new_bonus->Melee_Damage_Position_Mod[limit_value] += effect_value;
|
new_bonus->Melee_Damage_Position_Mod[limit_value] += effect_value;
|
||||||
else if (effect_value < 0 && new_bonus->Melee_Damage_Position_Mod[limit_value] > effect_value)
|
else if (effect_value < 0 && new_bonus->Melee_Damage_Position_Mod[limit_value] > effect_value)
|
||||||
@@ -3912,8 +3919,9 @@ void Mob::ApplySpellsBonuses(uint16 spell_id, uint8 casterlevel, StatBonuses *ne
|
|||||||
case SE_Damage_Taken_Position_Amt:
|
case SE_Damage_Taken_Position_Amt:
|
||||||
{
|
{
|
||||||
//Mitigate if damage taken from behind base2 = 0, from front base2 = 1
|
//Mitigate if damage taken from behind base2 = 0, from front base2 = 1
|
||||||
if (limit_value < 0 || limit_value > 2)
|
if (limit_value < 0 || limit_value >= 2) {
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
new_bonus->Damage_Taken_Position_Amt[limit_value] += effect_value;
|
new_bonus->Damage_Taken_Position_Amt[limit_value] += effect_value;
|
||||||
break;
|
break;
|
||||||
@@ -3922,8 +3930,9 @@ void Mob::ApplySpellsBonuses(uint16 spell_id, uint8 casterlevel, StatBonuses *ne
|
|||||||
case SE_Melee_Damage_Position_Amt:
|
case SE_Melee_Damage_Position_Amt:
|
||||||
{
|
{
|
||||||
//Mitigate if damage taken from behind base2 = 0, from front base2 = 1
|
//Mitigate if damage taken from behind base2 = 0, from front base2 = 1
|
||||||
if (limit_value < 0 || limit_value > 2)
|
if (limit_value < 0 || limit_value >= 2) {
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
new_bonus->Melee_Damage_Position_Amt[limit_value] += effect_value;
|
new_bonus->Melee_Damage_Position_Amt[limit_value] += effect_value;
|
||||||
break;
|
break;
|
||||||
|
|||||||
+192
-385
@@ -1112,7 +1112,7 @@ void Bot::GenerateAppearance() {
|
|||||||
|
|
||||||
uint16 Bot::GetPrimarySkillValue() {
|
uint16 Bot::GetPrimarySkillValue() {
|
||||||
EQ::skills::SkillType skill = EQ::skills::HIGHEST_SKILL; //because nullptr == 0, which is 1H Slashing, & we want it to return 0 from GetSkill
|
EQ::skills::SkillType skill = EQ::skills::HIGHEST_SKILL; //because nullptr == 0, which is 1H Slashing, & we want it to return 0 from GetSkill
|
||||||
if (bool equiped = m_inv.GetItem(EQ::invslot::slotPrimary); !equiped) {
|
if (bool equipped = m_inv.GetItem(EQ::invslot::slotPrimary); !equipped) {
|
||||||
skill = EQ::skills::SkillHandtoHand;
|
skill = EQ::skills::SkillHandtoHand;
|
||||||
} else {
|
} else {
|
||||||
uint8 type = m_inv.GetItem(EQ::invslot::slotPrimary)->GetItem()->ItemType; //is this the best way to do this?
|
uint8 type = m_inv.GetItem(EQ::invslot::slotPrimary)->GetItem()->ItemType; //is this the best way to do this?
|
||||||
@@ -1376,17 +1376,6 @@ bool Bot::DeleteBot()
|
|||||||
|
|
||||||
std::string error_message;
|
std::string error_message;
|
||||||
|
|
||||||
if (!database.botdb.RemoveMemberFromBotGroup(GetBotID())) {
|
|
||||||
bot_owner->Message(
|
|
||||||
Chat::White,
|
|
||||||
fmt::format(
|
|
||||||
"Failed to remove {} from their bot-group.",
|
|
||||||
GetCleanName()
|
|
||||||
).c_str()
|
|
||||||
);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!database.botdb.DeleteItems(GetBotID())) {
|
if (!database.botdb.DeleteItems(GetBotID())) {
|
||||||
bot_owner->Message(
|
bot_owner->Message(
|
||||||
Chat::White,
|
Chat::White,
|
||||||
@@ -1947,6 +1936,11 @@ void Bot::AI_Process()
|
|||||||
#define NOT_PASSIVE (GetBotStance() != EQ::constants::stancePassive)
|
#define NOT_PASSIVE (GetBotStance() != EQ::constants::stancePassive)
|
||||||
|
|
||||||
Client* bot_owner = (GetBotOwner() && GetBotOwner()->IsClient() ? GetBotOwner()->CastToClient() : nullptr);
|
Client* bot_owner = (GetBotOwner() && GetBotOwner()->IsClient() ? GetBotOwner()->CastToClient() : nullptr);
|
||||||
|
|
||||||
|
if (!bot_owner) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
auto raid = entity_list.GetRaidByBotName(GetName());
|
auto raid = entity_list.GetRaidByBotName(GetName());
|
||||||
uint32 r_group = RAID_GROUPLESS;
|
uint32 r_group = RAID_GROUPLESS;
|
||||||
if (raid) {
|
if (raid) {
|
||||||
@@ -2735,18 +2729,15 @@ void Bot::CalcMeleeDistances(const Mob* tar, const EQ::ItemInstance* const& p_it
|
|||||||
|
|
||||||
bool Bot::IsValidTarget(Client* bot_owner, Client* leash_owner, float lo_distance, float leash_distance, bool bo_alt_combat, Mob* tar, float tar_distance) {
|
bool Bot::IsValidTarget(Client* bot_owner, Client* leash_owner, float lo_distance, float leash_distance, bool bo_alt_combat, Mob* tar, float tar_distance) {
|
||||||
|
|
||||||
if (HOLDING ||
|
if (!tar || !bot_owner || !leash_owner) {
|
||||||
!tar->IsNPC() ||
|
return false;
|
||||||
tar->IsMezzed() ||
|
}
|
||||||
lo_distance > leash_distance ||
|
|
||||||
tar_distance > leash_distance ||
|
bool valid_target_state = HOLDING || !tar->IsNPC() || tar->IsMezzed() || lo_distance > leash_distance || tar_distance > leash_distance;
|
||||||
(!GetAttackingFlag() && !CheckLosFN(tar) && !leash_owner->CheckLosFN(tar)) || // This is suppose to keep bots from attacking things behind walls
|
bool valid_target = !GetAttackingFlag() && !CheckLosFN(tar) && !leash_owner->CheckLosFN(tar);
|
||||||
!IsAttackAllowed(tar) ||
|
bool valid_bo_target = !GetAttackingFlag() && NOT_PULLING_BOT && !leash_owner->AutoAttackEnabled() && !tar->GetHateAmount(this) && !tar->GetHateAmount(leash_owner);
|
||||||
(bo_alt_combat &&
|
|
||||||
(!GetAttackingFlag() && NOT_PULLING_BOT && !leash_owner->AutoAttackEnabled() && !tar->GetHateAmount(this) && !tar->GetHateAmount(leash_owner))
|
if (valid_target_state || valid_target || !IsAttackAllowed(tar) || (bo_alt_combat && valid_bo_target)) {
|
||||||
)
|
|
||||||
)
|
|
||||||
{
|
|
||||||
// Normally, we wouldn't want to do this without class checks..but, too many issues can arise if we let enchanter animation pets run rampant
|
// Normally, we wouldn't want to do this without class checks..but, too many issues can arise if we let enchanter animation pets run rampant
|
||||||
if (HasPet()) {
|
if (HasPet()) {
|
||||||
GetPet()->RemoveFromHateList(tar);
|
GetPet()->RemoveFromHateList(tar);
|
||||||
@@ -2810,12 +2801,13 @@ void Bot::AcquireBotTarget(Group* bot_group, Raid* raid, Client* leash_owner, fl
|
|||||||
Mob* assist_mob = nullptr;
|
Mob* assist_mob = nullptr;
|
||||||
bool find_target = true;
|
bool find_target = true;
|
||||||
|
|
||||||
if (bot_group) {
|
if (raid) {
|
||||||
assist_mob = entity_list.GetMob(bot_group->GetMainAssistName());
|
|
||||||
}
|
|
||||||
else if (raid) {
|
|
||||||
assist_mob = raid->GetRaidMainAssistOne();
|
assist_mob = raid->GetRaidMainAssistOne();
|
||||||
}
|
}
|
||||||
|
else if (bot_group) {
|
||||||
|
assist_mob = entity_list.GetMob(bot_group->GetMainAssistName());
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
if (assist_mob) {
|
if (assist_mob) {
|
||||||
if (assist_mob->GetTarget()) {
|
if (assist_mob->GetTarget()) {
|
||||||
@@ -2947,24 +2939,10 @@ void Bot::SetBotTarget(Client* bot_owner, Raid* raid, Group* bot_group, Client*
|
|||||||
|
|
||||||
if (bo_alt_combat && m_alt_combat_hate_timer.Check(false)) {
|
if (bo_alt_combat && m_alt_combat_hate_timer.Check(false)) {
|
||||||
// Empty hate list - let's find some aggro
|
// Empty hate list - let's find some aggro
|
||||||
if (!IsEngaged() && NOT_HOLDING && NOT_PASSIVE && (!bot_owner->GetBotPulling() || NOT_PULLING_BOT)) {
|
if (bot_owner->IsEngaged() && !IsEngaged() && NOT_HOLDING && NOT_PASSIVE && (!bot_owner->GetBotPulling() || NOT_PULLING_BOT)) {
|
||||||
SetLeashOwnerTarget(leash_owner, bot_owner, lo_distance, leash_distance);
|
SetLeashOwnerTarget(leash_owner, bot_owner, lo_distance, leash_distance);
|
||||||
}
|
}
|
||||||
|
else if (!IsEngaged() && raid) {
|
||||||
else if (bot_group) {
|
|
||||||
for (const auto& bg_member: bot_group->members) {
|
|
||||||
if (!bg_member) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
auto bgm_target = bg_member->GetTarget();
|
|
||||||
if (!bgm_target || !bgm_target->IsNPC()) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
SetBotGroupTarget(bot_owner, leash_owner, lo_distance, leash_distance, bg_member, bgm_target);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (raid) {
|
|
||||||
for (const auto& raid_member : raid->members) {
|
for (const auto& raid_member : raid->members) {
|
||||||
if (!raid_member.member) {
|
if (!raid_member.member) {
|
||||||
continue;
|
continue;
|
||||||
@@ -2977,6 +2955,19 @@ void Bot::SetBotTarget(Client* bot_owner, Raid* raid, Group* bot_group, Client*
|
|||||||
SetBotGroupTarget(bot_owner, leash_owner, lo_distance, leash_distance, raid_member.member, rm_target);
|
SetBotGroupTarget(bot_owner, leash_owner, lo_distance, leash_distance, raid_member.member, rm_target);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else if (!IsEngaged() && bot_group) {
|
||||||
|
for (const auto& bg_member: bot_group->members) {
|
||||||
|
if (!bg_member) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto bgm_target = bg_member->GetTarget();
|
||||||
|
if (!bgm_target || !bgm_target->IsNPC()) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
SetBotGroupTarget(bot_owner, leash_owner, lo_distance, leash_distance, bg_member, bgm_target);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2997,7 +2988,7 @@ void Bot::HealRotationChecks() {
|
|||||||
|
|
||||||
bool Bot::IsAIProcessValid(const Client* bot_owner, const Group* bot_group, const Raid* raid) {
|
bool Bot::IsAIProcessValid(const Client* bot_owner, const Group* bot_group, const Raid* raid) {
|
||||||
|
|
||||||
if (!bot_owner || !bot_group && !raid || !IsAIControlled()) {
|
if (!bot_owner || (!bot_group && !raid) || !IsAIControlled()) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -3314,14 +3305,11 @@ bool Bot::Spawn(Client* botCharacterOwner) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Raid* raid = nullptr;
|
if (auto raid = entity_list.GetRaidByBotName(GetName())) {
|
||||||
Group* group = nullptr;
|
|
||||||
|
|
||||||
if (raid = entity_list.GetRaidByBotName(GetName())) {
|
|
||||||
raid->VerifyRaid();
|
raid->VerifyRaid();
|
||||||
SetRaidGrouped(true);
|
SetRaidGrouped(true);
|
||||||
}
|
}
|
||||||
else if (group = entity_list.GetGroupByMobName(GetName())) {
|
else if (auto group = entity_list.GetGroupByMobName(GetName())) {
|
||||||
group->VerifyGroup();
|
group->VerifyGroup();
|
||||||
SetGrouped(true);
|
SetGrouped(true);
|
||||||
}
|
}
|
||||||
@@ -3497,9 +3485,7 @@ Bot* Bot::LoadBot(uint32 botID)
|
|||||||
|
|
||||||
// Load and spawn all zoned bots by bot owner character
|
// Load and spawn all zoned bots by bot owner character
|
||||||
void Bot::LoadAndSpawnAllZonedBots(Client* bot_owner) {
|
void Bot::LoadAndSpawnAllZonedBots(Client* bot_owner) {
|
||||||
if (bot_owner) {
|
if (bot_owner && bot_owner->HasGroup()) {
|
||||||
std::list<std::pair<uint32,std::string>> auto_spawn_botgroups;
|
|
||||||
if (bot_owner->HasGroup()) {
|
|
||||||
std::vector<int> bot_class_spawn_limits;
|
std::vector<int> bot_class_spawn_limits;
|
||||||
std::vector<int> bot_class_spawned_count = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
|
std::vector<int> bot_class_spawned_count = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
|
||||||
|
|
||||||
@@ -3516,15 +3502,6 @@ void Bot::LoadAndSpawnAllZonedBots(Client* bot_owner) {
|
|||||||
auto spawned_bots_count = 0;
|
auto spawned_bots_count = 0;
|
||||||
auto bot_spawn_limit = bot_owner->GetBotSpawnLimit();
|
auto bot_spawn_limit = bot_owner->GetBotSpawnLimit();
|
||||||
|
|
||||||
if (!database.botdb.LoadAutoSpawnBotGroupsByOwnerID(bot_owner->CharacterID(), auto_spawn_botgroups)) {
|
|
||||||
bot_owner->Message(Chat::White, "Failed to load auto spawn bot groups by group ID.");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (const auto& botgroup : auto_spawn_botgroups) {
|
|
||||||
Bot::SpawnBotGroupByName(bot_owner, botgroup.second, botgroup.first);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!database.botdb.LoadGroupedBotsByGroupID(bot_owner->CharacterID(), group_id, active_bots)) {
|
if (!database.botdb.LoadGroupedBotsByGroupID(bot_owner->CharacterID(), group_id, active_bots)) {
|
||||||
bot_owner->Message(Chat::White, "Failed to load grouped bots by group ID.");
|
bot_owner->Message(Chat::White, "Failed to load grouped bots by group ID.");
|
||||||
return;
|
return;
|
||||||
@@ -3575,16 +3552,6 @@ void Bot::LoadAndSpawnAllZonedBots(Client* bot_owner) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
if (!database.botdb.LoadAutoSpawnBotGroupsByOwnerID(bot_owner->CharacterID(), auto_spawn_botgroups)) {
|
|
||||||
bot_owner->Message(Chat::White, "Failed to load auto spawn bot groups by group ID.");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (const auto& botgroup : auto_spawn_botgroups) {
|
|
||||||
Bot::SpawnBotGroupByName(bot_owner, botgroup.second, botgroup.first);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -3840,6 +3807,7 @@ bool Bot::RemoveBotFromGroup(Bot* bot, Group* group) {
|
|||||||
if (!group->IsLeader(bot)) {
|
if (!group->IsLeader(bot)) {
|
||||||
bot->SetFollowID(0);
|
bot->SetFollowID(0);
|
||||||
if (group->DelMember(bot)) {
|
if (group->DelMember(bot)) {
|
||||||
|
group->DelMemberOOZ(bot->GetName());
|
||||||
database.SetGroupID(bot->GetCleanName(), 0, bot->GetBotID());
|
database.SetGroupID(bot->GetCleanName(), 0, bot->GetBotID());
|
||||||
if (group->GroupCount() < 1) {
|
if (group->GroupCount() < 1) {
|
||||||
group->DisbandGroup();
|
group->DisbandGroup();
|
||||||
@@ -3862,8 +3830,12 @@ bool Bot::RemoveBotFromGroup(Bot* bot, Group* group) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
bool Bot::AddBotToGroup(Bot* bot, Group* group) {
|
bool Bot::AddBotToGroup(Bot* bot, Group* group) {
|
||||||
bool Result = false;
|
bool result = false;
|
||||||
if (bot && group && group->AddMember(bot)) {
|
if (!group || group->GroupCount() >= MAX_GROUP_MEMBERS) {
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (bot && group->AddMember(bot)) {
|
||||||
if (group->GetLeader()) {
|
if (group->GetLeader()) {
|
||||||
bot->SetFollowID(group->GetLeader()->GetID());
|
bot->SetFollowID(group->GetLeader()->GetID());
|
||||||
// Need to send this only once when a group is formed with a bot so the client knows it is also the group leader
|
// Need to send this only once when a group is formed with a bot so the client knows it is also the group leader
|
||||||
@@ -3874,9 +3846,10 @@ bool Bot::AddBotToGroup(Bot* bot, Group* group) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
group->VerifyGroup();
|
group->VerifyGroup();
|
||||||
Result = true;
|
group->SendGroupJoinOOZ(bot);
|
||||||
|
result = true;
|
||||||
}
|
}
|
||||||
return Result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Completes a trade with a client bot owner
|
// Completes a trade with a client bot owner
|
||||||
@@ -4562,8 +4535,17 @@ bool Bot::Death(Mob *killerMob, int64 damage, uint16 spell_id, EQ::skills::Skill
|
|||||||
if (entity_list.GetCorpseByID(GetID()))
|
if (entity_list.GetCorpseByID(GetID()))
|
||||||
entity_list.GetCorpseByID(GetID())->Depop();
|
entity_list.GetCorpseByID(GetID())->Depop();
|
||||||
|
|
||||||
Group *g = GetGroup();
|
if (HasRaid()) {
|
||||||
if (g) {
|
if (auto raid = entity_list.GetRaidByBotName(GetName()); raid) {
|
||||||
|
for (auto& m: raid->members) {
|
||||||
|
if (strcmp(m.member_name, GetName()) == 0) {
|
||||||
|
m.member = nullptr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (HasGroup()) {
|
||||||
|
if (auto g = GetGroup()) {
|
||||||
for (int i = 0; i < MAX_GROUP_MEMBERS; i++) {
|
for (int i = 0; i < MAX_GROUP_MEMBERS; i++) {
|
||||||
if (g->members[i]) {
|
if (g->members[i]) {
|
||||||
if (g->members[i] == this) {
|
if (g->members[i] == this) {
|
||||||
@@ -4616,6 +4598,7 @@ bool Bot::Death(Mob *killerMob, int64 damage, uint16 spell_id, EQ::skills::Skill
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
LeaveHealRotationMemberPool();
|
LeaveHealRotationMemberPool();
|
||||||
|
|
||||||
@@ -4623,18 +4606,6 @@ bool Bot::Death(Mob *killerMob, int64 damage, uint16 spell_id, EQ::skills::Skill
|
|||||||
my_owner->CastToClient()->SetBotPulling(false);
|
my_owner->CastToClient()->SetBotPulling(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (auto raid = entity_list.GetRaidByBotName(GetName()); raid)
|
|
||||||
{
|
|
||||||
|
|
||||||
for (auto& m : raid->members)
|
|
||||||
{
|
|
||||||
if (strcmp(m.member_name, GetName()) == 0)
|
|
||||||
{
|
|
||||||
m.member = nullptr;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (parse->BotHasQuestSub(EVENT_DEATH_COMPLETE)) {
|
if (parse->BotHasQuestSub(EVENT_DEATH_COMPLETE)) {
|
||||||
const auto& export_string = fmt::format(
|
const auto& export_string = fmt::format(
|
||||||
"{} {} {} {}",
|
"{} {} {} {}",
|
||||||
@@ -4671,8 +4642,10 @@ void Bot::Damage(Mob *from, int64 damage, uint16 spell_id, EQ::skills::SkillType
|
|||||||
int64 healed = GetActSpellHealing(spell_id, damage);
|
int64 healed = GetActSpellHealing(spell_id, damage);
|
||||||
LogCombatDetail("Applying lifetap heal of [{}] to [{}]", healed, GetCleanName());
|
LogCombatDetail("Applying lifetap heal of [{}] to [{}]", healed, GetCleanName());
|
||||||
HealDamage(healed);
|
HealDamage(healed);
|
||||||
|
if (from) {
|
||||||
entity_list.FilteredMessageClose(this, true, RuleI(Range, SpellMessages), Chat::Emote, FilterSocials, "%s beams a smile at %s", GetCleanName(), from->GetCleanName());
|
entity_list.FilteredMessageClose(this, true, RuleI(Range, SpellMessages), Chat::Emote, FilterSocials, "%s beams a smile at %s", GetCleanName(), from->GetCleanName());
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
CommonDamage(from, damage, spell_id, attack_skill, avoidable, buffslot, iBuffTic, special);
|
CommonDamage(from, damage, spell_id, attack_skill, avoidable, buffslot, iBuffTic, special);
|
||||||
if (GetHP() < 0) {
|
if (GetHP() < 0) {
|
||||||
@@ -4870,7 +4843,7 @@ int Bot::GetBaseSkillDamage(EQ::skills::SkillType skill, Mob *target)
|
|||||||
float skill_bonus = skill_level / 10.0f;
|
float skill_bonus = skill_level / 10.0f;
|
||||||
float ac_bonus = 0.0f;
|
float ac_bonus = 0.0f;
|
||||||
const EQ::ItemInstance *inst = nullptr;
|
const EQ::ItemInstance *inst = nullptr;
|
||||||
if (HasShieldEquiped())
|
if (HasShieldEquipped())
|
||||||
inst = GetBotItem(EQ::invslot::slotSecondary);
|
inst = GetBotItem(EQ::invslot::slotSecondary);
|
||||||
else if (HasTwoHanderEquipped())
|
else if (HasTwoHanderEquipped())
|
||||||
inst = GetBotItem(EQ::invslot::slotPrimary);
|
inst = GetBotItem(EQ::invslot::slotPrimary);
|
||||||
@@ -6667,8 +6640,7 @@ void Bot::Camp(bool save_to_database) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void Bot::Zone() {
|
void Bot::Zone() {
|
||||||
Raid* raid = entity_list.GetRaidByBotName(GetName());
|
if (auto raid = entity_list.GetRaidByBotName(GetName())) {
|
||||||
if (raid) {
|
|
||||||
raid->MemberZoned(CastToClient());
|
raid->MemberZoned(CastToClient());
|
||||||
}
|
}
|
||||||
else if (HasGroup()) {
|
else if (HasGroup()) {
|
||||||
@@ -6856,7 +6828,7 @@ Bot* Bot::GetBotByBotClientOwnerAndBotName(Client* c, const std::string& botName
|
|||||||
}
|
}
|
||||||
|
|
||||||
void Bot::ProcessBotGroupInvite(Client* c, std::string const& botName) {
|
void Bot::ProcessBotGroupInvite(Client* c, std::string const& botName) {
|
||||||
if (c) {
|
if (c && !c->HasRaid()) {
|
||||||
Bot* invitedBot = GetBotByBotClientOwnerAndBotName(c, botName);
|
Bot* invitedBot = GetBotByBotClientOwnerAndBotName(c, botName);
|
||||||
|
|
||||||
if (invitedBot && !invitedBot->HasGroup() && !invitedBot->HasRaid()) {
|
if (invitedBot && !invitedBot->HasGroup() && !invitedBot->HasRaid()) {
|
||||||
@@ -6872,14 +6844,9 @@ void Bot::ProcessBotGroupInvite(Client* c, std::string const& botName) {
|
|||||||
delete g;
|
delete g;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
AddBotToGroup(invitedBot, c->GetGroup());
|
if (AddBotToGroup(invitedBot, c->GetGroup())) {
|
||||||
database.SetGroupID(invitedBot->GetCleanName(), c->GetGroup()->GetID(), invitedBot->GetBotID());
|
database.SetGroupID(invitedBot->GetCleanName(), c->GetGroup()->GetID(), invitedBot->GetBotID());
|
||||||
}
|
}
|
||||||
if (c->HasRaid() && c->HasGroup()) {
|
|
||||||
Raid* raid = entity_list.GetRaidByClient(c);
|
|
||||||
if (raid) {
|
|
||||||
raid->AddBot(invitedBot, raid->GetGroup(c), false, false, false);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
} else if (invitedBot->HasGroup()) {
|
} else if (invitedBot->HasGroup()) {
|
||||||
c->MessageString(Chat::LightGray, TARGET_ALREADY_IN_GROUP, invitedBot->GetCleanName());
|
c->MessageString(Chat::LightGray, TARGET_ALREADY_IN_GROUP, invitedBot->GetCleanName());
|
||||||
@@ -7107,45 +7074,12 @@ bool EntityList::Bot_AICheckCloseBeneficialSpells(Bot* caster, uint8 iChance, fl
|
|||||||
|
|
||||||
if (iSpellTypes == SpellType_Heal) {
|
if (iSpellTypes == SpellType_Heal) {
|
||||||
if (botCasterClass == CLERIC || botCasterClass == DRUID || botCasterClass == SHAMAN) {
|
if (botCasterClass == CLERIC || botCasterClass == DRUID || botCasterClass == SHAMAN) {
|
||||||
if (caster->HasGroup()) {
|
if (caster->IsRaidGrouped()) {
|
||||||
Group *g = caster->GetGroup();
|
|
||||||
if (g) {
|
|
||||||
for (int i = 0; i < MAX_GROUP_MEMBERS; i++) {
|
|
||||||
if (g->members[i] && !g->members[i]->qglobal) {
|
|
||||||
if (g->members[i]->IsClient() && g->members[i]->GetHPRatio() < 90) {
|
|
||||||
if (caster->AICastSpell(g->members[i], 100, SpellType_Heal))
|
|
||||||
return true;
|
|
||||||
} else if ((g->members[i]->GetClass() == WARRIOR || g->members[i]->GetClass() == PALADIN || g->members[i]->GetClass() == SHADOWKNIGHT) && g->members[i]->GetHPRatio() < 95) {
|
|
||||||
if (caster->AICastSpell(g->members[i], 100, SpellType_Heal))
|
|
||||||
return true;
|
|
||||||
} else if (g->members[i]->GetClass() == ENCHANTER && g->members[i]->GetHPRatio() < 80) {
|
|
||||||
if (caster->AICastSpell(g->members[i], 100, SpellType_Heal))
|
|
||||||
return true;
|
|
||||||
} else if (g->members[i]->GetHPRatio() < 70) {
|
|
||||||
if (caster->AICastSpell(g->members[i], 100, SpellType_Heal))
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (g->members[i] && !g->members[i]->qglobal && g->members[i]->HasPet() && g->members[i]->GetPet()->GetHPRatio() < 50) {
|
|
||||||
if (g->members[i]->GetPet()->GetOwner() != caster && caster->IsEngaged() && g->members[i]->IsCasting() && g->members[i]->GetClass() != ENCHANTER )
|
|
||||||
continue;
|
|
||||||
|
|
||||||
if (caster->AICastSpell(g->members[i]->GetPet(), 100, SpellType_Heal))
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (caster->IsRaidGrouped())
|
|
||||||
{
|
|
||||||
//added raid check
|
|
||||||
Raid* raid = entity_list.GetRaidByBotName(caster->GetName());
|
Raid* raid = entity_list.GetRaidByBotName(caster->GetName());
|
||||||
uint32 gid = raid->GetGroup(caster->GetName());
|
uint32 gid = raid->GetGroup(caster->GetName());
|
||||||
if (gid < MAX_RAID_GROUPS) {
|
if (gid < MAX_RAID_GROUPS) {
|
||||||
std::vector<RaidMember> raid_group_members = raid->GetRaidGroupMembers(gid);
|
std::vector<RaidMember> raid_group_members = raid->GetRaidGroupMembers(gid);
|
||||||
for (std::vector<RaidMember>::iterator iter = raid_group_members.begin(); iter != raid_group_members.end(); ++iter) {
|
for (std::vector<RaidMember>::iterator iter = raid_group_members.begin(); iter != raid_group_members.end(); ++iter) {
|
||||||
//for (auto& iter : raid->GetRaidGroupMembers(g)) {
|
|
||||||
if (iter->member && !iter->member->qglobal) {
|
if (iter->member && !iter->member->qglobal) {
|
||||||
if (iter->member->IsClient() && iter->member->GetHPRatio() < 90) {
|
if (iter->member->IsClient() && iter->member->GetHPRatio() < 90) {
|
||||||
if (caster->AICastSpell(iter->member, 100, SpellType_Heal))
|
if (caster->AICastSpell(iter->member, 100, SpellType_Heal))
|
||||||
@@ -7176,6 +7110,37 @@ bool EntityList::Bot_AICheckCloseBeneficialSpells(Bot* caster, uint8 iChance, fl
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
else if (caster->HasGroup()) {
|
||||||
|
Group *g = caster->GetGroup();
|
||||||
|
if (g) {
|
||||||
|
for (int i = 0; i < MAX_GROUP_MEMBERS; i++) {
|
||||||
|
if (g->members[i] && !g->members[i]->qglobal) {
|
||||||
|
if (g->members[i]->IsClient() && g->members[i]->GetHPRatio() < 90) {
|
||||||
|
if (caster->AICastSpell(g->members[i], 100, SpellType_Heal))
|
||||||
|
return true;
|
||||||
|
} else if ((g->members[i]->GetClass() == WARRIOR || g->members[i]->GetClass() == PALADIN || g->members[i]->GetClass() == SHADOWKNIGHT) && g->members[i]->GetHPRatio() < 95) {
|
||||||
|
if (caster->AICastSpell(g->members[i], 100, SpellType_Heal))
|
||||||
|
return true;
|
||||||
|
} else if (g->members[i]->GetClass() == ENCHANTER && g->members[i]->GetHPRatio() < 80) {
|
||||||
|
if (caster->AICastSpell(g->members[i], 100, SpellType_Heal))
|
||||||
|
return true;
|
||||||
|
} else if (g->members[i]->GetHPRatio() < 70) {
|
||||||
|
if (caster->AICastSpell(g->members[i], 100, SpellType_Heal))
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (g->members[i] && !g->members[i]->qglobal && g->members[i]->HasPet() && g->members[i]->GetPet()->GetHPRatio() < 50) {
|
||||||
|
if (g->members[i]->GetPet()->GetOwner() != caster && caster->IsEngaged() && g->members[i]->IsCasting() && g->members[i]->GetClass() != ENCHANTER )
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (caster->AICastSpell(g->members[i]->GetPet(), 100, SpellType_Heal))
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((botCasterClass == PALADIN || botCasterClass == BEASTLORD || botCasterClass == RANGER) && (caster->HasGroup() || caster->IsRaidGrouped())) {
|
if ((botCasterClass == PALADIN || botCasterClass == BEASTLORD || botCasterClass == RANGER) && (caster->HasGroup() || caster->IsRaidGrouped())) {
|
||||||
@@ -7195,23 +7160,61 @@ bool EntityList::Bot_AICheckCloseBeneficialSpells(Bot* caster, uint8 iChance, fl
|
|||||||
hpRatioToHeal = 25.0f;
|
hpRatioToHeal = 25.0f;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
Group* g = caster->GetGroup();
|
if (caster->IsRaidGrouped()) {
|
||||||
|
if (auto raid = entity_list.GetRaidByBotName(caster->GetName())) {
|
||||||
uint32 gid = RAID_GROUPLESS;
|
uint32 gid = RAID_GROUPLESS;
|
||||||
Raid* raid = entity_list.GetRaidByBotName(caster->GetName());
|
|
||||||
if (raid) {
|
|
||||||
gid = raid->GetGroup(caster->GetName());
|
gid = raid->GetGroup(caster->GetName());
|
||||||
|
if (gid < MAX_RAID_GROUPS) {
|
||||||
|
std::vector<RaidMember> raid_group_members = raid->GetRaidGroupMembers(gid);
|
||||||
|
for (std::vector<RaidMember>::iterator iter = raid_group_members.begin();
|
||||||
|
iter != raid_group_members.end(); ++iter) {
|
||||||
|
if (iter->member && !iter->member->qglobal) {
|
||||||
|
if (iter->member->IsClient() && iter->member->GetHPRatio() < hpRatioToHeal) {
|
||||||
|
if (caster->AICastSpell(iter->member, 100, SpellType_Heal))
|
||||||
|
return true;
|
||||||
|
} else if (
|
||||||
|
(iter->member->GetClass() == WARRIOR || iter->member->GetClass() == PALADIN ||
|
||||||
|
iter->member->GetClass() == SHADOWKNIGHT) &&
|
||||||
|
iter->member->GetHPRatio() < hpRatioToHeal) {
|
||||||
|
if (caster->AICastSpell(iter->member, 100, SpellType_Heal))
|
||||||
|
return true;
|
||||||
|
} else if (iter->member->GetClass() == ENCHANTER &&
|
||||||
|
iter->member->GetHPRatio() < hpRatioToHeal) {
|
||||||
|
if (caster->AICastSpell(iter->member, 100, SpellType_Heal))
|
||||||
|
return true;
|
||||||
|
} else if (iter->member->GetHPRatio() < hpRatioToHeal / 2) {
|
||||||
|
if (caster->AICastSpell(iter->member, 100, SpellType_Heal))
|
||||||
|
return true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (g) {
|
if (iter->member && !iter->member->qglobal && iter->member->HasPet() &&
|
||||||
|
iter->member->GetPet()->GetHPRatio() < 25) {
|
||||||
|
if (iter->member->GetPet()->GetOwner() != caster && caster->IsEngaged() &&
|
||||||
|
iter->member->IsCasting() && iter->member->GetClass() != ENCHANTER)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (caster->AICastSpell(iter->member->GetPet(), 100, SpellType_Heal))
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (caster->HasGroup()) {
|
||||||
|
if (auto g = caster->GetGroup()) {
|
||||||
for (int i = 0; i < MAX_GROUP_MEMBERS; i++) {
|
for (int i = 0; i < MAX_GROUP_MEMBERS; i++) {
|
||||||
if (g->members[i] && !g->members[i]->qglobal) {
|
if (g->members[i] && !g->members[i]->qglobal) {
|
||||||
if (g->members[i]->IsClient() && g->members[i]->GetHPRatio() < hpRatioToHeal) {
|
if (g->members[i]->IsClient() && g->members[i]->GetHPRatio() < hpRatioToHeal) {
|
||||||
if (caster->AICastSpell(g->members[i], 100, SpellType_Heal))
|
if (caster->AICastSpell(g->members[i], 100, SpellType_Heal))
|
||||||
return true;
|
return true;
|
||||||
} else if ((g->members[i]->GetClass() == WARRIOR || g->members[i]->GetClass() == PALADIN || g->members[i]->GetClass() == SHADOWKNIGHT) && g->members[i]->GetHPRatio() < hpRatioToHeal) {
|
} else if ((g->members[i]->GetClass() == WARRIOR || g->members[i]->GetClass() == PALADIN ||
|
||||||
|
g->members[i]->GetClass() == SHADOWKNIGHT) &&
|
||||||
|
g->members[i]->GetHPRatio() < hpRatioToHeal) {
|
||||||
if (caster->AICastSpell(g->members[i], 100, SpellType_Heal))
|
if (caster->AICastSpell(g->members[i], 100, SpellType_Heal))
|
||||||
return true;
|
return true;
|
||||||
} else if (g->members[i]->GetClass() == ENCHANTER && g->members[i]->GetHPRatio() < hpRatioToHeal) {
|
} else if (g->members[i]->GetClass() == ENCHANTER &&
|
||||||
|
g->members[i]->GetHPRatio() < hpRatioToHeal) {
|
||||||
if (caster->AICastSpell(g->members[i], 100, SpellType_Heal))
|
if (caster->AICastSpell(g->members[i], 100, SpellType_Heal))
|
||||||
return true;
|
return true;
|
||||||
} else if (g->members[i]->GetHPRatio() < hpRatioToHeal / 2) {
|
} else if (g->members[i]->GetHPRatio() < hpRatioToHeal / 2) {
|
||||||
@@ -7220,8 +7223,10 @@ bool EntityList::Bot_AICheckCloseBeneficialSpells(Bot* caster, uint8 iChance, fl
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (g->members[i] && !g->members[i]->qglobal && g->members[i]->HasPet() && g->members[i]->GetPet()->GetHPRatio() < 25) {
|
if (g->members[i] && !g->members[i]->qglobal && g->members[i]->HasPet() &&
|
||||||
if (g->members[i]->GetPet()->GetOwner() != caster && caster->IsEngaged() && g->members[i]->IsCasting() && g->members[i]->GetClass() != ENCHANTER )
|
g->members[i]->GetPet()->GetHPRatio() < 25) {
|
||||||
|
if (g->members[i]->GetPet()->GetOwner() != caster && caster->IsEngaged() &&
|
||||||
|
g->members[i]->IsCasting() && g->members[i]->GetClass() != ENCHANTER)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (caster->AICastSpell(g->members[i]->GetPet(), 100, SpellType_Heal))
|
if (caster->AICastSpell(g->members[i]->GetPet(), 100, SpellType_Heal))
|
||||||
@@ -7229,38 +7234,6 @@ bool EntityList::Bot_AICheckCloseBeneficialSpells(Bot* caster, uint8 iChance, fl
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (gid < MAX_RAID_GROUPS)
|
|
||||||
{
|
|
||||||
std::vector<RaidMember> raid_group_members = raid->GetRaidGroupMembers(gid);
|
|
||||||
for (std::vector<RaidMember>::iterator iter = raid_group_members.begin(); iter != raid_group_members.end(); ++iter) {
|
|
||||||
//for (auto& iter : raid->GetRaidGroupMembers(gid)) {
|
|
||||||
if (iter->member && !iter->member->qglobal) {
|
|
||||||
if (iter->member->IsClient() && iter->member->GetHPRatio() < hpRatioToHeal) {
|
|
||||||
if (caster->AICastSpell(iter->member, 100, SpellType_Heal))
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
else if ((iter->member->GetClass() == WARRIOR || iter->member->GetClass() == PALADIN || iter->member->GetClass() == SHADOWKNIGHT) && iter->member->GetHPRatio() < hpRatioToHeal) {
|
|
||||||
if (caster->AICastSpell(iter->member, 100, SpellType_Heal))
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
else if (iter->member->GetClass() == ENCHANTER && iter->member->GetHPRatio() < hpRatioToHeal) {
|
|
||||||
if (caster->AICastSpell(iter->member, 100, SpellType_Heal))
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
else if (iter->member->GetHPRatio() < hpRatioToHeal / 2) {
|
|
||||||
if (caster->AICastSpell(iter->member, 100, SpellType_Heal))
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (iter->member && !iter->member->qglobal && iter->member->HasPet() && iter->member->GetPet()->GetHPRatio() < 25) {
|
|
||||||
if (iter->member->GetPet()->GetOwner() != caster && caster->IsEngaged() && iter->member->IsCasting() && iter->member->GetClass() != ENCHANTER)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
if (caster->AICastSpell(iter->member->GetPet(), 100, SpellType_Heal))
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -7301,7 +7274,28 @@ bool EntityList::Bot_AICheckCloseBeneficialSpells(Bot* caster, uint8 iChance, fl
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (iSpellTypes == SpellType_Cure) {
|
if (iSpellTypes == SpellType_Cure) {
|
||||||
if (caster->HasGroup()) {
|
if (caster->IsRaidGrouped()) {
|
||||||
|
Raid* raid = entity_list.GetRaidByBotName(caster->GetName());
|
||||||
|
uint32 gid = raid->GetGroup(caster->GetName());
|
||||||
|
if (gid < MAX_RAID_GROUPS) {
|
||||||
|
std::vector<RaidMember> raid_group_members = raid->GetRaidGroupMembers(gid);
|
||||||
|
for (std::vector<RaidMember>::iterator iter = raid_group_members.begin(); iter != raid_group_members.end(); ++iter) {
|
||||||
|
if (iter->member && caster->GetNeedsCured(iter->member)) {
|
||||||
|
if (caster->AICastSpell(iter->member, caster->GetChanceToCastBySpellType(SpellType_Cure), SpellType_Cure))
|
||||||
|
return true;
|
||||||
|
else if (botCasterClass == BARD) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (iter->member && iter->member->GetPet() && caster->GetNeedsCured(iter->member->GetPet())) {
|
||||||
|
if (caster->AICastSpell(iter->member->GetPet(), (int)caster->GetChanceToCastBySpellType(SpellType_Cure) / 4, SpellType_Cure))
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (caster->HasGroup()) {
|
||||||
Group *g = caster->GetGroup();
|
Group *g = caster->GetGroup();
|
||||||
if (g) {
|
if (g) {
|
||||||
for (int i = 0; i < MAX_GROUP_MEMBERS; i++) {
|
for (int i = 0; i < MAX_GROUP_MEMBERS; i++) {
|
||||||
@@ -7319,46 +7313,13 @@ bool EntityList::Bot_AICheckCloseBeneficialSpells(Bot* caster, uint8 iChance, fl
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (caster->IsRaidGrouped())
|
|
||||||
{
|
|
||||||
Raid* raid = entity_list.GetRaidByBotName(caster->GetName());
|
|
||||||
uint32 gid = raid->GetGroup(caster->GetName());
|
|
||||||
if (gid < MAX_RAID_GROUPS) {
|
|
||||||
std::vector<RaidMember> raid_group_members = raid->GetRaidGroupMembers(gid);
|
|
||||||
for (std::vector<RaidMember>::iterator iter = raid_group_members.begin(); iter != raid_group_members.end(); ++iter) {
|
|
||||||
if (iter->member && caster->GetNeedsCured(iter->member)) {
|
|
||||||
if (caster->AICastSpell(iter->member, caster->GetChanceToCastBySpellType(SpellType_Cure), SpellType_Cure))
|
|
||||||
return true;
|
|
||||||
else if (botCasterClass == BARD)
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (iter->member && iter->member->GetPet() && caster->GetNeedsCured(iter->member->GetPet())) {
|
|
||||||
if (caster->AICastSpell(iter->member->GetPet(), (int)caster->GetChanceToCastBySpellType(SpellType_Cure) / 4, SpellType_Cure))
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (iSpellTypes == SpellType_HateRedux) {
|
if (iSpellTypes == SpellType_HateRedux) {
|
||||||
if (!caster->IsEngaged())
|
if (!caster->IsEngaged())
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
if (caster->HasGroup()) {
|
if (caster->IsRaidGrouped()) {
|
||||||
Group *g = caster->GetGroup();
|
|
||||||
if (g) {
|
|
||||||
for (int i = 0; i < MAX_GROUP_MEMBERS; i++) {
|
|
||||||
if (g->members[i] && caster->GetNeedsHateRedux(g->members[i])) {
|
|
||||||
if (caster->AICastSpell(g->members[i], caster->GetChanceToCastBySpellType(SpellType_HateRedux), SpellType_HateRedux))
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (caster->IsRaidGrouped())
|
|
||||||
{
|
|
||||||
Raid* raid = entity_list.GetRaidByBotName(caster->GetName());
|
Raid* raid = entity_list.GetRaidByBotName(caster->GetName());
|
||||||
uint32 gid = raid->GetGroup(caster->GetName());
|
uint32 gid = raid->GetGroup(caster->GetName());
|
||||||
if (gid < MAX_RAID_GROUPS) {
|
if (gid < MAX_RAID_GROUPS) {
|
||||||
@@ -7371,7 +7332,17 @@ bool EntityList::Bot_AICheckCloseBeneficialSpells(Bot* caster, uint8 iChance, fl
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else if (caster->HasGroup()) {
|
||||||
|
Group *g = caster->GetGroup();
|
||||||
|
if (g) {
|
||||||
|
for (int i = 0; i < MAX_GROUP_MEMBERS; i++) {
|
||||||
|
if (g->members[i] && caster->GetNeedsHateRedux(g->members[i])) {
|
||||||
|
if (caster->AICastSpell(g->members[i], caster->GetChanceToCastBySpellType(SpellType_HateRedux), SpellType_HateRedux))
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (iSpellTypes == SpellType_PreCombatBuff) {
|
if (iSpellTypes == SpellType_PreCombatBuff) {
|
||||||
@@ -8202,173 +8173,6 @@ std::string Bot::CreateSayLink(Client* c, const char* message, const char* name)
|
|||||||
return saylink;
|
return saylink;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Bot::SpawnBotGroupByName(Client* c, const std::string& botgroup_name, uint32 leader_id)
|
|
||||||
{
|
|
||||||
auto leader = Bot::LoadBot(leader_id);
|
|
||||||
if (!leader) {
|
|
||||||
c->Message(
|
|
||||||
Chat::White,
|
|
||||||
fmt::format(
|
|
||||||
"Could not load bot-group leader for '{}'.",
|
|
||||||
botgroup_name
|
|
||||||
).c_str()
|
|
||||||
);
|
|
||||||
safe_delete(leader);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!leader->spawned) {
|
|
||||||
if (!leader->Spawn(c)) {
|
|
||||||
c->Message(
|
|
||||||
Chat::White,
|
|
||||||
fmt::format(
|
|
||||||
"Could not spawn bot-group leader {} for '{}'.",
|
|
||||||
leader->GetName(),
|
|
||||||
botgroup_name
|
|
||||||
).c_str()
|
|
||||||
);
|
|
||||||
safe_delete(leader);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
auto group = leader->GetGroupByLeaderName();
|
|
||||||
auto raid = leader->GetRaid();
|
|
||||||
|
|
||||||
if (!raid && group) {
|
|
||||||
group->SetLeader(leader);
|
|
||||||
}
|
|
||||||
else if (!raid) {
|
|
||||||
group = new Group(leader);
|
|
||||||
entity_list.AddGroup(group);
|
|
||||||
database.SetGroupID(leader->GetCleanName(), group->GetID(), leader->GetBotID());
|
|
||||||
database.SetGroupLeaderName(group->GetID(), leader->GetCleanName());
|
|
||||||
}
|
|
||||||
|
|
||||||
leader->SetFollowID(c->GetID());
|
|
||||||
|
|
||||||
uint32 botgroup_id = 0;
|
|
||||||
database.botdb.LoadBotGroupIDByBotGroupName(botgroup_name, botgroup_id);
|
|
||||||
|
|
||||||
std::map<uint32, std::list<uint32>> member_list;
|
|
||||||
if (!database.botdb.LoadBotGroup(botgroup_name, member_list)) {
|
|
||||||
c->Message(
|
|
||||||
Chat::White,
|
|
||||||
fmt::format(
|
|
||||||
"Failed to load bot-group '{}'.",
|
|
||||||
botgroup_name
|
|
||||||
).c_str()
|
|
||||||
);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (member_list.find(botgroup_id) == member_list.end() || member_list[botgroup_id].empty()) {
|
|
||||||
c->Message(
|
|
||||||
Chat::White,
|
|
||||||
fmt::format(
|
|
||||||
"Could not locate member list for bot-group '{}'.",
|
|
||||||
botgroup_name
|
|
||||||
).c_str()
|
|
||||||
);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
member_list[botgroup_id].remove(0);
|
|
||||||
member_list[botgroup_id].remove(leader->GetBotID());
|
|
||||||
|
|
||||||
auto bot_spawn_limit = c->GetBotSpawnLimit();
|
|
||||||
auto spawned_bot_count = 0;
|
|
||||||
|
|
||||||
std::vector<int> bot_class_spawn_limits;
|
|
||||||
std::vector<int> bot_class_spawned_count = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
|
|
||||||
|
|
||||||
for (uint8 class_id = WARRIOR; class_id <= BERSERKER; class_id++) {
|
|
||||||
auto bot_class_limit = c->GetBotSpawnLimit(class_id);
|
|
||||||
bot_class_spawn_limits.push_back(bot_class_limit);
|
|
||||||
}
|
|
||||||
|
|
||||||
for (const auto& member_iter : member_list[botgroup_id]) {
|
|
||||||
auto member = Bot::LoadBot(member_iter);
|
|
||||||
if (!member) {
|
|
||||||
c->Message(
|
|
||||||
Chat::White,
|
|
||||||
fmt::format(
|
|
||||||
"Could not load bot id {}.",
|
|
||||||
member_iter
|
|
||||||
).c_str()
|
|
||||||
);
|
|
||||||
safe_delete(member);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (bot_spawn_limit >= 0 && spawned_bot_count >= bot_spawn_limit) {
|
|
||||||
c->Message(
|
|
||||||
Chat::White,
|
|
||||||
fmt::format(
|
|
||||||
"Failed to spawn {} because you have a max of {} bot{} spawned.",
|
|
||||||
member->GetCleanName(),
|
|
||||||
bot_spawn_limit,
|
|
||||||
bot_spawn_limit != 1 ? "s" : ""
|
|
||||||
).c_str()
|
|
||||||
);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
auto spawned_bot_count_class = bot_class_spawned_count[member->GetClass() - 1];
|
|
||||||
auto bot_spawn_limit_class = bot_class_spawn_limits[member->GetClass() - 1];
|
|
||||||
|
|
||||||
if (bot_spawn_limit_class >= 0 && spawned_bot_count_class >= bot_spawn_limit_class) {
|
|
||||||
c->Message(
|
|
||||||
Chat::White,
|
|
||||||
fmt::format(
|
|
||||||
"Failed to spawn {} because you have a max of {} {} bot{} spawned.",
|
|
||||||
member->GetCleanName(),
|
|
||||||
bot_spawn_limit_class,
|
|
||||||
GetClassIDName(member->GetClass()),
|
|
||||||
bot_spawn_limit_class != 1 ? "s" : ""
|
|
||||||
).c_str()
|
|
||||||
);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!member->spawned) {
|
|
||||||
if (!member->Spawn(c)) {
|
|
||||||
c->Message(
|
|
||||||
Chat::White,
|
|
||||||
fmt::format(
|
|
||||||
"Could not spawn bot '{}' (ID {}).",
|
|
||||||
member->GetName(),
|
|
||||||
member_iter
|
|
||||||
).c_str()
|
|
||||||
);
|
|
||||||
safe_delete(member);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
spawned_bot_count++;
|
|
||||||
bot_class_spawned_count[member->GetClass() - 1]++;
|
|
||||||
|
|
||||||
if (group) {
|
|
||||||
Bot::AddBotToGroup(member, group);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (group) {
|
|
||||||
group->VerifyGroup();
|
|
||||||
} else if (raid) {
|
|
||||||
raid->VerifyRaid();
|
|
||||||
}
|
|
||||||
|
|
||||||
c->Message(
|
|
||||||
Chat::White,
|
|
||||||
fmt::format(
|
|
||||||
"Successfully loaded bot-group {}.",
|
|
||||||
botgroup_name
|
|
||||||
).c_str()
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
void Bot::Signal(int signal_id)
|
void Bot::Signal(int signal_id)
|
||||||
{
|
{
|
||||||
if (parse->BotHasQuestSub(EVENT_SIGNAL)) {
|
if (parse->BotHasQuestSub(EVENT_SIGNAL)) {
|
||||||
@@ -8755,13 +8559,15 @@ std::vector<Mob*> Bot::GetApplySpellList(
|
|||||||
|
|
||||||
if (apply_type == ApplySpellType::Raid && IsRaidGrouped()) {
|
if (apply_type == ApplySpellType::Raid && IsRaidGrouped()) {
|
||||||
auto* r = GetRaid();
|
auto* r = GetRaid();
|
||||||
|
if (r) {
|
||||||
auto group_id = r->GetGroup(GetCleanName());
|
auto group_id = r->GetGroup(GetCleanName());
|
||||||
if (r && EQ::ValueWithin(group_id, 0, (MAX_RAID_GROUPS - 1))) {
|
if (EQ::ValueWithin(group_id, 0, (MAX_RAID_GROUPS - 1))) {
|
||||||
for (const auto& m: r->members) {
|
for (const auto& m: r->members) {
|
||||||
if (m.is_bot) {
|
if (m.is_bot) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (m.member && m.member->IsClient() && (!is_raid_group_only || r->GetGroup(m.member) == group_id)) {
|
if (m.member && m.member->IsClient() &&
|
||||||
|
(!is_raid_group_only || r->GetGroup(m.member) == group_id)) {
|
||||||
l.push_back(m.member);
|
l.push_back(m.member);
|
||||||
|
|
||||||
if (allow_pets && m.member->HasPet()) {
|
if (allow_pets && m.member->HasPet()) {
|
||||||
@@ -8775,6 +8581,7 @@ std::vector<Mob*> Bot::GetApplySpellList(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
} else if (apply_type == ApplySpellType::Group && IsGrouped()) {
|
} else if (apply_type == ApplySpellType::Group && IsGrouped()) {
|
||||||
auto* g = GetGroup();
|
auto* g = GetGroup();
|
||||||
if (g) {
|
if (g) {
|
||||||
@@ -8944,6 +8751,12 @@ bool Bot::CheckSpawnConditions(Client* c) {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Raid* raid = entity_list.GetRaidByClient(c);
|
||||||
|
if (raid && raid->IsEngaged()) {
|
||||||
|
c->Message(Chat::White, "You cannot spawn bots while your raid is engaged.");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
auto* owner_group = c->GetGroup();
|
auto* owner_group = c->GetGroup();
|
||||||
if (owner_group) {
|
if (owner_group) {
|
||||||
std::list<Client*> member_list;
|
std::list<Client*> member_list;
|
||||||
@@ -8963,12 +8776,6 @@ bool Bot::CheckSpawnConditions(Client* c) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Raid* raid = entity_list.GetRaidByClient(c);
|
|
||||||
if (raid && raid->IsEngaged()) {
|
|
||||||
c->Message(Chat::White, "You cannot spawn bots while your raid is engaged.");
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -645,8 +645,6 @@ public:
|
|||||||
void SetBotEnforceSpellSetting(bool enforcespellsettings, bool save = false);
|
void SetBotEnforceSpellSetting(bool enforcespellsettings, bool save = false);
|
||||||
bool GetBotEnforceSpellSetting() const { return m_enforce_spell_settings; }
|
bool GetBotEnforceSpellSetting() const { return m_enforce_spell_settings; }
|
||||||
|
|
||||||
static void SpawnBotGroupByName(Client* c, const std::string& botgroup_name, uint32 leader_id);
|
|
||||||
|
|
||||||
std::string CreateSayLink(Client* botOwner, const char* message, const char* name);
|
std::string CreateSayLink(Client* botOwner, const char* message, const char* name);
|
||||||
|
|
||||||
// Class Destructors
|
// Class Destructors
|
||||||
|
|||||||
+2
-851
@@ -1361,14 +1361,6 @@ int bot_command_init(void)
|
|||||||
bot_command_add("boteyes", "Changes the eye colors of a bot", AccountStatus::Player, bot_subcommand_bot_eyes) ||
|
bot_command_add("boteyes", "Changes the eye colors of a bot", AccountStatus::Player, bot_subcommand_bot_eyes) ||
|
||||||
bot_command_add("botface", "Changes the facial appearance of your bot", AccountStatus::Player, bot_subcommand_bot_face) ||
|
bot_command_add("botface", "Changes the facial appearance of your bot", AccountStatus::Player, bot_subcommand_bot_face) ||
|
||||||
bot_command_add("botfollowdistance", "Changes the follow distance(s) of a bot(s)", AccountStatus::Player, bot_subcommand_bot_follow_distance) ||
|
bot_command_add("botfollowdistance", "Changes the follow distance(s) of a bot(s)", AccountStatus::Player, bot_subcommand_bot_follow_distance) ||
|
||||||
bot_command_add("botgroup", "Lists the available bot-group [subcommands]", AccountStatus::Player, bot_command_botgroup) ||
|
|
||||||
bot_command_add("botgroupaddmember", "Adds a member to a bot-group", AccountStatus::Player, bot_subcommand_botgroup_add_member) ||
|
|
||||||
bot_command_add("botgroupautospawn", "Toggles auto spawning for a bot-group, spawning the bot group when you zone automatically", AccountStatus::Player, bot_subcommand_botgroup_auto_spawn) ||
|
|
||||||
bot_command_add("botgroupcreate", "Creates a bot-group and designates a leader", AccountStatus::Player, bot_subcommand_botgroup_create) ||
|
|
||||||
bot_command_add("botgroupdelete", "Deletes a bot-group and releases its members", AccountStatus::Player, bot_subcommand_botgroup_delete) ||
|
|
||||||
bot_command_add("botgrouplist", "Lists all of your existing bot-groups", AccountStatus::Player, bot_subcommand_botgroup_list) ||
|
|
||||||
bot_command_add("botgroupload", "Loads all members of a bot-group", AccountStatus::Player, bot_subcommand_botgroup_load) ||
|
|
||||||
bot_command_add("botgroupremovemember", "Removes a bot from its bot-group", AccountStatus::Player, bot_subcommand_botgroup_remove_member) ||
|
|
||||||
bot_command_add("bothaircolor", "Changes the hair color of a bot", AccountStatus::Player, bot_subcommand_bot_hair_color) ||
|
bot_command_add("bothaircolor", "Changes the hair color of a bot", AccountStatus::Player, bot_subcommand_bot_hair_color) ||
|
||||||
bot_command_add("bothairstyle", "Changes the hairstyle of a bot", AccountStatus::Player, bot_subcommand_bot_hairstyle) ||
|
bot_command_add("bothairstyle", "Changes the hairstyle of a bot", AccountStatus::Player, bot_subcommand_bot_hairstyle) ||
|
||||||
bot_command_add("botheritage", "Changes the Drakkin heritage of a bot", AccountStatus::Player, bot_subcommand_bot_heritage) ||
|
bot_command_add("botheritage", "Changes the Drakkin heritage of a bot", AccountStatus::Player, bot_subcommand_bot_heritage) ||
|
||||||
@@ -1911,43 +1903,6 @@ namespace MyBots
|
|||||||
sbl.remove(nullptr);
|
sbl.remove(nullptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void PopulateSBL_ByBotGroup(Client *bot_owner, std::list<Bot*> &sbl, const char* name, bool clear_list = true) {
|
|
||||||
if (clear_list)
|
|
||||||
sbl.clear();
|
|
||||||
if (!bot_owner || !name)
|
|
||||||
return;
|
|
||||||
|
|
||||||
std::string group_name = name;
|
|
||||||
|
|
||||||
uint32 botgroup_id = 0;
|
|
||||||
if (!database.botdb.LoadBotGroupIDForLoadBotGroup(bot_owner->CharacterID(), group_name, botgroup_id) || !botgroup_id)
|
|
||||||
return;
|
|
||||||
|
|
||||||
std::map<uint32, std::list<uint32>> botgroup_list;
|
|
||||||
if (!database.botdb.LoadBotGroup(group_name, botgroup_list) || botgroup_list.find(botgroup_id) == botgroup_list.end() || !botgroup_list[botgroup_id].size())
|
|
||||||
return;
|
|
||||||
|
|
||||||
std::list<Bot*> selectable_bot_list;
|
|
||||||
PopulateSBL_BySpawnedBots(bot_owner, selectable_bot_list);
|
|
||||||
if (selectable_bot_list.empty())
|
|
||||||
return;
|
|
||||||
|
|
||||||
selectable_bot_list.remove(nullptr);
|
|
||||||
for (auto group_iter : botgroup_list[botgroup_id]) {
|
|
||||||
for (auto bot_iter : selectable_bot_list) {
|
|
||||||
if (bot_iter->GetBotID() != group_iter)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
if (IsMyBot(bot_owner, bot_iter)) {
|
|
||||||
sbl.push_back(bot_iter);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!clear_list)
|
|
||||||
UniquifySBL(sbl);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
namespace ActionableTarget
|
namespace ActionableTarget
|
||||||
@@ -2166,7 +2121,6 @@ namespace ActionableBots
|
|||||||
ABM_Target = (1 << (ABT_Target - 1)),
|
ABM_Target = (1 << (ABT_Target - 1)),
|
||||||
ABM_ByName = (1 << (ABT_ByName - 1)),
|
ABM_ByName = (1 << (ABT_ByName - 1)),
|
||||||
ABM_OwnerGroup = (1 << (ABT_OwnerGroup - 1)),
|
ABM_OwnerGroup = (1 << (ABT_OwnerGroup - 1)),
|
||||||
ABM_BotGroup = (1 << (ABT_BotGroup - 1)),
|
|
||||||
ABM_TargetGroup = (1 << (ABT_TargetGroup - 1)),
|
ABM_TargetGroup = (1 << (ABT_TargetGroup - 1)),
|
||||||
ABM_NamesGroup = (1 << (ABT_NamesGroup - 1)),
|
ABM_NamesGroup = (1 << (ABT_NamesGroup - 1)),
|
||||||
ABM_HealRotation = (1 << (ABT_HealRotation - 1)),
|
ABM_HealRotation = (1 << (ABT_HealRotation - 1)),
|
||||||
@@ -2177,8 +2131,8 @@ namespace ActionableBots
|
|||||||
ABM_Spawned_All = (3 << (ABT_Spawned - 1)),
|
ABM_Spawned_All = (3 << (ABT_Spawned - 1)),
|
||||||
ABM_NoFilter = ~0,
|
ABM_NoFilter = ~0,
|
||||||
// grouped values
|
// grouped values
|
||||||
ABM_Type1 = (ABM_Target | ABM_ByName | ABM_OwnerGroup | ABM_BotGroup | ABM_TargetGroup | ABM_NamesGroup | ABM_HealRotationTargets | ABM_Spawned),
|
ABM_Type1 = (ABM_Target | ABM_ByName | ABM_OwnerGroup | ABM_TargetGroup | ABM_NamesGroup | ABM_HealRotationTargets | ABM_Spawned),
|
||||||
ABM_Type2 = (ABM_ByName | ABM_OwnerGroup | ABM_BotGroup | ABM_NamesGroup | ABM_HealRotation | ABM_Spawned)
|
ABM_Type2 = (ABM_ByName | ABM_OwnerGroup | ABM_NamesGroup | ABM_HealRotation | ABM_Spawned)
|
||||||
};
|
};
|
||||||
|
|
||||||
// Populates 'sbl'
|
// Populates 'sbl'
|
||||||
@@ -2195,8 +2149,6 @@ namespace ActionableBots
|
|||||||
ab_type = ABT_ByName;
|
ab_type = ABT_ByName;
|
||||||
else if (!ab_type_arg.compare("ownergroup"))
|
else if (!ab_type_arg.compare("ownergroup"))
|
||||||
ab_type = ABT_OwnerGroup;
|
ab_type = ABT_OwnerGroup;
|
||||||
else if (!ab_type_arg.compare("botgroup"))
|
|
||||||
ab_type = ABT_BotGroup;
|
|
||||||
else if (!ab_type_arg.compare("targetgroup"))
|
else if (!ab_type_arg.compare("targetgroup"))
|
||||||
ab_type = ABT_TargetGroup;
|
ab_type = ABT_TargetGroup;
|
||||||
else if (!ab_type_arg.compare("namesgroup"))
|
else if (!ab_type_arg.compare("namesgroup"))
|
||||||
@@ -2228,10 +2180,6 @@ namespace ActionableBots
|
|||||||
if (ab_mask & ABM_OwnerGroup)
|
if (ab_mask & ABM_OwnerGroup)
|
||||||
MyBots::PopulateSBL_ByMyGroupedBots(bot_owner, sbl, clear_list);
|
MyBots::PopulateSBL_ByMyGroupedBots(bot_owner, sbl, clear_list);
|
||||||
break;
|
break;
|
||||||
case ABT_BotGroup:
|
|
||||||
if (ab_mask & ABM_BotGroup)
|
|
||||||
MyBots::PopulateSBL_ByBotGroup(bot_owner, sbl, name, clear_list);
|
|
||||||
break;
|
|
||||||
case ABT_TargetGroup:
|
case ABT_TargetGroup:
|
||||||
if (ab_mask & ABM_TargetGroup)
|
if (ab_mask & ABM_TargetGroup)
|
||||||
MyBots::PopulateSBL_ByTargetsGroupedBots(bot_owner, sbl, clear_list);
|
MyBots::PopulateSBL_ByTargetsGroupedBots(bot_owner, sbl, clear_list);
|
||||||
@@ -7157,803 +7105,6 @@ void bot_subcommand_bot_woad(Client *c, const Seperator *sep)
|
|||||||
helper_bot_appearance_form_final(c, my_bot);
|
helper_bot_appearance_form_final(c, my_bot);
|
||||||
}
|
}
|
||||||
|
|
||||||
void bot_subcommand_botgroup_add_member(Client *c, const Seperator *sep)
|
|
||||||
{
|
|
||||||
if (helper_command_alias_fail(c, "bot_subcommand_botgroup_add_member", sep->arg[0], "botgroupaddmember")) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (helper_is_help_or_usage(sep->arg[1])) {
|
|
||||||
c->Message(
|
|
||||||
Chat::White,
|
|
||||||
fmt::format(
|
|
||||||
"Usage: (<target_leader>) {} [member_name] ([leader_name])",
|
|
||||||
sep->arg[0]
|
|
||||||
).c_str()
|
|
||||||
);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
std::list<Bot*> sbl;
|
|
||||||
MyBots::PopulateSBL_ByNamedBot(c, sbl, sep->arg[1]);
|
|
||||||
if (sbl.empty()) {
|
|
||||||
c->Message(
|
|
||||||
Chat::White,
|
|
||||||
fmt::format(
|
|
||||||
"Usage: (<target_leader>) {} [member_name]",
|
|
||||||
sep->arg[0]
|
|
||||||
).c_str()
|
|
||||||
);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
auto new_member = sbl.front();
|
|
||||||
if (!new_member) {
|
|
||||||
c->Message(Chat::White, "Error: New member bot dereferenced to nullptr");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (new_member->HasGroup()) {
|
|
||||||
c->Message(
|
|
||||||
Chat::White,
|
|
||||||
fmt::format(
|
|
||||||
"{} is already member of a group.",
|
|
||||||
new_member->GetCleanName()
|
|
||||||
).c_str()
|
|
||||||
);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
uint32 botgroup_id = 0;
|
|
||||||
if (!database.botdb.LoadBotGroupIDByMemberID(new_member->GetBotID(), botgroup_id)) {
|
|
||||||
c->Message(
|
|
||||||
Chat::White,
|
|
||||||
fmt::format(
|
|
||||||
"Failed to load bot-group id by member ID for '{}'.",
|
|
||||||
new_member->GetCleanName()
|
|
||||||
).c_str()
|
|
||||||
);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (botgroup_id) {
|
|
||||||
c->Message(
|
|
||||||
Chat::White,
|
|
||||||
fmt::format(
|
|
||||||
"{} is already a member of a bot-group.",
|
|
||||||
new_member->GetCleanName()
|
|
||||||
).c_str()
|
|
||||||
);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
MyBots::PopulateSBL_ByNamedBot(c, sbl, sep->arg[2]);
|
|
||||||
|
|
||||||
if (sbl.empty()) {
|
|
||||||
MyBots::PopulateSBL_ByTargetedBot(c, sbl);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (sbl.empty()) {
|
|
||||||
c->Message(Chat::White, "You must target or name a group leader as a bot that you own to use this command.");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
auto leader = sbl.front();
|
|
||||||
if (!leader) {
|
|
||||||
c->Message(Chat::White, "Error: Group leader bot dereferenced to nullptr.");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
auto* g = leader->GetGroup();
|
|
||||||
if (!g || g->GetLeader() != leader) {
|
|
||||||
c->Message(
|
|
||||||
Chat::White,
|
|
||||||
fmt::format(
|
|
||||||
"{} is not the leader of a group.",
|
|
||||||
leader->GetCleanName()
|
|
||||||
).c_str()
|
|
||||||
);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
botgroup_id = 0;
|
|
||||||
if (!database.botdb.LoadBotGroupIDByLeaderID(leader->GetBotID(), botgroup_id)) {
|
|
||||||
c->Message(
|
|
||||||
Chat::White,
|
|
||||||
fmt::format(
|
|
||||||
"Failed to load bot-group ID by leader ID for '{}'.",
|
|
||||||
leader->GetCleanName()
|
|
||||||
).c_str()
|
|
||||||
);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!botgroup_id) {
|
|
||||||
c->Message(
|
|
||||||
Chat::White,
|
|
||||||
fmt::format(
|
|
||||||
"{} is not the leader of a bot-group.",
|
|
||||||
leader->GetCleanName()
|
|
||||||
).c_str()
|
|
||||||
);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!Bot::AddBotToGroup(new_member, g)) {
|
|
||||||
c->Message(
|
|
||||||
Chat::White,
|
|
||||||
fmt::format(
|
|
||||||
"Could not add {} as a new member to a group with {}.",
|
|
||||||
new_member->GetCleanName(),
|
|
||||||
leader->GetCleanName()
|
|
||||||
).c_str()
|
|
||||||
);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
database.SetGroupID(new_member->GetName(), g->GetID(), new_member->GetBotID());
|
|
||||||
|
|
||||||
if (!database.botdb.AddMemberToBotGroup(leader->GetBotID(), new_member->GetBotID())) {
|
|
||||||
c->Message(
|
|
||||||
Chat::White,
|
|
||||||
fmt::format(
|
|
||||||
"Failed to add member to bot-group, {} could not be added to a group with {}.",
|
|
||||||
new_member->GetCleanName(),
|
|
||||||
leader->GetCleanName()
|
|
||||||
).c_str()
|
|
||||||
);
|
|
||||||
Bot::RemoveBotFromGroup(new_member, leader->GetGroup());
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
std::string botgroup_name;
|
|
||||||
if (!database.botdb.LoadBotGroupNameByLeaderID(leader->GetBotID(), botgroup_name)) {
|
|
||||||
c->Message(
|
|
||||||
Chat::White,
|
|
||||||
fmt::format(
|
|
||||||
"Failed to load bot-group name by leader ID for bot ID {}.",
|
|
||||||
leader->GetBotID()
|
|
||||||
).c_str()
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
c->Message(
|
|
||||||
Chat::White,
|
|
||||||
fmt::format(
|
|
||||||
"Successfully added {} to bot-group {}.",
|
|
||||||
new_member->GetCleanName(),
|
|
||||||
botgroup_name
|
|
||||||
).c_str()
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
void bot_subcommand_botgroup_auto_spawn(Client *c, const Seperator *sep)
|
|
||||||
{
|
|
||||||
if (helper_command_alias_fail(c, "bot_subcommand_botgroup_auto_spawn", sep->arg[0], "botgroupautospawn")) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (helper_is_help_or_usage(sep->arg[1])) {
|
|
||||||
c->Message(
|
|
||||||
Chat::White,
|
|
||||||
fmt::format(
|
|
||||||
"Usage: (<target_leader>) {} ([leader_name])",
|
|
||||||
sep->arg[0]
|
|
||||||
).c_str()
|
|
||||||
);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
std::list<Bot*> sbl;
|
|
||||||
|
|
||||||
if (sbl.empty()) {
|
|
||||||
MyBots::PopulateSBL_ByTargetedBot(c, sbl);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (sbl.empty()) {
|
|
||||||
c->Message(Chat::White, "You must target or name a group leader as a bot that you own to use this command.");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
auto leader = sbl.front();
|
|
||||||
if (!leader) {
|
|
||||||
c->Message(Chat::White, "Error: Group leader bot dereferenced to nullptr.");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
auto* g = leader->GetGroup();
|
|
||||||
if (!g || g->GetLeader() != leader) {
|
|
||||||
c->Message(
|
|
||||||
Chat::White,
|
|
||||||
fmt::format(
|
|
||||||
"{} is not the leader of a group.",
|
|
||||||
leader->GetCleanName()
|
|
||||||
).c_str()
|
|
||||||
);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
uint32 botgroup_id = 0;
|
|
||||||
if (!database.botdb.LoadBotGroupIDByLeaderID(leader->GetBotID(), botgroup_id)) {
|
|
||||||
c->Message(
|
|
||||||
Chat::White,
|
|
||||||
fmt::format(
|
|
||||||
"Failed to load bot-group ID by leader ID for '{}'.",
|
|
||||||
leader->GetCleanName()
|
|
||||||
).c_str()
|
|
||||||
);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!botgroup_id) {
|
|
||||||
c->Message(
|
|
||||||
Chat::White,
|
|
||||||
fmt::format(
|
|
||||||
"{} is not the leader of a bot-group.",
|
|
||||||
leader->GetCleanName()
|
|
||||||
).c_str()
|
|
||||||
);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
std::string botgroup_name;
|
|
||||||
if (!database.botdb.LoadBotGroupNameByLeaderID(leader->GetBotID(), botgroup_name)) {
|
|
||||||
c->Message(Chat::White, "Failed to load bot-group name by leader ID.");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!database.botdb.ToggleBotGroupAutoSpawn(botgroup_id)) {
|
|
||||||
c->Message(
|
|
||||||
Chat::White,
|
|
||||||
fmt::format(
|
|
||||||
"Failed to toggle auto spawn for bot-group '{}'.",
|
|
||||||
botgroup_name
|
|
||||||
).c_str()
|
|
||||||
);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool auto_spawn = database.botdb.IsBotGroupAutoSpawn(botgroup_name);
|
|
||||||
|
|
||||||
c->Message(
|
|
||||||
Chat::White,
|
|
||||||
fmt::format(
|
|
||||||
"Auto spawn is now {}active bot-group '{}'.",
|
|
||||||
!auto_spawn ? "in" : "",
|
|
||||||
botgroup_name
|
|
||||||
).c_str()
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
void bot_subcommand_botgroup_create(Client *c, const Seperator *sep)
|
|
||||||
{
|
|
||||||
if (helper_command_alias_fail(c, "bot_subcommand_botgroup_create", sep->arg[0], "botgroupcreate")) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (helper_is_help_or_usage(sep->arg[1])) {
|
|
||||||
c->Message(
|
|
||||||
Chat::White,
|
|
||||||
fmt::format(
|
|
||||||
"Usage: (<target_leader>) {} [group_name] ([leader_name])",
|
|
||||||
sep->arg[0]
|
|
||||||
).c_str()
|
|
||||||
);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
std::string botgroup_name = sep->argplus[1];
|
|
||||||
if (botgroup_name.empty()) {
|
|
||||||
c->Message(Chat::White, "You must specify a name for this bot-group to use this command.");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (database.botdb.QueryBotGroupExistence(botgroup_name)) {
|
|
||||||
c->Message(
|
|
||||||
Chat::White,
|
|
||||||
fmt::format(
|
|
||||||
"The name '{}' already exists for a bot-group. Please choose another.",
|
|
||||||
botgroup_name
|
|
||||||
).c_str()
|
|
||||||
);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
std::list<Bot*> sbl;
|
|
||||||
MyBots::PopulateSBL_ByNamedBot(c, sbl, sep->arg[2]);
|
|
||||||
|
|
||||||
if (sbl.empty()) {
|
|
||||||
MyBots::PopulateSBL_ByTargetedBot(c, sbl);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (sbl.empty()) {
|
|
||||||
c->Message(Chat::White, "You must target or name a group leader as a bot that you own to use this command.");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
auto leader = sbl.front();
|
|
||||||
if (!leader) {
|
|
||||||
c->Message(Chat::White, "Error: Group leader bot dereferenced to nullptr.");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (leader->HasGroup()) {
|
|
||||||
c->Message(
|
|
||||||
Chat::White,
|
|
||||||
fmt::format(
|
|
||||||
"{} is already a current member of a group.",
|
|
||||||
leader->GetCleanName()
|
|
||||||
).c_str()
|
|
||||||
);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
uint32 botgroup_id = 0;
|
|
||||||
if (!database.botdb.LoadBotGroupIDByLeaderID(leader->GetBotID(), botgroup_id)) {
|
|
||||||
c->Message(
|
|
||||||
Chat::White,
|
|
||||||
fmt::format(
|
|
||||||
"Failed to load bot-group ID by leader ID for '{}'.",
|
|
||||||
leader->GetCleanName()
|
|
||||||
).c_str()
|
|
||||||
);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (botgroup_id) {
|
|
||||||
c->Message(
|
|
||||||
Chat::White,
|
|
||||||
fmt::format(
|
|
||||||
"{} is already the current leader of a bot-group.",
|
|
||||||
leader->GetCleanName()
|
|
||||||
).c_str()
|
|
||||||
);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
botgroup_id = 0;
|
|
||||||
if (!database.botdb.LoadBotGroupIDByMemberID(leader->GetBotID(), botgroup_id)) {
|
|
||||||
c->Message(
|
|
||||||
Chat::White,
|
|
||||||
fmt::format(
|
|
||||||
"Failed to load bot-group id by member ID for '{}'.",
|
|
||||||
leader->GetCleanName()
|
|
||||||
).c_str()
|
|
||||||
);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (botgroup_id) {
|
|
||||||
c->Message(
|
|
||||||
Chat::White,
|
|
||||||
fmt::format(
|
|
||||||
"{} is already a current member of a bot-group.",
|
|
||||||
leader->GetCleanName()
|
|
||||||
).c_str()
|
|
||||||
);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
auto* g = new Group(leader);
|
|
||||||
if (!g) {
|
|
||||||
c->Message(Chat::White, "Could not create a new group instance.");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!database.botdb.CreateBotGroup(botgroup_name, leader->GetBotID())) {
|
|
||||||
c->Message(
|
|
||||||
Chat::White,
|
|
||||||
fmt::format(
|
|
||||||
"Failed to create bot-group '{}'.",
|
|
||||||
botgroup_name
|
|
||||||
).c_str()
|
|
||||||
);
|
|
||||||
safe_delete(g);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
entity_list.AddGroup(g);
|
|
||||||
database.SetGroupID(leader->GetCleanName(), g->GetID(), leader->GetBotID());
|
|
||||||
database.SetGroupLeaderName(g->GetID(), leader->GetCleanName());
|
|
||||||
leader->SetFollowID(c->GetID());
|
|
||||||
|
|
||||||
c->Message(
|
|
||||||
Chat::White,
|
|
||||||
fmt::format(
|
|
||||||
"Successfully created bot-group '{}' with '{}' as its leader.",
|
|
||||||
botgroup_name,
|
|
||||||
leader->GetCleanName()
|
|
||||||
).c_str()
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
void bot_subcommand_botgroup_delete(Client *c, const Seperator *sep)
|
|
||||||
{
|
|
||||||
if (helper_command_alias_fail(c, "bot_subcommand_botgroup_delete", sep->arg[0], "botgroupdelete")) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (helper_is_help_or_usage(sep->arg[1])) {
|
|
||||||
c->Message(Chat::White, "usage: %s [botgroup_name]", sep->arg[0]);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
std::string botgroup_name = sep->argplus[1];
|
|
||||||
if (botgroup_name.empty()) {
|
|
||||||
c->Message(Chat::White, "You must specify a [name] for this bot-group to use this command");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
uint32 botgroup_id = 0;
|
|
||||||
if (!database.botdb.LoadBotGroupIDForLoadBotGroup(c->CharacterID(), botgroup_name, botgroup_id)) {
|
|
||||||
c->Message(
|
|
||||||
Chat::White,
|
|
||||||
fmt::format(
|
|
||||||
"Failed to load bot-group ID for load bot-group for '{}'.",
|
|
||||||
botgroup_name
|
|
||||||
).c_str()
|
|
||||||
);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!botgroup_id) {
|
|
||||||
c->Message(
|
|
||||||
Chat::White,
|
|
||||||
fmt::format(
|
|
||||||
"Could not locate group ID for '{}'.",
|
|
||||||
botgroup_name
|
|
||||||
).c_str()
|
|
||||||
);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
uint32 leader_id = 0;
|
|
||||||
if (!database.botdb.LoadLeaderIDByBotGroupID(botgroup_id, leader_id)) {
|
|
||||||
c->Message(
|
|
||||||
Chat::White,
|
|
||||||
fmt::format(
|
|
||||||
"Failed to load leader ID by bot-group ID for '{}'.",
|
|
||||||
botgroup_name
|
|
||||||
).c_str()
|
|
||||||
);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!leader_id) {
|
|
||||||
c->Message(
|
|
||||||
Chat::White,
|
|
||||||
fmt::format(
|
|
||||||
"Could not locate leader ID for '{}'.",
|
|
||||||
botgroup_name
|
|
||||||
).c_str()
|
|
||||||
);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
std::list<Bot*> gbl;
|
|
||||||
std::list<Bot*> sbl;
|
|
||||||
MyBots::PopulateSBL_BySpawnedBots(c, sbl);
|
|
||||||
|
|
||||||
std::map<uint32, std::list<uint32>> member_list;
|
|
||||||
if (!database.botdb.LoadBotGroup(botgroup_name, member_list)) {
|
|
||||||
c->Message(
|
|
||||||
Chat::White,
|
|
||||||
fmt::format(
|
|
||||||
"Failed to load bot-group '{}'.",
|
|
||||||
botgroup_name
|
|
||||||
).c_str()
|
|
||||||
);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (member_list.find(botgroup_id) == member_list.end() || member_list[botgroup_id].empty()) {
|
|
||||||
c->Message(
|
|
||||||
Chat::White,
|
|
||||||
fmt::format(
|
|
||||||
"Could not locate member list for bot-group '{}'.",
|
|
||||||
botgroup_name
|
|
||||||
).c_str()
|
|
||||||
);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (auto bot_iter : sbl) {
|
|
||||||
for (auto group_iter : member_list[botgroup_id]) {
|
|
||||||
if (bot_iter->GetBotID() == group_iter) {
|
|
||||||
gbl.push_back(bot_iter);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
gbl.unique();
|
|
||||||
|
|
||||||
for (auto group_member : gbl) {
|
|
||||||
if (group_member->HasGroup()) {
|
|
||||||
Bot::RemoveBotFromGroup(group_member, group_member->GetGroup());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!database.botdb.DeleteBotGroup(leader_id)) {
|
|
||||||
c->Message(
|
|
||||||
Chat::White,
|
|
||||||
fmt::format(
|
|
||||||
"Failed to delete bot-group '{}'.",
|
|
||||||
botgroup_name
|
|
||||||
).c_str()
|
|
||||||
);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
c->Message(
|
|
||||||
Chat::White,
|
|
||||||
fmt::format(
|
|
||||||
"Successfully deleted bot-group '{}'.",
|
|
||||||
botgroup_name
|
|
||||||
).c_str()
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
void bot_subcommand_botgroup_list(Client *c, const Seperator *sep)
|
|
||||||
{
|
|
||||||
if (helper_command_alias_fail(c, "bot_subcommand_botgroup_list", sep->arg[0], "botgrouplist")) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (helper_is_help_or_usage(sep->arg[1])) {
|
|
||||||
c->Message(
|
|
||||||
Chat::White,
|
|
||||||
fmt::format(
|
|
||||||
"Usage: {}",
|
|
||||||
sep->arg[0]
|
|
||||||
).c_str()
|
|
||||||
);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
std::list<std::pair<std::string, uint32>> botgroups_list;
|
|
||||||
if (!database.botdb.LoadBotGroupsListByOwnerID(c->CharacterID(), botgroups_list)) {
|
|
||||||
c->Message(Chat::White, "Failed to load bot-group.");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (botgroups_list.empty()) {
|
|
||||||
c->Message(Chat::White, "You have no saved bot-groups.");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
uint32 botgroup_count = 0;
|
|
||||||
|
|
||||||
for (const auto& [group_name, group_leader_id] : botgroups_list) {
|
|
||||||
c->Message(
|
|
||||||
Chat::White,
|
|
||||||
fmt::format(
|
|
||||||
"Bot-group {} | Name: {} | Leader: {}{} | {}",
|
|
||||||
(botgroup_count + 1),
|
|
||||||
group_name,
|
|
||||||
database.botdb.GetBotNameByID(group_leader_id),
|
|
||||||
database.botdb.IsBotGroupAutoSpawn(group_name) ? " (Auto Spawn)" : "",
|
|
||||||
Saylink::Silent(
|
|
||||||
fmt::format("^botgroupload {}", group_name),
|
|
||||||
"Load"
|
|
||||||
)
|
|
||||||
).c_str()
|
|
||||||
);
|
|
||||||
|
|
||||||
botgroup_count++;
|
|
||||||
}
|
|
||||||
|
|
||||||
c->Message(
|
|
||||||
Chat::White,
|
|
||||||
fmt::format(
|
|
||||||
"{} Bot-group{} listed.",
|
|
||||||
botgroup_count,
|
|
||||||
botgroup_count != 1 ? "s" : ""
|
|
||||||
).c_str()
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
void bot_subcommand_botgroup_load(Client *c, const Seperator *sep)
|
|
||||||
{
|
|
||||||
if (helper_command_alias_fail(c, "bot_subcommand_botgroup_load", sep->arg[0], "botgroupload")) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (helper_is_help_or_usage(sep->arg[1])) {
|
|
||||||
c->Message(
|
|
||||||
Chat::White,
|
|
||||||
fmt::format(
|
|
||||||
"Usage: {} [botgroup_name]",
|
|
||||||
sep->arg[0]
|
|
||||||
).c_str()
|
|
||||||
);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
std::string botgroup_name = sep->argplus[1];
|
|
||||||
if (botgroup_name.empty()) {
|
|
||||||
c->Message(Chat::White, "You must specify the name of a bot-group to load to use this command.");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!database.botdb.QueryBotGroupExistence(botgroup_name)) {
|
|
||||||
c->Message(
|
|
||||||
Chat::White,
|
|
||||||
fmt::format(
|
|
||||||
"Failed to query bot-group existence for '{}'.",
|
|
||||||
botgroup_name
|
|
||||||
).c_str()
|
|
||||||
);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!Bot::CheckSpawnConditions(c)) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
uint32 botgroup_id = 0;
|
|
||||||
if (!database.botdb.LoadBotGroupIDForLoadBotGroup(c->CharacterID(), botgroup_name, botgroup_id) || !botgroup_id) {
|
|
||||||
c->Message(
|
|
||||||
Chat::White,
|
|
||||||
fmt::format(
|
|
||||||
"Failed to load bot-group ID for load bot-group for '{}'.",
|
|
||||||
botgroup_name
|
|
||||||
).c_str()
|
|
||||||
);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
std::map<uint32, std::list<uint32>> member_list;
|
|
||||||
if (!database.botdb.LoadBotGroup(botgroup_name, member_list)) {
|
|
||||||
c->Message(
|
|
||||||
Chat::White,
|
|
||||||
fmt::format(
|
|
||||||
"Failed to load bot-group for '{}'.",
|
|
||||||
botgroup_name
|
|
||||||
).c_str()
|
|
||||||
);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (member_list.find(botgroup_id) == member_list.end() || member_list[botgroup_id].empty()) {
|
|
||||||
c->Message(
|
|
||||||
Chat::White,
|
|
||||||
fmt::format(
|
|
||||||
"Database returned an empty list for bot-group '{}'.",
|
|
||||||
botgroup_name
|
|
||||||
).c_str()
|
|
||||||
);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
auto spawned_bot_count = Bot::SpawnedBotCount(c->CharacterID());
|
|
||||||
|
|
||||||
auto bot_spawn_limit = c->GetBotSpawnLimit();
|
|
||||||
if (
|
|
||||||
bot_spawn_limit >= 0 &&
|
|
||||||
(
|
|
||||||
spawned_bot_count >= bot_spawn_limit ||
|
|
||||||
(spawned_bot_count + member_list.begin()->second.size()) > bot_spawn_limit
|
|
||||||
)
|
|
||||||
) {
|
|
||||||
std::string message;
|
|
||||||
if (bot_spawn_limit) {
|
|
||||||
message = fmt::format(
|
|
||||||
"You cannot have more than {} spawned bot{}.",
|
|
||||||
bot_spawn_limit,
|
|
||||||
bot_spawn_limit != 1 ? "s" : ""
|
|
||||||
);
|
|
||||||
} else {
|
|
||||||
message = "You are not currently allowed to spawn any bots.";
|
|
||||||
}
|
|
||||||
|
|
||||||
c->Message(Chat::White, message.c_str());
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
uint32 leader_id = 0;
|
|
||||||
if (!database.botdb.LoadLeaderIDByBotGroupName(botgroup_name, leader_id)) {
|
|
||||||
c->Message(
|
|
||||||
Chat::White,
|
|
||||||
fmt::format(
|
|
||||||
"Failed to load leader ID by bot-group name for '{}'.",
|
|
||||||
botgroup_name
|
|
||||||
).c_str()
|
|
||||||
);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!leader_id) {
|
|
||||||
c->Message(
|
|
||||||
Chat::White,
|
|
||||||
fmt::format(
|
|
||||||
"Cannot locate bot-group leader ID for '{}'.",
|
|
||||||
botgroup_name
|
|
||||||
).c_str()
|
|
||||||
);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
Bot::SpawnBotGroupByName(c, botgroup_name, leader_id);
|
|
||||||
}
|
|
||||||
|
|
||||||
void bot_subcommand_botgroup_remove_member(Client *c, const Seperator *sep)
|
|
||||||
{
|
|
||||||
if (helper_command_alias_fail(c, "bot_subcommand_botgroup_remove_member", sep->arg[0], "botgroupremovemember")) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (helper_is_help_or_usage(sep->arg[1])) {
|
|
||||||
c->Message(
|
|
||||||
Chat::White,
|
|
||||||
fmt::format(
|
|
||||||
"Usage: (<target_member>) {} ([member_name])",
|
|
||||||
sep->arg[0]
|
|
||||||
).c_str()
|
|
||||||
);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
std::list<Bot*> sbl;
|
|
||||||
MyBots::PopulateSBL_ByNamedBot(c, sbl, sep->arg[1]);
|
|
||||||
|
|
||||||
if (sbl.empty()) {
|
|
||||||
MyBots::PopulateSBL_ByTargetedBot(c, sbl);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (sbl.empty()) {
|
|
||||||
c->Message(Chat::White, "You must target or name a group member as a bot that you own to use this command.");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
auto group_member = sbl.front();
|
|
||||||
if (!group_member) {
|
|
||||||
c->Message(Chat::White, "Error: Group member bot dereferenced to nullptr.");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!group_member->HasGroup()) {
|
|
||||||
c->Message(
|
|
||||||
Chat::White,
|
|
||||||
fmt::format(
|
|
||||||
"{} is not a current member of a group.",
|
|
||||||
group_member->GetCleanName()
|
|
||||||
).c_str()
|
|
||||||
);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!Bot::RemoveBotFromGroup(group_member, group_member->GetGroup())) {
|
|
||||||
c->Message(
|
|
||||||
Chat::White,
|
|
||||||
fmt::format(
|
|
||||||
"Could not remove {} from their group.",
|
|
||||||
group_member->GetCleanName()
|
|
||||||
).c_str()
|
|
||||||
);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!database.botdb.RemoveMemberFromBotGroup(group_member->GetBotID())) {
|
|
||||||
c->Message(
|
|
||||||
Chat::White,
|
|
||||||
fmt::format(
|
|
||||||
"Could not remove {} from their bot-group.",
|
|
||||||
group_member->GetCleanName()
|
|
||||||
).c_str()
|
|
||||||
);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
c->Message(
|
|
||||||
Chat::White,
|
|
||||||
fmt::format(
|
|
||||||
"Successfully removed {} from their bot-group.",
|
|
||||||
group_member->GetCleanName()
|
|
||||||
).c_str()
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
void bot_subcommand_circle(Client *c, const Seperator *sep)
|
void bot_subcommand_circle(Client *c, const Seperator *sep)
|
||||||
{
|
{
|
||||||
bcst_list* local_list = &bot_command_spells[BCEnum::SpT_Depart];
|
bcst_list* local_list = &bot_command_spells[BCEnum::SpT_Depart];
|
||||||
|
|||||||
+1
-7
@@ -631,13 +631,7 @@ void bot_subcommand_bot_toggle_archer(Client *c, const Seperator *sep);
|
|||||||
void bot_subcommand_bot_toggle_helm(Client *c, const Seperator *sep);
|
void bot_subcommand_bot_toggle_helm(Client *c, const Seperator *sep);
|
||||||
void bot_subcommand_bot_update(Client *c, const Seperator *sep);
|
void bot_subcommand_bot_update(Client *c, const Seperator *sep);
|
||||||
void bot_subcommand_bot_woad(Client *c, const Seperator *sep);
|
void bot_subcommand_bot_woad(Client *c, const Seperator *sep);
|
||||||
void bot_subcommand_botgroup_add_member(Client *c, const Seperator *sep);
|
|
||||||
void bot_subcommand_botgroup_auto_spawn(Client *c, const Seperator *sep);
|
|
||||||
void bot_subcommand_botgroup_create(Client *c, const Seperator *sep);
|
|
||||||
void bot_subcommand_botgroup_delete(Client *c, const Seperator *sep);
|
|
||||||
void bot_subcommand_botgroup_list(Client *c, const Seperator *sep);
|
|
||||||
void bot_subcommand_botgroup_load(Client *c, const Seperator *sep);
|
|
||||||
void bot_subcommand_botgroup_remove_member(Client *c, const Seperator *sep);
|
|
||||||
void bot_subcommand_circle(Client *c, const Seperator *sep);
|
void bot_subcommand_circle(Client *c, const Seperator *sep);
|
||||||
void bot_subcommand_heal_rotation_adaptive_targeting(Client *c, const Seperator *sep);
|
void bot_subcommand_heal_rotation_adaptive_targeting(Client *c, const Seperator *sep);
|
||||||
void bot_subcommand_heal_rotation_add_member(Client *c, const Seperator *sep);
|
void bot_subcommand_heal_rotation_add_member(Client *c, const Seperator *sep);
|
||||||
|
|||||||
+1
-517
@@ -2204,523 +2204,6 @@ bool BotDatabase::SaveOwnerOption(const uint32 owner_id, const std::pair<size_t,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* Bot bot-group functions */
|
|
||||||
bool BotDatabase::QueryBotGroupExistence(const std::string& group_name)
|
|
||||||
{
|
|
||||||
if (group_name.empty()) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
query = fmt::format(
|
|
||||||
"SELECT `group_name` FROM `bot_groups` WHERE `group_name` = '{}' LIMIT 1",
|
|
||||||
group_name
|
|
||||||
);
|
|
||||||
|
|
||||||
auto results = database.QueryDatabase(query);
|
|
||||||
if (!results.Success() || !results.RowCount()) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool BotDatabase::LoadBotGroupIDByBotGroupName(const std::string& group_name, uint32& botgroup_id)
|
|
||||||
{
|
|
||||||
if (group_name.empty()) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
query = fmt::format(
|
|
||||||
"SELECT `groups_index` FROM `bot_groups` WHERE `group_name` = '{}' LIMIT 1",
|
|
||||||
Strings::Escape(group_name)
|
|
||||||
);
|
|
||||||
|
|
||||||
auto results = database.QueryDatabase(query);
|
|
||||||
if (!results.Success()) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!results.RowCount()) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
auto row = results.begin();
|
|
||||||
botgroup_id = Strings::ToUnsignedInt(row[0]);
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool BotDatabase::LoadBotGroupIDByLeaderID(const uint32 leader_id, uint32& botgroup_id)
|
|
||||||
{
|
|
||||||
if (!leader_id) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
query = fmt::format(
|
|
||||||
"SELECT `groups_index` FROM `bot_groups` WHERE `group_leader_id` = {} LIMIT 1",
|
|
||||||
leader_id
|
|
||||||
);
|
|
||||||
|
|
||||||
auto results = database.QueryDatabase(query);
|
|
||||||
if (!results.Success()) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!results.RowCount()) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
auto row = results.begin();
|
|
||||||
botgroup_id = Strings::ToUnsignedInt(row[0]);
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool BotDatabase::LoadBotGroupIDByMemberID(const uint32 member_id, uint32& botgroup_id)
|
|
||||||
{
|
|
||||||
if (!member_id) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
query = fmt::format(
|
|
||||||
"SELECT `groups_index` FROM `bot_group_members` WHERE `bot_id` = {} LIMIT 1",
|
|
||||||
member_id
|
|
||||||
);
|
|
||||||
|
|
||||||
auto results = database.QueryDatabase(query);
|
|
||||||
if (!results.Success()) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!results.RowCount()) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
auto row = results.begin();
|
|
||||||
botgroup_id = Strings::ToUnsignedInt(row[0]);
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool BotDatabase::LoadLeaderIDByBotGroupName(const std::string& group_name, uint32& leader_id)
|
|
||||||
{
|
|
||||||
if (group_name.empty()) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
query = fmt::format(
|
|
||||||
"SELECT `group_leader_id` FROM `bot_groups` WHERE `group_name` = '{}' LIMIT 1",
|
|
||||||
group_name
|
|
||||||
);
|
|
||||||
|
|
||||||
auto results = database.QueryDatabase(query);
|
|
||||||
if (!results.Success()) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!results.RowCount()) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
auto row = results.begin();
|
|
||||||
leader_id = Strings::ToUnsignedInt(row[0]);
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool BotDatabase::LoadLeaderIDByBotGroupID(const uint32 group_id, uint32& leader_id)
|
|
||||||
{
|
|
||||||
if (!group_id) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
query = fmt::format(
|
|
||||||
"SELECT `group_leader_id` FROM `bot_groups` WHERE `groups_index` = {} LIMIT 1",
|
|
||||||
group_id
|
|
||||||
);
|
|
||||||
|
|
||||||
auto results = database.QueryDatabase(query);
|
|
||||||
if (!results.Success()) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!results.RowCount()) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
auto row = results.begin();
|
|
||||||
leader_id = Strings::ToUnsignedInt(row[0]);
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool BotDatabase::LoadBotGroupNameByBotGroupID(const uint32 group_id, std::string& botgroup_name)
|
|
||||||
{
|
|
||||||
if (!group_id) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
query = fmt::format(
|
|
||||||
"SELECT `group_name` FROM `bot_groups` WHERE `groups_index` = {} LIMIT 1",
|
|
||||||
group_id
|
|
||||||
);
|
|
||||||
|
|
||||||
auto results = database.QueryDatabase(query);
|
|
||||||
if (!results.Success()) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!results.RowCount()) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
auto row = results.begin();
|
|
||||||
botgroup_name = row[0];
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool BotDatabase::LoadBotGroupNameByLeaderID(const uint32 leader_id, std::string& botgroup_name)
|
|
||||||
{
|
|
||||||
if (!leader_id) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
query = fmt::format(
|
|
||||||
"SELECT `group_name` FROM `bot_groups` WHERE `group_leader_id` = {} LIMIT 1",
|
|
||||||
leader_id
|
|
||||||
);
|
|
||||||
|
|
||||||
auto results = database.QueryDatabase(query);
|
|
||||||
if (!results.Success()) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!results.RowCount()) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
auto row = results.begin();
|
|
||||||
botgroup_name = row[0];
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool BotDatabase::CreateBotGroup(const std::string& group_name, const uint32 leader_id)
|
|
||||||
{
|
|
||||||
if (group_name.empty() || !leader_id) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (QueryBotGroupExistence(group_name)) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
query = fmt::format(
|
|
||||||
"INSERT INTO `bot_groups` (`group_leader_id`, `group_name`) VALUES ({}, '{}')",
|
|
||||||
leader_id,
|
|
||||||
group_name
|
|
||||||
);
|
|
||||||
|
|
||||||
auto results = database.QueryDatabase(query);
|
|
||||||
if (!results.Success()) {
|
|
||||||
DeleteBotGroup(leader_id);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
auto botgroup_id = results.LastInsertedID();
|
|
||||||
if (!botgroup_id) {
|
|
||||||
DeleteBotGroup(leader_id);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
query = fmt::format(
|
|
||||||
"INSERT INTO `bot_group_members` (`groups_index`, `bot_id`) VALUES ({}, {})",
|
|
||||||
botgroup_id,
|
|
||||||
leader_id
|
|
||||||
);
|
|
||||||
|
|
||||||
results = database.QueryDatabase(query);
|
|
||||||
if (!results.Success()) {
|
|
||||||
RemoveMemberFromBotGroup(leader_id);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool BotDatabase::DeleteBotGroup(const uint32 leader_id)
|
|
||||||
{
|
|
||||||
if (!leader_id) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
uint32 botgroup_id = 0;
|
|
||||||
if (!LoadBotGroupIDByLeaderID(leader_id, botgroup_id)) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!botgroup_id) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
query = fmt::format(
|
|
||||||
"DELETE FROM `bot_group_members` WHERE `groups_index` = {}",
|
|
||||||
botgroup_id
|
|
||||||
);
|
|
||||||
|
|
||||||
auto results = database.QueryDatabase(query);
|
|
||||||
if (!results.Success() || !results.RowsAffected()) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
query = fmt::format(
|
|
||||||
"DELETE FROM `bot_groups` WHERE `groups_index` = {}",
|
|
||||||
botgroup_id
|
|
||||||
);
|
|
||||||
|
|
||||||
results = database.QueryDatabase(query);
|
|
||||||
if (!results.Success() || !results.RowsAffected()) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool BotDatabase::AddMemberToBotGroup(const uint32 leader_id, const uint32 member_id)
|
|
||||||
{
|
|
||||||
if (!leader_id || !member_id) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
uint32 botgroup_id = 0;
|
|
||||||
if (!LoadBotGroupIDByLeaderID(leader_id, botgroup_id)) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!botgroup_id) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
query = fmt::format(
|
|
||||||
"INSERT INTO `bot_group_members` (`groups_index`, `bot_id`) VALUES ({}, {})",
|
|
||||||
botgroup_id,
|
|
||||||
member_id
|
|
||||||
);
|
|
||||||
|
|
||||||
auto results = database.QueryDatabase(query);
|
|
||||||
if (!results.Success()) {
|
|
||||||
RemoveMemberFromBotGroup(member_id);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool BotDatabase::RemoveMemberFromBotGroup(const uint32 member_id)
|
|
||||||
{
|
|
||||||
if (!member_id) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
uint32 botgroup_id = 0;
|
|
||||||
if (!LoadBotGroupIDByLeaderID(member_id, botgroup_id)) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (botgroup_id) {
|
|
||||||
return DeleteBotGroup(member_id);
|
|
||||||
}
|
|
||||||
|
|
||||||
query = fmt::format(
|
|
||||||
"DELETE FROM `bot_group_members` WHERE `bot_id` = {}",
|
|
||||||
member_id
|
|
||||||
);
|
|
||||||
|
|
||||||
auto results = database.QueryDatabase(query);
|
|
||||||
if (!results.Success()) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool BotDatabase::LoadBotGroupIDForLoadBotGroup(const uint32 owner_id, std::string_view group_name, uint32& botgroup_id)
|
|
||||||
{
|
|
||||||
if (!owner_id || group_name.empty()) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
query = fmt::format(
|
|
||||||
"SELECT bg.groups_index, group_name FROM "
|
|
||||||
"bot_groups bg INNER JOIN bot_group_members bgm "
|
|
||||||
"ON bg.groups_index = bgm.groups_index "
|
|
||||||
"WHERE bgm.bot_id IN "
|
|
||||||
"(SELECT bot_id FROM bot_data WHERE owner_id = {})",
|
|
||||||
owner_id
|
|
||||||
);
|
|
||||||
|
|
||||||
auto results = database.QueryDatabase(query);
|
|
||||||
if (!results.Success()) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!results.RowCount()) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (auto row : results) {
|
|
||||||
if (!group_name.compare(row[1])) {
|
|
||||||
botgroup_id = Strings::ToUnsignedInt(row[0]);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool BotDatabase::LoadBotGroup(const std::string& group_name, std::map<uint32, std::list<uint32>>& member_list)
|
|
||||||
{
|
|
||||||
if (group_name.empty()) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
uint32 botgroup_id = 0;
|
|
||||||
if (!LoadBotGroupIDByBotGroupName(group_name, botgroup_id)) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!botgroup_id) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
query = fmt::format(
|
|
||||||
"SELECT `bot_id` FROM `bot_group_members` WHERE `groups_index` = {} LIMIT 6",
|
|
||||||
botgroup_id
|
|
||||||
);
|
|
||||||
|
|
||||||
auto results = database.QueryDatabase(query);
|
|
||||||
if (!results.Success()) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!results.RowCount()) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (auto row : results) {
|
|
||||||
member_list[botgroup_id].push_back(Strings::ToUnsignedInt(row[0]));
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool BotDatabase::LoadBotGroupsListByOwnerID(const uint32 owner_id, std::list<std::pair<std::string, uint32>>& botgroups_list)
|
|
||||||
{
|
|
||||||
if (!owner_id) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
query = fmt::format(
|
|
||||||
"SELECT DISTINCT(group_name), group_leader_id FROM "
|
|
||||||
"bot_groups bg INNER JOIN bot_group_members bgm "
|
|
||||||
"ON bg.groups_index = bgm.groups_index "
|
|
||||||
"WHERE bgm.bot_id IN "
|
|
||||||
"(SELECT bot_id FROM bot_data WHERE owner_id = {})",
|
|
||||||
owner_id
|
|
||||||
);
|
|
||||||
|
|
||||||
auto results = database.QueryDatabase(query);
|
|
||||||
if (!results.Success()) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!results.RowCount()) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (auto row : results) {
|
|
||||||
botgroups_list.push_back(std::pair<std::string, uint32>(row[0], Strings::ToUnsignedInt(row[1])));
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool BotDatabase::IsBotGroupAutoSpawn(const std::string& botgroup_name)
|
|
||||||
{
|
|
||||||
if (botgroup_name.empty()) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
query = fmt::format(
|
|
||||||
"SELECT group_name FROM bot_groups WHERE group_name = '{}' AND auto_spawn = 1",
|
|
||||||
botgroup_name
|
|
||||||
);
|
|
||||||
|
|
||||||
auto results = database.QueryDatabase(query);
|
|
||||||
if (!results.RowCount() || !results.Success()) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool BotDatabase::ToggleBotGroupAutoSpawn(const uint32 group_id)
|
|
||||||
{
|
|
||||||
if (!group_id) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
query = fmt::format(
|
|
||||||
"UPDATE bot_groups SET auto_spawn = 1 - auto_spawn WHERE groups_index = {}",
|
|
||||||
group_id
|
|
||||||
);
|
|
||||||
|
|
||||||
auto results = database.QueryDatabase(query);
|
|
||||||
if (!results.Success() || !results.RowsAffected()) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool BotDatabase::LoadAutoSpawnBotGroupsByOwnerID(const uint32 owner_id, std::list<std::pair<uint32,std::string>>& group_list)
|
|
||||||
{
|
|
||||||
if (!owner_id) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
query = fmt::format(
|
|
||||||
SQL(
|
|
||||||
SELECT group_leader_id, group_name FROM bot_groups WHERE groups_index IN (
|
|
||||||
SELECT groups_index FROM bot_group_members WHERE bot_id IN (
|
|
||||||
SELECT bot_id FROM bot_data WHERE owner_id = {}
|
|
||||||
)
|
|
||||||
) AND auto_spawn = 1
|
|
||||||
),
|
|
||||||
owner_id
|
|
||||||
);
|
|
||||||
|
|
||||||
auto results = database.QueryDatabase(query);
|
|
||||||
if (!results.Success()) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!results.RowCount()) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (auto row : results) {
|
|
||||||
group_list.push_back(
|
|
||||||
std::pair<uint32,std::string>(Strings::ToUnsignedInt(row[0]), row[1])
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Bot owner group functions */
|
/* Bot owner group functions */
|
||||||
// added owner ID to this function to fix groups with mulitple players grouped with bots.
|
// added owner ID to this function to fix groups with mulitple players grouped with bots.
|
||||||
bool BotDatabase::LoadGroupedBotsByGroupID(const uint32 owner_id, const uint32 group_id, std::list<uint32>& group_list)
|
bool BotDatabase::LoadGroupedBotsByGroupID(const uint32 owner_id, const uint32 group_id, std::list<uint32>& group_list)
|
||||||
@@ -3238,3 +2721,4 @@ const char* BotDatabase::fail::DeleteAllHealRotations() { return "Failed to dele
|
|||||||
|
|
||||||
/* fail::Bot miscellaneous functions */
|
/* fail::Bot miscellaneous functions */
|
||||||
const char* BotDatabase::fail::GetBotNameByID() { return "Failed to get bot name by bot ID"; }
|
const char* BotDatabase::fail::GetBotNameByID() { return "Failed to get bot name by bot ID"; }
|
||||||
|
const char* BotDatabase::fail::LoadGroupedBotsByGroupID() { return "Failed to load grouped bots by group ID."; }
|
||||||
|
|||||||
@@ -148,36 +148,8 @@ public:
|
|||||||
|
|
||||||
bool SaveBotCasterRange(const uint32 owner_id, const uint32 bot_id, const uint32 bot_caster_range_value);
|
bool SaveBotCasterRange(const uint32 owner_id, const uint32 bot_id, const uint32 bot_caster_range_value);
|
||||||
|
|
||||||
/* Bot bot-group functions */
|
|
||||||
bool QueryBotGroupExistence(const std::string& botgroup_name);
|
|
||||||
|
|
||||||
bool LoadBotGroupIDByBotGroupName(const std::string& botgroup_name, uint32& botgroup_id);
|
|
||||||
bool LoadBotGroupIDByLeaderID(const uint32 leader_id, uint32& botgroup_id);
|
|
||||||
bool LoadBotGroupIDByMemberID(const uint32 member_id, uint32& botgroup_id);
|
|
||||||
|
|
||||||
bool LoadLeaderIDByBotGroupName(const std::string& botgroup_name, uint32& leader_id);
|
|
||||||
bool LoadLeaderIDByBotGroupID(const uint32 botgroup_id, uint32& leader_id);
|
|
||||||
|
|
||||||
bool LoadBotGroupNameByBotGroupID(const uint32 botgroup_id, std::string& botgroup_name);
|
|
||||||
bool LoadBotGroupNameByLeaderID(const uint32 leader_id, std::string& botgroup_name);
|
|
||||||
|
|
||||||
bool CreateBotGroup(const std::string& botgroup_name, const uint32 leader_id);
|
|
||||||
bool DeleteBotGroup(const uint32 leader_id);
|
|
||||||
bool AddMemberToBotGroup(const uint32 leader_id, const uint32 member_id);
|
|
||||||
bool RemoveMemberFromBotGroup(const uint32 member_id);
|
|
||||||
|
|
||||||
bool LoadBotGroupIDForLoadBotGroup(const uint32 owner_id, std::string_view botgroup_name, uint32& botgroup_id);
|
|
||||||
bool LoadBotGroup(const std::string& botgroup_name, std::map<uint32, std::list<uint32>>& member_list);
|
|
||||||
|
|
||||||
bool LoadBotGroupsListByOwnerID(const uint32 owner_id, std::list<std::pair<std::string, uint32>>& botgroups_list);
|
|
||||||
|
|
||||||
|
|
||||||
/* Bot group functions */
|
/* Bot group functions */
|
||||||
bool IsBotGroupAutoSpawn(const std::string& botgroup_name);
|
|
||||||
bool LoadAutoSpawnBotGroupsByOwnerID(const uint32 owner_id, std::list<std::pair<uint32,std::string>>& group_list);
|
|
||||||
bool LoadGroupedBotsByGroupID(const uint32 owner_id, const uint32 group_id, std::list<uint32>& group_list);
|
bool LoadGroupedBotsByGroupID(const uint32 owner_id, const uint32 group_id, std::list<uint32>& group_list);
|
||||||
bool ToggleBotGroupAutoSpawn(const uint32 group_id);
|
|
||||||
|
|
||||||
|
|
||||||
/* Bot heal rotation functions */
|
/* Bot heal rotation functions */
|
||||||
bool LoadHealRotationIDByBotID(const uint32 bot_id, uint32& hr_index);
|
bool LoadHealRotationIDByBotID(const uint32 bot_id, uint32& hr_index);
|
||||||
@@ -254,23 +226,6 @@ public:
|
|||||||
static const char* SaveStopMeleeLevel();
|
static const char* SaveStopMeleeLevel();
|
||||||
static const char* SaveBotCasterRange();
|
static const char* SaveBotCasterRange();
|
||||||
|
|
||||||
/* fail::Bot bot-group functions */
|
|
||||||
static const char* QueryBotGroupExistence();
|
|
||||||
static const char* LoadBotGroupIDByBotGroupName();
|
|
||||||
static const char* LoadBotGroupIDByLeaderID();
|
|
||||||
static const char* LoadBotGroupIDByMemberID();
|
|
||||||
static const char* LoadLeaderIDByBotGroupName();
|
|
||||||
static const char* LoadLeaderIDByBotGroupID();
|
|
||||||
static const char* LoadBotGroupNameByBotGroupID();
|
|
||||||
static const char* LoadBotGroupNameByLeaderID();
|
|
||||||
static const char* CreateBotGroup();
|
|
||||||
static const char* DeleteBotGroup();
|
|
||||||
static const char* AddMemberToBotGroup();
|
|
||||||
static const char* RemoveMemberFromBotGroup();
|
|
||||||
static const char* LoadBotGroupIDForLoadBotGroup();
|
|
||||||
static const char* LoadBotGroup();
|
|
||||||
static const char* LoadBotGroupsListByOwnerID();
|
|
||||||
|
|
||||||
/* fail::Bot group functions */
|
/* fail::Bot group functions */
|
||||||
static const char* LoadGroupedBotsByGroupID();
|
static const char* LoadGroupedBotsByGroupID();
|
||||||
|
|
||||||
|
|||||||
@@ -17,6 +17,8 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include "bot.h"
|
#include "bot.h"
|
||||||
|
#include "bot_command.h"
|
||||||
|
#include "client.h"
|
||||||
#include "object.h"
|
#include "object.h"
|
||||||
#include "raids.h"
|
#include "raids.h"
|
||||||
#include "doors.h"
|
#include "doors.h"
|
||||||
@@ -186,6 +188,10 @@ void Bot::ProcessRaidInvite(Mob* invitee, Client* invitor, bool group_invite) {
|
|||||||
|
|
||||||
Raid* raid = entity_list.GetRaidByClient(invitor);
|
Raid* raid = entity_list.GetRaidByClient(invitor);
|
||||||
|
|
||||||
|
if (raid && raid->RaidCount() >= MAX_RAID_MEMBERS) {
|
||||||
|
invitor->MessageString(Chat::Red, RAID_IS_FULL);
|
||||||
|
return;
|
||||||
|
}
|
||||||
Bot::CreateBotRaid(invitee, invitor, group_invite, raid);
|
Bot::CreateBotRaid(invitee, invitor, group_invite, raid);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -296,4 +302,30 @@ void Bot::ProcessBotGroupAdd(Group* group, Raid* raid, Client* client, bool new_
|
|||||||
raid->GroupUpdate(raid_free_group_id);
|
raid->GroupUpdate(raid_free_group_id);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Client::SpawnRaidBotsOnConnect(Raid* raid) {
|
||||||
|
std::list<BotsAvailableList> bots_list;
|
||||||
|
if (!database.botdb.LoadBotsList(CharacterID(), bots_list) || bots_list.empty()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<RaidMember> r_members = raid->GetMembers();
|
||||||
|
for (const auto& m: r_members) {
|
||||||
|
if (strlen(m.member_name) != 0) {
|
||||||
|
|
||||||
|
for (const auto& b: bots_list) {
|
||||||
|
if (strcmp(m.member_name, b.Name) == 0) {
|
||||||
|
std::string buffer = "^spawn ";
|
||||||
|
buffer.append(m.member_name);
|
||||||
|
bot_command_real_dispatch(this, buffer.c_str());
|
||||||
|
auto bot = entity_list.GetBotByBotName(m.member_name);
|
||||||
|
|
||||||
|
if (bot) {
|
||||||
|
bot->SetRaidGrouped(true);
|
||||||
|
bot->p_raid_instance = raid;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|||||||
+20
-7
@@ -1888,11 +1888,15 @@ bool Bot::AIHealRotation(Mob* tar, bool useFastHeals) {
|
|||||||
std::list<BotSpell> Bot::GetBotSpellsForSpellEffect(Bot* botCaster, int spellEffect) {
|
std::list<BotSpell> Bot::GetBotSpellsForSpellEffect(Bot* botCaster, int spellEffect) {
|
||||||
std::list<BotSpell> result;
|
std::list<BotSpell> result;
|
||||||
|
|
||||||
|
if (!botCaster) {
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
if (auto bot_owner = botCaster->GetBotOwner(); !bot_owner) {
|
if (auto bot_owner = botCaster->GetBotOwner(); !bot_owner) {
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (botCaster && botCaster->AI_HasSpells()) {
|
if (botCaster->AI_HasSpells()) {
|
||||||
std::vector<BotSpells_Struct> botSpellList = botCaster->AIBot_spells;
|
std::vector<BotSpells_Struct> botSpellList = botCaster->AIBot_spells;
|
||||||
|
|
||||||
for (int i = botSpellList.size() - 1; i >= 0; i--) {
|
for (int i = botSpellList.size() - 1; i >= 0; i--) {
|
||||||
@@ -1919,11 +1923,15 @@ std::list<BotSpell> Bot::GetBotSpellsForSpellEffect(Bot* botCaster, int spellEff
|
|||||||
std::list<BotSpell> Bot::GetBotSpellsForSpellEffectAndTargetType(Bot* botCaster, int spellEffect, SpellTargetType targetType) {
|
std::list<BotSpell> Bot::GetBotSpellsForSpellEffectAndTargetType(Bot* botCaster, int spellEffect, SpellTargetType targetType) {
|
||||||
std::list<BotSpell> result;
|
std::list<BotSpell> result;
|
||||||
|
|
||||||
|
if (!botCaster) {
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
if (auto bot_owner = botCaster->GetBotOwner(); !bot_owner) {
|
if (auto bot_owner = botCaster->GetBotOwner(); !bot_owner) {
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (botCaster && botCaster->AI_HasSpells()) {
|
if (botCaster->AI_HasSpells()) {
|
||||||
std::vector<BotSpells_Struct> botSpellList = botCaster->AIBot_spells;
|
std::vector<BotSpells_Struct> botSpellList = botCaster->AIBot_spells;
|
||||||
|
|
||||||
for (int i = botSpellList.size() - 1; i >= 0; i--) {
|
for (int i = botSpellList.size() - 1; i >= 0; i--) {
|
||||||
@@ -1955,11 +1963,15 @@ std::list<BotSpell> Bot::GetBotSpellsForSpellEffectAndTargetType(Bot* botCaster,
|
|||||||
std::list<BotSpell> Bot::GetBotSpellsBySpellType(Bot* botCaster, uint32 spellType) {
|
std::list<BotSpell> Bot::GetBotSpellsBySpellType(Bot* botCaster, uint32 spellType) {
|
||||||
std::list<BotSpell> result;
|
std::list<BotSpell> result;
|
||||||
|
|
||||||
|
if (!botCaster) {
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
if (auto bot_owner = botCaster->GetBotOwner(); !bot_owner) {
|
if (auto bot_owner = botCaster->GetBotOwner(); !bot_owner) {
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (botCaster && botCaster->AI_HasSpells()) {
|
if (botCaster->AI_HasSpells()) {
|
||||||
std::vector<BotSpells_Struct> botSpellList = botCaster->AIBot_spells;
|
std::vector<BotSpells_Struct> botSpellList = botCaster->AIBot_spells;
|
||||||
|
|
||||||
for (int i = botSpellList.size() - 1; i >= 0; i--) {
|
for (int i = botSpellList.size() - 1; i >= 0; i--) {
|
||||||
@@ -2694,21 +2706,22 @@ BotSpell Bot::GetBestBotSpellForResistDebuff(Bot* botCaster, Mob *tar) {
|
|||||||
result.SpellIndex = 0;
|
result.SpellIndex = 0;
|
||||||
result.ManaCost = 0;
|
result.ManaCost = 0;
|
||||||
|
|
||||||
if (!tar)
|
if (!tar || !botCaster) {
|
||||||
return result;
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
int level_mod = (tar->GetLevel() - botCaster->GetLevel())* (tar->GetLevel() - botCaster->GetLevel()) / 2;
|
int level_mod = (tar->GetLevel() - botCaster->GetLevel())* (tar->GetLevel() - botCaster->GetLevel()) / 2;
|
||||||
if (tar->GetLevel() - botCaster->GetLevel() < 0)
|
if (tar->GetLevel() - botCaster->GetLevel() < 0) {
|
||||||
{
|
|
||||||
level_mod = -level_mod;
|
level_mod = -level_mod;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool needsMagicResistDebuff = (tar->GetMR() + level_mod) > 100;
|
bool needsMagicResistDebuff = (tar->GetMR() + level_mod) > 100;
|
||||||
bool needsColdResistDebuff = (tar->GetCR() + level_mod) > 100;
|
bool needsColdResistDebuff = (tar->GetCR() + level_mod) > 100;
|
||||||
bool needsFireResistDebuff = (tar->GetFR() + level_mod) > 100;
|
bool needsFireResistDebuff = (tar->GetFR() + level_mod) > 100;
|
||||||
bool needsPoisonResistDebuff = (tar->GetPR() + level_mod) > 100;
|
bool needsPoisonResistDebuff = (tar->GetPR() + level_mod) > 100;
|
||||||
bool needsDiseaseResistDebuff = (tar->GetDR() + level_mod) > 100;
|
bool needsDiseaseResistDebuff = (tar->GetDR() + level_mod) > 100;
|
||||||
|
|
||||||
if (botCaster && botCaster->AI_HasSpells()) {
|
if (botCaster->AI_HasSpells()) {
|
||||||
std::vector<BotSpells_Struct> botSpellList = botCaster->AIBot_spells;
|
std::vector<BotSpells_Struct> botSpellList = botCaster->AIBot_spells;
|
||||||
|
|
||||||
for (int i = botSpellList.size() - 1; i >= 0; i--) {
|
for (int i = botSpellList.size() - 1; i >= 0; i--) {
|
||||||
|
|||||||
+23
-19
@@ -4162,7 +4162,7 @@ bool Client::GroupFollow(Client* inviter) {
|
|||||||
if (iraid == raid) {
|
if (iraid == raid) {
|
||||||
//both in same raid
|
//both in same raid
|
||||||
uint32 ngid = raid->GetGroup(inviter->GetName());
|
uint32 ngid = raid->GetGroup(inviter->GetName());
|
||||||
if (raid->GroupCount(ngid) < 6) {
|
if (raid->GroupCount(ngid) < MAX_GROUP_MEMBERS) {
|
||||||
raid->MoveMember(GetName(), ngid);
|
raid->MoveMember(GetName(), ngid);
|
||||||
raid->SendGroupDisband(this);
|
raid->SendGroupDisband(this);
|
||||||
raid->GroupUpdate(ngid);
|
raid->GroupUpdate(ngid);
|
||||||
@@ -4183,7 +4183,7 @@ bool Client::GroupFollow(Client* inviter) {
|
|||||||
if (!GetXTargetAutoMgr()->empty())
|
if (!GetXTargetAutoMgr()->empty())
|
||||||
SetDirtyAutoHaters();
|
SetDirtyAutoHaters();
|
||||||
|
|
||||||
if (raid->GroupCount(groupToUse) < 6)
|
if (raid->GroupCount(groupToUse) < MAX_GROUP_MEMBERS)
|
||||||
{
|
{
|
||||||
raid->SendRaidCreate(this);
|
raid->SendRaidCreate(this);
|
||||||
raid->SendMakeLeaderPacketTo(raid->leadername, this);
|
raid->SendMakeLeaderPacketTo(raid->leadername, this);
|
||||||
@@ -4323,9 +4323,9 @@ bool Client::GroupFollow(Client* inviter) {
|
|||||||
uint16 Client::GetPrimarySkillValue()
|
uint16 Client::GetPrimarySkillValue()
|
||||||
{
|
{
|
||||||
EQ::skills::SkillType skill = EQ::skills::HIGHEST_SKILL; //because nullptr == 0, which is 1H Slashing, & we want it to return 0 from GetSkill
|
EQ::skills::SkillType skill = EQ::skills::HIGHEST_SKILL; //because nullptr == 0, which is 1H Slashing, & we want it to return 0 from GetSkill
|
||||||
bool equiped = m_inv.GetItem(EQ::invslot::slotPrimary);
|
bool equipped = m_inv.GetItem(EQ::invslot::slotPrimary);
|
||||||
|
|
||||||
if (!equiped)
|
if (!equipped)
|
||||||
skill = EQ::skills::SkillHandtoHand;
|
skill = EQ::skills::SkillHandtoHand;
|
||||||
|
|
||||||
else {
|
else {
|
||||||
@@ -7470,8 +7470,9 @@ const char* Client::GetClassPlural(Client* client) {
|
|||||||
|
|
||||||
void Client::SendWebLink(const char *website)
|
void Client::SendWebLink(const char *website)
|
||||||
{
|
{
|
||||||
|
if (website) {
|
||||||
size_t len = strlen(website) + 1;
|
size_t len = strlen(website) + 1;
|
||||||
if(website != 0 && len > 1)
|
if (len > 1)
|
||||||
{
|
{
|
||||||
auto outapp = new EQApplicationPacket(OP_Weblink, sizeof(Weblink_Struct) + len);
|
auto outapp = new EQApplicationPacket(OP_Weblink, sizeof(Weblink_Struct) + len);
|
||||||
Weblink_Struct* wl = (Weblink_Struct*)outapp->pBuffer;
|
Weblink_Struct* wl = (Weblink_Struct*)outapp->pBuffer;
|
||||||
@@ -7481,6 +7482,7 @@ void Client::SendWebLink(const char *website)
|
|||||||
FastQueuePacket(&outapp);
|
FastQueuePacket(&outapp);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void Client::SendMercPersonalInfo()
|
void Client::SendMercPersonalInfo()
|
||||||
{
|
{
|
||||||
@@ -10444,7 +10446,7 @@ void Client::SendToInstance(std::string instance_type, std::string zone_short_na
|
|||||||
uint16 instance_id = 0;
|
uint16 instance_id = 0;
|
||||||
|
|
||||||
if (current_bucket_value.length() > 0) {
|
if (current_bucket_value.length() > 0) {
|
||||||
instance_id = Strings::ToInt(current_bucket_value.c_str());
|
instance_id = Strings::ToInt(current_bucket_value);
|
||||||
} else {
|
} else {
|
||||||
if(!database.GetUnusedInstanceID(instance_id)) {
|
if(!database.GetUnusedInstanceID(instance_id)) {
|
||||||
Message(Chat::White, "Server was unable to find a free instance id.");
|
Message(Chat::White, "Server was unable to find a free instance id.");
|
||||||
@@ -10710,11 +10712,11 @@ void Client::ApplyWeaponsStance()
|
|||||||
FindBuff(spellbonuses.WeaponStance[WEAPON_STANCE_TYPE_2H])) {
|
FindBuff(spellbonuses.WeaponStance[WEAPON_STANCE_TYPE_2H])) {
|
||||||
BuffFadeBySpellID(spellbonuses.WeaponStance[WEAPON_STANCE_TYPE_2H]);
|
BuffFadeBySpellID(spellbonuses.WeaponStance[WEAPON_STANCE_TYPE_2H]);
|
||||||
}
|
}
|
||||||
else if (!HasShieldEquiped() && IsBuffSpell(spellbonuses.WeaponStance[WEAPON_STANCE_TYPE_SHIELD]) &&
|
else if (!HasShieldEquipped() && IsBuffSpell(spellbonuses.WeaponStance[WEAPON_STANCE_TYPE_SHIELD]) &&
|
||||||
FindBuff(spellbonuses.WeaponStance[WEAPON_STANCE_TYPE_SHIELD])) {
|
FindBuff(spellbonuses.WeaponStance[WEAPON_STANCE_TYPE_SHIELD])) {
|
||||||
BuffFadeBySpellID(spellbonuses.WeaponStance[WEAPON_STANCE_TYPE_SHIELD]);
|
BuffFadeBySpellID(spellbonuses.WeaponStance[WEAPON_STANCE_TYPE_SHIELD]);
|
||||||
}
|
}
|
||||||
else if (!HasDualWeaponsEquiped() &&
|
else if (!HasDualWeaponsEquipped() &&
|
||||||
IsBuffSpell(spellbonuses.WeaponStance[WEAPON_STANCE_TYPE_DUAL_WIELD]) &&
|
IsBuffSpell(spellbonuses.WeaponStance[WEAPON_STANCE_TYPE_DUAL_WIELD]) &&
|
||||||
FindBuff(spellbonuses.WeaponStance[WEAPON_STANCE_TYPE_DUAL_WIELD])) {
|
FindBuff(spellbonuses.WeaponStance[WEAPON_STANCE_TYPE_DUAL_WIELD])) {
|
||||||
BuffFadeBySpellID(spellbonuses.WeaponStance[WEAPON_STANCE_TYPE_DUAL_WIELD]);
|
BuffFadeBySpellID(spellbonuses.WeaponStance[WEAPON_STANCE_TYPE_DUAL_WIELD]);
|
||||||
@@ -10726,14 +10728,14 @@ void Client::ApplyWeaponsStance()
|
|||||||
}
|
}
|
||||||
weaponstance.spellbonus_buff_spell_id = spellbonuses.WeaponStance[WEAPON_STANCE_TYPE_2H];
|
weaponstance.spellbonus_buff_spell_id = spellbonuses.WeaponStance[WEAPON_STANCE_TYPE_2H];
|
||||||
}
|
}
|
||||||
else if (HasShieldEquiped() && IsBuffSpell(spellbonuses.WeaponStance[WEAPON_STANCE_TYPE_SHIELD])) {
|
else if (HasShieldEquipped() && IsBuffSpell(spellbonuses.WeaponStance[WEAPON_STANCE_TYPE_SHIELD])) {
|
||||||
|
|
||||||
if (!FindBuff(spellbonuses.WeaponStance[WEAPON_STANCE_TYPE_SHIELD])) {
|
if (!FindBuff(spellbonuses.WeaponStance[WEAPON_STANCE_TYPE_SHIELD])) {
|
||||||
SpellOnTarget(spellbonuses.WeaponStance[WEAPON_STANCE_TYPE_SHIELD], this);
|
SpellOnTarget(spellbonuses.WeaponStance[WEAPON_STANCE_TYPE_SHIELD], this);
|
||||||
}
|
}
|
||||||
weaponstance.spellbonus_buff_spell_id = spellbonuses.WeaponStance[WEAPON_STANCE_TYPE_SHIELD];
|
weaponstance.spellbonus_buff_spell_id = spellbonuses.WeaponStance[WEAPON_STANCE_TYPE_SHIELD];
|
||||||
}
|
}
|
||||||
else if (HasDualWeaponsEquiped() && IsBuffSpell(spellbonuses.WeaponStance[WEAPON_STANCE_TYPE_DUAL_WIELD])) {
|
else if (HasDualWeaponsEquipped() && IsBuffSpell(spellbonuses.WeaponStance[WEAPON_STANCE_TYPE_DUAL_WIELD])) {
|
||||||
|
|
||||||
if (!FindBuff(spellbonuses.WeaponStance[WEAPON_STANCE_TYPE_DUAL_WIELD])) {
|
if (!FindBuff(spellbonuses.WeaponStance[WEAPON_STANCE_TYPE_DUAL_WIELD])) {
|
||||||
SpellOnTarget(spellbonuses.WeaponStance[WEAPON_STANCE_TYPE_DUAL_WIELD], this);
|
SpellOnTarget(spellbonuses.WeaponStance[WEAPON_STANCE_TYPE_DUAL_WIELD], this);
|
||||||
@@ -10776,11 +10778,11 @@ void Client::ApplyWeaponsStance()
|
|||||||
FindBuff(itembonuses.WeaponStance[WEAPON_STANCE_TYPE_2H])) {
|
FindBuff(itembonuses.WeaponStance[WEAPON_STANCE_TYPE_2H])) {
|
||||||
BuffFadeBySpellID(itembonuses.WeaponStance[WEAPON_STANCE_TYPE_2H]);
|
BuffFadeBySpellID(itembonuses.WeaponStance[WEAPON_STANCE_TYPE_2H]);
|
||||||
}
|
}
|
||||||
else if (!HasShieldEquiped() && IsBuffSpell(itembonuses.WeaponStance[WEAPON_STANCE_TYPE_SHIELD]) &&
|
else if (!HasShieldEquipped() && IsBuffSpell(itembonuses.WeaponStance[WEAPON_STANCE_TYPE_SHIELD]) &&
|
||||||
FindBuff(itembonuses.WeaponStance[WEAPON_STANCE_TYPE_SHIELD])) {
|
FindBuff(itembonuses.WeaponStance[WEAPON_STANCE_TYPE_SHIELD])) {
|
||||||
BuffFadeBySpellID(itembonuses.WeaponStance[WEAPON_STANCE_TYPE_SHIELD]);
|
BuffFadeBySpellID(itembonuses.WeaponStance[WEAPON_STANCE_TYPE_SHIELD]);
|
||||||
}
|
}
|
||||||
else if (!HasDualWeaponsEquiped() && IsBuffSpell(itembonuses.WeaponStance[WEAPON_STANCE_TYPE_DUAL_WIELD]) &&
|
else if (!HasDualWeaponsEquipped() && IsBuffSpell(itembonuses.WeaponStance[WEAPON_STANCE_TYPE_DUAL_WIELD]) &&
|
||||||
FindBuff(itembonuses.WeaponStance[WEAPON_STANCE_TYPE_DUAL_WIELD])) {
|
FindBuff(itembonuses.WeaponStance[WEAPON_STANCE_TYPE_DUAL_WIELD])) {
|
||||||
BuffFadeBySpellID(itembonuses.WeaponStance[WEAPON_STANCE_TYPE_DUAL_WIELD]);
|
BuffFadeBySpellID(itembonuses.WeaponStance[WEAPON_STANCE_TYPE_DUAL_WIELD]);
|
||||||
}
|
}
|
||||||
@@ -10793,14 +10795,14 @@ void Client::ApplyWeaponsStance()
|
|||||||
}
|
}
|
||||||
weaponstance.itembonus_buff_spell_id = itembonuses.WeaponStance[WEAPON_STANCE_TYPE_2H];
|
weaponstance.itembonus_buff_spell_id = itembonuses.WeaponStance[WEAPON_STANCE_TYPE_2H];
|
||||||
}
|
}
|
||||||
else if (HasShieldEquiped() && IsBuffSpell(itembonuses.WeaponStance[WEAPON_STANCE_TYPE_SHIELD])) {
|
else if (HasShieldEquipped() && IsBuffSpell(itembonuses.WeaponStance[WEAPON_STANCE_TYPE_SHIELD])) {
|
||||||
|
|
||||||
if (!FindBuff(itembonuses.WeaponStance[WEAPON_STANCE_TYPE_SHIELD])) {
|
if (!FindBuff(itembonuses.WeaponStance[WEAPON_STANCE_TYPE_SHIELD])) {
|
||||||
SpellOnTarget(itembonuses.WeaponStance[WEAPON_STANCE_TYPE_SHIELD], this);
|
SpellOnTarget(itembonuses.WeaponStance[WEAPON_STANCE_TYPE_SHIELD], this);
|
||||||
}
|
}
|
||||||
weaponstance.itembonus_buff_spell_id = itembonuses.WeaponStance[WEAPON_STANCE_TYPE_SHIELD];
|
weaponstance.itembonus_buff_spell_id = itembonuses.WeaponStance[WEAPON_STANCE_TYPE_SHIELD];
|
||||||
}
|
}
|
||||||
else if (HasDualWeaponsEquiped() && IsBuffSpell(itembonuses.WeaponStance[WEAPON_STANCE_TYPE_DUAL_WIELD])) {
|
else if (HasDualWeaponsEquipped() && IsBuffSpell(itembonuses.WeaponStance[WEAPON_STANCE_TYPE_DUAL_WIELD])) {
|
||||||
if (!FindBuff(itembonuses.WeaponStance[WEAPON_STANCE_TYPE_DUAL_WIELD])) {
|
if (!FindBuff(itembonuses.WeaponStance[WEAPON_STANCE_TYPE_DUAL_WIELD])) {
|
||||||
SpellOnTarget(itembonuses.WeaponStance[WEAPON_STANCE_TYPE_DUAL_WIELD], this);
|
SpellOnTarget(itembonuses.WeaponStance[WEAPON_STANCE_TYPE_DUAL_WIELD], this);
|
||||||
}
|
}
|
||||||
@@ -10833,12 +10835,12 @@ void Client::ApplyWeaponsStance()
|
|||||||
BuffFadeBySpellID(aabonuses.WeaponStance[WEAPON_STANCE_TYPE_2H]);
|
BuffFadeBySpellID(aabonuses.WeaponStance[WEAPON_STANCE_TYPE_2H]);
|
||||||
}
|
}
|
||||||
|
|
||||||
else if (!HasShieldEquiped() && IsBuffSpell(aabonuses.WeaponStance[WEAPON_STANCE_TYPE_SHIELD]) &&
|
else if (!HasShieldEquipped() && IsBuffSpell(aabonuses.WeaponStance[WEAPON_STANCE_TYPE_SHIELD]) &&
|
||||||
FindBuff(aabonuses.WeaponStance[WEAPON_STANCE_TYPE_SHIELD])) {
|
FindBuff(aabonuses.WeaponStance[WEAPON_STANCE_TYPE_SHIELD])) {
|
||||||
BuffFadeBySpellID(aabonuses.WeaponStance[WEAPON_STANCE_TYPE_SHIELD]);
|
BuffFadeBySpellID(aabonuses.WeaponStance[WEAPON_STANCE_TYPE_SHIELD]);
|
||||||
}
|
}
|
||||||
|
|
||||||
else if (!HasDualWeaponsEquiped() && IsBuffSpell(aabonuses.WeaponStance[WEAPON_STANCE_TYPE_DUAL_WIELD]) &&
|
else if (!HasDualWeaponsEquipped() && IsBuffSpell(aabonuses.WeaponStance[WEAPON_STANCE_TYPE_DUAL_WIELD]) &&
|
||||||
FindBuff(aabonuses.WeaponStance[WEAPON_STANCE_TYPE_DUAL_WIELD])) {
|
FindBuff(aabonuses.WeaponStance[WEAPON_STANCE_TYPE_DUAL_WIELD])) {
|
||||||
BuffFadeBySpellID(aabonuses.WeaponStance[WEAPON_STANCE_TYPE_DUAL_WIELD]);
|
BuffFadeBySpellID(aabonuses.WeaponStance[WEAPON_STANCE_TYPE_DUAL_WIELD]);
|
||||||
}
|
}
|
||||||
@@ -10851,14 +10853,14 @@ void Client::ApplyWeaponsStance()
|
|||||||
weaponstance.aabonus_buff_spell_id = aabonuses.WeaponStance[WEAPON_STANCE_TYPE_2H];
|
weaponstance.aabonus_buff_spell_id = aabonuses.WeaponStance[WEAPON_STANCE_TYPE_2H];
|
||||||
}
|
}
|
||||||
|
|
||||||
else if (HasShieldEquiped() && IsBuffSpell(aabonuses.WeaponStance[WEAPON_STANCE_TYPE_SHIELD])) {
|
else if (HasShieldEquipped() && IsBuffSpell(aabonuses.WeaponStance[WEAPON_STANCE_TYPE_SHIELD])) {
|
||||||
if (!FindBuff(aabonuses.WeaponStance[WEAPON_STANCE_TYPE_SHIELD])) {
|
if (!FindBuff(aabonuses.WeaponStance[WEAPON_STANCE_TYPE_SHIELD])) {
|
||||||
SpellOnTarget(aabonuses.WeaponStance[WEAPON_STANCE_TYPE_SHIELD], this);
|
SpellOnTarget(aabonuses.WeaponStance[WEAPON_STANCE_TYPE_SHIELD], this);
|
||||||
}
|
}
|
||||||
weaponstance.aabonus_buff_spell_id = aabonuses.WeaponStance[WEAPON_STANCE_TYPE_SHIELD];
|
weaponstance.aabonus_buff_spell_id = aabonuses.WeaponStance[WEAPON_STANCE_TYPE_SHIELD];
|
||||||
}
|
}
|
||||||
|
|
||||||
else if (HasDualWeaponsEquiped() && IsBuffSpell(aabonuses.WeaponStance[WEAPON_STANCE_TYPE_DUAL_WIELD])) {
|
else if (HasDualWeaponsEquipped() && IsBuffSpell(aabonuses.WeaponStance[WEAPON_STANCE_TYPE_DUAL_WIELD])) {
|
||||||
|
|
||||||
if (!FindBuff(aabonuses.WeaponStance[WEAPON_STANCE_TYPE_DUAL_WIELD])) {
|
if (!FindBuff(aabonuses.WeaponStance[WEAPON_STANCE_TYPE_DUAL_WIELD])) {
|
||||||
SpellOnTarget(aabonuses.WeaponStance[WEAPON_STANCE_TYPE_DUAL_WIELD], this);
|
SpellOnTarget(aabonuses.WeaponStance[WEAPON_STANCE_TYPE_DUAL_WIELD], this);
|
||||||
@@ -11734,8 +11736,9 @@ std::vector<Mob*> Client::GetApplySpellList(
|
|||||||
|
|
||||||
if (apply_type == ApplySpellType::Raid && IsRaidGrouped()) {
|
if (apply_type == ApplySpellType::Raid && IsRaidGrouped()) {
|
||||||
auto* r = GetRaid();
|
auto* r = GetRaid();
|
||||||
|
if (r) {
|
||||||
auto group_id = r->GetGroup(this);
|
auto group_id = r->GetGroup(this);
|
||||||
if (r && EQ::ValueWithin(group_id, 0, (MAX_RAID_GROUPS - 1))) {
|
if (EQ::ValueWithin(group_id, 0, (MAX_RAID_GROUPS - 1))) {
|
||||||
for (const auto& m : r->members) {
|
for (const auto& m : r->members) {
|
||||||
if (m.member && m.member->IsClient() && (!is_raid_group_only || r->GetGroup(m.member) == group_id)) {
|
if (m.member && m.member->IsClient() && (!is_raid_group_only || r->GetGroup(m.member) == group_id)) {
|
||||||
l.push_back(m.member);
|
l.push_back(m.member);
|
||||||
@@ -11753,6 +11756,7 @@ std::vector<Mob*> Client::GetApplySpellList(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
} else if (apply_type == ApplySpellType::Group && IsGrouped()) {
|
} else if (apply_type == ApplySpellType::Group && IsGrouped()) {
|
||||||
auto* g = GetGroup();
|
auto* g = GetGroup();
|
||||||
if (g) {
|
if (g) {
|
||||||
|
|||||||
+4
-4
@@ -203,8 +203,8 @@ enum eInnateSkill {
|
|||||||
InnateDisabled = 255
|
InnateDisabled = 255
|
||||||
};
|
};
|
||||||
|
|
||||||
const std::string DIAWIND_RESPONSE_ONE_KEY = "diawind_npc_response_one";
|
inline const std::string DIAWIND_RESPONSE_ONE_KEY = "diawind_npc_response_one";
|
||||||
const std::string DIAWIND_RESPONSE_TWO_KEY = "diawind_npc_response_two";
|
inline const std::string DIAWIND_RESPONSE_TWO_KEY = "diawind_npc_response_two";
|
||||||
const uint32 POPUPID_DIAWIND_ONE = 99999;
|
const uint32 POPUPID_DIAWIND_ONE = 99999;
|
||||||
const uint32 POPUPID_DIAWIND_TWO = 100000;
|
const uint32 POPUPID_DIAWIND_TWO = 100000;
|
||||||
const uint32 POPUPID_UPDATE_SHOWSTATSWINDOW = 1000000;
|
const uint32 POPUPID_UPDATE_SHOWSTATSWINDOW = 1000000;
|
||||||
@@ -588,7 +588,7 @@ public:
|
|||||||
//This calculates total Attack Rating to match very close to what the client should show
|
//This calculates total Attack Rating to match very close to what the client should show
|
||||||
uint32 GetTotalATK();
|
uint32 GetTotalATK();
|
||||||
uint32 GetATKRating();
|
uint32 GetATKRating();
|
||||||
//This gets the skill value of the item type equiped in the Primary Slot
|
//This gets the skill value of the item type equipped in the Primary Slot
|
||||||
uint16 GetPrimarySkillValue();
|
uint16 GetPrimarySkillValue();
|
||||||
|
|
||||||
bool Flurry();
|
bool Flurry();
|
||||||
@@ -2033,6 +2033,7 @@ public:
|
|||||||
void SetBotSpawnLimit(int new_spawn_limit, uint8 class_id = NO_CLASS);
|
void SetBotSpawnLimit(int new_spawn_limit, uint8 class_id = NO_CLASS);
|
||||||
|
|
||||||
void CampAllBots(uint8 class_id = NO_CLASS);
|
void CampAllBots(uint8 class_id = NO_CLASS);
|
||||||
|
void SpawnRaidBotsOnConnect(Raid* raid);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
bool bot_owner_options[_booCount];
|
bool bot_owner_options[_booCount];
|
||||||
@@ -2042,7 +2043,6 @@ private:
|
|||||||
bool CanTradeFVNoDropItem();
|
bool CanTradeFVNoDropItem();
|
||||||
void SendMobPositions();
|
void SendMobPositions();
|
||||||
void PlayerTradeEventLog(Trade *t, Trade *t2);
|
void PlayerTradeEventLog(Trade *t, Trade *t2);
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
+10
-30
@@ -607,28 +607,8 @@ void Client::CompleteConnect()
|
|||||||
if (raid) {
|
if (raid) {
|
||||||
SetRaidGrouped(true);
|
SetRaidGrouped(true);
|
||||||
raid->LearnMembers();
|
raid->LearnMembers();
|
||||||
std::list<BotsAvailableList> bots_list;
|
if (RuleB(Bots, Enabled)) {
|
||||||
database.botdb.LoadBotsList(this->CharacterID(), bots_list);
|
SpawnRaidBotsOnConnect(raid);
|
||||||
std::vector<RaidMember> r_members = raid->GetMembers();
|
|
||||||
for (const RaidMember& iter : r_members) {
|
|
||||||
if (iter.member_name) {
|
|
||||||
for (const BotsAvailableList& b_iter : bots_list)
|
|
||||||
{
|
|
||||||
if (strcmp(iter.member_name, b_iter.Name) == 0)
|
|
||||||
{
|
|
||||||
char buffer[71] = "^spawn ";
|
|
||||||
strcat(buffer, iter.member_name);
|
|
||||||
bot_command_real_dispatch(this, buffer);
|
|
||||||
Bot* b = entity_list.GetBotByBotName(iter.member_name);
|
|
||||||
if (b)
|
|
||||||
{
|
|
||||||
b->SetRaidGrouped(true);
|
|
||||||
b->p_raid_instance = raid;
|
|
||||||
//b->SetFollowID(this->GetID());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
raid->VerifyRaid();
|
raid->VerifyRaid();
|
||||||
raid->GetRaidDetails();
|
raid->GetRaidDetails();
|
||||||
@@ -867,7 +847,7 @@ void Client::CompleteConnect()
|
|||||||
CalcItemScale();
|
CalcItemScale();
|
||||||
DoItemEnterZone();
|
DoItemEnterZone();
|
||||||
|
|
||||||
if (zone->GetZoneID() == RuleI(World, GuildBankZoneID) && GuildBanks)
|
if (zone->GetZoneID() == Zones::GUILDHALL && GuildBanks)
|
||||||
GuildBanks->SendGuildBank(this);
|
GuildBanks->SendGuildBank(this);
|
||||||
|
|
||||||
if (ClientVersion() >= EQ::versions::ClientVersion::SoD)
|
if (ClientVersion() >= EQ::versions::ClientVersion::SoD)
|
||||||
@@ -1426,7 +1406,7 @@ void Client::Handle_Connect_OP_ZoneEntry(const EQApplicationPacket *app)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
m_pp.guildrank = rank;
|
m_pp.guildrank = rank;
|
||||||
if (zone->GetZoneID() == RuleI(World, GuildBankZoneID))
|
if (zone->GetZoneID() == Zones::GUILDHALL)
|
||||||
GuildBanker = (guild_mgr.IsGuildLeader(GuildID(), CharacterID()) || guild_mgr.GetBankerFlag(CharacterID()));
|
GuildBanker = (guild_mgr.IsGuildLeader(GuildID(), CharacterID()) || guild_mgr.GetBankerFlag(CharacterID()));
|
||||||
}
|
}
|
||||||
m_pp.guildbanker = GuildBanker;
|
m_pp.guildbanker = GuildBanker;
|
||||||
@@ -7446,7 +7426,7 @@ void Client::Handle_OP_GuildBank(const EQApplicationPacket *app)
|
|||||||
if (!GuildBanks)
|
if (!GuildBanks)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if ((int)zone->GetZoneID() != RuleI(World, GuildBankZoneID))
|
if (zone->GetZoneID() != Zones::GUILDHALL)
|
||||||
{
|
{
|
||||||
Message(Chat::Red, "The Guild Bank is not available in this zone.");
|
Message(Chat::Red, "The Guild Bank is not available in this zone.");
|
||||||
|
|
||||||
@@ -7796,7 +7776,7 @@ void Client::Handle_OP_GuildCreate(const EQApplicationPacket *app)
|
|||||||
{
|
{
|
||||||
Message(Chat::Yellow, "You are now the leader of %s", GuildName);
|
Message(Chat::Yellow, "You are now the leader of %s", GuildName);
|
||||||
|
|
||||||
if (zone->GetZoneID() == RuleI(World, GuildBankZoneID) && GuildBanks)
|
if (zone->GetZoneID() == Zones::GUILDHALL && GuildBanks)
|
||||||
GuildBanks->SendGuildBank(this);
|
GuildBanks->SendGuildBank(this);
|
||||||
SendGuildRanks();
|
SendGuildRanks();
|
||||||
}
|
}
|
||||||
@@ -8126,7 +8106,7 @@ void Client::Handle_OP_GuildInviteAccept(const EQApplicationPacket *app)
|
|||||||
Message(Chat::Red, "There was an error during the invite, DB may now be inconsistent.");
|
Message(Chat::Red, "There was an error during the invite, DB may now be inconsistent.");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (zone->GetZoneID() == RuleI(World, GuildBankZoneID) && GuildBanks)
|
if (zone->GetZoneID() == Zones::GUILDHALL && GuildBanks)
|
||||||
GuildBanks->SendGuildBank(this);
|
GuildBanks->SendGuildBank(this);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -11795,13 +11775,13 @@ void Client::Handle_OP_RaidCommand(const EQApplicationPacket* app)
|
|||||||
Bot* player_to_invite = nullptr;
|
Bot* player_to_invite = nullptr;
|
||||||
|
|
||||||
if (RuleB(Bots, Enabled) && entity_list.GetBotByBotName(raid_command_packet->player_name)) {
|
if (RuleB(Bots, Enabled) && entity_list.GetBotByBotName(raid_command_packet->player_name)) {
|
||||||
Bot* player_to_invite = entity_list.GetBotByBotName(raid_command_packet->player_name);
|
|
||||||
Group* player_to_invite_group = player_to_invite->GetGroup();
|
|
||||||
|
|
||||||
if (!player_to_invite) {
|
if (!player_to_invite) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Bot* player_to_invite = entity_list.GetBotByBotName(raid_command_packet->player_name);
|
||||||
|
Group* player_to_invite_group = player_to_invite->GetGroup();
|
||||||
|
|
||||||
if (player_to_invite_group && player_to_invite_group->IsGroupMember(this)) {
|
if (player_to_invite_group && player_to_invite_group->IsGroupMember(this)) {
|
||||||
MessageString(Chat::Red, ALREADY_IN_PARTY);
|
MessageString(Chat::Red, ALREADY_IN_PARTY);
|
||||||
break;
|
break;
|
||||||
|
|||||||
+21
-20
@@ -689,23 +689,18 @@ bool Client::Process() {
|
|||||||
|
|
||||||
/* Just a set of actions preformed all over in Client::Process */
|
/* Just a set of actions preformed all over in Client::Process */
|
||||||
void Client::OnDisconnect(bool hard_disconnect) {
|
void Client::OnDisconnect(bool hard_disconnect) {
|
||||||
if(hard_disconnect)
|
if (hard_disconnect) {
|
||||||
{
|
|
||||||
LeaveGroup();
|
LeaveGroup();
|
||||||
if (GetMerc())
|
|
||||||
{
|
if (GetMerc()) {
|
||||||
GetMerc()->Save();
|
GetMerc()->Save();
|
||||||
GetMerc()->Depop();
|
GetMerc()->Depop();
|
||||||
}
|
}
|
||||||
Raid *MyRaid = entity_list.GetRaidByClient(this);
|
|
||||||
|
|
||||||
if (MyRaid)
|
auto* r = entity_list.GetRaidByClient(this);
|
||||||
MyRaid->MemberZoned(this);
|
|
||||||
|
|
||||||
RecordPlayerEventLog(PlayerEvent::WENT_OFFLINE, PlayerEvent::EmptyEvent{});
|
if (r) {
|
||||||
|
r->MemberZoned(this);
|
||||||
if (parse->PlayerHasQuestSub(EVENT_DISCONNECT)) {
|
|
||||||
parse->EventPlayer(EVENT_DISCONNECT, this, "", 0);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* QS: PlayerLogConnectDisconnect */
|
/* QS: PlayerLogConnectDisconnect */
|
||||||
@@ -715,35 +710,40 @@ void Client::OnDisconnect(bool hard_disconnect) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!bZoning)
|
if (!bZoning) {
|
||||||
{
|
|
||||||
SetDynamicZoneMemberStatus(DynamicZoneMemberStatus::Offline);
|
SetDynamicZoneMemberStatus(DynamicZoneMemberStatus::Offline);
|
||||||
}
|
}
|
||||||
|
|
||||||
RemoveAllAuras();
|
RemoveAllAuras();
|
||||||
|
|
||||||
Mob *Other = trade->With();
|
auto* o = trade->With();
|
||||||
if(Other)
|
if (o) {
|
||||||
{
|
|
||||||
LogTrading("Client disconnected during a trade. Returning their items");
|
LogTrading("Client disconnected during a trade. Returning their items");
|
||||||
FinishTrade(this);
|
FinishTrade(this);
|
||||||
|
|
||||||
if(Other->IsClient())
|
if (o->IsClient()) {
|
||||||
Other->CastToClient()->FinishTrade(Other);
|
o->CastToClient()->FinishTrade(o);
|
||||||
|
}
|
||||||
|
|
||||||
/* Reset both sides of the trade */
|
/* Reset both sides of the trade */
|
||||||
trade->Reset();
|
trade->Reset();
|
||||||
Other->trade->Reset();
|
o->trade->Reset();
|
||||||
}
|
}
|
||||||
|
|
||||||
database.SetFirstLogon(CharacterID(), 0); //We change firstlogon status regardless of if a player logs out to zone or not, because we only want to trigger it on their first login from world.
|
database.SetFirstLogon(CharacterID(), 0); //We change firstlogon status regardless of if a player logs out to zone or not, because we only want to trigger it on their first login from world.
|
||||||
|
|
||||||
/* Remove ourself from all proximities */
|
/* Remove from all proximities */
|
||||||
ClearAllProximities();
|
ClearAllProximities();
|
||||||
|
|
||||||
auto outapp = new EQApplicationPacket(OP_LogoutReply);
|
auto outapp = new EQApplicationPacket(OP_LogoutReply);
|
||||||
FastQueuePacket(&outapp);
|
FastQueuePacket(&outapp);
|
||||||
|
|
||||||
|
RecordPlayerEventLog(PlayerEvent::WENT_OFFLINE, PlayerEvent::EmptyEvent{});
|
||||||
|
|
||||||
|
if (parse->PlayerHasQuestSub(EVENT_DISCONNECT)) {
|
||||||
|
parse->EventPlayer(EVENT_DISCONNECT, this, "", 0);
|
||||||
|
}
|
||||||
|
|
||||||
Disconnect();
|
Disconnect();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1145,6 +1145,7 @@ void Client::OPMemorizeSpell(const EQApplicationPacket* app)
|
|||||||
const auto* item = inst->GetItem();
|
const auto* item = inst->GetItem();
|
||||||
|
|
||||||
if (
|
if (
|
||||||
|
item &&
|
||||||
RuleB(Character, RestrictSpellScribing) &&
|
RuleB(Character, RestrictSpellScribing) &&
|
||||||
!item->IsEquipable(GetRace(), GetClass())
|
!item->IsEquipable(GetRace(), GetClass())
|
||||||
) {
|
) {
|
||||||
|
|||||||
+1
-2
@@ -392,8 +392,7 @@ Corpse::Corpse(Client* client, int32 in_rezexp) : Mob (
|
|||||||
|
|
||||||
/* Check Rule to see if we can leave corpses */
|
/* Check Rule to see if we can leave corpses */
|
||||||
if (
|
if (
|
||||||
!RuleB(Character, LeaveNakedCorpses) ||
|
(!RuleB(Character, LeaveNakedCorpses) || RuleB(Character, LeaveCorpses)) &&
|
||||||
RuleB(Character, LeaveCorpses) &&
|
|
||||||
GetLevel() >= RuleI(Character, DeathItemLossLevel)
|
GetLevel() >= RuleI(Character, DeathItemLossLevel)
|
||||||
) {
|
) {
|
||||||
// cash
|
// cash
|
||||||
|
|||||||
@@ -23,7 +23,7 @@ void DataBucket::SetData(const std::string& bucket_key, const std::string& bucke
|
|||||||
if (isalpha(expires_time[0]) || isalpha(expires_time[expires_time.length() - 1])) {
|
if (isalpha(expires_time[0]) || isalpha(expires_time[expires_time.length() - 1])) {
|
||||||
expires_time_unix = (long long) std::time(nullptr) + Strings::TimeToSeconds(expires_time);
|
expires_time_unix = (long long) std::time(nullptr) + Strings::TimeToSeconds(expires_time);
|
||||||
} else {
|
} else {
|
||||||
expires_time_unix = (long long) std::time(nullptr) + Strings::ToInt(expires_time.c_str());
|
expires_time_unix = (long long) std::time(nullptr) + Strings::ToInt(expires_time);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -199,7 +199,7 @@ void DialogueWindow::Render(Client *c, std::string markdown)
|
|||||||
|
|
||||||
// set the popup id
|
// set the popup id
|
||||||
if (!popupid.empty()) {
|
if (!popupid.empty()) {
|
||||||
popup_id = (Strings::IsNumber(popupid) ? Strings::ToInt(popupid.c_str()) : 0);
|
popup_id = (Strings::IsNumber(popupid) ? Strings::ToInt(popupid) : 0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -231,7 +231,7 @@ void DialogueWindow::Render(Client *c, std::string markdown)
|
|||||||
Strings::FindReplace(output, fmt::format("secondresponseid:{}", secondresponseid), "");
|
Strings::FindReplace(output, fmt::format("secondresponseid:{}", secondresponseid), "");
|
||||||
|
|
||||||
if (!secondresponseid.empty()) {
|
if (!secondresponseid.empty()) {
|
||||||
negative_id = (Strings::IsNumber(secondresponseid) ? Strings::ToInt(secondresponseid.c_str()) : 0);
|
negative_id = (Strings::IsNumber(secondresponseid) ? Strings::ToInt(secondresponseid) : 0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -410,7 +410,7 @@ void DialogueWindow::Render(Client *c, std::string markdown)
|
|||||||
|
|
||||||
// click response
|
// click response
|
||||||
// window type response
|
// window type response
|
||||||
uint32 window_type = (Strings::IsNumber(wintype) ? Strings::ToInt(wintype.c_str()) : 0);
|
uint32 window_type = (Strings::IsNumber(wintype) ? Strings::ToInt(wintype) : 0);
|
||||||
std::string click_response_button = (window_type == 1 ? "Yes" : "OK");
|
std::string click_response_button = (window_type == 1 ? "Yes" : "OK");
|
||||||
std::string click_response = fmt::format(
|
std::string click_response = fmt::format(
|
||||||
"<c \"#F07F00\">Click [{}] to continue...</c>",
|
"<c \"#F07F00\">Click [{}] to continue...</c>",
|
||||||
|
|||||||
+1
-1
@@ -222,7 +222,7 @@ void Doors::HandleClick(Client *sender, uint8 trigger)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (m_dz_switch_id != 0) {
|
if (sender && m_dz_switch_id != 0) {
|
||||||
sender->UpdateTasksOnTouchSwitch(m_dz_switch_id);
|
sender->UpdateTasksOnTouchSwitch(m_dz_switch_id);
|
||||||
if (sender->TryMovePCDynamicZoneSwitch(m_dz_switch_id)) {
|
if (sender->TryMovePCDynamicZoneSwitch(m_dz_switch_id)) {
|
||||||
safe_delete(outapp);
|
safe_delete(outapp);
|
||||||
|
|||||||
+3
-2
@@ -520,8 +520,6 @@ bool PerlembParser::SpellHasQuestSub(uint32 spell_id, QuestEventID evt)
|
|||||||
|
|
||||||
bool PerlembParser::ItemHasQuestSub(EQ::ItemInstance *itm, QuestEventID evt)
|
bool PerlembParser::ItemHasQuestSub(EQ::ItemInstance *itm, QuestEventID evt)
|
||||||
{
|
{
|
||||||
std::stringstream package_name;
|
|
||||||
package_name << "qst_item_" << itm->GetID();
|
|
||||||
|
|
||||||
if (!perl) {
|
if (!perl) {
|
||||||
return false;
|
return false;
|
||||||
@@ -535,6 +533,9 @@ bool PerlembParser::ItemHasQuestSub(EQ::ItemInstance *itm, QuestEventID evt)
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::stringstream package_name;
|
||||||
|
package_name << "qst_item_" << itm->GetID();
|
||||||
|
|
||||||
const char *subname = QuestEventSubroutines[evt];
|
const char *subname = QuestEventSubroutines[evt];
|
||||||
|
|
||||||
auto iter = item_quest_status_.find(itm->GetID());
|
auto iter = item_quest_status_.find(itm->GetID());
|
||||||
|
|||||||
@@ -55,23 +55,23 @@ void DoorManipulation::CommandHandler(Client *c, const Seperator *sep)
|
|||||||
float set_size = 0.0f;
|
float set_size = 0.0f;
|
||||||
|
|
||||||
if (arg2 == move_x_action) {
|
if (arg2 == move_x_action) {
|
||||||
x_move = Strings::ToFloat(arg3.c_str());
|
x_move = Strings::ToFloat(arg3);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (arg2 == move_y_action) {
|
if (arg2 == move_y_action) {
|
||||||
y_move = Strings::ToFloat(arg3.c_str());
|
y_move = Strings::ToFloat(arg3);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (arg2 == move_z_action) {
|
if (arg2 == move_z_action) {
|
||||||
z_move = Strings::ToFloat(arg3.c_str());
|
z_move = Strings::ToFloat(arg3);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (arg2 == move_h_action) {
|
if (arg2 == move_h_action) {
|
||||||
h_move = Strings::ToFloat(arg3.c_str());
|
h_move = Strings::ToFloat(arg3);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (arg2 == set_size_action) {
|
if (arg2 == set_size_action) {
|
||||||
set_size = Strings::ToFloat(arg3.c_str());
|
set_size = Strings::ToFloat(arg3);
|
||||||
}
|
}
|
||||||
|
|
||||||
door->SetLocation(
|
door->SetLocation(
|
||||||
@@ -370,7 +370,7 @@ void DoorManipulation::CommandHandler(Client *c, const Seperator *sep)
|
|||||||
if (arg1 == "opentype" && !arg2.empty() && Strings::IsNumber(arg2)) {
|
if (arg1 == "opentype" && !arg2.empty() && Strings::IsNumber(arg2)) {
|
||||||
Doors *door = entity_list.GetDoorsByID(c->GetDoorToolEntityId());
|
Doors *door = entity_list.GetDoorsByID(c->GetDoorToolEntityId());
|
||||||
if (door) {
|
if (door) {
|
||||||
door->SetOpenType(Strings::ToInt(arg2.c_str()));
|
door->SetOpenType(Strings::ToInt(arg2));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -378,7 +378,7 @@ void DoorManipulation::CommandHandler(Client *c, const Seperator *sep)
|
|||||||
if (arg1 == "setincline" && !arg2.empty() && Strings::IsNumber(arg2)) {
|
if (arg1 == "setincline" && !arg2.empty() && Strings::IsNumber(arg2)) {
|
||||||
Doors *door = entity_list.GetDoorsByID(c->GetDoorToolEntityId());
|
Doors *door = entity_list.GetDoorsByID(c->GetDoorToolEntityId());
|
||||||
if (door) {
|
if (door) {
|
||||||
door->SetIncline(Strings::ToInt(arg2.c_str()));
|
door->SetIncline(Strings::ToInt(arg2));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -386,7 +386,7 @@ void DoorManipulation::CommandHandler(Client *c, const Seperator *sep)
|
|||||||
if (arg1 == "setinvertstate" && !arg2.empty() && Strings::IsNumber(arg2)) {
|
if (arg1 == "setinvertstate" && !arg2.empty() && Strings::IsNumber(arg2)) {
|
||||||
Doors *door = entity_list.GetDoorsByID(c->GetDoorToolEntityId());
|
Doors *door = entity_list.GetDoorsByID(c->GetDoorToolEntityId());
|
||||||
if (door) {
|
if (door) {
|
||||||
door->SetInvertState(Strings::ToInt(arg2.c_str()));
|
door->SetInvertState(Strings::ToInt(arg2));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -403,7 +403,7 @@ void DoorManipulation::CommandHandler(Client *c, const Seperator *sep)
|
|||||||
if (arg1 == "setinclineinc" && !arg2.empty() && Strings::IsNumber(arg2)) {
|
if (arg1 == "setinclineinc" && !arg2.empty() && Strings::IsNumber(arg2)) {
|
||||||
Doors *door = entity_list.GetDoorsByID(c->GetDoorToolEntityId());
|
Doors *door = entity_list.GetDoorsByID(c->GetDoorToolEntityId());
|
||||||
if (door) {
|
if (door) {
|
||||||
door->SetIncline(door->GetIncline() + Strings::ToInt(arg2.c_str()));
|
door->SetIncline(door->GetIncline() + Strings::ToInt(arg2));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -107,7 +107,7 @@ void command_faction(Client *c, const Seperator *sep)
|
|||||||
)
|
)
|
||||||
) {
|
) {
|
||||||
uint32 character_id = target->CharacterID();
|
uint32 character_id = target->CharacterID();
|
||||||
uint32 faction_id = Strings::ToUnsignedInt(faction_filter.c_str());
|
uint32 faction_id = Strings::ToUnsignedInt(faction_filter);
|
||||||
if (target->ReloadCharacterFaction(target, faction_id, character_id)) {
|
if (target->ReloadCharacterFaction(target, faction_id, character_id)) {
|
||||||
c->Message(
|
c->Message(
|
||||||
Chat::White,
|
Chat::White,
|
||||||
|
|||||||
+21
-14
@@ -298,7 +298,7 @@ bool Group::AddMember(Mob* newmember, const char *NewMemberName, uint32 Characte
|
|||||||
}
|
}
|
||||||
|
|
||||||
//put existing group member(s) into the new member's list
|
//put existing group member(s) into the new member's list
|
||||||
if(InZone && newmember->IsClient())
|
if(InZone && newmember && newmember->IsClient())
|
||||||
{
|
{
|
||||||
if(IsLeader(members[i]))
|
if(IsLeader(members[i]))
|
||||||
{
|
{
|
||||||
@@ -307,13 +307,13 @@ bool Group::AddMember(Mob* newmember, const char *NewMemberName, uint32 Characte
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
strcpy(newmember->CastToClient()->GetPP().groupMembers[x], members[i]->GetCleanName());
|
strcpy(newmember->CastToClient()->GetPP().groupMembers[x], members[i]->GetCleanName());
|
||||||
x++;
|
++x;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if(InZone)
|
if(InZone && newmember)
|
||||||
{
|
{
|
||||||
//put new member in his own list.
|
//put new member in his own list.
|
||||||
newmember->SetGrouped(true);
|
newmember->SetGrouped(true);
|
||||||
@@ -545,7 +545,6 @@ bool Group::UpdatePlayer(Mob* update) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void Group::MemberZoned(Mob* removemob) {
|
void Group::MemberZoned(Mob* removemob) {
|
||||||
uint32 i;
|
|
||||||
|
|
||||||
if (!removemob) {
|
if (!removemob) {
|
||||||
return;
|
return;
|
||||||
@@ -557,21 +556,21 @@ void Group::MemberZoned(Mob* removemob) {
|
|||||||
|
|
||||||
//should NOT clear the name, it is used for world communication.
|
//should NOT clear the name, it is used for world communication.
|
||||||
for (auto & m : members) {
|
for (auto & m : members) {
|
||||||
if (m && (m == removemob || m->IsBot() && m->CastToBot()->GetBotOwner() == removemob)) {
|
if (m && (m == removemob || (m->IsBot() && m->CastToBot()->GetBotOwner() == removemob))) {
|
||||||
m = nullptr;
|
m = nullptr;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (removemob->IsClient() && HasRole(removemob, RoleAssist)) {
|
if (removemob->IsClient() && HasRole(removemob, RoleAssist)) {
|
||||||
SetGroupAssistTarget(0);
|
SetGroupAssistTarget(nullptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (removemob->IsClient() && HasRole(removemob, RoleTank)) {
|
if (removemob->IsClient() && HasRole(removemob, RoleTank)) {
|
||||||
SetGroupTankTarget(0);
|
SetGroupTankTarget(nullptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (removemob->IsClient() && HasRole(removemob, RolePuller)) {
|
if (removemob->IsClient() && HasRole(removemob, RolePuller)) {
|
||||||
SetGroupPullerTarget(0);
|
SetGroupPullerTarget(nullptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (removemob->IsClient() && removemob == mentoree) {
|
if (removemob->IsClient() && removemob == mentoree) {
|
||||||
@@ -1158,17 +1157,26 @@ bool Group::LearnMembers() {
|
|||||||
"Error getting group members for group [{}]",
|
"Error getting group members for group [{}]",
|
||||||
GetID()
|
GetID()
|
||||||
);
|
);
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int memberIndex = 0;
|
int memberIndex = 0;
|
||||||
for (const auto& member : rows) {
|
for (const auto& member : rows) {
|
||||||
if (member.name.empty()) {
|
if (memberIndex >= MAX_GROUP_MEMBERS) {
|
||||||
continue;
|
LogError(
|
||||||
|
"Too many members in group [{}]",
|
||||||
|
GetID()
|
||||||
|
);
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (member.name.empty()) {
|
||||||
|
members[memberIndex] = nullptr;
|
||||||
|
membername[memberIndex][0] = '\0';
|
||||||
|
} else {
|
||||||
members[memberIndex] = nullptr;
|
members[memberIndex] = nullptr;
|
||||||
strn0cpy(membername[memberIndex], member.name.c_str(), 64);
|
strn0cpy(membername[memberIndex], member.name.c_str(), 64);
|
||||||
memberIndex++;
|
}
|
||||||
|
++memberIndex;
|
||||||
}
|
}
|
||||||
|
|
||||||
VerifyGroup();
|
VerifyGroup();
|
||||||
@@ -1189,8 +1197,7 @@ void Group::VerifyGroup() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Mob *them = entity_list.GetMob(membername[i]);
|
Mob *them = entity_list.GetMob(membername[i]);
|
||||||
if(them == nullptr && members[i] != nullptr) { //they aren't in zone
|
if (!them && members[i]) { //they aren't in zone
|
||||||
membername[i][0] = '\0';
|
|
||||||
members[i] = nullptr;
|
members[i] = nullptr;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|||||||
+5
-5
@@ -153,11 +153,11 @@ public:
|
|||||||
|
|
||||||
bool DoesAnyMemberHaveExpeditionLockout(const std::string& expedition_name, const std::string& event_name, int max_check_count = 0);
|
bool DoesAnyMemberHaveExpeditionLockout(const std::string& expedition_name, const std::string& event_name, int max_check_count = 0);
|
||||||
|
|
||||||
Mob* members[MAX_GROUP_MEMBERS];
|
Mob* members[MAX_GROUP_MEMBERS] {nullptr};
|
||||||
char membername[MAX_GROUP_MEMBERS][64];
|
char membername[MAX_GROUP_MEMBERS][64] {""};
|
||||||
uint8 MemberRoles[MAX_GROUP_MEMBERS];
|
uint8 MemberRoles[MAX_GROUP_MEMBERS] {0};
|
||||||
bool disbandcheck;
|
bool disbandcheck {false};
|
||||||
bool castspell;
|
bool castspell {false};
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Mob* leader;
|
Mob* leader;
|
||||||
|
|||||||
+1
-1
@@ -236,7 +236,7 @@ void Client::RefreshGuildInfo()
|
|||||||
guild_id = info.guild_id;
|
guild_id = info.guild_id;
|
||||||
GuildBanker = info.banker || guild_mgr.IsGuildLeader(GuildID(), CharacterID());
|
GuildBanker = info.banker || guild_mgr.IsGuildLeader(GuildID(), CharacterID());
|
||||||
|
|
||||||
if(((int)zone->GetZoneID() == RuleI(World, GuildBankZoneID)))
|
if(zone->GetZoneID() == Zones::GUILDHALL)
|
||||||
{
|
{
|
||||||
if(WasBanker != GuildBanker)
|
if(WasBanker != GuildBanker)
|
||||||
{
|
{
|
||||||
|
|||||||
+6
-1
@@ -483,6 +483,7 @@ Mob *HateList::GetEntWithMostHateOnList(Mob *center, Mob *skip, bool skip_mezzed
|
|||||||
while (iterator != list.end())
|
while (iterator != list.end())
|
||||||
{
|
{
|
||||||
struct_HateList *cur = (*iterator);
|
struct_HateList *cur = (*iterator);
|
||||||
|
if (cur) {
|
||||||
if (cur->entity_on_hatelist == skip) {
|
if (cur->entity_on_hatelist == skip) {
|
||||||
++iterator;
|
++iterator;
|
||||||
continue;
|
continue;
|
||||||
@@ -498,6 +499,7 @@ Mob *HateList::GetEntWithMostHateOnList(Mob *center, Mob *skip, bool skip_mezzed
|
|||||||
top_hate = cur->entity_on_hatelist;
|
top_hate = cur->entity_on_hatelist;
|
||||||
hate = cur->stored_hate_amount;
|
hate = cur->stored_hate_amount;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
++iterator;
|
++iterator;
|
||||||
}
|
}
|
||||||
if (top_hate == nullptr && skipped_count > 0) {
|
if (top_hate == nullptr && skipped_count > 0) {
|
||||||
@@ -516,6 +518,8 @@ Mob *HateList::GetEntWithMostHateOnList(bool skip_mezzed){
|
|||||||
while (iterator != list.end())
|
while (iterator != list.end())
|
||||||
{
|
{
|
||||||
struct_HateList *cur = (*iterator);
|
struct_HateList *cur = (*iterator);
|
||||||
|
|
||||||
|
if (cur) {
|
||||||
LogHateDetail(
|
LogHateDetail(
|
||||||
"Looping GetEntWithMostHateOnList1 [{}] cur [{}] hate [{}] calc [{}]",
|
"Looping GetEntWithMostHateOnList1 [{}] cur [{}] hate [{}] calc [{}]",
|
||||||
cur->entity_on_hatelist->GetMobDescription(),
|
cur->entity_on_hatelist->GetMobDescription(),
|
||||||
@@ -524,7 +528,7 @@ Mob *HateList::GetEntWithMostHateOnList(bool skip_mezzed){
|
|||||||
(cur->stored_hate_amount > hate)
|
(cur->stored_hate_amount > hate)
|
||||||
);
|
);
|
||||||
|
|
||||||
if (cur && cur->entity_on_hatelist != nullptr && (cur->stored_hate_amount > hate))
|
if (cur->entity_on_hatelist != nullptr && (cur->stored_hate_amount > hate))
|
||||||
{
|
{
|
||||||
LogHateDetail(
|
LogHateDetail(
|
||||||
"Looping GetEntWithMostHateOnList2 [{}]",
|
"Looping GetEntWithMostHateOnList2 [{}]",
|
||||||
@@ -536,6 +540,7 @@ Mob *HateList::GetEntWithMostHateOnList(bool skip_mezzed){
|
|||||||
hate = cur->stored_hate_amount;
|
hate = cur->stored_hate_amount;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
++iterator;
|
++iterator;
|
||||||
}
|
}
|
||||||
return top;
|
return top;
|
||||||
|
|||||||
@@ -170,7 +170,7 @@ bool HealRotation::ClearMemberPool()
|
|||||||
if (!ClearTargetPool())
|
if (!ClearTargetPool())
|
||||||
LogError("failed to clear m_target_pool (size: [{}])", m_target_pool.size());
|
LogError("failed to clear m_target_pool (size: [{}])", m_target_pool.size());
|
||||||
|
|
||||||
auto clear_list = const_cast<const std::list<Bot*>&>(m_member_pool);
|
auto& clear_list = const_cast<const std::list<Bot*>&>(m_member_pool);
|
||||||
for (auto member_iter : clear_list)
|
for (auto member_iter : clear_list)
|
||||||
member_iter->LeaveHealRotationMemberPool();
|
member_iter->LeaveHealRotationMemberPool();
|
||||||
|
|
||||||
@@ -183,7 +183,7 @@ bool HealRotation::ClearTargetPool()
|
|||||||
m_hot_active = false;
|
m_hot_active = false;
|
||||||
m_is_active = false;
|
m_is_active = false;
|
||||||
|
|
||||||
auto clear_list = const_cast<const std::list<Mob*>&>(m_target_pool);
|
auto& clear_list = const_cast<const std::list<Mob*>&>(m_target_pool);
|
||||||
for (auto target_iter : clear_list)
|
for (auto target_iter : clear_list)
|
||||||
target_iter->LeaveHealRotationTargetPool();
|
target_iter->LeaveHealRotationTargetPool();
|
||||||
|
|
||||||
|
|||||||
+6
-3
@@ -717,14 +717,17 @@ bool Client::SummonItem(uint32 item_id, int16 charges, uint32 aug1, uint32 aug2,
|
|||||||
|
|
||||||
EQ::ItemInstance* inst = database.CreateItem(item, charges);
|
EQ::ItemInstance* inst = database.CreateItem(item, charges);
|
||||||
auto timestamps = database.GetItemRecastTimestamps(CharacterID());
|
auto timestamps = database.GetItemRecastTimestamps(CharacterID());
|
||||||
|
if (inst) {
|
||||||
const auto* d = inst->GetItem();
|
const auto* d = inst->GetItem();
|
||||||
if (d->RecastDelay) {
|
if (d->RecastDelay) {
|
||||||
if (d->RecastType != RECAST_TYPE_UNLINKED_ITEM) {
|
if (d->RecastType != RECAST_TYPE_UNLINKED_ITEM) {
|
||||||
inst->SetRecastTimestamp(timestamps.count(d->RecastType) ? timestamps.at(d->RecastType) : 0);
|
inst->SetRecastTimestamp(timestamps.count(d->RecastType) ? timestamps.at(d->RecastType) : 0);
|
||||||
} else {
|
}
|
||||||
|
else {
|
||||||
inst->SetRecastTimestamp(timestamps.count(d->ID) ? timestamps.at(d->ID) : 0);
|
inst->SetRecastTimestamp(timestamps.count(d->ID) ? timestamps.at(d->ID) : 0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if(inst == nullptr) {
|
if(inst == nullptr) {
|
||||||
Message(Chat::Red, "An unknown server error has occurred and your item was not created.");
|
Message(Chat::Red, "An unknown server error has occurred and your item was not created.");
|
||||||
@@ -2043,8 +2046,8 @@ bool Client::SwapItem(MoveItem_Struct* move_in) {
|
|||||||
}
|
}
|
||||||
if ((srcbagid && srcbag->GetItem()->BagType == EQ::item::BagTypeTradersSatchel) ||
|
if ((srcbagid && srcbag->GetItem()->BagType == EQ::item::BagTypeTradersSatchel) ||
|
||||||
(dstbagid && dstbag->GetItem()->BagType == EQ::item::BagTypeTradersSatchel) ||
|
(dstbagid && dstbag->GetItem()->BagType == EQ::item::BagTypeTradersSatchel) ||
|
||||||
(srcitemid && src_inst->GetItem()->BagType == EQ::item::BagTypeTradersSatchel) ||
|
(srcitemid && src_inst && src_inst->GetItem()->BagType == EQ::item::BagTypeTradersSatchel) ||
|
||||||
(dstitemid && dst_inst->GetItem()->BagType == EQ::item::BagTypeTradersSatchel)) {
|
(dstitemid && dst_inst && dst_inst->GetItem()->BagType == EQ::item::BagTypeTradersSatchel)) {
|
||||||
Trader_EndTrader();
|
Trader_EndTrader();
|
||||||
Message(Chat::Red,"You cannot move your Trader Satchels, or items inside them, while Trading.");
|
Message(Chat::Red,"You cannot move your Trader Satchels, or items inside them, while Trading.");
|
||||||
}
|
}
|
||||||
|
|||||||
+2
-2
@@ -2828,7 +2828,7 @@ luabind::object Lua_Client::GetPEQZoneFlags(lua_State* L) {
|
|||||||
if (d_) {
|
if (d_) {
|
||||||
auto self = reinterpret_cast<NativeType*>(d_);
|
auto self = reinterpret_cast<NativeType*>(d_);
|
||||||
auto l = self->GetPEQZoneFlags();
|
auto l = self->GetPEQZoneFlags();
|
||||||
auto i = 0;
|
auto i = 1;
|
||||||
for (const auto& f : l) {
|
for (const auto& f : l) {
|
||||||
t[i] = f;
|
t[i] = f;
|
||||||
i++;
|
i++;
|
||||||
@@ -2843,7 +2843,7 @@ luabind::object Lua_Client::GetZoneFlags(lua_State* L) {
|
|||||||
if (d_) {
|
if (d_) {
|
||||||
auto self = reinterpret_cast<NativeType*>(d_);
|
auto self = reinterpret_cast<NativeType*>(d_);
|
||||||
auto l = self->GetZoneFlags();
|
auto l = self->GetZoneFlags();
|
||||||
auto i = 0;
|
auto i = 1;
|
||||||
for (const auto& f : l) {
|
for (const auto& f : l) {
|
||||||
t[i] = f;
|
t[i] = f;
|
||||||
i++;
|
i++;
|
||||||
|
|||||||
+13
-5
@@ -907,12 +907,12 @@ std::string lua_say_link(const char *phrase) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void lua_set_rule(std::string rule_name, std::string rule_value) {
|
void lua_set_rule(std::string rule_name, std::string rule_value) {
|
||||||
RuleManager::Instance()->SetRule(rule_name.c_str(), rule_value.c_str());
|
RuleManager::Instance()->SetRule(rule_name, rule_value);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string lua_get_rule(std::string rule_name) {
|
std::string lua_get_rule(std::string rule_name) {
|
||||||
std::string rule_value;
|
std::string rule_value;
|
||||||
RuleManager::Instance()->GetRule(rule_name.c_str(), rule_value);
|
RuleManager::Instance()->GetRule(rule_name, rule_value);
|
||||||
return rule_value;
|
return rule_value;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1017,7 +1017,7 @@ luabind::adl::object lua_get_instance_ids(lua_State* L, std::string zone_name) {
|
|||||||
|
|
||||||
auto instance_ids = quest_manager.GetInstanceIDs(zone_name);
|
auto instance_ids = quest_manager.GetInstanceIDs(zone_name);
|
||||||
for (int i = 0; i < instance_ids.size(); i++) {
|
for (int i = 0; i < instance_ids.size(); i++) {
|
||||||
ret[i] = instance_ids[i];
|
ret[i + 1] = instance_ids[i];
|
||||||
}
|
}
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
@@ -1028,7 +1028,7 @@ luabind::adl::object lua_get_instance_ids_by_char_id(lua_State* L, std::string z
|
|||||||
|
|
||||||
auto instance_ids = quest_manager.GetInstanceIDs(zone_name, character_id);
|
auto instance_ids = quest_manager.GetInstanceIDs(zone_name, character_id);
|
||||||
for (int i = 0; i < instance_ids.size(); i++) {
|
for (int i = 0; i < instance_ids.size(); i++) {
|
||||||
ret[i] = instance_ids[i];
|
ret[i + 1] = instance_ids[i];
|
||||||
}
|
}
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
@@ -4182,7 +4182,7 @@ luabind::scope lua_register_general() {
|
|||||||
luabind::def("get_instance_id", &lua_get_instance_id),
|
luabind::def("get_instance_id", &lua_get_instance_id),
|
||||||
luabind::def("get_instance_id_by_char_id", &lua_get_instance_id_by_char_id),
|
luabind::def("get_instance_id_by_char_id", &lua_get_instance_id_by_char_id),
|
||||||
luabind::def("get_instance_ids", &lua_get_instance_ids),
|
luabind::def("get_instance_ids", &lua_get_instance_ids),
|
||||||
luabind::def("get_instance_ids_by_char_id", &lua_get_instance_id_by_char_id),
|
luabind::def("get_instance_ids_by_char_id", &lua_get_instance_ids_by_char_id),
|
||||||
luabind::def("get_instance_timer", &lua_get_instance_timer),
|
luabind::def("get_instance_timer", &lua_get_instance_timer),
|
||||||
luabind::def("get_instance_timer_by_id", &lua_get_instance_timer_by_id),
|
luabind::def("get_instance_timer_by_id", &lua_get_instance_timer_by_id),
|
||||||
luabind::def("get_instance_version_by_id", &lua_get_instance_version_by_id),
|
luabind::def("get_instance_version_by_id", &lua_get_instance_version_by_id),
|
||||||
@@ -4269,6 +4269,8 @@ luabind::scope lua_register_general() {
|
|||||||
luabind::def("add_ldon_loss", &lua_add_ldon_loss),
|
luabind::def("add_ldon_loss", &lua_add_ldon_loss),
|
||||||
luabind::def("add_ldon_points", &lua_add_ldon_points),
|
luabind::def("add_ldon_points", &lua_add_ldon_points),
|
||||||
luabind::def("add_ldon_win", &lua_add_ldon_win),
|
luabind::def("add_ldon_win", &lua_add_ldon_win),
|
||||||
|
luabind::def("remove_ldon_loss", &lua_remove_ldon_loss),
|
||||||
|
luabind::def("remove_ldon_win", &lua_remove_ldon_win),
|
||||||
luabind::def("get_gender_name", &lua_get_gender_name),
|
luabind::def("get_gender_name", &lua_get_gender_name),
|
||||||
luabind::def("get_deity_name", &lua_get_deity_name),
|
luabind::def("get_deity_name", &lua_get_deity_name),
|
||||||
luabind::def("get_inventory_slot_name", &lua_get_inventory_slot_name),
|
luabind::def("get_inventory_slot_name", &lua_get_inventory_slot_name),
|
||||||
@@ -4523,6 +4525,12 @@ luabind::scope lua_register_general() {
|
|||||||
luabind::def("world_wide_move_instance", (void(*)(uint16))&lua_world_wide_move_instance),
|
luabind::def("world_wide_move_instance", (void(*)(uint16))&lua_world_wide_move_instance),
|
||||||
luabind::def("world_wide_move_instance", (void(*)(uint16,uint8))&lua_world_wide_move_instance),
|
luabind::def("world_wide_move_instance", (void(*)(uint16,uint8))&lua_world_wide_move_instance),
|
||||||
luabind::def("world_wide_move_instance", (void(*)(uint16,uint8,uint8))&lua_world_wide_move_instance),
|
luabind::def("world_wide_move_instance", (void(*)(uint16,uint8,uint8))&lua_world_wide_move_instance),
|
||||||
|
luabind::def("world_wide_remove_ldon_loss", (void(*)(uint32))&lua_world_wide_remove_ldon_loss),
|
||||||
|
luabind::def("world_wide_remove_ldon_loss", (void(*)(uint32,uint8))&lua_world_wide_remove_ldon_loss),
|
||||||
|
luabind::def("world_wide_remove_ldon_loss", (void(*)(uint32,uint8,uint8))&lua_world_wide_remove_ldon_loss),
|
||||||
|
luabind::def("world_wide_remove_ldon_win", (void(*)(uint32))&lua_world_wide_remove_ldon_win),
|
||||||
|
luabind::def("world_wide_remove_ldon_win", (void(*)(uint32,uint8))&lua_world_wide_remove_ldon_win),
|
||||||
|
luabind::def("world_wide_remove_ldon_win", (void(*)(uint32,uint8,uint8))&lua_world_wide_remove_ldon_win),
|
||||||
luabind::def("world_wide_remove_spell", (void(*)(uint32))&lua_world_wide_remove_spell),
|
luabind::def("world_wide_remove_spell", (void(*)(uint32))&lua_world_wide_remove_spell),
|
||||||
luabind::def("world_wide_remove_spell", (void(*)(uint32,uint8))&lua_world_wide_remove_spell),
|
luabind::def("world_wide_remove_spell", (void(*)(uint32,uint8))&lua_world_wide_remove_spell),
|
||||||
luabind::def("world_wide_remove_spell", (void(*)(uint32,uint8,uint8))&lua_world_wide_remove_spell),
|
luabind::def("world_wide_remove_spell", (void(*)(uint32,uint8,uint8))&lua_world_wide_remove_spell),
|
||||||
|
|||||||
+7
-7
@@ -2170,14 +2170,14 @@ bool Lua_Mob::IsTargetable() {
|
|||||||
return self->IsTargetable();
|
return self->IsTargetable();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Lua_Mob::HasShieldEquiped() {
|
bool Lua_Mob::HasShieldEquipped() {
|
||||||
Lua_Safe_Call_Bool();
|
Lua_Safe_Call_Bool();
|
||||||
return self->HasShieldEquiped();
|
return self->HasShieldEquipped();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Lua_Mob::HasTwoHandBluntEquiped() {
|
bool Lua_Mob::HasTwoHandBluntEquipped() {
|
||||||
Lua_Safe_Call_Bool();
|
Lua_Safe_Call_Bool();
|
||||||
return self->HasTwoHandBluntEquiped();
|
return self->HasTwoHandBluntEquipped();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Lua_Mob::HasTwoHanderEquipped() {
|
bool Lua_Mob::HasTwoHanderEquipped() {
|
||||||
@@ -2709,7 +2709,7 @@ luabind::object Lua_Mob::GetEntityVariables(lua_State* L) {
|
|||||||
if (d_) {
|
if (d_) {
|
||||||
auto self = reinterpret_cast<NativeType*>(d_);
|
auto self = reinterpret_cast<NativeType*>(d_);
|
||||||
auto l = self->GetEntityVariables();
|
auto l = self->GetEntityVariables();
|
||||||
auto i = 0;
|
auto i = 1;
|
||||||
for (const auto& v : l) {
|
for (const auto& v : l) {
|
||||||
t[i] = v;
|
t[i] = v;
|
||||||
i++;
|
i++;
|
||||||
@@ -3321,9 +3321,9 @@ luabind::scope lua_register_mob() {
|
|||||||
.def("HasOwner", (bool(Lua_Mob::*)(void))&Lua_Mob::HasOwner)
|
.def("HasOwner", (bool(Lua_Mob::*)(void))&Lua_Mob::HasOwner)
|
||||||
.def("HasPet", (bool(Lua_Mob::*)(void))&Lua_Mob::HasPet)
|
.def("HasPet", (bool(Lua_Mob::*)(void))&Lua_Mob::HasPet)
|
||||||
.def("HasProcs", &Lua_Mob::HasProcs)
|
.def("HasProcs", &Lua_Mob::HasProcs)
|
||||||
.def("HasShieldEquiped", (bool(Lua_Mob::*)(void))&Lua_Mob::HasShieldEquiped)
|
.def("HasShieldEquipped", (bool(Lua_Mob::*)(void))&Lua_Mob::HasShieldEquipped)
|
||||||
.def("HasTimer", &Lua_Mob::HasTimer)
|
.def("HasTimer", &Lua_Mob::HasTimer)
|
||||||
.def("HasTwoHandBluntEquiped", (bool(Lua_Mob::*)(void))&Lua_Mob::HasTwoHandBluntEquiped)
|
.def("HasTwoHandBluntEquipped", (bool(Lua_Mob::*)(void))&Lua_Mob::HasTwoHandBluntEquipped)
|
||||||
.def("HasTwoHanderEquipped", (bool(Lua_Mob::*)(void))&Lua_Mob::HasTwoHanderEquipped)
|
.def("HasTwoHanderEquipped", (bool(Lua_Mob::*)(void))&Lua_Mob::HasTwoHanderEquipped)
|
||||||
.def("Heal", &Lua_Mob::Heal)
|
.def("Heal", &Lua_Mob::Heal)
|
||||||
.def("HealDamage", (void(Lua_Mob::*)(uint64))&Lua_Mob::HealDamage)
|
.def("HealDamage", (void(Lua_Mob::*)(uint64))&Lua_Mob::HealDamage)
|
||||||
|
|||||||
+2
-2
@@ -431,8 +431,8 @@ public:
|
|||||||
uint8 GetNimbusEffect2();
|
uint8 GetNimbusEffect2();
|
||||||
uint8 GetNimbusEffect3();
|
uint8 GetNimbusEffect3();
|
||||||
bool IsTargetable();
|
bool IsTargetable();
|
||||||
bool HasShieldEquiped();
|
bool HasShieldEquipped();
|
||||||
bool HasTwoHandBluntEquiped();
|
bool HasTwoHandBluntEquipped();
|
||||||
bool HasTwoHanderEquipped();
|
bool HasTwoHanderEquipped();
|
||||||
uint32 GetHerosForgeModel(uint8 material_slot);
|
uint32 GetHerosForgeModel(uint8 material_slot);
|
||||||
uint32 IsEliteMaterialItem(uint8 material_slot);
|
uint32 IsEliteMaterialItem(uint8 material_slot);
|
||||||
|
|||||||
+1
-1
@@ -173,7 +173,7 @@ luabind::object Lua_Object::GetEntityVariables(lua_State* L) {
|
|||||||
if (d_) {
|
if (d_) {
|
||||||
auto self = reinterpret_cast<NativeType*>(d_);
|
auto self = reinterpret_cast<NativeType*>(d_);
|
||||||
auto l = self->GetEntityVariables();
|
auto l = self->GetEntityVariables();
|
||||||
auto i = 0;
|
auto i = 1;
|
||||||
for (const auto& v : l) {
|
for (const auto& v : l) {
|
||||||
t[i] = v;
|
t[i] = v;
|
||||||
i++;
|
i++;
|
||||||
|
|||||||
+4
-4
@@ -172,7 +172,7 @@ int main(int argc, char** argv) {
|
|||||||
|
|
||||||
if (zone_port.size() > 1) {
|
if (zone_port.size() > 1) {
|
||||||
std::string p_name = zone_port[1];
|
std::string p_name = zone_port[1];
|
||||||
Config->SetZonePort(Strings::ToInt(p_name.c_str()));
|
Config->SetZonePort(Strings::ToInt(p_name));
|
||||||
}
|
}
|
||||||
|
|
||||||
worldserver.SetLaunchedName(z_name.c_str());
|
worldserver.SetLaunchedName(z_name.c_str());
|
||||||
@@ -193,7 +193,7 @@ int main(int argc, char** argv) {
|
|||||||
|
|
||||||
if (zone_port.size() > 1) {
|
if (zone_port.size() > 1) {
|
||||||
std::string p_name = zone_port[1];
|
std::string p_name = zone_port[1];
|
||||||
Config->SetZonePort(Strings::ToInt(p_name.c_str()));
|
Config->SetZonePort(Strings::ToInt(p_name));
|
||||||
}
|
}
|
||||||
|
|
||||||
worldserver.SetLaunchedName(z_name.c_str());
|
worldserver.SetLaunchedName(z_name.c_str());
|
||||||
@@ -214,7 +214,7 @@ int main(int argc, char** argv) {
|
|||||||
|
|
||||||
if (zone_port.size() > 1) {
|
if (zone_port.size() > 1) {
|
||||||
std::string p_name = zone_port[1];
|
std::string p_name = zone_port[1];
|
||||||
Config->SetZonePort(Strings::ToInt(p_name.c_str()));
|
Config->SetZonePort(Strings::ToInt(p_name));
|
||||||
}
|
}
|
||||||
|
|
||||||
worldserver.SetLaunchedName(z_name.c_str());
|
worldserver.SetLaunchedName(z_name.c_str());
|
||||||
@@ -380,7 +380,7 @@ int main(int argc, char** argv) {
|
|||||||
std::string tmp;
|
std::string tmp;
|
||||||
if (database.GetVariable("RuleSet", tmp)) {
|
if (database.GetVariable("RuleSet", tmp)) {
|
||||||
LogInfo("Loading rule set [{}]", tmp.c_str());
|
LogInfo("Loading rule set [{}]", tmp.c_str());
|
||||||
if (!RuleManager::Instance()->LoadRules(&database, tmp.c_str(), false)) {
|
if (!RuleManager::Instance()->LoadRules(&database, tmp, false)) {
|
||||||
LogError("Failed to load ruleset [{}], falling back to defaults", tmp.c_str());
|
LogError("Failed to load ruleset [{}], falling back to defaults", tmp.c_str());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+17
-6
@@ -3261,6 +3261,10 @@ MercSpell Merc::GetBestMercSpellForTargetedAENuke(Merc* caster, Mob* tar) {
|
|||||||
result.proc_chance = 0;
|
result.proc_chance = 0;
|
||||||
result.time_cancast = 0;
|
result.time_cancast = 0;
|
||||||
|
|
||||||
|
if (!caster) {
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
switch(caster->GetStance())
|
switch(caster->GetStance())
|
||||||
{
|
{
|
||||||
case EQ::constants::stanceBurnAE:
|
case EQ::constants::stanceBurnAE:
|
||||||
@@ -3272,7 +3276,6 @@ MercSpell Merc::GetBestMercSpellForTargetedAENuke(Merc* caster, Mob* tar) {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(caster) {
|
|
||||||
std::list<MercSpell> mercSpellList = GetMercSpellsBySpellType(caster, SpellType_Nuke);
|
std::list<MercSpell> mercSpellList = GetMercSpellsBySpellType(caster, SpellType_Nuke);
|
||||||
|
|
||||||
for (auto mercSpellListItr = mercSpellList.begin(); mercSpellListItr != mercSpellList.end();
|
for (auto mercSpellListItr = mercSpellList.begin(); mercSpellListItr != mercSpellList.end();
|
||||||
@@ -3295,7 +3298,6 @@ MercSpell Merc::GetBestMercSpellForTargetedAENuke(Merc* caster, Mob* tar) {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
@@ -3313,6 +3315,10 @@ MercSpell Merc::GetBestMercSpellForPBAENuke(Merc* caster, Mob* tar) {
|
|||||||
result.proc_chance = 0;
|
result.proc_chance = 0;
|
||||||
result.time_cancast = 0;
|
result.time_cancast = 0;
|
||||||
|
|
||||||
|
if (!caster) {
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
switch(caster->GetStance())
|
switch(caster->GetStance())
|
||||||
{
|
{
|
||||||
case EQ::constants::stanceBurnAE:
|
case EQ::constants::stanceBurnAE:
|
||||||
@@ -3324,7 +3330,6 @@ MercSpell Merc::GetBestMercSpellForPBAENuke(Merc* caster, Mob* tar) {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(caster) {
|
|
||||||
std::list<MercSpell> mercSpellList = GetMercSpellsBySpellType(caster, SpellType_Nuke);
|
std::list<MercSpell> mercSpellList = GetMercSpellsBySpellType(caster, SpellType_Nuke);
|
||||||
|
|
||||||
for (auto mercSpellListItr = mercSpellList.begin(); mercSpellListItr != mercSpellList.end();
|
for (auto mercSpellListItr = mercSpellList.begin(); mercSpellListItr != mercSpellList.end();
|
||||||
@@ -3346,7 +3351,6 @@ MercSpell Merc::GetBestMercSpellForPBAENuke(Merc* caster, Mob* tar) {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
@@ -3364,6 +3368,10 @@ MercSpell Merc::GetBestMercSpellForAERainNuke(Merc* caster, Mob* tar) {
|
|||||||
result.proc_chance = 0;
|
result.proc_chance = 0;
|
||||||
result.time_cancast = 0;
|
result.time_cancast = 0;
|
||||||
|
|
||||||
|
if (!caster) {
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
switch(caster->GetStance())
|
switch(caster->GetStance())
|
||||||
{
|
{
|
||||||
case EQ::constants::stanceBurnAE:
|
case EQ::constants::stanceBurnAE:
|
||||||
@@ -3375,7 +3383,6 @@ MercSpell Merc::GetBestMercSpellForAERainNuke(Merc* caster, Mob* tar) {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(caster) {
|
|
||||||
std::list<MercSpell> mercSpellList = GetMercSpellsBySpellType(caster, SpellType_Nuke);
|
std::list<MercSpell> mercSpellList = GetMercSpellsBySpellType(caster, SpellType_Nuke);
|
||||||
|
|
||||||
for (auto mercSpellListItr = mercSpellList.begin(); mercSpellListItr != mercSpellList.end();
|
for (auto mercSpellListItr = mercSpellList.begin(); mercSpellListItr != mercSpellList.end();
|
||||||
@@ -3397,7 +3404,6 @@ MercSpell Merc::GetBestMercSpellForAERainNuke(Merc* caster, Mob* tar) {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
@@ -4302,7 +4308,12 @@ Merc* Merc::LoadMerc(Client *c, MercTemplate* merc_template, uint32 merchant_id,
|
|||||||
if(merc_template)
|
if(merc_template)
|
||||||
{
|
{
|
||||||
//TODO: Maybe add a way of updating client merc stats in a seperate function? like, for example, on leveling up.
|
//TODO: Maybe add a way of updating client merc stats in a seperate function? like, for example, on leveling up.
|
||||||
|
|
||||||
|
const NPCType* npc_type_to_copy = nullptr;
|
||||||
|
if (c) {
|
||||||
const NPCType* npc_type_to_copy = content_db.GetMercType(merc_template->MercNPCID, merc_template->RaceID, c->GetLevel());
|
const NPCType* npc_type_to_copy = content_db.GetMercType(merc_template->MercNPCID, merc_template->RaceID, c->GetLevel());
|
||||||
|
}
|
||||||
|
|
||||||
if(npc_type_to_copy != nullptr)
|
if(npc_type_to_copy != nullptr)
|
||||||
{
|
{
|
||||||
//This is actually a very terrible method of assigning stats, and should be changed at some point. See the comment in merc's deconstructor.
|
//This is actually a very terrible method of assigning stats, and should be changed at some point. See the comment in merc's deconstructor.
|
||||||
|
|||||||
+16
-19
@@ -136,6 +136,7 @@ Mob::Mob(
|
|||||||
|
|
||||||
AI_Init();
|
AI_Init();
|
||||||
SetMoving(false);
|
SetMoving(false);
|
||||||
|
|
||||||
moved = false;
|
moved = false;
|
||||||
turning = false;
|
turning = false;
|
||||||
m_RewindLocation = glm::vec3();
|
m_RewindLocation = glm::vec3();
|
||||||
@@ -146,13 +147,16 @@ Mob::Mob(
|
|||||||
|
|
||||||
clean_name[0] = 0;
|
clean_name[0] = 0;
|
||||||
lastname[0] = 0;
|
lastname[0] = 0;
|
||||||
|
|
||||||
if (in_name) {
|
if (in_name) {
|
||||||
strn0cpy(name, in_name, 64);
|
strn0cpy(name, in_name, 64);
|
||||||
strn0cpy(orig_name, in_name, 64);
|
strn0cpy(orig_name, in_name, 64);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (in_lastname) {
|
if (in_lastname) {
|
||||||
strn0cpy(lastname, in_lastname, 64);
|
strn0cpy(lastname, in_lastname, 64);
|
||||||
}
|
}
|
||||||
|
|
||||||
current_hp = in_cur_hp;
|
current_hp = in_cur_hp;
|
||||||
max_hp = in_max_hp;
|
max_hp = in_max_hp;
|
||||||
base_hp = in_max_hp;
|
base_hp = in_max_hp;
|
||||||
@@ -185,8 +189,7 @@ Mob::Mob(
|
|||||||
fearspeed = 0.625f;
|
fearspeed = 0.625f;
|
||||||
base_fearspeed = 25;
|
base_fearspeed = 25;
|
||||||
// npcs
|
// npcs
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
base_walkspeed = base_runspeed * 100 / 265;
|
base_walkspeed = base_runspeed * 100 / 265;
|
||||||
walkspeed = ((float) base_walkspeed) * 0.025f;
|
walkspeed = ((float) base_walkspeed) * 0.025f;
|
||||||
base_fearspeed = base_runspeed * 100 / 127;
|
base_fearspeed = base_runspeed * 100 / 127;
|
||||||
@@ -200,7 +203,6 @@ Mob::Mob(
|
|||||||
|
|
||||||
m_PlayerState = 0;
|
m_PlayerState = 0;
|
||||||
|
|
||||||
|
|
||||||
// sanity check
|
// sanity check
|
||||||
if (runspeed < 0 || runspeed > 20) {
|
if (runspeed < 0 || runspeed > 20) {
|
||||||
runspeed = 1.25f;
|
runspeed = 1.25f;
|
||||||
@@ -235,10 +237,10 @@ Mob::Mob(
|
|||||||
slow_mitigation = 0;
|
slow_mitigation = 0;
|
||||||
findable = false;
|
findable = false;
|
||||||
trackable = true;
|
trackable = true;
|
||||||
has_shieldequiped = false;
|
has_shield_equipped = false;
|
||||||
has_twohandbluntequiped = false;
|
has_two_hand_blunt_equipped = false;
|
||||||
has_twohanderequipped = false;
|
has_two_hander_equipped = false;
|
||||||
has_duelweaponsequiped = false;
|
has_dual_weapons_equipped = false;
|
||||||
can_facestab = false;
|
can_facestab = false;
|
||||||
has_numhits = false;
|
has_numhits = false;
|
||||||
has_MGB = false;
|
has_MGB = false;
|
||||||
@@ -246,12 +248,7 @@ Mob::Mob(
|
|||||||
SpellPowerDistanceMod = 0;
|
SpellPowerDistanceMod = 0;
|
||||||
last_los_check = false;
|
last_los_check = false;
|
||||||
|
|
||||||
if (in_aa_title > 0) {
|
aa_title = in_aa_title > 0 ? in_aa_title : 0xFF;
|
||||||
aa_title = in_aa_title;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
aa_title = 0xFF;
|
|
||||||
}
|
|
||||||
|
|
||||||
AC = in_ac;
|
AC = in_ac;
|
||||||
ATK = in_atk;
|
ATK = in_atk;
|
||||||
@@ -1138,7 +1135,6 @@ void Mob::SetSpawnLastNameByClass(NewSpawn_Struct* ns)
|
|||||||
strcpy(ns->spawn.lastName, "Mercenary Liaison");
|
strcpy(ns->spawn.lastName, "Mercenary Liaison");
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
strcpy(ns->spawn.lastName, ns->spawn.lastName);
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -5113,6 +5109,10 @@ void Mob::TarGlobal(const char *varname, const char *value, const char *duration
|
|||||||
|
|
||||||
void Mob::DelGlobal(const char *varname) {
|
void Mob::DelGlobal(const char *varname) {
|
||||||
|
|
||||||
|
if (!zone) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
int qgZoneid=zone->GetZoneID();
|
int qgZoneid=zone->GetZoneID();
|
||||||
int qgCharid=0;
|
int qgCharid=0;
|
||||||
int qgNpcid=0;
|
int qgNpcid=0;
|
||||||
@@ -5133,8 +5133,6 @@ void Mob::DelGlobal(const char *varname) {
|
|||||||
|
|
||||||
database.QueryDatabase(query);
|
database.QueryDatabase(query);
|
||||||
|
|
||||||
if(zone)
|
|
||||||
{
|
|
||||||
auto pack = new ServerPacket(ServerOP_QGlobalDelete, sizeof(ServerQGlobalDelete_Struct));
|
auto pack = new ServerPacket(ServerOP_QGlobalDelete, sizeof(ServerQGlobalDelete_Struct));
|
||||||
ServerQGlobalDelete_Struct *qgu = (ServerQGlobalDelete_Struct*)pack->pBuffer;
|
ServerQGlobalDelete_Struct *qgu = (ServerQGlobalDelete_Struct*)pack->pBuffer;
|
||||||
|
|
||||||
@@ -5149,7 +5147,6 @@ void Mob::DelGlobal(const char *varname) {
|
|||||||
worldserver.SendPacket(pack);
|
worldserver.SendPacket(pack);
|
||||||
safe_delete(pack);
|
safe_delete(pack);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
// Inserts global variable into quest_globals table
|
// Inserts global variable into quest_globals table
|
||||||
void Mob::InsertQuestGlobal(int charid, int npcid, int zoneid, const char *varname, const char *varvalue, int duration) {
|
void Mob::InsertQuestGlobal(int charid, int npcid, int zoneid, const char *varname, const char *varvalue, int duration) {
|
||||||
@@ -6979,9 +6976,9 @@ std::string Mob::GetBucketKey() {
|
|||||||
std::string Mob::GetBucketRemaining(std::string bucket_name) {
|
std::string Mob::GetBucketRemaining(std::string bucket_name) {
|
||||||
std::string full_bucket_name = fmt::format("{}-{}", GetBucketKey(), bucket_name);
|
std::string full_bucket_name = fmt::format("{}-{}", GetBucketKey(), bucket_name);
|
||||||
std::string bucket_remaining = DataBucket::GetDataRemaining(full_bucket_name);
|
std::string bucket_remaining = DataBucket::GetDataRemaining(full_bucket_name);
|
||||||
if (!bucket_remaining.empty() && Strings::ToInt(bucket_remaining.c_str()) > 0) {
|
if (!bucket_remaining.empty() && Strings::ToInt(bucket_remaining) > 0) {
|
||||||
return bucket_remaining;
|
return bucket_remaining;
|
||||||
} else if (Strings::ToInt(bucket_remaining.c_str()) == 0) {
|
} else if (Strings::ToInt(bucket_remaining) == 0) {
|
||||||
return "0";
|
return "0";
|
||||||
}
|
}
|
||||||
return std::string();
|
return std::string();
|
||||||
|
|||||||
+12
-12
@@ -484,19 +484,19 @@ public:
|
|||||||
void TempName(const char *newname = nullptr);
|
void TempName(const char *newname = nullptr);
|
||||||
void SetTargetable(bool on);
|
void SetTargetable(bool on);
|
||||||
bool IsTargetable() const { return m_targetable; }
|
bool IsTargetable() const { return m_targetable; }
|
||||||
bool HasShieldEquiped() const { return has_shieldequiped; }
|
bool HasShieldEquipped() const { return has_shield_equipped; }
|
||||||
inline void SetShieldEquiped(bool val) { has_shieldequiped = val; }
|
inline void SetShieldEquipped(bool val) { has_shield_equipped = val; }
|
||||||
bool HasTwoHandBluntEquiped() const { return has_twohandbluntequiped; }
|
bool HasTwoHandBluntEquipped() const { return has_two_hand_blunt_equipped; }
|
||||||
inline void SetTwoHandBluntEquiped(bool val) { has_twohandbluntequiped = val; }
|
inline void SetTwoHandBluntEquipped(bool val) { has_two_hand_blunt_equipped = val; }
|
||||||
bool HasTwoHanderEquipped() { return has_twohanderequipped; }
|
bool HasTwoHanderEquipped() { return has_two_hander_equipped; }
|
||||||
void SetTwoHanderEquipped(bool val) { has_twohanderequipped = val; }
|
void SetTwoHanderEquipped(bool val) { has_two_hander_equipped = val; }
|
||||||
bool HasDualWeaponsEquiped() const { return has_duelweaponsequiped; }
|
bool HasDualWeaponsEquipped() const { return has_dual_weapons_equipped; }
|
||||||
bool HasBowEquipped() const { return has_bowequipped; }
|
bool HasBowEquipped() const { return has_bowequipped; }
|
||||||
void SetBowEquipped(bool val) { has_bowequipped = val; }
|
void SetBowEquipped(bool val) { has_bowequipped = val; }
|
||||||
bool HasArrowEquipped() const { return has_arrowequipped; }
|
bool HasArrowEquipped() const { return has_arrowequipped; }
|
||||||
void SetArrowEquipped(bool val) { has_arrowequipped = val; }
|
void SetArrowEquipped(bool val) { has_arrowequipped = val; }
|
||||||
bool HasBowAndArrowEquipped() const { return HasBowEquipped() && HasArrowEquipped(); }
|
bool HasBowAndArrowEquipped() const { return HasBowEquipped() && HasArrowEquipped(); }
|
||||||
inline void SetDuelWeaponsEquiped(bool val) { has_duelweaponsequiped = val; }
|
inline void SetDualWeaponsEquipped(bool val) { has_dual_weapons_equipped = val; }
|
||||||
bool CanFacestab() { return can_facestab; }
|
bool CanFacestab() { return can_facestab; }
|
||||||
void SetFacestab(bool val) { can_facestab = val; }
|
void SetFacestab(bool val) { can_facestab = val; }
|
||||||
virtual uint8 ConvertItemTypeToSkillID(uint8 item_type);
|
virtual uint8 ConvertItemTypeToSkillID(uint8 item_type);
|
||||||
@@ -1699,10 +1699,10 @@ protected:
|
|||||||
bool silenced;
|
bool silenced;
|
||||||
bool amnesiad;
|
bool amnesiad;
|
||||||
bool offhand;
|
bool offhand;
|
||||||
bool has_shieldequiped;
|
bool has_shield_equipped;
|
||||||
bool has_twohandbluntequiped;
|
bool has_two_hand_blunt_equipped;
|
||||||
bool has_twohanderequipped;
|
bool has_two_hander_equipped;
|
||||||
bool has_duelweaponsequiped;
|
bool has_dual_weapons_equipped;
|
||||||
bool has_bowequipped = false;
|
bool has_bowequipped = false;
|
||||||
bool has_arrowequipped = false;
|
bool has_arrowequipped = false;
|
||||||
bool use_double_melee_round_dmg_bonus;
|
bool use_double_melee_round_dmg_bonus;
|
||||||
|
|||||||
+6
-6
@@ -2273,14 +2273,14 @@ bool Perl_Mob_IsTargetable(Mob* self) // @categories Stats and Attributes
|
|||||||
return self->IsTargetable();
|
return self->IsTargetable();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Perl_Mob_HasShieldEquiped(Mob* self) // @categories Stats and Attributes
|
bool Perl_Mob_HasShieldEquipped(Mob* self) // @categories Stats and Attributes
|
||||||
{
|
{
|
||||||
return self->HasShieldEquiped();
|
return self->HasShieldEquipped();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Perl_Mob_HasTwoHandBluntEquiped(Mob* self) // @categories Stats and Attributes
|
bool Perl_Mob_HasTwoHandBluntEquipped(Mob* self) // @categories Stats and Attributes
|
||||||
{
|
{
|
||||||
return self->HasTwoHandBluntEquiped();
|
return self->HasTwoHandBluntEquipped();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Perl_Mob_HasTwoHanderEquipped(Mob* self) // @categories Stats and Attributes
|
bool Perl_Mob_HasTwoHanderEquipped(Mob* self) // @categories Stats and Attributes
|
||||||
@@ -3257,9 +3257,9 @@ void perl_register_mob()
|
|||||||
package.add("HasOwner", &Perl_Mob_HasOwner);
|
package.add("HasOwner", &Perl_Mob_HasOwner);
|
||||||
package.add("HasPet", &Perl_Mob_HasPet);
|
package.add("HasPet", &Perl_Mob_HasPet);
|
||||||
package.add("HasProcs", &Perl_Mob_HasProcs);
|
package.add("HasProcs", &Perl_Mob_HasProcs);
|
||||||
package.add("HasShieldEquiped", &Perl_Mob_HasShieldEquiped);
|
package.add("HasShieldEquipped", &Perl_Mob_HasShieldEquipped);
|
||||||
package.add("HasTimer", &Perl_Mob_HasTimer);
|
package.add("HasTimer", &Perl_Mob_HasTimer);
|
||||||
package.add("HasTwoHandBluntEquiped", &Perl_Mob_HasTwoHandBluntEquiped);
|
package.add("HasTwoHandBluntEquipped", &Perl_Mob_HasTwoHandBluntEquipped);
|
||||||
package.add("HasTwoHanderEquipped", &Perl_Mob_HasTwoHanderEquipped);
|
package.add("HasTwoHanderEquipped", &Perl_Mob_HasTwoHanderEquipped);
|
||||||
package.add("HateSummon", &Perl_Mob_HateSummon);
|
package.add("HateSummon", &Perl_Mob_HateSummon);
|
||||||
package.add("Heal", &Perl_Mob_Heal);
|
package.add("Heal", &Perl_Mob_Heal);
|
||||||
|
|||||||
+1
-1
@@ -445,7 +445,7 @@ Pet::Pet(NPCType *type_data, Mob *owner, PetType type, uint16 spell_id, int16 po
|
|||||||
GiveNPCTypeData(type_data);
|
GiveNPCTypeData(type_data);
|
||||||
typeofpet = type;
|
typeofpet = type;
|
||||||
petpower = power;
|
petpower = power;
|
||||||
SetOwnerID(owner->GetID());
|
SetOwnerID(owner ? owner->GetID() : 0);
|
||||||
SetPetSpellID(spell_id);
|
SetPetSpellID(spell_id);
|
||||||
|
|
||||||
// All pets start at false on newer clients. The client
|
// All pets start at false on newer clients. The client
|
||||||
|
|||||||
+24
-24
@@ -3535,71 +3535,71 @@ std::string QuestManager::GetEncounter() const {
|
|||||||
|
|
||||||
void QuestManager::UpdateZoneHeader(std::string type, std::string value) {
|
void QuestManager::UpdateZoneHeader(std::string type, std::string value) {
|
||||||
if (strcasecmp(type.c_str(), "ztype") == 0)
|
if (strcasecmp(type.c_str(), "ztype") == 0)
|
||||||
zone->newzone_data.ztype = Strings::ToInt(value.c_str());
|
zone->newzone_data.ztype = Strings::ToInt(value);
|
||||||
else if (strcasecmp(type.c_str(), "fog_red") == 0) {
|
else if (strcasecmp(type.c_str(), "fog_red") == 0) {
|
||||||
for (int i = 0; i < 4; i++) {
|
for (int i = 0; i < 4; i++) {
|
||||||
zone->newzone_data.fog_red[i] = Strings::ToInt(value.c_str());
|
zone->newzone_data.fog_red[i] = Strings::ToInt(value);
|
||||||
}
|
}
|
||||||
} else if (strcasecmp(type.c_str(), "fog_green") == 0) {
|
} else if (strcasecmp(type.c_str(), "fog_green") == 0) {
|
||||||
for (int i = 0; i < 4; i++) {
|
for (int i = 0; i < 4; i++) {
|
||||||
zone->newzone_data.fog_green[i] = Strings::ToInt(value.c_str());
|
zone->newzone_data.fog_green[i] = Strings::ToInt(value);
|
||||||
}
|
}
|
||||||
} else if (strcasecmp(type.c_str(), "fog_blue") == 0) {
|
} else if (strcasecmp(type.c_str(), "fog_blue") == 0) {
|
||||||
for (int i = 0; i < 4; i++) {
|
for (int i = 0; i < 4; i++) {
|
||||||
zone->newzone_data.fog_blue[i] = Strings::ToInt(value.c_str());
|
zone->newzone_data.fog_blue[i] = Strings::ToInt(value);
|
||||||
}
|
}
|
||||||
} else if (strcasecmp(type.c_str(), "fog_minclip") == 0) {
|
} else if (strcasecmp(type.c_str(), "fog_minclip") == 0) {
|
||||||
for (int i = 0; i < 4; i++) {
|
for (int i = 0; i < 4; i++) {
|
||||||
zone->newzone_data.fog_minclip[i] = Strings::ToFloat(value.c_str());
|
zone->newzone_data.fog_minclip[i] = Strings::ToFloat(value);
|
||||||
}
|
}
|
||||||
} else if (strcasecmp(type.c_str(), "fog_maxclip") == 0) {
|
} else if (strcasecmp(type.c_str(), "fog_maxclip") == 0) {
|
||||||
for (int i = 0; i < 4; i++) {
|
for (int i = 0; i < 4; i++) {
|
||||||
zone->newzone_data.fog_maxclip[i] = Strings::ToFloat(value.c_str());
|
zone->newzone_data.fog_maxclip[i] = Strings::ToFloat(value);
|
||||||
}
|
}
|
||||||
} else if (strcasecmp(type.c_str(), "gravity") == 0) {
|
} else if (strcasecmp(type.c_str(), "gravity") == 0) {
|
||||||
zone->newzone_data.gravity = Strings::ToFloat(value.c_str());
|
zone->newzone_data.gravity = Strings::ToFloat(value);
|
||||||
} else if (strcasecmp(type.c_str(), "time_type") == 0) {
|
} else if (strcasecmp(type.c_str(), "time_type") == 0) {
|
||||||
zone->newzone_data.time_type = Strings::ToInt(value.c_str());
|
zone->newzone_data.time_type = Strings::ToInt(value);
|
||||||
} else if (strcasecmp(type.c_str(), "rain_chance") == 0) {
|
} else if (strcasecmp(type.c_str(), "rain_chance") == 0) {
|
||||||
for (int i = 0; i < 4; i++) {
|
for (int i = 0; i < 4; i++) {
|
||||||
zone->newzone_data.rain_chance[i] = Strings::ToInt(value.c_str());
|
zone->newzone_data.rain_chance[i] = Strings::ToInt(value);
|
||||||
}
|
}
|
||||||
} else if (strcasecmp(type.c_str(), "rain_duration") == 0) {
|
} else if (strcasecmp(type.c_str(), "rain_duration") == 0) {
|
||||||
for (int i = 0; i < 4; i++) {
|
for (int i = 0; i < 4; i++) {
|
||||||
zone->newzone_data.rain_duration[i] = Strings::ToInt(value.c_str());
|
zone->newzone_data.rain_duration[i] = Strings::ToInt(value);
|
||||||
}
|
}
|
||||||
} else if (strcasecmp(type.c_str(), "snow_chance") == 0) {
|
} else if (strcasecmp(type.c_str(), "snow_chance") == 0) {
|
||||||
for (int i = 0; i < 4; i++) {
|
for (int i = 0; i < 4; i++) {
|
||||||
zone->newzone_data.snow_chance[i] = Strings::ToInt(value.c_str());
|
zone->newzone_data.snow_chance[i] = Strings::ToInt(value);
|
||||||
}
|
}
|
||||||
} else if (strcasecmp(type.c_str(), "snow_duration") == 0) {
|
} else if (strcasecmp(type.c_str(), "snow_duration") == 0) {
|
||||||
for (int i = 0; i < 4; i++) {
|
for (int i = 0; i < 4; i++) {
|
||||||
zone->newzone_data.snow_duration[i] = Strings::ToInt(value.c_str());
|
zone->newzone_data.snow_duration[i] = Strings::ToInt(value);
|
||||||
}
|
}
|
||||||
} else if (strcasecmp(type.c_str(), "sky") == 0) {
|
} else if (strcasecmp(type.c_str(), "sky") == 0) {
|
||||||
zone->newzone_data.sky = Strings::ToInt(value.c_str());
|
zone->newzone_data.sky = Strings::ToInt(value);
|
||||||
} else if (strcasecmp(type.c_str(), "safe_x") == 0) {
|
} else if (strcasecmp(type.c_str(), "safe_x") == 0) {
|
||||||
zone->newzone_data.safe_x = Strings::ToFloat(value.c_str());
|
zone->newzone_data.safe_x = Strings::ToFloat(value);
|
||||||
} else if (strcasecmp(type.c_str(), "safe_y") == 0) {
|
} else if (strcasecmp(type.c_str(), "safe_y") == 0) {
|
||||||
zone->newzone_data.safe_y = Strings::ToFloat(value.c_str());
|
zone->newzone_data.safe_y = Strings::ToFloat(value);
|
||||||
} else if (strcasecmp(type.c_str(), "safe_z") == 0) {
|
} else if (strcasecmp(type.c_str(), "safe_z") == 0) {
|
||||||
zone->newzone_data.safe_z = Strings::ToFloat(value.c_str());
|
zone->newzone_data.safe_z = Strings::ToFloat(value);
|
||||||
} else if (strcasecmp(type.c_str(), "max_z") == 0) {
|
} else if (strcasecmp(type.c_str(), "max_z") == 0) {
|
||||||
zone->newzone_data.max_z = Strings::ToFloat(value.c_str());
|
zone->newzone_data.max_z = Strings::ToFloat(value);
|
||||||
} else if (strcasecmp(type.c_str(), "underworld") == 0) {
|
} else if (strcasecmp(type.c_str(), "underworld") == 0) {
|
||||||
zone->newzone_data.underworld = Strings::ToFloat(value.c_str());
|
zone->newzone_data.underworld = Strings::ToFloat(value);
|
||||||
} else if (strcasecmp(type.c_str(), "minclip") == 0) {
|
} else if (strcasecmp(type.c_str(), "minclip") == 0) {
|
||||||
zone->newzone_data.minclip = Strings::ToFloat(value.c_str());
|
zone->newzone_data.minclip = Strings::ToFloat(value);
|
||||||
} else if (strcasecmp(type.c_str(), "maxclip") == 0) {
|
} else if (strcasecmp(type.c_str(), "maxclip") == 0) {
|
||||||
zone->newzone_data.maxclip = Strings::ToFloat(value.c_str());
|
zone->newzone_data.maxclip = Strings::ToFloat(value);
|
||||||
} else if (strcasecmp(type.c_str(), "fog_density") == 0) {
|
} else if (strcasecmp(type.c_str(), "fog_density") == 0) {
|
||||||
zone->newzone_data.fog_density = Strings::ToFloat(value.c_str());
|
zone->newzone_data.fog_density = Strings::ToFloat(value);
|
||||||
} else if (strcasecmp(type.c_str(), "suspendbuffs") == 0) {
|
} else if (strcasecmp(type.c_str(), "suspendbuffs") == 0) {
|
||||||
zone->newzone_data.suspend_buffs = Strings::ToInt(value.c_str());
|
zone->newzone_data.suspend_buffs = Strings::ToInt(value);
|
||||||
} else if (strcasecmp(type.c_str(), "lavadamage") == 0) {
|
} else if (strcasecmp(type.c_str(), "lavadamage") == 0) {
|
||||||
zone->newzone_data.lava_damage = Strings::ToInt(value.c_str());
|
zone->newzone_data.lava_damage = Strings::ToInt(value);
|
||||||
} else if (strcasecmp(type.c_str(), "minlavadamage") == 0) {
|
} else if (strcasecmp(type.c_str(), "minlavadamage") == 0) {
|
||||||
zone->newzone_data.min_lava_damage = Strings::ToInt(value.c_str());
|
zone->newzone_data.min_lava_damage = Strings::ToInt(value);
|
||||||
}
|
}
|
||||||
|
|
||||||
auto outapp = new EQApplicationPacket(OP_NewZone, sizeof(NewZone_Struct));
|
auto outapp = new EQApplicationPacket(OP_NewZone, sizeof(NewZone_Struct));
|
||||||
|
|||||||
+1
-1
@@ -631,7 +631,7 @@ uint32 Raid::GetPlayerIndex(Client *c)
|
|||||||
|
|
||||||
Client *Raid::GetClientByIndex(uint16 index)
|
Client *Raid::GetClientByIndex(uint16 index)
|
||||||
{
|
{
|
||||||
if (index > MAX_RAID_MEMBERS) {
|
if (index >= MAX_RAID_MEMBERS) {
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+1
-1
@@ -150,7 +150,7 @@ bool Spawn2::Process() {
|
|||||||
//grab our spawn group
|
//grab our spawn group
|
||||||
SpawnGroup *spawn_group = zone->spawn_group_list.GetSpawnGroup(spawngroup_id_);
|
SpawnGroup *spawn_group = zone->spawn_group_list.GetSpawnGroup(spawngroup_id_);
|
||||||
|
|
||||||
if (NPCPointerValid() && (spawn_group->despawn == 0 || condition_id != 0)) {
|
if (NPCPointerValid() && (spawn_group && spawn_group->despawn == 0 || condition_id != 0)) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -133,7 +133,7 @@ int Mob::GetBaseSkillDamage(EQ::skills::SkillType skill, Mob *target)
|
|||||||
float ac_bonus = 0.0f;
|
float ac_bonus = 0.0f;
|
||||||
const EQ::ItemInstance *inst = nullptr;
|
const EQ::ItemInstance *inst = nullptr;
|
||||||
if (IsClient()) {
|
if (IsClient()) {
|
||||||
if (HasShieldEquiped()) {
|
if (HasShieldEquipped()) {
|
||||||
inst = CastToClient()->GetInv().GetItem(EQ::invslot::slotSecondary);
|
inst = CastToClient()->GetInv().GetItem(EQ::invslot::slotSecondary);
|
||||||
} else if (HasTwoHanderEquipped()) {
|
} else if (HasTwoHanderEquipped()) {
|
||||||
inst = CastToClient()->GetInv().GetItem(EQ::invslot::slotPrimary);
|
inst = CastToClient()->GetInv().GetItem(EQ::invslot::slotPrimary);
|
||||||
|
|||||||
+44
-28
@@ -147,9 +147,10 @@ bool Mob::SpellEffect(Mob* caster, uint16 spell_id, float partial, int level_ove
|
|||||||
if (spells[spell_id].hit_number > 0) {
|
if (spells[spell_id].hit_number > 0) {
|
||||||
|
|
||||||
int numhit = spells[spell_id].hit_number;
|
int numhit = spells[spell_id].hit_number;
|
||||||
|
if (caster) {
|
||||||
numhit += numhit * caster->GetFocusEffect(focusFcLimitUse, spell_id) / 100;
|
numhit += numhit * caster->GetFocusEffect(focusFcLimitUse, spell_id) / 100;
|
||||||
numhit += caster->GetFocusEffect(focusIncreaseNumHits, spell_id);
|
numhit += caster->GetFocusEffect(focusIncreaseNumHits, spell_id);
|
||||||
|
}
|
||||||
buffs[buffslot].hit_number = numhit;
|
buffs[buffslot].hit_number = numhit;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -207,11 +208,11 @@ bool Mob::SpellEffect(Mob* caster, uint16 spell_id, float partial, int level_ove
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if(IsVirusSpell(spell_id)) {
|
if (IsVirusSpell(spell_id) && buffslot > -1) {
|
||||||
|
|
||||||
if (!viral_timer.Enabled()) {
|
if (!viral_timer.Enabled()) {
|
||||||
viral_timer.Start(1000);
|
viral_timer.Start(1000);
|
||||||
}
|
}
|
||||||
|
|
||||||
buffs[buffslot].virus_spread_time = zone->random.Int(GetViralMinSpreadTime(spell_id), GetViralMaxSpreadTime(spell_id));
|
buffs[buffslot].virus_spread_time = zone->random.Int(GetViralMinSpreadTime(spell_id), GetViralMaxSpreadTime(spell_id));
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -262,7 +263,7 @@ bool Mob::SpellEffect(Mob* caster, uint16 spell_id, float partial, int level_ove
|
|||||||
// SE_CurrentHP is calculated at first tick if its a dot/buff
|
// SE_CurrentHP is calculated at first tick if its a dot/buff
|
||||||
if (buffslot >= 0) {
|
if (buffslot >= 0) {
|
||||||
//This is here so dots with hit counters tic down on initial cast.
|
//This is here so dots with hit counters tic down on initial cast.
|
||||||
if (effect_value < 0) {
|
if (caster && effect_value < 0) {
|
||||||
caster->GetActDoTDamage(spell_id, effect_value, this, false);
|
caster->GetActDoTDamage(spell_id, effect_value, this, false);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@@ -819,21 +820,21 @@ bool Mob::SpellEffect(Mob* caster, uint16 spell_id, float partial, int level_ove
|
|||||||
|
|
||||||
// define spells with fixed duration
|
// define spells with fixed duration
|
||||||
// charm spells with -1 in field 209 are all of fixed duration, so lets use that instead of spell_ids
|
// charm spells with -1 in field 209 are all of fixed duration, so lets use that instead of spell_ids
|
||||||
if(spells[spell_id].no_resist)
|
if (spells[spell_id].no_resist) {
|
||||||
bBreak = true;
|
bBreak = true;
|
||||||
|
}
|
||||||
|
|
||||||
if (!bBreak)
|
if (buffslot > -1) {
|
||||||
{
|
if (!bBreak) {
|
||||||
int resistMod = static_cast<int>(partial) + (GetCHA() / 25);
|
int resistMod = static_cast<int>(partial) + (GetCHA() / 25);
|
||||||
resistMod = resistMod > 100 ? 100 : resistMod;
|
resistMod = resistMod > 100 ? 100 : resistMod;
|
||||||
buffs[buffslot].ticsremaining = resistMod * buffs[buffslot].ticsremaining / 100;
|
buffs[buffslot].ticsremaining = resistMod * buffs[buffslot].ticsremaining / 100;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (IsClient() || IsBot())
|
if (IsOfClientBot() && buffs[buffslot].ticsremaining > RuleI(Character, MaxCharmDurationForPlayerCharacter)) {
|
||||||
{
|
|
||||||
if(buffs[buffslot].ticsremaining > RuleI(Character, MaxCharmDurationForPlayerCharacter))
|
|
||||||
buffs[buffslot].ticsremaining = RuleI(Character, MaxCharmDurationForPlayerCharacter);
|
buffs[buffslot].ticsremaining = RuleI(Character, MaxCharmDurationForPlayerCharacter);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -887,8 +888,7 @@ bool Mob::SpellEffect(Mob* caster, uint16 spell_id, float partial, int level_ove
|
|||||||
#ifdef SPELL_EFFECT_SPAM
|
#ifdef SPELL_EFFECT_SPAM
|
||||||
snprintf(effect_desc, _EDLEN, "Fear: %+i", effect_value);
|
snprintf(effect_desc, _EDLEN, "Fear: %+i", effect_value);
|
||||||
#endif
|
#endif
|
||||||
if (IsClient() || IsBot())
|
if (IsOfClientBot() && buffslot > -1) {
|
||||||
{
|
|
||||||
if (buffs[buffslot].ticsremaining > RuleI(Character, MaxFearDurationForPlayerCharacter)) {
|
if (buffs[buffslot].ticsremaining > RuleI(Character, MaxFearDurationForPlayerCharacter)) {
|
||||||
buffs[buffslot].ticsremaining = RuleI(Character, MaxFearDurationForPlayerCharacter);
|
buffs[buffslot].ticsremaining = RuleI(Character, MaxFearDurationForPlayerCharacter);
|
||||||
}
|
}
|
||||||
@@ -902,13 +902,11 @@ bool Mob::SpellEffect(Mob* caster, uint16 spell_id, float partial, int level_ove
|
|||||||
}
|
}
|
||||||
|
|
||||||
CalculateNewFearpoint();
|
CalculateNewFearpoint();
|
||||||
if (currently_fleeing)
|
if (currently_fleeing) {
|
||||||
{
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else if (buffslot > -1) {
|
||||||
{
|
|
||||||
Stun(buffs[buffslot].ticsremaining * 6000 - (6000 - tic_timer.GetRemainingTime()));
|
Stun(buffs[buffslot].ticsremaining * 6000 - (6000 - tic_timer.GetRemainingTime()));
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@@ -1307,8 +1305,9 @@ bool Mob::SpellEffect(Mob* caster, uint16 spell_id, float partial, int level_ove
|
|||||||
#ifdef SPELL_EFFECT_SPAM
|
#ifdef SPELL_EFFECT_SPAM
|
||||||
snprintf(effect_desc, _EDLEN, "Invulnerability");
|
snprintf(effect_desc, _EDLEN, "Invulnerability");
|
||||||
#endif
|
#endif
|
||||||
if(spell_id==4789) // Touch of the Divine - Divine Save
|
if (spell_id == 4789 && buffslot > -1) { // Touch of the Divine - Divine Save
|
||||||
buffs[buffslot].ticsremaining = spells[spell_id].buff_duration; // Prevent focus/aa buff extension
|
buffs[buffslot].ticsremaining = spells[spell_id].buff_duration;
|
||||||
|
} // Prevent focus/aa buff extension
|
||||||
|
|
||||||
SetInvul(true);
|
SetInvul(true);
|
||||||
break;
|
break;
|
||||||
@@ -1355,7 +1354,9 @@ bool Mob::SpellEffect(Mob* caster, uint16 spell_id, float partial, int level_ove
|
|||||||
#ifdef SPELL_EFFECT_SPAM
|
#ifdef SPELL_EFFECT_SPAM
|
||||||
snprintf(effect_desc, _EDLEN, "Melee Absorb Rune: %+i", effect_value);
|
snprintf(effect_desc, _EDLEN, "Melee Absorb Rune: %+i", effect_value);
|
||||||
#endif
|
#endif
|
||||||
|
if (buffslot > -1) {
|
||||||
buffs[buffslot].melee_rune = effect_value;
|
buffs[buffslot].melee_rune = effect_value;
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1364,47 +1365,60 @@ bool Mob::SpellEffect(Mob* caster, uint16 spell_id, float partial, int level_ove
|
|||||||
#ifdef SPELL_EFFECT_SPAM
|
#ifdef SPELL_EFFECT_SPAM
|
||||||
snprintf(effect_desc, _EDLEN, "Spell Absorb Rune: %+i", effect_value);
|
snprintf(effect_desc, _EDLEN, "Spell Absorb Rune: %+i", effect_value);
|
||||||
#endif
|
#endif
|
||||||
if(effect_value > 0)
|
if (effect_value > 0 && buffslot > -1) {
|
||||||
buffs[buffslot].magic_rune = effect_value;
|
buffs[buffslot].magic_rune = effect_value;
|
||||||
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
case SE_MitigateMeleeDamage:
|
case SE_MitigateMeleeDamage:
|
||||||
{
|
{
|
||||||
|
if (buffslot > -1) {
|
||||||
buffs[buffslot].melee_rune = spells[spell_id].max_value[i];
|
buffs[buffslot].melee_rune = spells[spell_id].max_value[i];
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
case SE_MeleeThresholdGuard:
|
case SE_MeleeThresholdGuard:
|
||||||
{
|
{
|
||||||
|
if (buffslot > -1) {
|
||||||
buffs[buffslot].melee_rune = spells[spell_id].max_value[i];
|
buffs[buffslot].melee_rune = spells[spell_id].max_value[i];
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
case SE_SpellThresholdGuard:
|
case SE_SpellThresholdGuard:
|
||||||
{
|
{
|
||||||
|
if (buffslot > -1) {
|
||||||
buffs[buffslot].magic_rune = spells[spell_id].max_value[i];
|
buffs[buffslot].magic_rune = spells[spell_id].max_value[i];
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
case SE_MitigateSpellDamage:
|
case SE_MitigateSpellDamage:
|
||||||
{
|
{
|
||||||
|
if (buffslot > -1) {
|
||||||
buffs[buffslot].magic_rune = spells[spell_id].max_value[i];
|
buffs[buffslot].magic_rune = spells[spell_id].max_value[i];
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
case SE_MitigateDotDamage:
|
case SE_MitigateDotDamage:
|
||||||
{
|
{
|
||||||
|
if (buffslot > -1) {
|
||||||
buffs[buffslot].dot_rune = spells[spell_id].max_value[i];
|
buffs[buffslot].dot_rune = spells[spell_id].max_value[i];
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
case SE_DistanceRemoval:
|
case SE_DistanceRemoval:
|
||||||
{
|
{
|
||||||
|
if (buffslot > -1) {
|
||||||
buffs[buffslot].caston_x = int(GetX());
|
buffs[buffslot].caston_x = int(GetX());
|
||||||
buffs[buffslot].caston_y = int(GetY());
|
buffs[buffslot].caston_y = int(GetY());
|
||||||
buffs[buffslot].caston_z = int(GetZ());
|
buffs[buffslot].caston_z = int(GetZ());
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1434,7 +1448,9 @@ bool Mob::SpellEffect(Mob* caster, uint16 spell_id, float partial, int level_ove
|
|||||||
caster->spellbonuses.UnfailingDivinity;
|
caster->spellbonuses.UnfailingDivinity;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (buffslot > -1) {
|
||||||
buffs[buffslot].ExtraDIChance = mod;
|
buffs[buffslot].ExtraDIChance = mod;
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1694,7 +1710,7 @@ bool Mob::SpellEffect(Mob* caster, uint16 spell_id, float partial, int level_ove
|
|||||||
#endif
|
#endif
|
||||||
rooted = true;
|
rooted = true;
|
||||||
|
|
||||||
if (caster){
|
if (caster && buffslot > -1) {
|
||||||
buffs[buffslot].RootBreakChance = caster->aabonuses.RootBreakChance +
|
buffs[buffslot].RootBreakChance = caster->aabonuses.RootBreakChance +
|
||||||
caster->itembonuses.RootBreakChance +
|
caster->itembonuses.RootBreakChance +
|
||||||
caster->spellbonuses.RootBreakChance;
|
caster->spellbonuses.RootBreakChance;
|
||||||
@@ -1751,7 +1767,7 @@ bool Mob::SpellEffect(Mob* caster, uint16 spell_id, float partial, int level_ove
|
|||||||
gid = r->GetGroup(caster->GetName());
|
gid = r->GetGroup(caster->GetName());
|
||||||
if(gid < 11)
|
if(gid < 11)
|
||||||
{
|
{
|
||||||
if(r->GetGroup(TargetClient->GetName()) != gid) {
|
if (TargetClient && r->GetGroup(TargetClient->GetName()) != gid) {
|
||||||
Message(Chat::Red, "Your target must be a group member for this spell.");
|
Message(Chat::Red, "Your target must be a group member for this spell.");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -1802,7 +1818,7 @@ bool Mob::SpellEffect(Mob* caster, uint16 spell_id, float partial, int level_ove
|
|||||||
{
|
{
|
||||||
if (IsClient()) {
|
if (IsClient()) {
|
||||||
Client* client_target = CastToClient();
|
Client* client_target = CastToClient();
|
||||||
if (client_target->IsGrouped()) {
|
if (client_target && client_target->IsGrouped()) {
|
||||||
Group* group = client_target->GetGroup();
|
Group* group = client_target->GetGroup();
|
||||||
if (!group->IsGroupMember(caster)) {
|
if (!group->IsGroupMember(caster)) {
|
||||||
if (caster != this) {
|
if (caster != this) {
|
||||||
@@ -1815,7 +1831,7 @@ bool Mob::SpellEffect(Mob* caster, uint16 spell_id, float partial, int level_ove
|
|||||||
Raid *raid = caster->GetRaid();
|
Raid *raid = caster->GetRaid();
|
||||||
uint32 group_id = raid->GetGroup(caster->GetName());
|
uint32 group_id = raid->GetGroup(caster->GetName());
|
||||||
if (group_id > 0 && group_id < MAX_RAID_GROUPS) {
|
if (group_id > 0 && group_id < MAX_RAID_GROUPS) {
|
||||||
if (raid->GetGroup(client_target->GetName()) != group_id) {
|
if (client_target && raid->GetGroup(client_target->GetName()) != group_id) {
|
||||||
caster->MessageString(Chat::Red, SUMMON_ONLY_GROUP_CORPSE);
|
caster->MessageString(Chat::Red, SUMMON_ONLY_GROUP_CORPSE);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -2948,10 +2964,10 @@ bool Mob::SpellEffect(Mob* caster, uint16 spell_id, float partial, int level_ove
|
|||||||
if (caster && !caster->IsClient())
|
if (caster && !caster->IsClient())
|
||||||
break;
|
break;
|
||||||
|
|
||||||
if (zone->random.Roll(spells[spell_id].base_value[i])) {
|
if (caster && zone->random.Roll(spells[spell_id].base_value[i])) {
|
||||||
uint32 best_spell_id = caster->CastToClient()->GetHighestScribedSpellinSpellGroup(spells[spell_id].limit_value[i]);
|
uint32 best_spell_id = caster->CastToClient()->GetHighestScribedSpellinSpellGroup(spells[spell_id].limit_value[i]);
|
||||||
|
|
||||||
if (caster && IsValidSpell(best_spell_id))
|
if (IsValidSpell(best_spell_id))
|
||||||
caster->SpellFinished(best_spell_id, this, EQ::spells::CastingSlot::Item, 0, -1, spells[best_spell_id].resist_difficulty);
|
caster->SpellFinished(best_spell_id, this, EQ::spells::CastingSlot::Item, 0, -1, spells[best_spell_id].resist_difficulty);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@@ -8075,8 +8091,8 @@ bool Mob::PassCastRestriction(int value)
|
|||||||
return true;
|
return true;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case IS_OFF_HAND_EQUIPED:
|
case IS_OFF_HAND_EQUIPPED:
|
||||||
if (HasShieldEquiped() || CanThisClassDualWield())
|
if (HasShieldEquipped() || CanThisClassDualWield())
|
||||||
return true;
|
return true;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@@ -9284,7 +9300,7 @@ void Mob::SendCastRestrictionMessage(int requirement_id, bool target_requirement
|
|||||||
case IS_HP_UNDER_50_PCT:
|
case IS_HP_UNDER_50_PCT:
|
||||||
Message(Chat::Red, fmt::format("{} This target must be at oe below 50 pct of its maximum hit points.", msg).c_str());
|
Message(Chat::Red, fmt::format("{} This target must be at oe below 50 pct of its maximum hit points.", msg).c_str());
|
||||||
break;
|
break;
|
||||||
case IS_OFF_HAND_EQUIPED:
|
case IS_OFF_HAND_EQUIPPED:
|
||||||
Message(Chat::Red, fmt::format("{} You must be wielding a weapon or shield in your offhand to use this ability.", msg).c_str());
|
Message(Chat::Red, fmt::format("{} You must be wielding a weapon or shield in your offhand to use this ability.", msg).c_str());
|
||||||
break;
|
break;
|
||||||
case HAS_NO_PACT_OF_FATE_RECOURSE_BUFF:
|
case HAS_NO_PACT_OF_FATE_RECOURSE_BUFF:
|
||||||
|
|||||||
+2
-1
@@ -437,11 +437,12 @@ bool Mob::DoCastSpell(uint16 spell_id, uint16 target_id, CastingSlot slot,
|
|||||||
//this is a special case for NPCs with no mana...
|
//this is a special case for NPCs with no mana...
|
||||||
if (IsNPC() && my_curmana == my_maxmana) {
|
if (IsNPC() && my_curmana == my_maxmana) {
|
||||||
mana_cost = 0;
|
mana_cost = 0;
|
||||||
}
|
} else {
|
||||||
DoSpellInterrupt(spell_id, mana_cost, my_curmana);
|
DoSpellInterrupt(spell_id, mana_cost, my_curmana);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (mana_cost > GetMana()) {
|
if (mana_cost > GetMana()) {
|
||||||
mana_cost = GetMana();
|
mana_cost = GetMana();
|
||||||
|
|||||||
@@ -358,6 +358,7 @@
|
|||||||
#define WHOALL_NO_RESULTS 5029 //There are no players in EverQuest that match those who filters.
|
#define WHOALL_NO_RESULTS 5029 //There are no players in EverQuest that match those who filters.
|
||||||
#define TELL_QUEUED_MESSAGE 5045 //You told %1 '%T2. %3'
|
#define TELL_QUEUED_MESSAGE 5045 //You told %1 '%T2. %3'
|
||||||
#define TOLD_NOT_ONLINE 5046 //%1 is not online at this time.
|
#define TOLD_NOT_ONLINE 5046 //%1 is not online at this time.
|
||||||
|
#define RAID_IS_FULL 5048 //The raid is full.
|
||||||
#define ZONING_NO_EXPANSION 5052 //The zone that you are attempting to enter is part of an expansion that you do not yet own. You may need to return to the Login screen and enter an account key for that expansion. If you have received this message in error, please /petition or send an email to EQAccounts@soe.sony.com
|
#define ZONING_NO_EXPANSION 5052 //The zone that you are attempting to enter is part of an expansion that you do not yet own. You may need to return to the Login screen and enter an account key for that expansion. If you have received this message in error, please /petition or send an email to EQAccounts@soe.sony.com
|
||||||
#define PETITION_NO_DELETE 5053 //You do not have a petition in the queue.
|
#define PETITION_NO_DELETE 5053 //You do not have a petition in the queue.
|
||||||
#define PETITION_DELETED 5054 //Your petition was successfully deleted.
|
#define PETITION_DELETED 5054 //Your petition was successfully deleted.
|
||||||
@@ -460,6 +461,7 @@
|
|||||||
#define NO_ABILITY_OUT_OF_COMBAT 9194 //You can not use this ability while out of combat.
|
#define NO_ABILITY_OUT_OF_COMBAT 9194 //You can not use this ability while out of combat.
|
||||||
#define LESSER_SPELL_VERSION 11004 //%1 is a lesser version of %2 and cannot be scribed
|
#define LESSER_SPELL_VERSION 11004 //%1 is a lesser version of %2 and cannot be scribed
|
||||||
#define AE_RAMPAGE 11015 //%1 goes on a WILD RAMPAGE!
|
#define AE_RAMPAGE 11015 //%1 goes on a WILD RAMPAGE!
|
||||||
|
#define GROUP_IS_FULL 12000 //You cannot join that group, it is full.
|
||||||
#define FACE_ACCEPTED 12028 //Facial features accepted.
|
#define FACE_ACCEPTED 12028 //Facial features accepted.
|
||||||
#define TRACKING_BEGIN 12040 //You begin tracking %1.
|
#define TRACKING_BEGIN 12040 //You begin tracking %1.
|
||||||
#define SPELL_LEVEL_TO_LOW 12048 //You will have to achieve level %1 before you can scribe the %2.
|
#define SPELL_LEVEL_TO_LOW 12048 //You will have to achieve level %1 before you can scribe the %2.
|
||||||
|
|||||||
+2
-4
@@ -209,8 +209,7 @@ void Trap::Trigger(Mob* trigger)
|
|||||||
{
|
{
|
||||||
entity_list.MessageClose(trigger,false,100,13,"%s",message.c_str());
|
entity_list.MessageClose(trigger,false,100,13,"%s",message.c_str());
|
||||||
}
|
}
|
||||||
if(trigger->IsClient())
|
if (trigger && trigger->IsClient()) {
|
||||||
{
|
|
||||||
auto outapp = new EQApplicationPacket(OP_Damage, sizeof(CombatDamage_Struct));
|
auto outapp = new EQApplicationPacket(OP_Damage, sizeof(CombatDamage_Struct));
|
||||||
CombatDamage_Struct* a = (CombatDamage_Struct*)outapp->pBuffer;
|
CombatDamage_Struct* a = (CombatDamage_Struct*)outapp->pBuffer;
|
||||||
int64 dmg = zone->random.Int(effectvalue, effectvalue2);
|
int64 dmg = zone->random.Int(effectvalue, effectvalue2);
|
||||||
@@ -226,8 +225,7 @@ void Trap::Trigger(Mob* trigger)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (trigger && trigger->IsClient())
|
if (trigger && trigger->IsClient()) {
|
||||||
{
|
|
||||||
trigger->CastToClient()->trapid = trap_id;
|
trigger->CastToClient()->trapid = trap_id;
|
||||||
charid = trigger->CastToClient()->CharacterID();
|
charid = trigger->CastToClient()->CharacterID();
|
||||||
}
|
}
|
||||||
|
|||||||
+2
-2
@@ -920,7 +920,7 @@ int64 Mob::TuneClientAttack(Mob* other, bool no_avoid, bool no_hit_chance, int h
|
|||||||
if (Hand == EQ::invslot::slotPrimary || Hand == EQ::invslot::slotSecondary)
|
if (Hand == EQ::invslot::slotPrimary || Hand == EQ::invslot::slotSecondary)
|
||||||
my_hit.base_damage = CastToClient()->DoDamageCaps(my_hit.base_damage);
|
my_hit.base_damage = CastToClient()->DoDamageCaps(my_hit.base_damage);
|
||||||
auto shield_inc = spellbonuses.ShieldEquipDmgMod + itembonuses.ShieldEquipDmgMod + aabonuses.ShieldEquipDmgMod;
|
auto shield_inc = spellbonuses.ShieldEquipDmgMod + itembonuses.ShieldEquipDmgMod + aabonuses.ShieldEquipDmgMod;
|
||||||
if (shield_inc > 0 && HasShieldEquiped() && Hand == EQ::invslot::slotPrimary) {
|
if (shield_inc > 0 && HasShieldEquipped() && Hand == EQ::invslot::slotPrimary) {
|
||||||
my_hit.base_damage = my_hit.base_damage * (100 + shield_inc) / 100;
|
my_hit.base_damage = my_hit.base_damage * (100 + shield_inc) / 100;
|
||||||
hate = hate * (100 + shield_inc) / 100;
|
hate = hate * (100 + shield_inc) / 100;
|
||||||
}
|
}
|
||||||
@@ -1040,7 +1040,7 @@ int64 Mob::TuneACSum(bool skip_caps, int ac_override, int add_ac)
|
|||||||
}
|
}
|
||||||
|
|
||||||
int shield_ac = 0;
|
int shield_ac = 0;
|
||||||
if (HasShieldEquiped() && IsOfClientBot()) {
|
if (HasShieldEquipped() && IsOfClientBot()) {
|
||||||
auto inst = (IsClient()) ? GetInv().GetItem(EQ::invslot::slotSecondary) : CastToBot()->GetBotItem(EQ::invslot::slotSecondary);
|
auto inst = (IsClient()) ? GetInv().GetItem(EQ::invslot::slotSecondary) : CastToBot()->GetBotItem(EQ::invslot::slotSecondary);
|
||||||
if (inst) {
|
if (inst) {
|
||||||
if (inst->GetItemRecommendedLevel(true) <= GetLevel()) {
|
if (inst->GetItemRecommendedLevel(true) <= GetLevel()) {
|
||||||
|
|||||||
+11
-8
@@ -116,7 +116,7 @@ bool Zone::Bootup(uint32 iZoneID, uint32 iInstanceID, bool is_static) {
|
|||||||
std::string tmp;
|
std::string tmp;
|
||||||
if (database.GetVariable("loglevel", tmp)) {
|
if (database.GetVariable("loglevel", tmp)) {
|
||||||
int log_levels[4];
|
int log_levels[4];
|
||||||
int tmp_i = Strings::ToInt(tmp.c_str());
|
int tmp_i = Strings::ToInt(tmp);
|
||||||
if (tmp_i>9){ //Server is using the new code
|
if (tmp_i>9){ //Server is using the new code
|
||||||
for(int i=0;i<4;i++){
|
for(int i=0;i<4;i++){
|
||||||
if (((int)tmp[i]>=48) && ((int)tmp[i]<=57))
|
if (((int)tmp[i]>=48) && ((int)tmp[i]<=57))
|
||||||
@@ -1059,7 +1059,7 @@ Zone::Zone(uint32 in_zoneid, uint32 in_instanceid, const char* in_short_name)
|
|||||||
did_adventure_actions = false;
|
did_adventure_actions = false;
|
||||||
database.QGlobalPurge();
|
database.QGlobalPurge();
|
||||||
|
|
||||||
if(zoneid == RuleI(World, GuildBankZoneID))
|
if(zoneid == Zones::GUILDHALL)
|
||||||
GuildBanks = new GuildBankManager;
|
GuildBanks = new GuildBankManager;
|
||||||
else
|
else
|
||||||
GuildBanks = nullptr;
|
GuildBanks = nullptr;
|
||||||
@@ -1113,7 +1113,7 @@ bool Zone::Init(bool is_static) {
|
|||||||
if (RuleManager::Instance()->GetActiveRulesetID() != default_ruleset) {
|
if (RuleManager::Instance()->GetActiveRulesetID() != default_ruleset) {
|
||||||
std::string r_name = RuleSetsRepository::GetRuleSetName(database, default_ruleset);
|
std::string r_name = RuleSetsRepository::GetRuleSetName(database, default_ruleset);
|
||||||
if (r_name.size() > 0) {
|
if (r_name.size() > 0) {
|
||||||
RuleManager::Instance()->LoadRules(&database, r_name.c_str(), false);
|
RuleManager::Instance()->LoadRules(&database, r_name, false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1998,6 +1998,11 @@ void Zone::SetTime(uint8 hour, uint8 minute, bool update_world /*= true*/)
|
|||||||
ZonePoint* Zone::GetClosestZonePoint(const glm::vec3& location, uint32 to, Client* client, float max_distance) {
|
ZonePoint* Zone::GetClosestZonePoint(const glm::vec3& location, uint32 to, Client* client, float max_distance) {
|
||||||
LinkedListIterator<ZonePoint*> iterator(zone_point_list);
|
LinkedListIterator<ZonePoint*> iterator(zone_point_list);
|
||||||
ZonePoint* closest_zp = nullptr;
|
ZonePoint* closest_zp = nullptr;
|
||||||
|
|
||||||
|
if (!client) {
|
||||||
|
return closest_zp;
|
||||||
|
}
|
||||||
|
|
||||||
float closest_dist = FLT_MAX;
|
float closest_dist = FLT_MAX;
|
||||||
float max_distance2 = max_distance * max_distance;
|
float max_distance2 = max_distance * max_distance;
|
||||||
iterator.Reset();
|
iterator.Reset();
|
||||||
@@ -2027,13 +2032,12 @@ ZonePoint* Zone::GetClosestZonePoint(const glm::vec3& location, uint32 to, Clien
|
|||||||
|
|
||||||
// if we have a water map and it says we're in a zoneline, lets assume it's just a really big zone line
|
// if we have a water map and it says we're in a zoneline, lets assume it's just a really big zone line
|
||||||
// this shouldn't open up any exploits since those situations are detected later on
|
// this shouldn't open up any exploits since those situations are detected later on
|
||||||
if ((zone->HasWaterMap() && !zone->watermap->InZoneLine(glm::vec3(client->GetPosition()))) || (!zone->HasWaterMap() && closest_dist > 400.0f && closest_dist < max_distance2))
|
if ((client && zone->HasWaterMap() && !zone->watermap->InZoneLine(glm::vec3(client->GetPosition()))) || (!zone->HasWaterMap() && closest_dist > 400.0f && closest_dist < max_distance2))
|
||||||
{
|
{
|
||||||
if (client) {
|
|
||||||
if (!client->cheat_manager.GetExemptStatus(Port)) {
|
if (!client->cheat_manager.GetExemptStatus(Port)) {
|
||||||
client->cheat_manager.CheatDetected(MQZoneUnknownDest, location);
|
client->cheat_manager.CheatDetected(MQZoneUnknownDest, location);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
LogInfo("WARNING: Closest zone point for zone id [{}] is [{}], you might need to update your zone_points table if you dont arrive at the right spot", to, closest_dist);
|
LogInfo("WARNING: Closest zone point for zone id [{}] is [{}], you might need to update your zone_points table if you dont arrive at the right spot", to, closest_dist);
|
||||||
LogInfo("<Real Zone Points>. [{}]", to_string(location).c_str());
|
LogInfo("<Real Zone Points>. [{}]", to_string(location).c_str());
|
||||||
}
|
}
|
||||||
@@ -2231,11 +2235,10 @@ void Zone::LoadZoneBlockedSpells()
|
|||||||
|
|
||||||
void Zone::ClearBlockedSpells()
|
void Zone::ClearBlockedSpells()
|
||||||
{
|
{
|
||||||
if (blocked_spells) {
|
|
||||||
safe_delete_array(blocked_spells);
|
safe_delete_array(blocked_spells);
|
||||||
|
|
||||||
zone_total_blocked_spells = 0;
|
zone_total_blocked_spells = 0;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
bool Zone::IsSpellBlocked(uint32 spell_id, const glm::vec3 &location)
|
bool Zone::IsSpellBlocked(uint32 spell_id, const glm::vec3 &location)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -103,7 +103,7 @@ void ZoneEventScheduler::Process(Zone *zone, WorldContentService *content_servic
|
|||||||
rule_key,
|
rule_key,
|
||||||
rule_value
|
rule_value
|
||||||
);
|
);
|
||||||
RuleManager::Instance()->SetRule(rule_key.c_str(), rule_value.c_str(), nullptr, false, true);
|
RuleManager::Instance()->SetRule(rule_key, rule_value, nullptr, false, true);
|
||||||
}
|
}
|
||||||
m_active_events.push_back(e);
|
m_active_events.push_back(e);
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user