Compare commits

...

20 Commits

Author SHA1 Message Date
Aeadoin 090086f50c [Release] 22.9.0 (#3174) 2023-04-01 14:27:52 -04:00
Alex King 407b003f7d [Cleanup] Add client pointer validation to Zone::GetClosestZonePoint() (#3173)
# Notes
- We were not validating pointer here, could cause issues.
2023-04-01 14:22:52 -04:00
Alex King b6d315d803 [Cleanup] Remove unnecessary validation check in Zone::ClearBlockedSpells() (#3172)
# Notes
- This is unnecessary, since `safe_delete_array` checks for validity.
2023-04-01 13:59:03 -04:00
Aeadoin 6927177291 [Fix] Correct SE_SlayUndead & SE_HeadShotLevel limit Value when applied. (#3171) 2023-04-01 13:31:13 -04:00
Aeadoin 31ede355a8 [Cleanup] Cleanup excessive type casting: string -> char * -> string (#3169)
* [Cleanup] Cleanup excessive type casting: string -> char * -> string

* [Cleanup] Cleanup excessive type casting: string -> char * -> string
2023-04-01 12:45:16 -04:00
Aeadoin 0df84e1ee6 [Crash] Fix out of bound arrays, other potential crashes (#3166) 2023-04-01 12:44:41 -04:00
Aeadoin 0d509a7f3a [Crash] Add Checks for valid pointers or fix existing. (#3164) 2023-04-01 12:44:00 -04:00
Aeadoin 4c2271ff69 [Fix] Prevent VerifyGroup from setting OOZ membername to Null character. (#3168) 2023-04-01 12:40:55 -04:00
Aeadoin ca2072e7bf [Bots] Remove Bot Groups Functionality (#3165)
* [Bots] Remove Bot Groups Functionality

* in-class initializers for member variables.
2023-03-31 21:37:52 -04:00
Alex King e1eb1ff738 [Quest API] Add missing Luabind definitions to lua_general.cpp (#3167)
# Notes
- These definitions were missing somehow.
2023-03-31 21:05:01 -04:00
Aeadoin 25f5898bae [Release] 22.8.2 (#3161) 2023-03-30 09:22:58 -04:00
Aeadoin 934ff3dadf [Bug Fix] Correct logic checks for Bot rule AllowOwnerOptionAltCombat (#3158)
* [Bug Fix] Correct logic checks for Bot rule AllowOwnerOptionAltCombat

* fix ordering of raid/group checks
2023-03-30 08:31:57 -04:00
Aeadoin e4ff76dceb [Bug Fix] Fix for OOZ Group updates when removing/inviting Bots (#3159)
* [Bug Fix] Fix for Cross Zone Group updates with Bots when disbanding/joining groups.

* check for nullptr
2023-03-30 08:31:50 -04:00
Alex King 6960a1a682 [Bug Fix] Fix issues with Lua tables not starting at index 1 (#3160)
* [Bug Fix] Fix issues with Lua tables not starting at index 1

# Notes
- This would cause the first item in the table to be inaccessible since Lua tables start at index `1` instead of index `0`.
- All other spots using Lua tables have their indexes starting at `1`.

* Update lua_general.cpp
2023-03-30 06:02:53 -04:00
Aeadoin d4174ca236 [Fix] Fix strcpy-param-overlap (#3157) 2023-03-29 08:33:06 -04:00
Aeadoin 7854130a93 [Bug Fix] Check Rule "Bots Enabled" to prevent bot database calls on connect (#3154)
* [Bug Fix] Check for Rule "Bots Enabled" to prevent bot database calls if not enabled.

* formatting

* check if LoadBotsList failed, or is bots_list empty
2023-03-28 22:44:47 -04:00
Alex King e9c63c7d94 [Rules] Remove Guild Bank Zone ID Rule (#3156)
# notes
- This rule is useless as guild bank zone ID is hard-coded into the client.
2023-03-28 21:58:58 -04:00
Aeadoin 27e0665aae [Bug Fix] Fix bot_raid_members.sql for MYSQL. (#3155) 2023-03-28 15:25:16 -04:00
Alex King ea2f431fce [Fix] Fix an issue with EVENT_DISCONNECT not firing on regular /camp (#3153)
* [Fix] Fix an issue with EVENT_DISCONNECT not firing on regular /camp

# Notes
- We were only sending `EVENT_DISCONNECT` on GM instant camps or linkdeads.

* Update client_process.cpp
2023-03-27 21:45:02 -04:00
Aeadoin 8bdcf7cb94 [Crash] Add Checks for out of bounds & dereferencing nullptrs (#3151)
* [Crash] Add Checks for out of bounds/nullptr dereferences

* formatting

* formatting

* formatting

* Update bot.cpp

---------

Co-authored-by: Alex King <89047260+Kinglykrab@users.noreply.github.com>
2023-03-27 21:43:46 -04:00
63 changed files with 895 additions and 2355 deletions
+48
View File
@@ -1,3 +1,51 @@
## [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
+1 -1
View File
@@ -2345,7 +2345,7 @@ void Database::SourceDatabaseTableFromUrl(std::string table_name, std::string ur
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) {
for (auto &s: Strings::Split(res->body, ';')) {
if (!Strings::Trim(s).empty()) {
+4 -4
View File
@@ -6690,7 +6690,7 @@ static WSInit wsinit_;
if (params.empty()) { return Get(path, headers); }
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 &params,
@@ -6710,7 +6710,7 @@ static WSInit wsinit_;
}
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);
}
@@ -6807,7 +6807,7 @@ static WSInit wsinit_;
std::string content_type;
const auto &body = detail::serialize_multipart_formdata(
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,
@@ -6820,7 +6820,7 @@ static WSInit wsinit_;
std::string content_type;
const auto &body =
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) {
+1 -1
View File
@@ -151,7 +151,7 @@ static char *temp=nullptr;
return false;
}
ptr++;
uint32 id = Strings::ToUnsignedInt(field[id_pos].c_str());
uint32 id = Strings::ToUnsignedInt(field[id_pos]);
items[id]=field;
for(i=0;i<10;i++) {
+2 -2
View File
@@ -141,11 +141,11 @@ bool RuleManager::SetRule(const std::string &rule_name, const std::string &rule_
switch (type) {
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]);
break;
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]);
break;
case BoolRule:
-1
View File
@@ -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_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, 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, 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)")
+2 -2
View File
@@ -25,7 +25,7 @@
// Build variables
// these get injected during the build pipeline
#define CURRENT_VERSION "22.8.1-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 COMPILE_DATE __DATE__
#define COMPILE_TIME __TIME__
@@ -44,7 +44,7 @@
#define CURRENT_BINARY_DATABASE_VERSION 9227
#define CURRENT_BINARY_BOTS_DATABASE_VERSION 9038
#define CURRENT_BINARY_BOTS_DATABASE_VERSION 9039
#endif
+1 -1
View File
@@ -1,6 +1,6 @@
{
"name": "eqemu-server",
"version": "22.8.1",
"version": "22.9.0",
"repository": {
"type": "git",
"url": "https://github.com/EQEmu/Server.git"
+1 -1
View File
@@ -659,7 +659,7 @@ ChatChannel *ChatChannelList::RemoveClientFromChannel(const std::string& in_chan
std::string channel_name = in_channel_name;
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);
+14 -14
View File
@@ -379,14 +379,14 @@ static void ProcessSetMessageStatus(std::string SetMessageCommand) {
if (NumEnd == std::string::npos) {
MessageNumber = Strings::ToInt(SetMessageCommand.substr(NumStart).c_str());
MessageNumber = Strings::ToInt(SetMessageCommand.substr(NumStart));
database.SetMessageStatus(MessageNumber, Status);
break;
}
MessageNumber = Strings::ToInt(SetMessageCommand.substr(NumStart, NumEnd - NumStart).c_str());
MessageNumber = Strings::ToInt(SetMessageCommand.substr(NumStart, NumEnd - NumStart));
database.SetMessageStatus(MessageNumber, Status);
@@ -878,7 +878,7 @@ void Clientlist::ProcessOPMailCommand(Client *c, std::string command_string, boo
break;
case CommandGetBody:
database.SendBody(c, Strings::ToInt(parameters.c_str()));
database.SendBody(c, Strings::ToInt(parameters));
break;
case CommandMailTo:
@@ -893,7 +893,7 @@ void Clientlist::ProcessOPMailCommand(Client *c, std::string command_string, boo
case CommandSelectMailBox:
{
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;
}
case CommandSetMailForwarding:
@@ -1255,7 +1255,7 @@ void Client::ProcessChannelList(std::string Input) {
std::string ChannelName = Input;
if (isdigit(ChannelName[0]))
ChannelName = ChannelSlotName(Strings::ToInt(ChannelName.c_str()));
ChannelName = ChannelSlotName(Strings::ToInt(ChannelName));
ChatChannel *RequiredChannel = ChannelList->FindChannel(ChannelName);
@@ -1416,7 +1416,7 @@ void Client::SendChannelMessageByNumber(std::string Message) {
if (MessageStart == std::string::npos)
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)) {
@@ -1659,7 +1659,7 @@ void Client::SetChannelPassword(std::string ChannelPassword) {
std::string ChannelName = ChannelPassword.substr(ChannelStart);
if ((ChannelName.length() > 0) && isdigit(ChannelName[0]))
ChannelName = ChannelSlotName(Strings::ToInt(ChannelName.c_str()));
ChannelName = ChannelSlotName(Strings::ToInt(ChannelName));
std::string Message;
@@ -1724,7 +1724,7 @@ void Client::SetChannelOwner(std::string CommandString) {
std::string ChannelName = CapitaliseName(CommandString.substr(ChannelStart));
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());
@@ -1770,7 +1770,7 @@ void Client::OPList(std::string CommandString) {
std::string ChannelName = CapitaliseName(CommandString.substr(ChannelStart));
if ((ChannelName.length() > 0) && isdigit(ChannelName[0]))
ChannelName = ChannelSlotName(Strings::ToInt(ChannelName.c_str()));
ChannelName = ChannelSlotName(Strings::ToInt(ChannelName));
ChatChannel *RequiredChannel = ChannelList->FindChannel(ChannelName);
@@ -1813,7 +1813,7 @@ void Client::ChannelInvite(std::string CommandString) {
std::string ChannelName = CapitaliseName(CommandString.substr(ChannelStart));
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());
@@ -1883,7 +1883,7 @@ void Client::ChannelModerate(std::string CommandString) {
std::string ChannelName = CapitaliseName(CommandString.substr(ChannelStart));
if ((ChannelName.length() > 0) && isdigit(ChannelName[0]))
ChannelName = ChannelSlotName(Strings::ToInt(ChannelName.c_str()));
ChannelName = ChannelSlotName(Strings::ToInt(ChannelName));
ChatChannel *RequiredChannel = ChannelList->FindChannel(ChannelName);
@@ -1941,7 +1941,7 @@ void Client::ChannelGrantModerator(std::string CommandString) {
std::string ChannelName = CapitaliseName(CommandString.substr(ChannelStart));
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());
@@ -2022,7 +2022,7 @@ void Client::ChannelGrantVoice(std::string CommandString) {
std::string ChannelName = CapitaliseName(CommandString.substr(ChannelStart));
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());
@@ -2110,7 +2110,7 @@ void Client::ChannelKick(std::string CommandString) {
std::string ChannelName = CapitaliseName(CommandString.substr(ChannelStart));
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());
@@ -37,6 +37,7 @@
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|
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:
# 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`;
CREATE UNIQUE INDEX IF NOT EXISTS `UNIQUE` ON `raid_members`(`name`);
DROP INDEX `PRIMARY` ON `raid_members`;
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 `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
View File
@@ -1258,7 +1258,7 @@ bool Client::ChecksumVerificationCRCEQGame(uint64 checksum)
std::string checksumvar;
uint64_t checksumint;
if (database.GetVariable("crc_eqgame", checksumvar)) {
checksumint = Strings::ToBigInt(checksumvar.c_str());
checksumint = Strings::ToBigInt(checksumvar);
}
else {
LogChecksumVerification("variable not set in variables table.");
@@ -1281,7 +1281,7 @@ bool Client::ChecksumVerificationCRCSkillCaps(uint64 checksum)
std::string checksumvar;
uint64_t checksumint;
if (database.GetVariable("crc_skillcaps", checksumvar)) {
checksumint = Strings::ToBigInt(checksumvar.c_str());
checksumint = Strings::ToBigInt(checksumvar);
}
else {
LogChecksumVerification("[checksum_crc2_skillcaps] variable not set in variables table.");
@@ -1304,7 +1304,7 @@ bool Client::ChecksumVerificationCRCBaseData(uint64 checksum)
std::string checksumvar;
uint64_t checksumint;
if (database.GetVariable("crc_basedata", checksumvar)) {
checksumint = Strings::ToBigInt(checksumvar.c_str());
checksumint = Strings::ToBigInt(checksumvar);
}
else {
LogChecksumVerification("variable not set in variables table.");
+1 -1
View File
@@ -360,7 +360,7 @@ bool ClientListEntry::CheckAuth(uint32 loginserver_account_id, const char *key_p
}
std::string 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;
}
}
+18 -18
View File
@@ -166,14 +166,14 @@ void ConsoleWho(
}
else if (Strings::IsNumber(arg)) {
if (whom.lvllow == 0xFFFF) {
whom.lvllow = Strings::ToInt(arg.c_str());
whom.lvllow = Strings::ToInt(arg);
whom.lvlhigh = whom.lvllow;
}
else if (Strings::ToInt(arg.c_str()) > int(whom.lvllow)) {
whom.lvlhigh = Strings::ToInt(arg.c_str());
else if (Strings::ToInt(arg) > int(whom.lvllow)) {
whom.lvlhigh = Strings::ToInt(arg);
}
else {
whom.lvllow = Strings::ToInt(arg.c_str());
whom.lvllow = Strings::ToInt(arg);
}
}
else {
@@ -200,11 +200,11 @@ void ConsoleUptime(
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));
ServerUptime_Struct *sus = (ServerUptime_Struct *) pack->pBuffer;
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);
if (zs) {
zs->SendPacket(pack);
@@ -284,7 +284,7 @@ void ConsoleEmote(
0,
0,
AccountStatus::Player,
Strings::ToInt(args[1].c_str()),
Strings::ToInt(args[1]),
Strings::Join(join_args, " ").c_str()
);
}
@@ -295,7 +295,7 @@ void ConsoleEmote(
0,
0,
AccountStatus::Player,
Strings::ToInt(args[1].c_str()),
Strings::ToInt(args[1]),
Strings::Join(join_args, " ").c_str()
);
}
@@ -304,7 +304,7 @@ void ConsoleEmote(
args[0].c_str(),
0,
AccountStatus::Player,
Strings::ToInt(args[1].c_str()),
Strings::ToInt(args[1]),
Strings::Join(join_args, " ").c_str()
);
}
@@ -585,7 +585,7 @@ void ConsoleZoneShutdown(
pack->opcode = ServerOP_ZoneShutdown;
strcpy(s->adminname, tmpname);
if (Strings::IsNumber(args[0])) {
s->ZoneServerID = Strings::ToInt(args[0].c_str());
s->ZoneServerID = Strings::ToInt(args[0]);
}
else {
s->zoneid = ZoneID(args[0].c_str());
@@ -639,12 +639,12 @@ void ConsoleZoneBootup(
if (args.size() > 2) {
zoneserver_list.SOPZoneBootup(
tmpname,
Strings::ToInt(args[0].c_str()),
Strings::ToInt(args[0]),
args[1].c_str(),
(bool) (strcasecmp(args[1].c_str(), "static") == 0));
}
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]");
}
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");
}
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!");
}
else {
@@ -821,8 +821,8 @@ void ConsoleWorldShutdown(
{
if (args.size() == 2) {
int32 time, interval;
if (Strings::IsNumber(args[0]) && Strings::IsNumber(args[1]) && ((time = Strings::ToInt(args[0].c_str())) > 0) &&
((interval = Strings::ToInt(args[1].c_str())) > 0)) {
if (Strings::IsNumber(args[0]) && Strings::IsNumber(args[1]) && ((time = Strings::ToInt(args[0])) > 0) &&
((interval = Strings::ToInt(args[1])) > 0)) {
zoneserver_list.WorldShutDown(time, interval);
}
else {
@@ -886,7 +886,7 @@ void ConsoleSignalCharByName(
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;
auto pack = new ServerPacket(ServerOP_CZSignal, sizeof(CZSignal_Struct) + message_len);
CZSignal_Struct* CZS = (CZSignal_Struct*) pack->pBuffer;
@@ -894,7 +894,7 @@ void ConsoleSignalCharByName(
int update_identifier = 0;
CZS->update_type = update_type;
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);
zoneserver_list.SendPacket(pack);
safe_delete(pack);
+2 -2
View File
@@ -204,7 +204,7 @@ void WorldBoot::CheckForServerScript(bool force_download)
r.set_read_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) {
// write file
@@ -369,7 +369,7 @@ bool WorldBoot::DatabaseLoadRoutines(int argc, char **argv)
if (database.GetVariable("RuleSet", tmp)) {
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());
}
}
+2 -2
View File
@@ -1963,7 +1963,7 @@ void Client::TogglePassiveAlternativeAdvancement(const AA::Rank &rank, uint32 ab
AA::Rank *rank_next = zone->GetAlternateAdvancementRank(rank.next_id);
//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;
ApplyWeaponsStance();
}
@@ -2003,7 +2003,7 @@ bool Client::UseTogglePassiveHotkey(const AA::Rank &rank) {
else if (rank.prev_id != -1) {//Check when effect is Enabled.
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;
}
}
+3 -2
View File
@@ -904,8 +904,9 @@ bool Mob::IsBeneficialAllowed(Mob *target)
{
return false;
}
else if(mob2->IsBot())
else if (mob2 && mob2->IsBot()) {
return true;
}
}
else if(_NPC(mob1))
{
@@ -1436,7 +1437,7 @@ void Mob::ClearFeignMemory() {
while (remembered_feigned_mobid != feign_memory_list.end())
{
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_feigned_mobid;
+5 -5
View File
@@ -1484,7 +1484,6 @@ bool Mob::Attack(Mob* other, int Hand, bool bRiposte, bool IsStrikethrough, bool
if (
(IsCasting() && GetClass() != BARD && !IsFromSpell)
|| other == nullptr
|| ((IsClient() && CastToClient()->dead) || (other->IsClient() && other->CastToClient()->dead))
|| (GetHP() < 0)
|| (!IsAttackAllowed(other))
@@ -1979,10 +1978,10 @@ bool Client::Death(Mob* killerMob, int64 damage, uint16 spell, EQ::skills::Skill
database.GetVariable("ServerType", tmp);
if (tmp[0] == '1' && tmp[1] == '\0' && killerMob && killerMob->IsClient()) {
database.GetVariable("PvPreward", tmp);
auto reward = Strings::ToInt(tmp.c_str());
auto reward = Strings::ToInt(tmp);
if (reward == 3) {
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);
if (item) {
new_corpse->SetPlayerKillItemID(pvp_item_id);
@@ -2835,8 +2834,9 @@ bool NPC::Death(Mob* killer_mob, int64 damage, uint16 spell, EQ::skills::SkillTy
if (emote_id) {
oos->CastToNPC()->DoNPCEmote(EQ::constants::EmoteEventTypes::KilledNPC, emote_id);
}
killer_mob->TrySpellOnKill(killed_level, spell);
if (killer_mob) {
killer_mob->TrySpellOnKill(killed_level, spell);
}
}
}
+8 -2
View File
@@ -963,6 +963,10 @@ bool ZoneDatabase::GetAuraEntry(uint16 spell_id, AuraRecord &record)
void Mob::AddAura(Aura *aura, AuraRecord &record)
{
if (!aura) {
return;
}
LogAura(
"aura owner [{}] spawn_id [{}] aura_name [{}]",
GetCleanName(),
@@ -971,7 +975,6 @@ void Mob::AddAura(Aura *aura, AuraRecord &record)
);
// this is called only when it's safe
assert(aura != nullptr);
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].aura = aura;
@@ -998,6 +1001,10 @@ void Mob::AddAura(Aura *aura, AuraRecord &record)
void Mob::AddTrap(Aura *aura, AuraRecord &record)
{
if (!aura) {
return;
}
LogAura(
"aura owner [{}] spawn_id [{}] aura_name [{}]",
GetCleanName(),
@@ -1006,7 +1013,6 @@ void Mob::AddTrap(Aura *aura, AuraRecord &record)
);
// this is called only when it's safe
assert(aura != nullptr);
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].aura = aura;
+31 -22
View File
@@ -1442,9 +1442,10 @@ void Mob::ApplyAABonuses(const AA::Rank &rank, StatBonuses *newbon)
}
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_DMG_MOD] = limit_value; // Damage Modifier
newbon->SlayUndead[SBIndex::SLAYUNDEAD_DMG_MOD] = limit_value; // Damage Modifier
}
break;
}
@@ -1612,9 +1613,10 @@ void Mob::ApplyAABonuses(const AA::Rank &rank, StatBonuses *newbon)
}
case SE_HeadShotLevel: {
if (newbon->HSLevel[SBIndex::FINISHING_EFFECT_LEVEL_MAX] < base_value)
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_CHANCE_BONUS] = limit_value;
}
break;
}
@@ -1802,8 +1804,9 @@ void Mob::ApplyAABonuses(const AA::Rank &rank, StatBonuses *newbon)
case SE_Damage_Taken_Position_Mod:
{
//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;
}
else if (base_value < 0 && 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)
@@ -1813,8 +1816,9 @@ void Mob::ApplyAABonuses(const AA::Rank &rank, StatBonuses *newbon)
case SE_Melee_Damage_Position_Mod:
{
if (limit_value < 0 || limit_value > 2)
if (limit_value < 0 || limit_value >= 2) {
break;
}
else if (base_value < 0 && 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)
@@ -1825,9 +1829,9 @@ void Mob::ApplyAABonuses(const AA::Rank &rank, StatBonuses *newbon)
case SE_Damage_Taken_Position_Amt:
{
//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;
}
newbon->Damage_Taken_Position_Amt[limit_value] += base_value;
break;
}
@@ -1835,8 +1839,9 @@ void Mob::ApplyAABonuses(const AA::Rank &rank, StatBonuses *newbon)
case SE_Melee_Damage_Position_Amt:
{
//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;
}
newbon->Melee_Damage_Position_Amt[limit_value] += base_value;
break;
@@ -3175,8 +3180,9 @@ void Mob::ApplySpellsBonuses(uint16 spell_id, uint8 casterlevel, StatBonuses *ne
case SE_HPToMana:
{
//Lower the ratio the more favorable
if((!new_bonus->HPToManaConvert) || (new_bonus->HPToManaConvert >= effect_value))
new_bonus->HPToManaConvert = spells[spell_id].base_value[i];
if ((!new_bonus->HPToManaConvert) || (new_bonus->HPToManaConvert >= effect_value)) {
new_bonus->HPToManaConvert = spells[spell_id].base_value[i];
}
break;
}
@@ -3523,11 +3529,11 @@ void Mob::ApplySpellsBonuses(uint16 spell_id, uint8 casterlevel, StatBonuses *ne
break;
}
case SE_SlayUndead:
{
if(new_bonus->SlayUndead[SBIndex::SLAYUNDEAD_DMG_MOD] < effect_value)
case SE_SlayUndead: {
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_DMG_MOD] = limit_value; // Damage Modifier
new_bonus->SlayUndead[SBIndex::SLAYUNDEAD_DMG_MOD] = limit_value; // Damage Modifier
}
break;
}
@@ -3669,9 +3675,8 @@ void Mob::ApplySpellsBonuses(uint16 spell_id, uint8 casterlevel, StatBonuses *ne
break;
}
case SE_HeadShotLevel:
{
if(new_bonus->HSLevel[SBIndex::FINISHING_EFFECT_LEVEL_MAX] < effect_value) {
case SE_HeadShotLevel: {
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_CHANCE_BONUS] = limit_value;
}
@@ -3884,8 +3889,9 @@ void Mob::ApplySpellsBonuses(uint16 spell_id, uint8 casterlevel, StatBonuses *ne
case SE_Damage_Taken_Position_Mod:
{
//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;
}
if (AdditiveWornBonus)
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:
{
//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;
}
if (AdditiveWornBonus)
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:
{
//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;
}
new_bonus->Damage_Taken_Position_Amt[limit_value] += effect_value;
break;
@@ -3922,8 +3930,9 @@ void Mob::ApplySpellsBonuses(uint16 spell_id, uint8 casterlevel, StatBonuses *ne
case SE_Melee_Damage_Position_Amt:
{
//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;
}
new_bonus->Melee_Damage_Position_Amt[limit_value] += effect_value;
break;
+319 -512
View File
File diff suppressed because it is too large Load Diff
-2
View File
@@ -645,8 +645,6 @@ public:
void SetBotEnforceSpellSetting(bool enforcespellsettings, bool save = false);
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);
// Class Destructors
+2 -851
View File
@@ -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("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("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("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) ||
@@ -1911,43 +1903,6 @@ namespace MyBots
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
@@ -2166,7 +2121,6 @@ namespace ActionableBots
ABM_Target = (1 << (ABT_Target - 1)),
ABM_ByName = (1 << (ABT_ByName - 1)),
ABM_OwnerGroup = (1 << (ABT_OwnerGroup - 1)),
ABM_BotGroup = (1 << (ABT_BotGroup - 1)),
ABM_TargetGroup = (1 << (ABT_TargetGroup - 1)),
ABM_NamesGroup = (1 << (ABT_NamesGroup - 1)),
ABM_HealRotation = (1 << (ABT_HealRotation - 1)),
@@ -2177,8 +2131,8 @@ namespace ActionableBots
ABM_Spawned_All = (3 << (ABT_Spawned - 1)),
ABM_NoFilter = ~0,
// grouped values
ABM_Type1 = (ABM_Target | ABM_ByName | ABM_OwnerGroup | ABM_BotGroup | ABM_TargetGroup | ABM_NamesGroup | ABM_HealRotationTargets | ABM_Spawned),
ABM_Type2 = (ABM_ByName | ABM_OwnerGroup | ABM_BotGroup | ABM_NamesGroup | ABM_HealRotation | 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_NamesGroup | ABM_HealRotation | ABM_Spawned)
};
// Populates 'sbl'
@@ -2195,8 +2149,6 @@ namespace ActionableBots
ab_type = ABT_ByName;
else if (!ab_type_arg.compare("ownergroup"))
ab_type = ABT_OwnerGroup;
else if (!ab_type_arg.compare("botgroup"))
ab_type = ABT_BotGroup;
else if (!ab_type_arg.compare("targetgroup"))
ab_type = ABT_TargetGroup;
else if (!ab_type_arg.compare("namesgroup"))
@@ -2228,10 +2180,6 @@ namespace ActionableBots
if (ab_mask & ABM_OwnerGroup)
MyBots::PopulateSBL_ByMyGroupedBots(bot_owner, sbl, clear_list);
break;
case ABT_BotGroup:
if (ab_mask & ABM_BotGroup)
MyBots::PopulateSBL_ByBotGroup(bot_owner, sbl, name, clear_list);
break;
case ABT_TargetGroup:
if (ab_mask & ABM_TargetGroup)
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);
}
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)
{
bcst_list* local_list = &bot_command_spells[BCEnum::SpT_Depart];
+1 -7
View File
@@ -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_update(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_heal_rotation_adaptive_targeting(Client *c, const Seperator *sep);
void bot_subcommand_heal_rotation_add_member(Client *c, const Seperator *sep);
+1 -517
View File
@@ -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 */
// 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)
@@ -3238,3 +2721,4 @@ const char* BotDatabase::fail::DeleteAllHealRotations() { return "Failed to dele
/* fail::Bot miscellaneous functions */
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."; }
-45
View File
@@ -148,36 +148,8 @@ public:
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 */
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 ToggleBotGroupAutoSpawn(const uint32 group_id);
/* Bot heal rotation functions */
bool LoadHealRotationIDByBotID(const uint32 bot_id, uint32& hr_index);
@@ -254,23 +226,6 @@ public:
static const char* SaveStopMeleeLevel();
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 */
static const char* LoadGroupedBotsByGroupID();
+32
View File
@@ -17,6 +17,8 @@
*/
#include "bot.h"
#include "bot_command.h"
#include "client.h"
#include "object.h"
#include "raids.h"
#include "doors.h"
@@ -186,6 +188,10 @@ void Bot::ProcessRaidInvite(Mob* invitee, Client* invitor, bool group_invite) {
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);
}
@@ -296,4 +302,30 @@ void Bot::ProcessBotGroupAdd(Group* group, Raid* raid, Client* client, bool new_
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
View File
@@ -1888,11 +1888,15 @@ bool Bot::AIHealRotation(Mob* tar, bool useFastHeals) {
std::list<BotSpell> Bot::GetBotSpellsForSpellEffect(Bot* botCaster, int spellEffect) {
std::list<BotSpell> result;
if (!botCaster) {
return result;
}
if (auto bot_owner = botCaster->GetBotOwner(); !bot_owner) {
return result;
}
if (botCaster && botCaster->AI_HasSpells()) {
if (botCaster->AI_HasSpells()) {
std::vector<BotSpells_Struct> botSpellList = botCaster->AIBot_spells;
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> result;
if (!botCaster) {
return result;
}
if (auto bot_owner = botCaster->GetBotOwner(); !bot_owner) {
return result;
}
if (botCaster && botCaster->AI_HasSpells()) {
if (botCaster->AI_HasSpells()) {
std::vector<BotSpells_Struct> botSpellList = botCaster->AIBot_spells;
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> result;
if (!botCaster) {
return result;
}
if (auto bot_owner = botCaster->GetBotOwner(); !bot_owner) {
return result;
}
if (botCaster && botCaster->AI_HasSpells()) {
if (botCaster->AI_HasSpells()) {
std::vector<BotSpells_Struct> botSpellList = botCaster->AIBot_spells;
for (int i = botSpellList.size() - 1; i >= 0; i--) {
@@ -2694,21 +2706,22 @@ BotSpell Bot::GetBestBotSpellForResistDebuff(Bot* botCaster, Mob *tar) {
result.SpellIndex = 0;
result.ManaCost = 0;
if (!tar)
if (!tar || !botCaster) {
return result;
}
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;
}
bool needsMagicResistDebuff = (tar->GetMR() + level_mod) > 100;
bool needsColdResistDebuff = (tar->GetCR() + level_mod) > 100;
bool needsFireResistDebuff = (tar->GetFR() + level_mod) > 100;
bool needsPoisonResistDebuff = (tar->GetPR() + 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;
for (int i = botSpellList.size() - 1; i >= 0; i--) {
+27 -23
View File
@@ -4162,7 +4162,7 @@ bool Client::GroupFollow(Client* inviter) {
if (iraid == raid) {
//both in same raid
uint32 ngid = raid->GetGroup(inviter->GetName());
if (raid->GroupCount(ngid) < 6) {
if (raid->GroupCount(ngid) < MAX_GROUP_MEMBERS) {
raid->MoveMember(GetName(), ngid);
raid->SendGroupDisband(this);
raid->GroupUpdate(ngid);
@@ -4183,7 +4183,7 @@ bool Client::GroupFollow(Client* inviter) {
if (!GetXTargetAutoMgr()->empty())
SetDirtyAutoHaters();
if (raid->GroupCount(groupToUse) < 6)
if (raid->GroupCount(groupToUse) < MAX_GROUP_MEMBERS)
{
raid->SendRaidCreate(this);
raid->SendMakeLeaderPacketTo(raid->leadername, this);
@@ -7470,15 +7470,17 @@ const char* Client::GetClassPlural(Client* client) {
void Client::SendWebLink(const char *website)
{
size_t len = strlen(website) + 1;
if(website != 0 && len > 1)
{
auto outapp = new EQApplicationPacket(OP_Weblink, sizeof(Weblink_Struct) + len);
Weblink_Struct *wl = (Weblink_Struct*)outapp->pBuffer;
memcpy(wl->weblink, website, len);
wl->weblink[len] = '\0';
if (website) {
size_t len = strlen(website) + 1;
if (len > 1)
{
auto outapp = new EQApplicationPacket(OP_Weblink, sizeof(Weblink_Struct) + len);
Weblink_Struct* wl = (Weblink_Struct*)outapp->pBuffer;
memcpy(wl->weblink, website, len);
wl->weblink[len] = '\0';
FastQueuePacket(&outapp);
FastQueuePacket(&outapp);
}
}
}
@@ -10444,7 +10446,7 @@ void Client::SendToInstance(std::string instance_type, std::string zone_short_na
uint16 instance_id = 0;
if (current_bucket_value.length() > 0) {
instance_id = Strings::ToInt(current_bucket_value.c_str());
instance_id = Strings::ToInt(current_bucket_value);
} else {
if(!database.GetUnusedInstanceID(instance_id)) {
Message(Chat::White, "Server was unable to find a free instance id.");
@@ -11734,20 +11736,22 @@ std::vector<Mob*> Client::GetApplySpellList(
if (apply_type == ApplySpellType::Raid && IsRaidGrouped()) {
auto* r = GetRaid();
auto group_id = r->GetGroup(this);
if (r && EQ::ValueWithin(group_id, 0, (MAX_RAID_GROUPS - 1))) {
for (const auto& m : r->members) {
if (m.member && m.member->IsClient() && (!is_raid_group_only || r->GetGroup(m.member) == group_id)) {
l.push_back(m.member);
if (r) {
auto group_id = r->GetGroup(this);
if (EQ::ValueWithin(group_id, 0, (MAX_RAID_GROUPS - 1))) {
for (const auto& m : r->members) {
if (m.member && m.member->IsClient() && (!is_raid_group_only || r->GetGroup(m.member) == group_id)) {
l.push_back(m.member);
if (allow_pets && m.member->HasPet()) {
l.push_back(m.member->GetPet());
}
if (allow_pets && m.member->HasPet()) {
l.push_back(m.member->GetPet());
}
if (allow_bots) {
const auto& sbl = entity_list.GetBotListByCharacterID(m.member->CharacterID());
for (const auto& b : sbl) {
l.push_back(b);
if (allow_bots) {
const auto& sbl = entity_list.GetBotListByCharacterID(m.member->CharacterID());
for (const auto& b : sbl) {
l.push_back(b);
}
}
}
}
+3 -3
View File
@@ -203,8 +203,8 @@ enum eInnateSkill {
InnateDisabled = 255
};
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_ONE_KEY = "diawind_npc_response_one";
inline const std::string DIAWIND_RESPONSE_TWO_KEY = "diawind_npc_response_two";
const uint32 POPUPID_DIAWIND_ONE = 99999;
const uint32 POPUPID_DIAWIND_TWO = 100000;
const uint32 POPUPID_UPDATE_SHOWSTATSWINDOW = 1000000;
@@ -2033,6 +2033,7 @@ public:
void SetBotSpawnLimit(int new_spawn_limit, uint8 class_id = NO_CLASS);
void CampAllBots(uint8 class_id = NO_CLASS);
void SpawnRaidBotsOnConnect(Raid* raid);
private:
bool bot_owner_options[_booCount];
@@ -2042,7 +2043,6 @@ private:
bool CanTradeFVNoDropItem();
void SendMobPositions();
void PlayerTradeEventLog(Trade *t, Trade *t2);
};
#endif
+10 -30
View File
@@ -607,28 +607,8 @@ void Client::CompleteConnect()
if (raid) {
SetRaidGrouped(true);
raid->LearnMembers();
std::list<BotsAvailableList> bots_list;
database.botdb.LoadBotsList(this->CharacterID(), bots_list);
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());
}
}
}
}
if (RuleB(Bots, Enabled)) {
SpawnRaidBotsOnConnect(raid);
}
raid->VerifyRaid();
raid->GetRaidDetails();
@@ -867,7 +847,7 @@ void Client::CompleteConnect()
CalcItemScale();
DoItemEnterZone();
if (zone->GetZoneID() == RuleI(World, GuildBankZoneID) && GuildBanks)
if (zone->GetZoneID() == Zones::GUILDHALL && GuildBanks)
GuildBanks->SendGuildBank(this);
if (ClientVersion() >= EQ::versions::ClientVersion::SoD)
@@ -1426,7 +1406,7 @@ void Client::Handle_Connect_OP_ZoneEntry(const EQApplicationPacket *app)
}
}
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()));
}
m_pp.guildbanker = GuildBanker;
@@ -7446,7 +7426,7 @@ void Client::Handle_OP_GuildBank(const EQApplicationPacket *app)
if (!GuildBanks)
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.");
@@ -7796,7 +7776,7 @@ void Client::Handle_OP_GuildCreate(const EQApplicationPacket *app)
{
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);
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.");
return;
}
if (zone->GetZoneID() == RuleI(World, GuildBankZoneID) && GuildBanks)
if (zone->GetZoneID() == Zones::GUILDHALL && GuildBanks)
GuildBanks->SendGuildBank(this);
}
}
@@ -11795,13 +11775,13 @@ void Client::Handle_OP_RaidCommand(const EQApplicationPacket* app)
Bot* player_to_invite = nullptr;
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) {
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)) {
MessageString(Chat::Red, ALREADY_IN_PARTY);
break;
+22 -21
View File
@@ -689,61 +689,61 @@ bool Client::Process() {
/* Just a set of actions preformed all over in Client::Process */
void Client::OnDisconnect(bool hard_disconnect) {
if(hard_disconnect)
{
if (hard_disconnect) {
LeaveGroup();
if (GetMerc())
{
if (GetMerc()) {
GetMerc()->Save();
GetMerc()->Depop();
}
Raid *MyRaid = entity_list.GetRaidByClient(this);
if (MyRaid)
MyRaid->MemberZoned(this);
auto* r = entity_list.GetRaidByClient(this);
RecordPlayerEventLog(PlayerEvent::WENT_OFFLINE, PlayerEvent::EmptyEvent{});
if (parse->PlayerHasQuestSub(EVENT_DISCONNECT)) {
parse->EventPlayer(EVENT_DISCONNECT, this, "", 0);
if (r) {
r->MemberZoned(this);
}
/* QS: PlayerLogConnectDisconnect */
if (RuleB(QueryServ, PlayerLogConnectDisconnect)){
if (RuleB(QueryServ, PlayerLogConnectDisconnect)) {
std::string event_desc = StringFormat("Disconnect :: in zoneid:%i instid:%i", GetZoneID(), GetInstanceID());
QServ->PlayerLogEvent(Player_Log_Connect_State, CharacterID(), event_desc);
}
}
if (!bZoning)
{
if (!bZoning) {
SetDynamicZoneMemberStatus(DynamicZoneMemberStatus::Offline);
}
RemoveAllAuras();
Mob *Other = trade->With();
if(Other)
{
auto* o = trade->With();
if (o) {
LogTrading("Client disconnected during a trade. Returning their items");
FinishTrade(this);
if(Other->IsClient())
Other->CastToClient()->FinishTrade(Other);
if (o->IsClient()) {
o->CastToClient()->FinishTrade(o);
}
/* Reset both sides of the trade */
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.
/* Remove ourself from all proximities */
/* Remove from all proximities */
ClearAllProximities();
auto outapp = new EQApplicationPacket(OP_LogoutReply);
FastQueuePacket(&outapp);
RecordPlayerEventLog(PlayerEvent::WENT_OFFLINE, PlayerEvent::EmptyEvent{});
if (parse->PlayerHasQuestSub(EVENT_DISCONNECT)) {
parse->EventPlayer(EVENT_DISCONNECT, this, "", 0);
}
Disconnect();
}
@@ -1145,6 +1145,7 @@ void Client::OPMemorizeSpell(const EQApplicationPacket* app)
const auto* item = inst->GetItem();
if (
item &&
RuleB(Character, RestrictSpellScribing) &&
!item->IsEquipable(GetRace(), GetClass())
) {
+1 -2
View File
@@ -392,8 +392,7 @@ Corpse::Corpse(Client* client, int32 in_rezexp) : Mob (
/* Check Rule to see if we can leave corpses */
if (
!RuleB(Character, LeaveNakedCorpses) ||
RuleB(Character, LeaveCorpses) &&
(!RuleB(Character, LeaveNakedCorpses) || RuleB(Character, LeaveCorpses)) &&
GetLevel() >= RuleI(Character, DeathItemLossLevel)
) {
// cash
+1 -1
View File
@@ -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])) {
expires_time_unix = (long long) std::time(nullptr) + Strings::TimeToSeconds(expires_time);
} 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);
}
}
+3 -3
View File
@@ -199,7 +199,7 @@ void DialogueWindow::Render(Client *c, std::string markdown)
// set the popup id
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), "");
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
// 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 = fmt::format(
"<c \"#F07F00\">Click [{}] to continue...</c>",
+1 -1
View File
@@ -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);
if (sender->TryMovePCDynamicZoneSwitch(m_dz_switch_id)) {
safe_delete(outapp);
+3 -2
View File
@@ -520,8 +520,6 @@ bool PerlembParser::SpellHasQuestSub(uint32 spell_id, QuestEventID evt)
bool PerlembParser::ItemHasQuestSub(EQ::ItemInstance *itm, QuestEventID evt)
{
std::stringstream package_name;
package_name << "qst_item_" << itm->GetID();
if (!perl) {
return false;
@@ -535,6 +533,9 @@ bool PerlembParser::ItemHasQuestSub(EQ::ItemInstance *itm, QuestEventID evt)
return false;
}
std::stringstream package_name;
package_name << "qst_item_" << itm->GetID();
const char *subname = QuestEventSubroutines[evt];
auto iter = item_quest_status_.find(itm->GetID());
+9 -9
View File
@@ -55,23 +55,23 @@ void DoorManipulation::CommandHandler(Client *c, const Seperator *sep)
float set_size = 0.0f;
if (arg2 == move_x_action) {
x_move = Strings::ToFloat(arg3.c_str());
x_move = Strings::ToFloat(arg3);
}
if (arg2 == move_y_action) {
y_move = Strings::ToFloat(arg3.c_str());
y_move = Strings::ToFloat(arg3);
}
if (arg2 == move_z_action) {
z_move = Strings::ToFloat(arg3.c_str());
z_move = Strings::ToFloat(arg3);
}
if (arg2 == move_h_action) {
h_move = Strings::ToFloat(arg3.c_str());
h_move = Strings::ToFloat(arg3);
}
if (arg2 == set_size_action) {
set_size = Strings::ToFloat(arg3.c_str());
set_size = Strings::ToFloat(arg3);
}
door->SetLocation(
@@ -370,7 +370,7 @@ void DoorManipulation::CommandHandler(Client *c, const Seperator *sep)
if (arg1 == "opentype" && !arg2.empty() && Strings::IsNumber(arg2)) {
Doors *door = entity_list.GetDoorsByID(c->GetDoorToolEntityId());
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)) {
Doors *door = entity_list.GetDoorsByID(c->GetDoorToolEntityId());
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)) {
Doors *door = entity_list.GetDoorsByID(c->GetDoorToolEntityId());
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)) {
Doors *door = entity_list.GetDoorsByID(c->GetDoorToolEntityId());
if (door) {
door->SetIncline(door->GetIncline() + Strings::ToInt(arg2.c_str()));
door->SetIncline(door->GetIncline() + Strings::ToInt(arg2));
}
}
+1 -1
View File
@@ -107,7 +107,7 @@ void command_faction(Client *c, const Seperator *sep)
)
) {
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)) {
c->Message(
Chat::White,
+25 -18
View File
@@ -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
if(InZone && newmember->IsClient())
if(InZone && newmember && newmember->IsClient())
{
if(IsLeader(members[i]))
{
@@ -307,13 +307,13 @@ bool Group::AddMember(Mob* newmember, const char *NewMemberName, uint32 Characte
else
{
strcpy(newmember->CastToClient()->GetPP().groupMembers[x], members[i]->GetCleanName());
x++;
++x;
}
}
}
}
if(InZone)
if(InZone && newmember)
{
//put new member in his own list.
newmember->SetGrouped(true);
@@ -545,7 +545,6 @@ bool Group::UpdatePlayer(Mob* update) {
}
void Group::MemberZoned(Mob* removemob) {
uint32 i;
if (!removemob) {
return;
@@ -557,21 +556,21 @@ void Group::MemberZoned(Mob* removemob) {
//should NOT clear the name, it is used for world communication.
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;
}
}
if (removemob->IsClient() && HasRole(removemob, RoleAssist)) {
SetGroupAssistTarget(0);
SetGroupAssistTarget(nullptr);
}
if (removemob->IsClient() && HasRole(removemob, RoleTank)) {
SetGroupTankTarget(0);
SetGroupTankTarget(nullptr);
}
if (removemob->IsClient() && HasRole(removemob, RolePuller)) {
SetGroupPullerTarget(0);
SetGroupPullerTarget(nullptr);
}
if (removemob->IsClient() && removemob == mentoree) {
@@ -1158,17 +1157,26 @@ bool Group::LearnMembers() {
"Error getting group members for group [{}]",
GetID()
);
return false;
}
int memberIndex = 0;
for (const auto& member : rows) {
if (member.name.empty()) {
continue;
if (memberIndex >= MAX_GROUP_MEMBERS) {
LogError(
"Too many members in group [{}]",
GetID()
);
break;
}
members[memberIndex] = nullptr;
strn0cpy(membername[memberIndex], member.name.c_str(), 64);
memberIndex++;
if (member.name.empty()) {
members[memberIndex] = nullptr;
membername[memberIndex][0] = '\0';
} else {
members[memberIndex] = nullptr;
strn0cpy(membername[memberIndex], member.name.c_str(), 64);
}
++memberIndex;
}
VerifyGroup();
@@ -1189,13 +1197,12 @@ void Group::VerifyGroup() {
}
Mob *them = entity_list.GetMob(membername[i]);
if(them == nullptr && members[i] != nullptr) { //they aren't in zone
membername[i][0] = '\0';
if (!them && members[i]) { //they aren't in zone
members[i] = nullptr;
continue;
}
if(them != nullptr && members[i] != them) { //our pointer is out of date... not so good.
if (them != nullptr && members[i] != them) { //our pointer is out of date... not so good.
members[i] = them;
continue;
}
@@ -2491,4 +2498,4 @@ bool Group::IsLeader(const char* name) {
}
return false;
}
}
+5 -5
View File
@@ -153,11 +153,11 @@ public:
bool DoesAnyMemberHaveExpeditionLockout(const std::string& expedition_name, const std::string& event_name, int max_check_count = 0);
Mob* members[MAX_GROUP_MEMBERS];
char membername[MAX_GROUP_MEMBERS][64];
uint8 MemberRoles[MAX_GROUP_MEMBERS];
bool disbandcheck;
bool castspell;
Mob* members[MAX_GROUP_MEMBERS] {nullptr};
char membername[MAX_GROUP_MEMBERS][64] {""};
uint8 MemberRoles[MAX_GROUP_MEMBERS] {0};
bool disbandcheck {false};
bool castspell {false};
private:
Mob* leader;
+1 -1
View File
@@ -236,7 +236,7 @@ void Client::RefreshGuildInfo()
guild_id = info.guild_id;
GuildBanker = info.banker || guild_mgr.IsGuildLeader(GuildID(), CharacterID());
if(((int)zone->GetZoneID() == RuleI(World, GuildBankZoneID)))
if(zone->GetZoneID() == Zones::GUILDHALL)
{
if(WasBanker != GuildBanker)
{
+31 -26
View File
@@ -483,20 +483,22 @@ Mob *HateList::GetEntWithMostHateOnList(Mob *center, Mob *skip, bool skip_mezzed
while (iterator != list.end())
{
struct_HateList *cur = (*iterator);
if (cur->entity_on_hatelist == skip) {
++iterator;
continue;
}
if (cur) {
if (cur->entity_on_hatelist == skip) {
++iterator;
continue;
}
if (skip_mezzed && cur->entity_on_hatelist->IsMezzed()) {
++iterator;
continue;
}
if (skip_mezzed && cur->entity_on_hatelist->IsMezzed()) {
++iterator;
continue;
}
if (cur->entity_on_hatelist != nullptr && ((cur->stored_hate_amount > hate) || cur->is_entity_frenzy))
{
top_hate = cur->entity_on_hatelist;
hate = cur->stored_hate_amount;
if (cur->entity_on_hatelist != nullptr && ((cur->stored_hate_amount > hate) || cur->is_entity_frenzy))
{
top_hate = cur->entity_on_hatelist;
hate = cur->stored_hate_amount;
}
}
++iterator;
}
@@ -516,24 +518,27 @@ Mob *HateList::GetEntWithMostHateOnList(bool skip_mezzed){
while (iterator != list.end())
{
struct_HateList *cur = (*iterator);
LogHateDetail(
"Looping GetEntWithMostHateOnList1 [{}] cur [{}] hate [{}] calc [{}]",
cur->entity_on_hatelist->GetMobDescription(),
cur->stored_hate_amount,
hate,
(cur->stored_hate_amount > hate)
);
if (cur && cur->entity_on_hatelist != nullptr && (cur->stored_hate_amount > hate))
{
if (cur) {
LogHateDetail(
"Looping GetEntWithMostHateOnList2 [{}]",
cur->entity_on_hatelist->GetMobDescription()
"Looping GetEntWithMostHateOnList1 [{}] cur [{}] hate [{}] calc [{}]",
cur->entity_on_hatelist->GetMobDescription(),
cur->stored_hate_amount,
hate,
(cur->stored_hate_amount > hate)
);
if (!skip_mezzed || !cur->entity_on_hatelist->IsMezzed()) {
top = cur->entity_on_hatelist;
hate = cur->stored_hate_amount;
if (cur->entity_on_hatelist != nullptr && (cur->stored_hate_amount > hate))
{
LogHateDetail(
"Looping GetEntWithMostHateOnList2 [{}]",
cur->entity_on_hatelist->GetMobDescription()
);
if (!skip_mezzed || !cur->entity_on_hatelist->IsMezzed()) {
top = cur->entity_on_hatelist;
hate = cur->stored_hate_amount;
}
}
}
++iterator;
+2 -2
View File
@@ -170,7 +170,7 @@ bool HealRotation::ClearMemberPool()
if (!ClearTargetPool())
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)
member_iter->LeaveHealRotationMemberPool();
@@ -183,7 +183,7 @@ bool HealRotation::ClearTargetPool()
m_hot_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)
target_iter->LeaveHealRotationTargetPool();
+11 -8
View File
@@ -717,12 +717,15 @@ bool Client::SummonItem(uint32 item_id, int16 charges, uint32 aug1, uint32 aug2,
EQ::ItemInstance* inst = database.CreateItem(item, charges);
auto timestamps = database.GetItemRecastTimestamps(CharacterID());
const auto* d = inst->GetItem();
if (d->RecastDelay) {
if (d->RecastType != RECAST_TYPE_UNLINKED_ITEM) {
inst->SetRecastTimestamp(timestamps.count(d->RecastType) ? timestamps.at(d->RecastType) : 0);
} else {
inst->SetRecastTimestamp(timestamps.count(d->ID) ? timestamps.at(d->ID) : 0);
if (inst) {
const auto* d = inst->GetItem();
if (d->RecastDelay) {
if (d->RecastType != RECAST_TYPE_UNLINKED_ITEM) {
inst->SetRecastTimestamp(timestamps.count(d->RecastType) ? timestamps.at(d->RecastType) : 0);
}
else {
inst->SetRecastTimestamp(timestamps.count(d->ID) ? timestamps.at(d->ID) : 0);
}
}
}
@@ -2043,8 +2046,8 @@ bool Client::SwapItem(MoveItem_Struct* move_in) {
}
if ((srcbagid && srcbag->GetItem()->BagType == EQ::item::BagTypeTradersSatchel) ||
(dstbagid && dstbag->GetItem()->BagType == EQ::item::BagTypeTradersSatchel) ||
(srcitemid && src_inst->GetItem()->BagType == EQ::item::BagTypeTradersSatchel) ||
(dstitemid && dst_inst->GetItem()->BagType == EQ::item::BagTypeTradersSatchel)) {
(srcitemid && src_inst && src_inst->GetItem()->BagType == EQ::item::BagTypeTradersSatchel) ||
(dstitemid && dst_inst && dst_inst->GetItem()->BagType == EQ::item::BagTypeTradersSatchel)) {
Trader_EndTrader();
Message(Chat::Red,"You cannot move your Trader Satchels, or items inside them, while Trading.");
}
+2 -2
View File
@@ -2828,7 +2828,7 @@ luabind::object Lua_Client::GetPEQZoneFlags(lua_State* L) {
if (d_) {
auto self = reinterpret_cast<NativeType*>(d_);
auto l = self->GetPEQZoneFlags();
auto i = 0;
auto i = 1;
for (const auto& f : l) {
t[i] = f;
i++;
@@ -2843,7 +2843,7 @@ luabind::object Lua_Client::GetZoneFlags(lua_State* L) {
if (d_) {
auto self = reinterpret_cast<NativeType*>(d_);
auto l = self->GetZoneFlags();
auto i = 0;
auto i = 1;
for (const auto& f : l) {
t[i] = f;
i++;
+13 -5
View File
@@ -907,12 +907,12 @@ std::string lua_say_link(const char *phrase) {
}
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 rule_value;
RuleManager::Instance()->GetRule(rule_name.c_str(), rule_value);
RuleManager::Instance()->GetRule(rule_name, 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);
for (int i = 0; i < instance_ids.size(); i++) {
ret[i] = instance_ids[i];
ret[i + 1] = instance_ids[i];
}
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);
for (int i = 0; i < instance_ids.size(); i++) {
ret[i] = instance_ids[i];
ret[i + 1] = instance_ids[i];
}
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_by_char_id", &lua_get_instance_id_by_char_id),
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_by_id", &lua_get_instance_timer_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_points", &lua_add_ldon_points),
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_deity_name", &lua_get_deity_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,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,uint8))&lua_world_wide_remove_spell),
luabind::def("world_wide_remove_spell", (void(*)(uint32,uint8,uint8))&lua_world_wide_remove_spell),
+1 -1
View File
@@ -2709,7 +2709,7 @@ luabind::object Lua_Mob::GetEntityVariables(lua_State* L) {
if (d_) {
auto self = reinterpret_cast<NativeType*>(d_);
auto l = self->GetEntityVariables();
auto i = 0;
auto i = 1;
for (const auto& v : l) {
t[i] = v;
i++;
+1 -1
View File
@@ -173,7 +173,7 @@ luabind::object Lua_Object::GetEntityVariables(lua_State* L) {
if (d_) {
auto self = reinterpret_cast<NativeType*>(d_);
auto l = self->GetEntityVariables();
auto i = 0;
auto i = 1;
for (const auto& v : l) {
t[i] = v;
i++;
+4 -4
View File
@@ -172,7 +172,7 @@ int main(int argc, char** argv) {
if (zone_port.size() > 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());
@@ -193,7 +193,7 @@ int main(int argc, char** argv) {
if (zone_port.size() > 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());
@@ -214,7 +214,7 @@ int main(int argc, char** argv) {
if (zone_port.size() > 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());
@@ -380,7 +380,7 @@ int main(int argc, char** argv) {
std::string tmp;
if (database.GetVariable("RuleSet", tmp)) {
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());
}
}
+67 -56
View File
@@ -3261,6 +3261,10 @@ MercSpell Merc::GetBestMercSpellForTargetedAENuke(Merc* caster, Mob* tar) {
result.proc_chance = 0;
result.time_cancast = 0;
if (!caster) {
return result;
}
switch(caster->GetStance())
{
case EQ::constants::stanceBurnAE:
@@ -3272,28 +3276,26 @@ MercSpell Merc::GetBestMercSpellForTargetedAENuke(Merc* caster, Mob* tar) {
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();
++mercSpellListItr) {
// Assuming all the spells have been loaded into this list by level and in descending order
if(IsAENukeSpell(mercSpellListItr->spellid) && !IsAERainNukeSpell(mercSpellListItr->spellid)
&& !IsPBAENukeSpell(mercSpellListItr->spellid) && CheckSpellRecastTimers(caster, mercSpellListItr->spellid)) {
uint8 numTargets = 0;
if(CheckAENuke(caster, tar, mercSpellListItr->spellid, numTargets)) {
if(numTargets >= numTargetsCheck && zone->random.Roll(castChance)) {
result.spellid = mercSpellListItr->spellid;
result.stance = mercSpellListItr->stance;
result.type = mercSpellListItr->type;
result.slot = mercSpellListItr->slot;
result.proc_chance = mercSpellListItr->proc_chance;
result.time_cancast = mercSpellListItr->time_cancast;
}
for (auto mercSpellListItr = mercSpellList.begin(); mercSpellListItr != mercSpellList.end();
++mercSpellListItr) {
// Assuming all the spells have been loaded into this list by level and in descending order
if(IsAENukeSpell(mercSpellListItr->spellid) && !IsAERainNukeSpell(mercSpellListItr->spellid)
&& !IsPBAENukeSpell(mercSpellListItr->spellid) && CheckSpellRecastTimers(caster, mercSpellListItr->spellid)) {
uint8 numTargets = 0;
if(CheckAENuke(caster, tar, mercSpellListItr->spellid, numTargets)) {
if(numTargets >= numTargetsCheck && zone->random.Roll(castChance)) {
result.spellid = mercSpellListItr->spellid;
result.stance = mercSpellListItr->stance;
result.type = mercSpellListItr->type;
result.slot = mercSpellListItr->slot;
result.proc_chance = mercSpellListItr->proc_chance;
result.time_cancast = mercSpellListItr->time_cancast;
}
}
break;
}
break;
}
}
@@ -3313,6 +3315,10 @@ MercSpell Merc::GetBestMercSpellForPBAENuke(Merc* caster, Mob* tar) {
result.proc_chance = 0;
result.time_cancast = 0;
if (!caster) {
return result;
}
switch(caster->GetStance())
{
case EQ::constants::stanceBurnAE:
@@ -3324,27 +3330,25 @@ MercSpell Merc::GetBestMercSpellForPBAENuke(Merc* caster, Mob* tar) {
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();
++mercSpellListItr) {
// Assuming all the spells have been loaded into this list by level and in descending order
if(IsPBAENukeSpell(mercSpellListItr->spellid) && CheckSpellRecastTimers(caster, mercSpellListItr->spellid)) {
uint8 numTargets = 0;
if(CheckAENuke(caster, caster, mercSpellListItr->spellid, numTargets)) {
if(numTargets >= numTargetsCheck && zone->random.Roll(castChance)) {
result.spellid = mercSpellListItr->spellid;
result.stance = mercSpellListItr->stance;
result.type = mercSpellListItr->type;
result.slot = mercSpellListItr->slot;
result.proc_chance = mercSpellListItr->proc_chance;
result.time_cancast = mercSpellListItr->time_cancast;
}
for (auto mercSpellListItr = mercSpellList.begin(); mercSpellListItr != mercSpellList.end();
++mercSpellListItr) {
// Assuming all the spells have been loaded into this list by level and in descending order
if(IsPBAENukeSpell(mercSpellListItr->spellid) && CheckSpellRecastTimers(caster, mercSpellListItr->spellid)) {
uint8 numTargets = 0;
if(CheckAENuke(caster, caster, mercSpellListItr->spellid, numTargets)) {
if(numTargets >= numTargetsCheck && zone->random.Roll(castChance)) {
result.spellid = mercSpellListItr->spellid;
result.stance = mercSpellListItr->stance;
result.type = mercSpellListItr->type;
result.slot = mercSpellListItr->slot;
result.proc_chance = mercSpellListItr->proc_chance;
result.time_cancast = mercSpellListItr->time_cancast;
}
break;
}
break;
}
}
@@ -3364,6 +3368,10 @@ MercSpell Merc::GetBestMercSpellForAERainNuke(Merc* caster, Mob* tar) {
result.proc_chance = 0;
result.time_cancast = 0;
if (!caster) {
return result;
}
switch(caster->GetStance())
{
case EQ::constants::stanceBurnAE:
@@ -3375,27 +3383,25 @@ MercSpell Merc::GetBestMercSpellForAERainNuke(Merc* caster, Mob* tar) {
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();
++mercSpellListItr) {
// Assuming all the spells have been loaded into this list by level and in descending order
if(IsAERainNukeSpell(mercSpellListItr->spellid) && zone->random.Roll(castChance) && CheckSpellRecastTimers(caster, mercSpellListItr->spellid)) {
uint8 numTargets = 0;
if(CheckAENuke(caster, tar, mercSpellListItr->spellid, numTargets)) {
if(numTargets >= numTargetsCheck) {
result.spellid = mercSpellListItr->spellid;
result.stance = mercSpellListItr->stance;
result.type = mercSpellListItr->type;
result.slot = mercSpellListItr->slot;
result.proc_chance = mercSpellListItr->proc_chance;
result.time_cancast = mercSpellListItr->time_cancast;
}
for (auto mercSpellListItr = mercSpellList.begin(); mercSpellListItr != mercSpellList.end();
++mercSpellListItr) {
// Assuming all the spells have been loaded into this list by level and in descending order
if(IsAERainNukeSpell(mercSpellListItr->spellid) && zone->random.Roll(castChance) && CheckSpellRecastTimers(caster, mercSpellListItr->spellid)) {
uint8 numTargets = 0;
if(CheckAENuke(caster, tar, mercSpellListItr->spellid, numTargets)) {
if(numTargets >= numTargetsCheck) {
result.spellid = mercSpellListItr->spellid;
result.stance = mercSpellListItr->stance;
result.type = mercSpellListItr->type;
result.slot = mercSpellListItr->slot;
result.proc_chance = mercSpellListItr->proc_chance;
result.time_cancast = mercSpellListItr->time_cancast;
}
break;
}
break;
}
}
@@ -4302,7 +4308,12 @@ Merc* Merc::LoadMerc(Client *c, MercTemplate* merc_template, uint32 merchant_id,
if(merc_template)
{
//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 = content_db.GetMercType(merc_template->MercNPCID, merc_template->RaceID, c->GetLevel());
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());
}
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.
+16 -16
View File
@@ -1135,7 +1135,6 @@ void Mob::SetSpawnLastNameByClass(NewSpawn_Struct* ns)
strcpy(ns->spawn.lastName, "Mercenary Liaison");
break;
default:
strcpy(ns->spawn.lastName, ns->spawn.lastName);
break;
}
}
@@ -5110,6 +5109,10 @@ void Mob::TarGlobal(const char *varname, const char *value, const char *duration
void Mob::DelGlobal(const char *varname) {
if (!zone) {
return;
}
int qgZoneid=zone->GetZoneID();
int qgCharid=0;
int qgNpcid=0;
@@ -5130,22 +5133,19 @@ void Mob::DelGlobal(const char *varname) {
database.QueryDatabase(query);
if(zone)
{
auto pack = new ServerPacket(ServerOP_QGlobalDelete, sizeof(ServerQGlobalDelete_Struct));
ServerQGlobalDelete_Struct *qgu = (ServerQGlobalDelete_Struct*)pack->pBuffer;
auto pack = new ServerPacket(ServerOP_QGlobalDelete, sizeof(ServerQGlobalDelete_Struct));
ServerQGlobalDelete_Struct *qgu = (ServerQGlobalDelete_Struct*)pack->pBuffer;
qgu->npc_id = qgNpcid;
qgu->char_id = qgCharid;
qgu->zone_id = qgZoneid;
strcpy(qgu->name, varname);
qgu->npc_id = qgNpcid;
qgu->char_id = qgCharid;
qgu->zone_id = qgZoneid;
strcpy(qgu->name, varname);
entity_list.DeleteQGlobal(std::string((char*)qgu->name), qgu->npc_id, qgu->char_id, qgu->zone_id);
zone->DeleteQGlobal(std::string((char*)qgu->name), qgu->npc_id, qgu->char_id, qgu->zone_id);
entity_list.DeleteQGlobal(std::string((char*)qgu->name), qgu->npc_id, qgu->char_id, qgu->zone_id);
zone->DeleteQGlobal(std::string((char*)qgu->name), qgu->npc_id, qgu->char_id, qgu->zone_id);
worldserver.SendPacket(pack);
safe_delete(pack);
}
worldserver.SendPacket(pack);
safe_delete(pack);
}
// Inserts global variable into quest_globals table
@@ -6976,9 +6976,9 @@ std::string Mob::GetBucketKey() {
std::string Mob::GetBucketRemaining(std::string bucket_name) {
std::string full_bucket_name = fmt::format("{}-{}", GetBucketKey(), 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;
} else if (Strings::ToInt(bucket_remaining.c_str()) == 0) {
} else if (Strings::ToInt(bucket_remaining) == 0) {
return "0";
}
return std::string();
+1 -1
View File
@@ -445,7 +445,7 @@ Pet::Pet(NPCType *type_data, Mob *owner, PetType type, uint16 spell_id, int16 po
GiveNPCTypeData(type_data);
typeofpet = type;
petpower = power;
SetOwnerID(owner->GetID());
SetOwnerID(owner ? owner->GetID() : 0);
SetPetSpellID(spell_id);
// All pets start at false on newer clients. The client
+24 -24
View File
@@ -3535,71 +3535,71 @@ std::string QuestManager::GetEncounter() const {
void QuestManager::UpdateZoneHeader(std::string type, std::string value) {
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) {
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) {
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) {
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) {
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) {
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) {
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) {
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) {
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) {
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) {
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) {
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) {
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) {
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) {
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) {
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) {
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) {
zone->newzone_data.underworld = Strings::ToFloat(value.c_str());
zone->newzone_data.underworld = Strings::ToFloat(value);
} 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) {
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) {
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) {
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) {
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) {
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));
+2 -2
View File
@@ -631,7 +631,7 @@ uint32 Raid::GetPlayerIndex(Client *c)
Client *Raid::GetClientByIndex(uint16 index)
{
if (index > MAX_RAID_MEMBERS) {
if (index >= MAX_RAID_MEMBERS) {
return nullptr;
}
@@ -2204,4 +2204,4 @@ void Raid::SetNewRaidLeader(uint32 i)
}
}
}
}
}
+1 -1
View File
@@ -150,7 +150,7 @@ bool Spawn2::Process() {
//grab our spawn group
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;
}
+57 -41
View File
@@ -147,9 +147,10 @@ bool Mob::SpellEffect(Mob* caster, uint16 spell_id, float partial, int level_ove
if (spells[spell_id].hit_number > 0) {
int numhit = spells[spell_id].hit_number;
numhit += numhit * caster->GetFocusEffect(focusFcLimitUse, spell_id) / 100;
numhit += caster->GetFocusEffect(focusIncreaseNumHits, spell_id);
if (caster) {
numhit += numhit * caster->GetFocusEffect(focusFcLimitUse, spell_id) / 100;
numhit += caster->GetFocusEffect(focusIncreaseNumHits, spell_id);
}
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()) {
viral_timer.Start(1000);
}
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
if (buffslot >= 0) {
//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);
}
break;
@@ -819,20 +820,20 @@ bool Mob::SpellEffect(Mob* caster, uint16 spell_id, float partial, int level_ove
// 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
if(spells[spell_id].no_resist)
if (spells[spell_id].no_resist) {
bBreak = true;
if (!bBreak)
{
int resistMod = static_cast<int>(partial) + (GetCHA()/25);
resistMod = resistMod > 100 ? 100 : resistMod;
buffs[buffslot].ticsremaining = resistMod * buffs[buffslot].ticsremaining / 100;
}
if (IsClient() || IsBot())
{
if(buffs[buffslot].ticsremaining > RuleI(Character, MaxCharmDurationForPlayerCharacter))
if (buffslot > -1) {
if (!bBreak) {
int resistMod = static_cast<int>(partial) + (GetCHA() / 25);
resistMod = resistMod > 100 ? 100 : resistMod;
buffs[buffslot].ticsremaining = resistMod * buffs[buffslot].ticsremaining / 100;
}
if (IsOfClientBot() && buffs[buffslot].ticsremaining > RuleI(Character, MaxCharmDurationForPlayerCharacter)) {
buffs[buffslot].ticsremaining = RuleI(Character, MaxCharmDurationForPlayerCharacter);
}
}
break;
@@ -887,8 +888,7 @@ bool Mob::SpellEffect(Mob* caster, uint16 spell_id, float partial, int level_ove
#ifdef SPELL_EFFECT_SPAM
snprintf(effect_desc, _EDLEN, "Fear: %+i", effect_value);
#endif
if (IsClient() || IsBot())
{
if (IsOfClientBot() && buffslot > -1) {
if (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();
if (currently_fleeing)
{
if (currently_fleeing) {
break;
}
}
else
{
else if (buffslot > -1) {
Stun(buffs[buffslot].ticsremaining * 6000 - (6000 - tic_timer.GetRemainingTime()));
}
break;
@@ -1307,8 +1305,9 @@ bool Mob::SpellEffect(Mob* caster, uint16 spell_id, float partial, int level_ove
#ifdef SPELL_EFFECT_SPAM
snprintf(effect_desc, _EDLEN, "Invulnerability");
#endif
if(spell_id==4789) // Touch of the Divine - Divine Save
buffs[buffslot].ticsremaining = spells[spell_id].buff_duration; // Prevent focus/aa buff extension
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
SetInvul(true);
break;
@@ -1355,7 +1354,9 @@ bool Mob::SpellEffect(Mob* caster, uint16 spell_id, float partial, int level_ove
#ifdef SPELL_EFFECT_SPAM
snprintf(effect_desc, _EDLEN, "Melee Absorb Rune: %+i", effect_value);
#endif
buffs[buffslot].melee_rune = effect_value;
if (buffslot > -1) {
buffs[buffslot].melee_rune = effect_value;
}
break;
}
@@ -1364,47 +1365,60 @@ bool Mob::SpellEffect(Mob* caster, uint16 spell_id, float partial, int level_ove
#ifdef SPELL_EFFECT_SPAM
snprintf(effect_desc, _EDLEN, "Spell Absorb Rune: %+i", effect_value);
#endif
if(effect_value > 0)
if (effect_value > 0 && buffslot > -1) {
buffs[buffslot].magic_rune = effect_value;
}
break;
}
case SE_MitigateMeleeDamage:
{
buffs[buffslot].melee_rune = spells[spell_id].max_value[i];
if (buffslot > -1) {
buffs[buffslot].melee_rune = spells[spell_id].max_value[i];
}
break;
}
case SE_MeleeThresholdGuard:
{
buffs[buffslot].melee_rune = spells[spell_id].max_value[i];
if (buffslot > -1) {
buffs[buffslot].melee_rune = spells[spell_id].max_value[i];
}
break;
}
case SE_SpellThresholdGuard:
{
buffs[buffslot].magic_rune = spells[spell_id].max_value[i];
if (buffslot > -1) {
buffs[buffslot].magic_rune = spells[spell_id].max_value[i];
}
break;
}
case SE_MitigateSpellDamage:
{
buffs[buffslot].magic_rune = spells[spell_id].max_value[i];
if (buffslot > -1) {
buffs[buffslot].magic_rune = spells[spell_id].max_value[i];
}
break;
}
case SE_MitigateDotDamage:
{
buffs[buffslot].dot_rune = spells[spell_id].max_value[i];
if (buffslot > -1) {
buffs[buffslot].dot_rune = spells[spell_id].max_value[i];
}
break;
}
case SE_DistanceRemoval:
{
buffs[buffslot].caston_x = int(GetX());
buffs[buffslot].caston_y = int(GetY());
buffs[buffslot].caston_z = int(GetZ());
if (buffslot > -1) {
buffs[buffslot].caston_x = int(GetX());
buffs[buffslot].caston_y = int(GetY());
buffs[buffslot].caston_z = int(GetZ());
}
break;
}
@@ -1434,7 +1448,9 @@ bool Mob::SpellEffect(Mob* caster, uint16 spell_id, float partial, int level_ove
caster->spellbonuses.UnfailingDivinity;
}
buffs[buffslot].ExtraDIChance = mod;
if (buffslot > -1) {
buffs[buffslot].ExtraDIChance = mod;
}
break;
}
@@ -1694,7 +1710,7 @@ bool Mob::SpellEffect(Mob* caster, uint16 spell_id, float partial, int level_ove
#endif
rooted = true;
if (caster){
if (caster && buffslot > -1) {
buffs[buffslot].RootBreakChance = caster->aabonuses.RootBreakChance +
caster->itembonuses.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());
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.");
break;
}
@@ -1802,7 +1818,7 @@ bool Mob::SpellEffect(Mob* caster, uint16 spell_id, float partial, int level_ove
{
if (IsClient()) {
Client* client_target = CastToClient();
if (client_target->IsGrouped()) {
if (client_target && client_target->IsGrouped()) {
Group* group = client_target->GetGroup();
if (!group->IsGroupMember(caster)) {
if (caster != this) {
@@ -1815,7 +1831,7 @@ bool Mob::SpellEffect(Mob* caster, uint16 spell_id, float partial, int level_ove
Raid *raid = caster->GetRaid();
uint32 group_id = raid->GetGroup(caster->GetName());
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);
break;
}
@@ -2948,10 +2964,10 @@ bool Mob::SpellEffect(Mob* caster, uint16 spell_id, float partial, int level_ove
if (caster && !caster->IsClient())
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]);
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);
}
break;
+2
View File
@@ -358,6 +358,7 @@
#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 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 PETITION_NO_DELETE 5053 //You do not have a petition in the queue.
#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 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 GROUP_IS_FULL 12000 //You cannot join that group, it is full.
#define FACE_ACCEPTED 12028 //Facial features accepted.
#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.
+2 -4
View File
@@ -209,8 +209,7 @@ void Trap::Trigger(Mob* trigger)
{
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));
CombatDamage_Struct* a = (CombatDamage_Struct*)outapp->pBuffer;
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;
charid = trigger->CastToClient()->CharacterID();
}
+15 -12
View File
@@ -116,7 +116,7 @@ bool Zone::Bootup(uint32 iZoneID, uint32 iInstanceID, bool is_static) {
std::string tmp;
if (database.GetVariable("loglevel", tmp)) {
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
for(int i=0;i<4;i++){
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;
database.QGlobalPurge();
if(zoneid == RuleI(World, GuildBankZoneID))
if(zoneid == Zones::GUILDHALL)
GuildBanks = new GuildBankManager;
else
GuildBanks = nullptr;
@@ -1113,7 +1113,7 @@ bool Zone::Init(bool is_static) {
if (RuleManager::Instance()->GetActiveRulesetID() != default_ruleset) {
std::string r_name = RuleSetsRepository::GetRuleSetName(database, default_ruleset);
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) {
LinkedListIterator<ZonePoint*> iterator(zone_point_list);
ZonePoint* closest_zp = nullptr;
if (!client) {
return closest_zp;
}
float closest_dist = FLT_MAX;
float max_distance2 = max_distance * max_distance;
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
// 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)) {
client->cheat_manager.CheatDetected(MQZoneUnknownDest, location);
}
if (!client->cheat_manager.GetExemptStatus(Port)) {
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("<Real Zone Points>. [{}]", to_string(location).c_str());
}
@@ -2231,10 +2235,9 @@ void Zone::LoadZoneBlockedSpells()
void Zone::ClearBlockedSpells()
{
if (blocked_spells) {
safe_delete_array(blocked_spells);
zone_total_blocked_spells = 0;
}
safe_delete_array(blocked_spells);
zone_total_blocked_spells = 0;
}
bool Zone::IsSpellBlocked(uint32 spell_id, const glm::vec3 &location)
+1 -1
View File
@@ -103,7 +103,7 @@ void ZoneEventScheduler::Process(Zone *zone, WorldContentService *content_servic
rule_key,
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);
}