From 2415645b86358a186e2f4a3a5aadda040f26a444 Mon Sep 17 00:00:00 2001 From: Alex King <89047260+Kinglykrab@users.noreply.github.com> Date: Sun, 19 Mar 2023 22:32:35 -0400 Subject: [PATCH 01/22] [Fix] Fix typo for bot_id raid_members column in db_update_manifest.txt (#3132) # Notes - This was causing this query to run over and over. --- utils/sql/db_update_manifest.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/utils/sql/db_update_manifest.txt b/utils/sql/db_update_manifest.txt index 6b70625b9..14f6b208e 100644 --- a/utils/sql/db_update_manifest.txt +++ b/utils/sql/db_update_manifest.txt @@ -478,7 +478,7 @@ 9222|2023_02_28_npc_scaling_zone_list_version_list.sql|SHOW COLUMNS FROM `npc_scale_global_base` LIKE 'zone_id_list'|empty| 9223|2023_03_04_npc_scale_global_base_heroic_strikethrough.sql|SHOW COLUMNS FROM `npc_scale_global_base` LIKE 'heroic_strikethrough'|empty| 9224|2023_03_08_npc_scale_global_base_avoidance.sql|SHOW COLUMNS FROM `npc_scale_global_base` LIKE 'hp_regen_per_second'|empty| -9225|2023_01_21_bots_raid_members.sql|SHOW COLUMNS FROM `raid_members` LIKE 'botid'|empty| +9225|2023_01_21_bots_raid_members.sql|SHOW COLUMNS FROM `raid_members` LIKE 'bot_id'|empty| # Upgrade conditions: # This won't be needed after this system is implemented, but it is used database that are not From d6b954a4b936a6d583641c42ba35c2f9be16bdc6 Mon Sep 17 00:00:00 2001 From: Aeadoin <109764533+Aeadoin@users.noreply.github.com> Date: Mon, 20 Mar 2023 11:39:14 -0400 Subject: [PATCH 02/22] [Cleanup] Cleaning up Raid.cpp (#3125) * [Cleanup] Cleanup Raid.cpp * cleanup * fix is_bot instances * bracket cleanup * bracket cleanup * rename variables in struct * fix for merge --- common/patches/rof.cpp | 8 +- common/patches/rof2.cpp | 8 +- common/patches/rof2_structs.h | 4 +- common/patches/rof_structs.h | 4 +- common/patches/sod.cpp | 8 +- common/patches/sod_structs.h | 4 +- common/patches/uf.cpp | 8 +- common/patches/uf_structs.h | 4 +- ucs/chatchannel.cpp | 6 +- ucs/clientlist.cpp | 4 +- ucs/worldserver.cpp | 3 +- world/cliententry.cpp | 12 +- zone/attack.cpp | 11 +- zone/aura.cpp | 22 +- zone/bot.cpp | 32 +- zone/bot_raid.cpp | 87 +-- zone/client.cpp | 4 +- zone/client_packet.cpp | 59 +- zone/client_process.cpp | 6 +- zone/corpse.cpp | 44 +- zone/entity.cpp | 42 +- zone/exp.cpp | 2 +- zone/expedition.cpp | 3 +- zone/expedition_request.cpp | 8 +- zone/groups.cpp | 2 +- zone/lua_raid.cpp | 4 +- zone/mob_ai.cpp | 9 +- zone/perl_raids.cpp | 4 +- zone/raids.cpp | 1172 +++++++++++++++++---------------- zone/raids.h | 24 +- zone/spell_effects.cpp | 2 +- zone/spells.cpp | 2 +- zone/worldserver.cpp | 13 +- 33 files changed, 846 insertions(+), 779 deletions(-) diff --git a/common/patches/rof.cpp b/common/patches/rof.cpp index 44a2ae606..d6e0e2a17 100644 --- a/common/patches/rof.cpp +++ b/common/patches/rof.cpp @@ -1050,7 +1050,7 @@ namespace RoF { if ((gjs->action == groupActDisband) || !strcmp(gjs->yourname, gjs->membername)) { - //Log.LogDebugType(Logs::General, Logs::Netcode, "[ERROR] Group Leave, yourname = %s, membername = %s", gjs->yourname, gjs->membername); + //Log.LogDebugType(Logs::General, Logs::Netcode, "[ERROR] Group Leave, yourname = %s, member_name = %s", gjs->yourname, gjs->member_name); auto outapp = new EQApplicationPacket(OP_GroupDisbandYou, sizeof(structs::GroupGeneric_Struct)); @@ -1069,7 +1069,7 @@ namespace RoF return; } //if(gjs->action == groupActLeave) - // Log.LogDebugType(Logs::General, Logs::Netcode, "[ERROR] Group Leave, yourname = %s, membername = %s", gjs->yourname, gjs->membername); + // Log.LogDebugType(Logs::General, Logs::Netcode, "[ERROR] Group Leave, yourname = %s, member_name = %s", gjs->yourname, gjs->member_name); auto outapp = new EQApplicationPacket(OP_GroupDisbandOther, sizeof(structs::GroupGeneric_Struct)); @@ -1099,7 +1099,7 @@ namespace RoF for (int i = 0; i < 5; ++i) { - //Log.LogDebugType(Logs::General, Logs::Netcode, "[ERROR] Membername[%i] is %s", i, gu2->membername[i]); + //Log.LogDebugType(Logs::General, Logs::Netcode, "[ERROR] Membername[%i] is %s", i, gu2->member_name[i]); if (gu2->membername[i][0] != '\0') { PacketLength += (22 + strlen(gu2->membername[i]) + 1); @@ -1169,7 +1169,7 @@ namespace RoF return; } - //Log.LogDebugType(Logs::General, Logs::Netcode, "[ERROR] Generic GroupUpdate, yourname = %s, membername = %s", gjs->yourname, gjs->membername); + //Log.LogDebugType(Logs::General, Logs::Netcode, "[ERROR] Generic GroupUpdate, yourname = %s, member_name = %s", gjs->yourname, gjs->member_name); ENCODE_LENGTH_EXACT(GroupJoin_Struct); SETUP_DIRECT_ENCODE(GroupJoin_Struct, structs::GroupJoin_Struct); diff --git a/common/patches/rof2.cpp b/common/patches/rof2.cpp index c5facee0b..3c34cd011 100644 --- a/common/patches/rof2.cpp +++ b/common/patches/rof2.cpp @@ -1101,7 +1101,7 @@ namespace RoF2 { if ((gjs->action == groupActDisband) || !strcmp(gjs->yourname, gjs->membername)) { - //Log.LogDebugType(Logs::General, Logs::Netcode, "[ERROR] Group Leave, yourname = %s, membername = %s", gjs->yourname, gjs->membername); + //Log.LogDebugType(Logs::General, Logs::Netcode, "[ERROR] Group Leave, yourname = %s, member_name = %s", gjs->yourname, gjs->member_name); auto outapp = new EQApplicationPacket(OP_GroupDisbandYou, sizeof(structs::GroupGeneric_Struct)); @@ -1120,7 +1120,7 @@ namespace RoF2 return; } //if(gjs->action == groupActLeave) - // Log.LogDebugType(Logs::General, Logs::Netcode, "[ERROR] Group Leave, yourname = %s, membername = %s", gjs->yourname, gjs->membername); + // Log.LogDebugType(Logs::General, Logs::Netcode, "[ERROR] Group Leave, yourname = %s, member_name = %s", gjs->yourname, gjs->member_name); auto outapp = new EQApplicationPacket(OP_GroupDisbandOther, sizeof(structs::GroupGeneric_Struct)); @@ -1150,7 +1150,7 @@ namespace RoF2 for (int i = 0; i < 5; ++i) { - //Log.LogDebugType(Logs::General, Logs::Netcode, "[ERROR] Membername[%i] is %s", i, gu2->membername[i]); + //Log.LogDebugType(Logs::General, Logs::Netcode, "[ERROR] Membername[%i] is %s", i, gu2->member_name[i]); if (gu2->membername[i][0] != '\0') { PacketLength += (22 + strlen(gu2->membername[i]) + 1); @@ -1220,7 +1220,7 @@ namespace RoF2 return; } - //Log.LogDebugType(Logs::General, Logs::Netcode, "[ERROR] Generic GroupUpdate, yourname = %s, membername = %s", gjs->yourname, gjs->membername); + //Log.LogDebugType(Logs::General, Logs::Netcode, "[ERROR] Generic GroupUpdate, yourname = %s, member_name = %s", gjs->yourname, gjs->member_name); ENCODE_LENGTH_EXACT(GroupJoin_Struct); SETUP_DIRECT_ENCODE(GroupJoin_Struct, structs::GroupJoin_Struct); diff --git a/common/patches/rof2_structs.h b/common/patches/rof2_structs.h index 037574861..05cb4fb57 100644 --- a/common/patches/rof2_structs.h +++ b/common/patches/rof2_structs.h @@ -2590,7 +2590,7 @@ struct GroupUpdate_Struct_Live { // New for Live struct GroupMembers_Struct { // New for Live /*0000*/ uint32 membernumber; // Guess - number of member in the group (0 to 5?) -/*0000*/ //char membername[0]; // Member Name Null Terminated +/*0000*/ //char member_name[0]; // Member Name Null Terminated /*0000*/ uint8 unknown001[3]; // Seen 0 /*0000*/ uint32 memberlevel; // Guess /*0000*/ uint8 unknown002[11]; // Seen 0 @@ -2600,7 +2600,7 @@ struct GroupJoin_Struct_Live { // New for Live /*0000*/ uint32 unknown0000; // Matches unknown0136 from GroupFollow_Struct /*0004*/ uint32 action; /*0008*/ uint8 unknown0008[5]; // Seen 0 -/*0013*/ //char membername[0]; // Null Terminated? +/*0013*/ //char member_name[0]; // Null Terminated? /*0000*/ uint8 unknown0013[3]; // Seen 0 /*0000*/ uint32 unknown0016; // Matches unknown0132 from GroupFollow_Struct /*0000*/ uint8 unknown0020[11]; // Seen 0 diff --git a/common/patches/rof_structs.h b/common/patches/rof_structs.h index 3c81505d4..ef2f8cc3e 100644 --- a/common/patches/rof_structs.h +++ b/common/patches/rof_structs.h @@ -2566,7 +2566,7 @@ struct GroupUpdate_Struct_Live { // New for Live struct GroupMembers_Struct { // New for Live /*0000*/ uint32 membernumber; // Guess - number of member in the group (0 to 5?) -/*0000*/ //char membername[0]; // Member Name Null Terminated +/*0000*/ //char member_name[0]; // Member Name Null Terminated /*0000*/ uint8 unknown001[3]; // Seen 0 /*0000*/ uint32 memberlevel; // Guess /*0000*/ uint8 unknown002[11]; // Seen 0 @@ -2576,7 +2576,7 @@ struct GroupJoin_Struct_Live { // New for Live /*0000*/ uint32 unknown0000; // Matches unknown0136 from GroupFollow_Struct /*0004*/ uint32 action; /*0008*/ uint8 unknown0008[5]; // Seen 0 -/*0013*/ //char membername[0]; // Null Terminated? +/*0013*/ //char member_name[0]; // Null Terminated? /*0000*/ uint8 unknown0013[3]; // Seen 0 /*0000*/ uint32 unknown0016; // Matches unknown0132 from GroupFollow_Struct /*0000*/ uint8 unknown0020[11]; // Seen 0 diff --git a/common/patches/sod.cpp b/common/patches/sod.cpp index 98afcec62..4214e2730 100644 --- a/common/patches/sod.cpp +++ b/common/patches/sod.cpp @@ -785,7 +785,7 @@ namespace SoD { if ((gjs->action == groupActDisband) || !strcmp(gjs->yourname, gjs->membername)) { - //Log.LogDebugType(Logs::General, Logs::Netcode, "[ERROR] Group Leave, yourname = %s, membername = %s", gjs->yourname, gjs->membername); + //Log.LogDebugType(Logs::General, Logs::Netcode, "[ERROR] Group Leave, yourname = %s, member_name = %s", gjs->yourname, gjs->member_name); auto outapp = new EQApplicationPacket(OP_GroupDisbandYou, sizeof(structs::GroupGeneric_Struct)); @@ -804,7 +804,7 @@ namespace SoD return; } //if(gjs->action == groupActLeave) - // Log.LogDebugType(Logs::General, Logs::Netcode, "[ERROR] Group Leave, yourname = %s, membername = %s", gjs->yourname, gjs->membername); + // Log.LogDebugType(Logs::General, Logs::Netcode, "[ERROR] Group Leave, yourname = %s, member_name = %s", gjs->yourname, gjs->member_name); auto outapp = new EQApplicationPacket(OP_GroupDisbandOther, sizeof(structs::GroupGeneric_Struct)); @@ -834,7 +834,7 @@ namespace SoD for (int i = 0; i < 5; ++i) { - //Log.LogDebugType(Logs::General, Logs::Netcode, "[ERROR] Membername[%i] is %s", i, gu2->membername[i]); + //Log.LogDebugType(Logs::General, Logs::Netcode, "[ERROR] Membername[%i] is %s", i, gu2->member_name[i]); if (gu2->membername[i][0] != '\0') { PacketLength += (22 + strlen(gu2->membername[i]) + 1); @@ -902,7 +902,7 @@ namespace SoD return; } - //Log.LogDebugType(Logs::General, Logs::Netcode, "[ERROR] Generic GroupUpdate, yourname = %s, membername = %s", gjs->yourname, gjs->membername); + //Log.LogDebugType(Logs::General, Logs::Netcode, "[ERROR] Generic GroupUpdate, yourname = %s, member_name = %s", gjs->yourname, gjs->member_name); ENCODE_LENGTH_EXACT(GroupJoin_Struct); SETUP_DIRECT_ENCODE(GroupJoin_Struct, structs::GroupJoin_Struct); diff --git a/common/patches/sod_structs.h b/common/patches/sod_structs.h index fdfb42706..18c3c63d6 100644 --- a/common/patches/sod_structs.h +++ b/common/patches/sod_structs.h @@ -2085,7 +2085,7 @@ struct GroupUpdate_Struct_SoD { // New for SoD struct GroupMembers_Struct { // New for SoD /*0000*/ uint32 membernumber; // Guess - number of member in the group (0 to 5?) -/*0000*/ //char membername[0]; // Member Name Null Terminated +/*0000*/ //char member_name[0]; // Member Name Null Terminated /*0000*/ uint8 unknown001[3]; // Seen 0 /*0000*/ uint32 memberlevel; // Guess /*0000*/ uint8 unknown002[11]; // Seen 0 @@ -2095,7 +2095,7 @@ struct GroupJoin_Struct_SoD { // New for SoD /*0000*/ uint32 unknown0000; // Matches unknown0136 from GroupFollow_Struct /*0004*/ uint32 action; /*0008*/ uint8 unknown0008[5]; // Seen 0 -/*0013*/ //char membername[0]; // Null Terminated? +/*0013*/ //char member_name[0]; // Null Terminated? /*0000*/ uint8 unknown0013[3]; // Seen 0 /*0000*/ uint32 unknown0016; // Matches unknown0132 from GroupFollow_Struct /*0000*/ uint8 unknown0020[11]; // Seen 0 diff --git a/common/patches/uf.cpp b/common/patches/uf.cpp index b44524723..b632cb7e3 100644 --- a/common/patches/uf.cpp +++ b/common/patches/uf.cpp @@ -927,7 +927,7 @@ namespace UF { if ((gjs->action == groupActDisband) || !strcmp(gjs->yourname, gjs->membername)) { - //Log.LogDebugType(Logs::General, Logs::Netcode, "[ERROR] Group Leave, yourname = %s, membername = %s", gjs->yourname, gjs->membername); + //Log.LogDebugType(Logs::General, Logs::Netcode, "[ERROR] Group Leave, yourname = %s, member_name = %s", gjs->yourname, gjs->member_name); auto outapp = new EQApplicationPacket(OP_GroupDisbandYou, sizeof(structs::GroupGeneric_Struct)); @@ -947,7 +947,7 @@ namespace UF return; } //if(gjs->action == groupActLeave) - // Log.LogDebugType(Logs::General, Logs::Netcode, "[ERROR] Group Leave, yourname = %s, membername = %s", gjs->yourname, gjs->membername); + // Log.LogDebugType(Logs::General, Logs::Netcode, "[ERROR] Group Leave, yourname = %s, member_name = %s", gjs->yourname, gjs->member_name); auto outapp = new EQApplicationPacket(OP_GroupDisbandOther, sizeof(structs::GroupGeneric_Struct)); @@ -977,7 +977,7 @@ namespace UF for (int i = 0; i < 5; ++i) { - //Log.LogDebugType(Logs::General, Logs::Netcode, "[ERROR] Membername[%i] is %s", i, gu2->membername[i]); + //Log.LogDebugType(Logs::General, Logs::Netcode, "[ERROR] Membername[%i] is %s", i, gu2->member_name[i]); if (gu2->membername[i][0] != '\0') { PacketLength += (22 + strlen(gu2->membername[i]) + 1); @@ -1045,7 +1045,7 @@ namespace UF delete in; return; } - //Log.LogDebugType(Logs::General, Logs::Netcode, "[ERROR] Generic GroupUpdate, yourname = %s, membername = %s", gjs->yourname, gjs->membername); + //Log.LogDebugType(Logs::General, Logs::Netcode, "[ERROR] Generic GroupUpdate, yourname = %s, member_name = %s", gjs->yourname, gjs->member_name); ENCODE_LENGTH_EXACT(GroupJoin_Struct); SETUP_DIRECT_ENCODE(GroupJoin_Struct, structs::GroupJoin_Struct); diff --git a/common/patches/uf_structs.h b/common/patches/uf_structs.h index 86d6034f0..c629b19db 100644 --- a/common/patches/uf_structs.h +++ b/common/patches/uf_structs.h @@ -2128,7 +2128,7 @@ struct GroupUpdate_Struct_Underfoot { // New for Underfoot struct GroupMembers_Struct { // New for Underfoot /*0000*/ uint32 membernumber; // Guess - number of member in the group (0 to 5?) -/*0000*/ //char membername[0]; // Member Name Null Terminated +/*0000*/ //char member_name[0]; // Member Name Null Terminated /*0000*/ uint8 unknown001[3]; // Seen 0 /*0000*/ uint32 memberlevel; // Guess /*0000*/ uint8 unknown002[11]; // Seen 0 @@ -2138,7 +2138,7 @@ struct GroupJoin_Struct_Underfoot { // New for Underfoot /*0000*/ uint32 unknown0000; // Matches unknown0136 from GroupFollow_Struct /*0004*/ uint32 action; /*0008*/ uint8 unknown0008[5]; // Seen 0 -/*0013*/ //char membername[0]; // Null Terminated? +/*0013*/ //char member_name[0]; // Null Terminated? /*0000*/ uint8 unknown0013[3]; // Seen 0 /*0000*/ uint32 unknown0016; // Matches unknown0132 from GroupFollow_Struct /*0000*/ uint8 unknown0020[11]; // Seen 0 diff --git a/ucs/chatchannel.cpp b/ucs/chatchannel.cpp index 4da5aebc8..312b2a311 100644 --- a/ucs/chatchannel.cpp +++ b/ucs/chatchannel.cpp @@ -393,13 +393,15 @@ bool ChatChannel::RemoveClient(Client *c) { void ChatChannel::SendOPList(Client *c) { - if (!c) + if (!c) { return; + } c->GeneralChannelMessage("Channel " + m_name + " op-list: (Owner=" + m_owner + ")"); - for (auto &&m : m_moderators) + for (auto &&m : m_moderators) { c->GeneralChannelMessage(m); + } } void ChatChannel::SendChannelMembers(Client *c) { diff --git a/ucs/clientlist.cpp b/ucs/clientlist.cpp index cb5736725..fd2546941 100644 --- a/ucs/clientlist.cpp +++ b/ucs/clientlist.cpp @@ -571,7 +571,9 @@ void Clientlist::CheckForStaleConnectionsAll() void Clientlist::CheckForStaleConnections(Client *c) { - if (!c) return; + if (!c) { + return; + } std::list::iterator Iterator; diff --git a/ucs/worldserver.cpp b/ucs/worldserver.cpp index 39e076d7b..0e9ff3a02 100644 --- a/ucs/worldserver.cpp +++ b/ucs/worldserver.cpp @@ -120,8 +120,7 @@ void WorldServer::ProcessMessage(uint16 opcode, EQ::Net::Packet &p) if (Message.length() < 2) break; - if (!c) - { + if (!c) { LogInfo("Client not found"); break; } diff --git a/world/cliententry.cpp b/world/cliententry.cpp index f4270c4b5..142887b26 100644 --- a/world/cliententry.cpp +++ b/world/cliententry.cpp @@ -120,9 +120,9 @@ ClientListEntry::~ClientListEntry() Camp(); // updates zoneserver's numplayers client_list.RemoveCLEReferances(this); } - for (auto& elem: tell_queue) { - safe_delete_array(elem) - }; + for (auto& elem : tell_queue) { + safe_delete_array(elem); + } tell_queue.clear(); } @@ -283,9 +283,9 @@ void ClientListEntry::ClearVars(bool iAll) pLFG = 0; gm = 0; pClientVersion = 0; - for (auto& elem: tell_queue) { - safe_delete_array(elem) - }; + for (auto& elem : tell_queue) { + safe_delete_array(elem); + } tell_queue.clear(); } diff --git a/zone/attack.cpp b/zone/attack.cpp index 2f408e612..d7978e6d1 100644 --- a/zone/attack.cpp +++ b/zone/attack.cpp @@ -2746,23 +2746,23 @@ bool NPC::Death(Mob* killer_mob, int64 damage, uint16 spell, EQ::skills::SkillTy switch (r->GetLootType()) { case 0: case 1: - if (r->members[x].member && r->members[x].IsRaidLeader) { + if (r->members[x].member && r->members[x].is_raid_leader) { corpse->AllowPlayerLoot(r->members[x].member, i); i++; } break; case 2: - if (r->members[x].member && r->members[x].IsRaidLeader) { + if (r->members[x].member && r->members[x].is_raid_leader) { corpse->AllowPlayerLoot(r->members[x].member, i); i++; } - else if (r->members[x].member && r->members[x].IsGroupLeader) { + else if (r->members[x].member && r->members[x].is_group_leader) { corpse->AllowPlayerLoot(r->members[x].member, i); i++; } break; case 3: - if (r->members[x].member && r->members[x].IsLooter) { + if (r->members[x].member && r->members[x].is_looter) { corpse->AllowPlayerLoot(r->members[x].member, i); i++; } @@ -4395,8 +4395,7 @@ void Mob::CommonDamage(Mob* attacker, int64 &damage, const uint16 spell_id, cons ); } } - -} //end packet sending +} void Mob::HealDamage(uint64 amount, Mob* caster, uint16 spell_id) { diff --git a/zone/aura.cpp b/zone/aura.cpp index 4fd97dbf6..14ca590f2 100644 --- a/zone/aura.cpp +++ b/zone/aura.cpp @@ -144,8 +144,8 @@ void Aura::ProcessOnAllGroupMembers(Mob *owner) if (c->GetID() == m_owner) { return DistanceSquared(GetPosition(), c->GetPosition()) <= distance; } - else if (idx == 0xFFFFFFFF || raid->members[idx].GroupNumber != group_id || - raid->members[idx].GroupNumber == 0xFFFFFFFF) { + else if (idx == 0xFFFFFFFF || raid->members[idx].group_number != group_id || + raid->members[idx].group_number == 0xFFFFFFFF) { return false; } else if (DistanceSquared(GetPosition(), c->GetPosition()) > distance) { @@ -159,8 +159,8 @@ void Aura::ProcessOnAllGroupMembers(Mob *owner) if (m->GetOwner()->GetID() == m_owner) { return DistanceSquared(GetPosition(), m->GetPosition()) <= distance; } - else if (idx == 0xFFFFFFFF || raid->members[idx].GroupNumber != group_id || - raid->members[idx].GroupNumber == 0xFFFFFFFF) { + else if (idx == 0xFFFFFFFF || raid->members[idx].group_number != group_id || + raid->members[idx].group_number == 0xFFFFFFFF) { return false; } else if (DistanceSquared(GetPosition(), m->GetPosition()) > distance) { @@ -178,8 +178,8 @@ void Aura::ProcessOnAllGroupMembers(Mob *owner) if (owner->GetID() == m_owner) { return DistanceSquared(GetPosition(), n->GetPosition()) <= distance; } - else if (idx == 0xFFFFFFFF || raid->members[idx].GroupNumber != group_id || - raid->members[idx].GroupNumber == 0xFFFFFFFF) { + else if (idx == 0xFFFFFFFF || raid->members[idx].group_number != group_id || + raid->members[idx].group_number == 0xFFFFFFFF) { return false; } else if (DistanceSquared(GetPosition(), n->GetPosition()) > distance) { @@ -389,8 +389,8 @@ void Aura::ProcessOnGroupMembersPets(Mob *owner) if (m->GetOwner()->GetID() == group_member->GetID()) { return DistanceSquared(GetPosition(), m->GetPosition()) <= distance; } - else if (idx == 0xFFFFFFFF || raid->members[idx].GroupNumber != group_id || - raid->members[idx].GroupNumber == 0xFFFFFFFF) { + else if (idx == 0xFFFFFFFF || raid->members[idx].group_number != group_id || + raid->members[idx].group_number == 0xFFFFFFFF) { return false; } else if (DistanceSquared(GetPosition(), m->GetPosition()) > distance) { @@ -408,8 +408,8 @@ void Aura::ProcessOnGroupMembersPets(Mob *owner) if (owner->GetID() == group_member->GetID()) { return DistanceSquared(GetPosition(), n->GetPosition()) <= distance; } - else if (idx == 0xFFFFFFFF || raid->members[idx].GroupNumber != group_id || - raid->members[idx].GroupNumber == 0xFFFFFFFF) { + else if (idx == 0xFFFFFFFF || raid->members[idx].group_number != group_id || + raid->members[idx].group_number == 0xFFFFFFFF) { return false; } else if (DistanceSquared(GetPosition(), n->GetPosition()) > distance) { @@ -819,7 +819,7 @@ bool Aura::ShouldISpawnFor(Client *c) return false; } - if (raid->members[idx].GroupNumber != group_id) { // in our raid, but not our group + if (raid->members[idx].group_number != group_id) { // in our raid, but not our group return false; } diff --git a/zone/bot.cpp b/zone/bot.cpp index 0744ce94e..81981d01d 100644 --- a/zone/bot.cpp +++ b/zone/bot.cpp @@ -27,9 +27,6 @@ #include "../common/repositories/bot_spell_settings_repository.h" #include "../common/data_verification.h" -extern volatile bool is_zone_loaded; -extern bool Critical; - // This constructor is used during the bot create command Bot::Bot(NPCType *npcTypeData, Client* botOwner) : NPC(npcTypeData, nullptr, glm::vec4(), Ground, false), rest_timer(1), ping_timer(1) { GiveNPCTypeData(npcTypeData); @@ -2822,7 +2819,7 @@ void Bot::AcquireBotTarget(Group* bot_group, Raid* raid, Client* leash_owner, fl assist_mob = entity_list.GetMob(bot_group->GetMainAssistName()); } else if (raid) { - assist_mob = raid->GetRaidMainAssistOneByName(GetName()); + assist_mob = raid->GetRaidMainAssistOne(); } if (assist_mob) { @@ -4629,16 +4626,14 @@ bool Bot::Death(Mob *killerMob, int64 damage, uint16 spell_id, EQ::skills::Skill my_owner->CastToClient()->SetBotPulling(false); } -Raid* raid = entity_list.GetRaidByBotName(GetName()); - - if (raid) + if (auto raid = entity_list.GetRaidByBotName(GetName()); raid) { - for (int x = 0; x < MAX_RAID_MEMBERS; x++) + for (auto& m : raid->members) { - if (strcmp(raid->members[x].membername, GetName()) == 0) + if (strcmp(m.member_name, GetName()) == 0) { - raid->members[x].member = nullptr; + m.member = nullptr; } } } @@ -7803,7 +7798,6 @@ bool EntityList::Bot_AICheckCloseBeneficialSpells(Bot* caster, uint8 iChance, fl return false; } - Mob* EntityList::GetMobByBotID(uint32 botID) { Mob* Result = nullptr; if (botID > 0) { @@ -7837,10 +7831,9 @@ Bot* EntityList::GetBotByBotID(uint32 botID) { Bot* EntityList::GetBotByBotName(std::string_view botName) { Bot* Result = nullptr; if (!botName.empty()) { - for (std::list::iterator botListItr = bot_list.begin(); botListItr != bot_list.end(); ++botListItr) { - Bot* tempBot = *botListItr; - if (tempBot && std::string(tempBot->GetName()) == botName) { - Result = tempBot; + for (const auto b : bot_list) { + if (b && std::string_view(b->GetName()) == botName) { + Result = b; break; } } @@ -8252,15 +8245,6 @@ bool Bot::GetNeedsHateRedux(Mob *tar) { if (!tar || !tar->IsEngaged() || !tar->HasTargetReflection() || !tar->GetTarget()->IsNPC()) return false; - //if (tar->IsClient()) { - // switch (tar->GetClass()) { - // // TODO: figure out affectable classes.. - // // Might need flag to allow player to determine redux req... - // default: - // return false; - // } - //} - //else if (tar->IsBot()) { if (tar->IsBot()) { switch (tar->GetClass()) { case ROGUE: diff --git a/zone/bot_raid.cpp b/zone/bot_raid.cpp index 22edf3f76..13537e0e8 100644 --- a/zone/bot_raid.cpp +++ b/zone/bot_raid.cpp @@ -23,19 +23,16 @@ #include "quest_parser_collection.h" #include "../common/data_verification.h" -extern volatile bool is_zone_loaded; -extern bool Critical; - std::vector Raid::GetRaidGroupMembers(uint32 gid) { std::vector raid_group_members; raid_group_members.clear(); - for (int i = 0; i < MAX_RAID_MEMBERS; ++i) + for (const auto& m : members) { - if (members[i].member && members[i].GroupNumber == gid) + if (m.member && m.group_number == gid) { - raid_group_members.push_back(members[i]); + raid_group_members.push_back(m); } } return raid_group_members; @@ -48,12 +45,12 @@ std::vector Raid::GetRaidBotMembers(uint32 owner) std::vector raid_members_bots; raid_members_bots.clear(); - for (int i = 0; i < MAX_RAID_MEMBERS; i++) { + for (const auto& m : members) { if ( - members[i].member && - members[i].member->IsBot() + m.member && + m.member->IsBot() ) { - auto b_member = members[i].member->CastToBot(); + auto b_member = m.member->CastToBot(); if (owner && b_member->GetBotOwnerCharacterID() == owner) { raid_members_bots.emplace_back(b_member); } else if (!owner) { @@ -72,13 +69,13 @@ std::vector Raid::GetRaidGroupBotMembers(uint32 gid) std::vector raid_members_bots; raid_members_bots.clear(); - for (int i = 0; i < MAX_RAID_MEMBERS; i++) { + for (const auto& m : members) { if ( - members[i].member && - members[i].member->IsBot() && - members[i].GroupNumber == gid + m.member && + m.member->IsBot() && + m.group_number == gid ) { - auto b_member = members[i].member->CastToBot(); + auto b_member = m.member->CastToBot(); raid_members_bots.emplace_back(b_member); raid_members_bots.emplace_back(b_member); } @@ -92,34 +89,29 @@ void Raid::HandleBotGroupDisband(uint32 owner, uint32 gid) auto raid_members_bots = gid != RAID_GROUPLESS ? GetRaidGroupBotMembers(gid) : GetRaidBotMembers(owner); // If any of the bots are a group leader then re-create the botgroup on disband, dropping any clients - for (auto& bot_iter: raid_members_bots) { + for (const auto& b: raid_members_bots) { // Remove the entire BOT group in this case - if ( - bot_iter && - gid != RAID_GROUPLESS && - IsRaidMember(bot_iter->GetName()) && - IsGroupLeader(bot_iter->GetName()) - ) { - auto r_group_members = GetRaidGroupMembers(GetGroup(bot_iter->GetName())); - auto group_inst = new Group(bot_iter); - entity_list.AddGroup(group_inst); - database.SetGroupID(bot_iter->GetCleanName(), group_inst->GetID(), bot_iter->GetBotID()); - database.SetGroupLeaderName(group_inst->GetID(), bot_iter->GetName()); + if (b && gid != RAID_GROUPLESS && IsRaidMember(b->GetName()) && IsGroupLeader(b->GetName())) { + auto r_group_members = GetRaidGroupMembers(GetGroup(b->GetName())); + auto g = new Group(b); + entity_list.AddGroup(g); + database.SetGroupID(b->GetCleanName(), g->GetID(), b->GetBotID()); + database.SetGroupLeaderName(g->GetID(), b->GetName()); - for (auto member_iter: r_group_members) { - if (member_iter.member->IsBot()) { - auto b_member = member_iter.member->CastToBot(); - if (strcmp(b_member->GetName(), bot_iter->GetName()) == 0) { - bot_iter->SetFollowID(owner); + for (auto m: r_group_members) { + if (m.member->IsBot()) { + auto b_member = m.member->CastToBot(); + if (strcmp(b_member->GetName(), b->GetName()) == 0) { + b->SetFollowID(owner); } else { - Bot::AddBotToGroup(b_member, group_inst); + Bot::AddBotToGroup(b_member, g); } Bot::RemoveBotFromRaid(b_member); } } } else { - Bot::RemoveBotFromRaid(bot_iter); + Bot::RemoveBotFromRaid(b); } } } @@ -128,18 +120,15 @@ uint8 Bot::GetNumberNeedingHealedInRaidGroup(uint8& need_healed, uint8 hpr, bool if (raid) { uint32 r_group = raid->GetGroup(GetName()); - auto raid_group_members = raid->GetRaidGroupMembers(r_group); - for (auto& m: raid_group_members) { + for (auto& m: raid->GetRaidGroupMembers(r_group)) { if (m.member && !m.member->qglobal) { if (m.member->GetHPRatio() <= hpr) { need_healed++; } - if (includePets) { - if (m.member->GetPet() && m.member->GetPet()->GetHPRatio() <= hpr) { - need_healed++; - } + if (includePets && m.member->GetPet() && m.member->GetPet()->GetHPRatio() <= hpr) { + need_healed++; } } } @@ -246,22 +235,18 @@ void Bot::ProcessBotGroupAdd(Group* group, Raid* raid, Client* client, bool new_ uint32 raid_free_group_id = raid->GetFreeGroup(); if (group) { - for (int x = 0; x < MAX_GROUP_MEMBERS; x++) { - if (group->members[x]) { - Client* c = nullptr; - Bot* b = nullptr; - - if (group->members[x] && group->members[x]->IsBot()) { - b = group->members[x]->CastToBot(); - raid->AddBot(b, raid_free_group_id, false, x == 0, false); - } else if (group->members[x] && group->members[x]->IsClient()) { - c = group->members[x]->CastToClient(); + for (const auto& m : group->members) { + if (m) { + if (m && m->IsBot()) { + raid->AddBot(m->CastToBot(), raid_free_group_id, false, !raid->GroupCount(raid_free_group_id), false); + } else if (m && m->IsClient()) { + auto c = m->CastToClient(); raid->SendRaidCreate(c); raid->AddMember( c, raid_free_group_id, new_raid, - x == 0, + !raid->GroupCount(raid_free_group_id), false ); raid->SendMakeLeaderPacketTo(raid->leadername, c); diff --git a/zone/client.cpp b/zone/client.cpp index 7815e22c4..36d1334b5 100644 --- a/zone/client.cpp +++ b/zone/client.cpp @@ -4163,7 +4163,7 @@ bool Client::GroupFollow(Client* inviter) { { //this assumes the inviter is in the zone if (raid->members[x].member == inviter){ - groupToUse = raid->members[x].GroupNumber; + groupToUse = raid->members[x].group_number; break; } } @@ -8882,7 +8882,7 @@ void Client::ProcessAggroMeter() if (gid < 12) { int at_id = AggroMeter::AT_Group1; for (int i = 0; i < MAX_RAID_MEMBERS; ++i) { - if (raid->members[i].member && raid->members[i].member != this && raid->members[i].GroupNumber == gid) { + if (raid->members[i].member && raid->members[i].member != this && raid->members[i].group_number == gid) { if (m_aggrometer.set_pct(static_cast(at_id), cur_tar->GetHateRatio(cur_tar->GetTarget(), raid->members[i].member))) add_entry(static_cast(at_id)); at_id++; diff --git a/zone/client_packet.cpp b/zone/client_packet.cpp index 21140e337..cc48a9844 100644 --- a/zone/client_packet.cpp +++ b/zone/client_packet.cpp @@ -612,15 +612,15 @@ void Client::CompleteConnect() database.botdb.LoadBotsList(this->CharacterID(), bots_list); std::vector r_members = raid->GetMembers(); for (const RaidMember& iter : r_members) { - if (iter.membername) { + if (iter.member_name) { for (const BotsAvailableList& b_iter : bots_list) { - if (strcmp(iter.membername, b_iter.Name) == 0) + if (strcmp(iter.member_name, b_iter.Name) == 0) { char buffer[71] = "^spawn "; - strcat(buffer, iter.membername); + strcat(buffer, iter.member_name); bot_command_real_dispatch(this, buffer); - Bot* b = entity_list.GetBotByBotName(iter.membername); + Bot* b = entity_list.GetBotByBotName(iter.member_name); if (b) { b->SetRaidGrouped(true); @@ -7027,15 +7027,15 @@ void Client::Handle_OP_GroupDisband(const EQApplicationPacket *app) } //we have a raid.. see if we're in a raid group uint32 grp = raid->GetGroup(memberToDisband->GetName()); - bool wasGrpLdr = raid->members[raid->GetPlayerIndex(memberToDisband->GetName())].IsGroupLeader; + bool wasGrpLdr = raid->members[raid->GetPlayerIndex(memberToDisband->GetName())].is_group_leader; if (grp < 12) { if (wasGrpLdr) { raid->SetGroupLeader(memberToDisband->GetName(), false); for (int x = 0; x < MAX_RAID_MEMBERS; x++) { - if (raid->members[x].GroupNumber == grp) { - if (strlen(raid->members[x].membername) > 0 && - strcmp(raid->members[x].membername, memberToDisband->GetName()) != 0) { - raid->SetGroupLeader(raid->members[x].membername); + if (raid->members[x].group_number == grp) { + if (strlen(raid->members[x].member_name) > 0 && + strcmp(raid->members[x].member_name, memberToDisband->GetName()) != 0) { + raid->SetGroupLeader(raid->members[x].member_name); break; } } @@ -8423,8 +8423,7 @@ void Client::Handle_OP_GuildStatus(const EQApplicationPacket *app) Client *c = entity_list.GetClientByName(gss->Name); - if (!c) - { + if (!c) { MessageString(Chat::LightGray, TARGET_PLAYER_FOR_GUILD_STATUS); return; } @@ -12217,12 +12216,12 @@ void Client::Handle_OP_RaidCommand(const EQApplicationPacket* app) } if (group < 12) { uint32 i = raid->GetPlayerIndex(raid_command_packet->leader_name); - if (raid->members[i].IsGroupLeader) { //assign group leader to someone else + if (raid->members[i].is_group_leader) { //assign group leader to someone else for (int x = 0; x < MAX_RAID_MEMBERS; x++) { - if (strlen(raid->members[x].membername) > 0 && i != x) { - if (raid->members[x].GroupNumber == group) { + if (strlen(raid->members[x].member_name) > 0 && i != x) { + if (raid->members[x].group_number == group) { raid->SetGroupLeader(raid_command_packet->leader_name, false); - raid->SetGroupLeader(raid->members[x].membername); + raid->SetGroupLeader(raid->members[x].member_name); raid->UpdateGroupAAs(group); break; } @@ -12268,24 +12267,24 @@ void Client::Handle_OP_RaidCommand(const EQApplicationPacket* app) if (raid_command_packet->parameter == old_group) //don't rejoin grp if we order to join same group. break; - if (raid->members[raid->GetPlayerIndex(raid_command_packet->leader_name)].IsGroupLeader) { + if (raid->members[raid->GetPlayerIndex(raid_command_packet->leader_name)].is_group_leader) { raid->SetGroupLeader(raid_command_packet->leader_name, false); /* We were the leader of our old group */ if (old_group < 12) { /* Assign new group leader if we can */ for (int x = 0; x < MAX_RAID_MEMBERS; x++) { - if (raid->members[x].GroupNumber == old_group) { - if (strcmp(raid_command_packet->leader_name, raid->members[x].membername) != 0 && strlen(raid_command_packet->leader_name) > 0) { - raid->SetGroupLeader(raid->members[x].membername); + if (raid->members[x].group_number == old_group) { + if (strcmp(raid_command_packet->leader_name, raid->members[x].member_name) != 0 && strlen(raid_command_packet->leader_name) > 0) { + raid->SetGroupLeader(raid->members[x].member_name); raid->UpdateGroupAAs(old_group); - Client* client_to_update = entity_list.GetClientByName(raid->members[x].membername); + Client* client_to_update = entity_list.GetClientByName(raid->members[x].member_name); if (client_to_update) { - raid->SendRaidRemove(raid->members[x].membername, client_to_update); + raid->SendRaidRemove(raid->members[x].member_name, client_to_update); raid->SendRaidCreate(client_to_update); raid->SendMakeLeaderPacketTo(raid->leadername, client_to_update); - raid->SendRaidAdd(raid->members[x].membername, client_to_update); + raid->SendRaidAdd(raid->members[x].member_name, client_to_update); raid->SendBulkRaid(client_to_update); if (raid->IsLocked()) { raid->SendRaidLockTo(client_to_update); @@ -12298,7 +12297,7 @@ void Client::Handle_OP_RaidCommand(const EQApplicationPacket* app) raid_command_packet->rid = raid->GetID(); raid_command_packet->zoneid = zone->GetZoneID(); raid_command_packet->instance_id = zone->GetInstanceID(); - strn0cpy(raid_command_packet->playername, raid->members[x].membername, 64); + strn0cpy(raid_command_packet->playername, raid->members[x].member_name, 64); worldserver.SendPacket(pack); @@ -12343,20 +12342,20 @@ void Client::Handle_OP_RaidCommand(const EQApplicationPacket* app) else { Client* c = entity_list.GetClientByName(raid_command_packet->leader_name); uint32 oldgrp = raid->GetGroup(raid_command_packet->leader_name); - if (raid->members[raid->GetPlayerIndex(raid_command_packet->leader_name)].IsGroupLeader) { + if (raid->members[raid->GetPlayerIndex(raid_command_packet->leader_name)].is_group_leader) { raid->SetGroupLeader(raid_command_packet->leader_name, false); for (int x = 0; x < MAX_RAID_MEMBERS; x++) { - if (raid->members[x].GroupNumber == oldgrp && strlen(raid->members[x].membername) > 0 && strcmp(raid->members[x].membername, raid_command_packet->leader_name) != 0) { + if (raid->members[x].group_number == oldgrp && strlen(raid->members[x].member_name) > 0 && strcmp(raid->members[x].member_name, raid_command_packet->leader_name) != 0) { - raid->SetGroupLeader(raid->members[x].membername); + raid->SetGroupLeader(raid->members[x].member_name); raid->UpdateGroupAAs(oldgrp); - Client* client_leaving_group = entity_list.GetClientByName(raid->members[x].membername); + Client* client_leaving_group = entity_list.GetClientByName(raid->members[x].member_name); if (client_leaving_group) { - raid->SendRaidRemove(raid->members[x].membername, client_leaving_group); + raid->SendRaidRemove(raid->members[x].member_name, client_leaving_group); raid->SendRaidCreate(client_leaving_group); raid->SendMakeLeaderPacketTo(raid->leadername, client_leaving_group); - raid->SendRaidAdd(raid->members[x].membername, client_leaving_group); + raid->SendRaidAdd(raid->members[x].member_name, client_leaving_group); raid->SendBulkRaid(client_leaving_group); if (raid->IsLocked()) { raid->SendRaidLockTo(client_leaving_group); @@ -12367,7 +12366,7 @@ void Client::Handle_OP_RaidCommand(const EQApplicationPacket* app) ServerRaidGeneralAction_Struct* raid_command = (ServerRaidGeneralAction_Struct*)pack->pBuffer; raid_command->rid = raid->GetID(); - strn0cpy(raid_command->playername, raid->members[x].membername, 64); + strn0cpy(raid_command->playername, raid->members[x].member_name, 64); raid_command->zoneid = zone->GetZoneID(); raid_command->instance_id = zone->GetInstanceID(); diff --git a/zone/client_process.cpp b/zone/client_process.cpp index 01c92f75e..087e05fe5 100644 --- a/zone/client_process.cpp +++ b/zone/client_process.cpp @@ -600,11 +600,13 @@ bool Client::Process() { for (auto & close_mob : close_mobs) { Mob *mob = close_mob.second; - if (!mob) + if (!mob) { continue; + } - if (mob->IsClient()) + if (mob->IsClient()) { continue; + } if (mob->CheckWillAggro(this) && !mob->CheckAggro(this)) { mob->AddToHateList(this, 25); diff --git a/zone/corpse.cpp b/zone/corpse.cpp index dc026c94d..269beb428 100644 --- a/zone/corpse.cpp +++ b/zone/corpse.cpp @@ -1062,30 +1062,32 @@ void Corpse::AllowPlayerLoot(Mob *them, uint8 slot) { } void Corpse::MakeLootRequestPackets(Client* client, const EQApplicationPacket* app) { - if (!client) + if (!client) { return; + } // Added 12/08. Started compressing loot struct on live. - if(player_corpse_depop) { + if (player_corpse_depop) { SendLootReqErrorPacket(client, LootResponse::SomeoneElse); return; } - if(IsPlayerCorpse() && !corpse_db_id) { // really should try to resave in this case + if (IsPlayerCorpse() && !corpse_db_id) { // really should try to resave in this case // SendLootReqErrorPacket(client, 0); client->Message(Chat::Red, "Warning: Corpse's dbid = 0! Corpse will not survive zone shutdown!"); std::cout << "Error: PlayerCorpse::MakeLootRequestPackets: dbid = 0!" << std::endl; // return; } - if(is_locked && client->Admin() < AccountStatus::GMAdmin) { + if (is_locked && client->Admin() < AccountStatus::GMAdmin) { SendLootReqErrorPacket(client, LootResponse::SomeoneElse); client->Message(Chat::Red, "Error: Corpse locked by GM."); return; } - if(!being_looted_by || (being_looted_by != 0xFFFFFFFF && !entity_list.GetID(being_looted_by))) + if (!being_looted_by || (being_looted_by != 0xFFFFFFFF && !entity_list.GetID(being_looted_by))) { being_looted_by = 0xFFFFFFFF; + } if (DistanceSquaredNoZ(client->GetPosition(), m_Position) > 625) { SendLootReqErrorPacket(client, LootResponse::TooFar); @@ -1102,23 +1104,29 @@ void Corpse::MakeLootRequestPackets(Client* client, const EQApplicationPacket* a // loot_request_type is scoped to class Corpse and reset on a per-loot session basis if (client->GetGM()) { - if (client->Admin() >= AccountStatus::GMAdmin) + if (client->Admin() >= AccountStatus::GMAdmin) { loot_request_type = LootRequestType::GMAllowed; - else + + } else { loot_request_type = LootRequestType::GMPeek; + } } else { if (IsPlayerCorpse()) { if (char_id == client->CharacterID()) { loot_request_type = LootRequestType::Self; } + else if (CanPlayerLoot(client->CharacterID())) { - if (GetPlayerKillItem() == -1) + if (GetPlayerKillItem() == -1) { loot_request_type = LootRequestType::AllowedPVPAll; - else if (GetPlayerKillItem() == 1) + + } else if (GetPlayerKillItem() == 1) { loot_request_type = LootRequestType::AllowedPVPSingle; - else if (GetPlayerKillItem() > 1) + + } else if (GetPlayerKillItem() > 1) { loot_request_type = LootRequestType::AllowedPVPDefined; + } } } else if ((IsNPCCorpse() || become_npc) && CanPlayerLoot(client->CharacterID())) { @@ -1140,8 +1148,9 @@ void Corpse::MakeLootRequestPackets(Client* client, const EQApplicationPacket* a // process coin bool loot_coin = false; std::string tmp; - if (database.GetVariable("LootCoin", tmp)) + if (database.GetVariable("LootCoin", tmp)) { loot_coin = (tmp[0] == 1 && tmp[1] == '\0'); + } if (loot_request_type == LootRequestType::GMPeek || loot_request_type == LootRequestType::GMAllowed) { if ( @@ -1314,8 +1323,9 @@ void Corpse::MakeLootRequestPackets(Client* client, const EQApplicationPacket* a void Corpse::LootItem(Client *client, const EQApplicationPacket *app) { - if (!client) + if (!client) { return; + } auto lootitem = (LootingItem_Struct *)app->pBuffer; @@ -1325,8 +1335,10 @@ void Corpse::LootItem(Client *client, const EQApplicationPacket *app) client->QueuePacket(app); SendEndLootErrorPacket(client); // unlock corpse for others - if (IsBeingLootedBy(client)) + + if (IsBeingLootedBy(client)) { ResetLooter(); + } return; } @@ -1334,8 +1346,9 @@ void Corpse::LootItem(Client *client, const EQApplicationPacket *app) client->QueuePacket(app); SendEndLootErrorPacket(client); // unlock corpse for others - if (IsBeingLootedBy(client)) + if (IsBeingLootedBy(client)) { ResetLooter(); + } return; } @@ -1345,8 +1358,9 @@ void Corpse::LootItem(Client *client, const EQApplicationPacket *app) client->QueuePacket(app); SendEndLootErrorPacket(client); /* Unlock corpse for others */ - if (IsBeingLootedBy(client)) + if (IsBeingLootedBy(client)) { ResetLooter(); + } return; } diff --git a/zone/entity.cpp b/zone/entity.cpp index a447ec650..49c21a1da 100644 --- a/zone/entity.cpp +++ b/zone/entity.cpp @@ -1555,16 +1555,18 @@ void EntityList::RemoveFromAutoXTargets(Mob *mob) void EntityList::RefreshAutoXTargets(Client *c) { - if (!c) + if (!c) { return; + } auto it = mob_list.begin(); while (it != mob_list.end()) { Mob *m = it->second; ++it; - if (!m || m->GetHP() <= 0) + if (!m || m->GetHP() <= 0) { continue; + } if ((m->CheckAggro(c) || m->IsOnFeignMemory(c)) && !c->IsXTarget(m)) { c->AddAutoXTarget(m, false); // we only call this before a bulk, so lets not send right away @@ -1576,19 +1578,22 @@ void EntityList::RefreshAutoXTargets(Client *c) void EntityList::RefreshClientXTargets(Client *c) { - if (!c) + if (!c) { return; + } auto it = client_list.begin(); while (it != client_list.end()) { Client *c2 = it->second; ++it; - if (!c2) + if (!c2) { continue; + } - if (c2->IsClientXTarget(c)) + if (c2->IsClientXTarget(c)) { c2->UpdateClientXTarget(c); + } } } @@ -2222,7 +2227,7 @@ Raid* EntityList::GetRaidByBotName(const char* name) std::list rm; auto GetMembersWithNames = [&rm](Raid const* r) -> std::list { for (const auto& m : r->members) { - if (strlen(m.membername) > 0) + if (strlen(m.member_name) > 0) rm.push_back(m); } return rm; @@ -2230,7 +2235,7 @@ Raid* EntityList::GetRaidByBotName(const char* name) for (const auto& r : raid_list) { for (const auto& m : GetMembersWithNames(r)) { - if (strcmp(m.membername, name) == 0) { + if (strcmp(m.member_name, name) == 0) { return r; } } @@ -2243,7 +2248,7 @@ Raid* EntityList::GetRaidByBot(const Bot* bot) std::list rm; auto GetMembersWhoAreBots = [&rm](Raid* r) -> std::list { for (auto const& m : r->members) { - if (m.IsBot) { + if (m.is_bot) { rm.push_back(m); } } @@ -4890,8 +4895,9 @@ void EntityList::SendZoneAppearance(Client *c) void EntityList::SendNimbusEffects(Client *c) { - if (!c) + if (!c) { return; + } auto it = mob_list.begin(); while (it != mob_list.end()) { @@ -4918,8 +4924,9 @@ void EntityList::SendNimbusEffects(Client *c) void EntityList::SendUntargetable(Client *c) { - if (!c) + if (!c) { return; + } auto it = mob_list.begin(); while (it != mob_list.end()) { @@ -4930,8 +4937,9 @@ void EntityList::SendUntargetable(Client *c) ++it; continue; } - if (!cur->IsTargetable()) + if (!cur->IsTargetable()) { cur->SendTargetable(false, c); + } } ++it; } @@ -4939,8 +4947,9 @@ void EntityList::SendUntargetable(Client *c) void EntityList::SendAppearanceEffects(Client *c) { - if (!c) + if (!c) { return; + } auto it = mob_list.begin(); while (it != mob_list.end()) { @@ -5429,8 +5438,9 @@ void EntityList::DeleteQGlobal(std::string name, uint32 npcID, uint32 charID, ui void EntityList::SendFindableNPCList(Client *c) { - if (!c) + if (!c) { return; + } auto outapp = new EQApplicationPacket(OP_SendFindableNPCs, sizeof(FindableNPC_Struct)); @@ -5496,8 +5506,9 @@ void EntityList::UpdateFindableNPCState(NPC *n, bool Remove) void EntityList::HideCorpses(Client *c, uint8 CurrentMode, uint8 NewMode) { - if (!c) + if (!c) { return; + } if (NewMode == HideCorpseNone) { SendZoneCorpses(c); @@ -5509,8 +5520,9 @@ void EntityList::HideCorpses(Client *c, uint8 CurrentMode, uint8 NewMode) if (NewMode == HideCorpseAllButGroup) { g = c->GetGroup(); - if (!g) + if (!g) { NewMode = HideCorpseAll; + } } auto it = corpse_list.begin(); diff --git a/zone/exp.cpp b/zone/exp.cpp index 2907667d2..92890ed1d 100644 --- a/zone/exp.cpp +++ b/zone/exp.cpp @@ -1200,7 +1200,7 @@ void Raid::SplitExp(const uint64 exp, Mob* other) { } for (const auto& m : members) { - if (m.member && !m.IsBot) { + if (m.member && !m.is_bot) { const int32 diff = m.member->GetLevel() - highest_level; int32 max_diff = -(m.member->GetLevel() * 15 / 10 - m.member->GetLevel()); diff --git a/zone/expedition.cpp b/zone/expedition.cpp index 4233882f9..f92284d8f 100644 --- a/zone/expedition.cpp +++ b/zone/expedition.cpp @@ -427,8 +427,7 @@ void Expedition::RemoveLockout(const std::string& event_name) void Expedition::SendClientExpeditionInvite( Client* client, const std::string& inviter_name, const std::string& swap_remove_name) { - if (!client) - { + if (!client) { return; } diff --git a/zone/expedition_request.cpp b/zone/expedition_request.cpp index dfca1d581..85e27e725 100644 --- a/zone/expedition_request.cpp +++ b/zone/expedition_request.cpp @@ -96,12 +96,12 @@ bool ExpeditionRequest::CanRaidRequest(Raid* raid) // stable_sort not needed, order within a raid group may not be what is displayed std::sort(raid_members.begin(), raid_members.end(), [&](const RaidMember& lhs, const RaidMember& rhs) { - if (m_leader_name == lhs.membername) { // leader always added first + if (m_leader_name == lhs.member_name) { // leader always added first return true; - } else if (m_leader_name == rhs.membername) { + } else if (m_leader_name == rhs.member_name) { return false; } - return lhs.GroupNumber < rhs.GroupNumber; + return lhs.group_number < rhs.group_number; }); m_not_all_added_msg = fmt::format(CREATE_NOT_ALL_ADDED, "raid", SystemName, @@ -112,7 +112,7 @@ bool ExpeditionRequest::CanRaidRequest(Raid* raid) std::vector member_names; for (int i = 0; i < raid_members.size(); ++i) { - member_names.emplace_back(raid_members[i].membername); + member_names.emplace_back(raid_members[i].member_name); } return CanMembersJoin(member_names); diff --git a/zone/groups.cpp b/zone/groups.cpp index 7bb51bfb2..d803904d6 100644 --- a/zone/groups.cpp +++ b/zone/groups.cpp @@ -35,7 +35,7 @@ extern WorldServer worldserver; note about how groups work: A group contains 2 list, a list of pointers to members and a list of member names. All members of a group should have their -name in the membername array, whether they are in the zone or not. +name in the member_name array, whether they are in the zone or not. Only members in this zone will have non-null pointers in the members array. */ diff --git a/zone/lua_raid.cpp b/zone/lua_raid.cpp index 716d7ce12..6cb6cdf7d 100644 --- a/zone/lua_raid.cpp +++ b/zone/lua_raid.cpp @@ -148,12 +148,12 @@ int Lua_Raid::GetGroupNumber(int member_index) { if ( !EQ::ValueWithin(member_index, 0, 71) || - self->members[member_index].GroupNumber == RAID_GROUPLESS + self->members[member_index].group_number == RAID_GROUPLESS ) { return -1; } - return self->members[member_index].GroupNumber; + return self->members[member_index].group_number; } bool Lua_Raid::DoesAnyMemberHaveExpeditionLockout(std::string expedition_name, std::string event_name) diff --git a/zone/mob_ai.cpp b/zone/mob_ai.cpp index 685c65b26..325ab909c 100644 --- a/zone/mob_ai.cpp +++ b/zone/mob_ai.cpp @@ -2068,16 +2068,19 @@ bool Mob::Flurry(ExtraAttackOptions *opts) bool Mob::AddRampage(Mob *mob) { - if (!mob) + if (!mob) { return false; + } - if (!GetSpecialAbility(SPECATK_RAMPAGE)) + if (!GetSpecialAbility(SPECATK_RAMPAGE)) { return false; + } for (int i = 0; i < RampageArray.size(); i++) { // if Entity ID is already on the list don't add it again - if (mob->GetID() == RampageArray[i]) + if (mob->GetID() == RampageArray[i]) { return false; + } } RampageArray.push_back(mob->GetID()); return true; diff --git a/zone/perl_raids.cpp b/zone/perl_raids.cpp index 399e6636c..ad088698e 100644 --- a/zone/perl_raids.cpp +++ b/zone/perl_raids.cpp @@ -150,12 +150,12 @@ bool Perl_Raid_DoesAnyMemberHaveExpeditionLockout(Raid* self, std::string expedi int Perl_Raid_GetGroupNumber(Raid* self, int member_index) { if ( !EQ::ValueWithin(member_index, 0, 71) || - self->members[member_index].GroupNumber == RAID_GROUPLESS + self->members[member_index].group_number == RAID_GROUPLESS ) { return -1; } - return self->members[member_index].GroupNumber; + return self->members[member_index].group_number; } void perl_register_raid() diff --git a/zone/raids.cpp b/zone/raids.cpp index 91f44d962..c64d0ea42 100644 --- a/zone/raids.cpp +++ b/zone/raids.cpp @@ -39,9 +39,9 @@ Raid::Raid(uint32 raidID) memset(members ,0, (sizeof(RaidMember)*MAX_RAID_MEMBERS)); memset(&raid_aa, 0, sizeof(RaidLeadershipAA_Struct)); memset(group_aa, 0, sizeof(GroupLeadershipAA_Struct) * MAX_RAID_GROUPS); - for (int i = 0; i < MAX_RAID_GROUPS; i++) { - group_mentor[i].mentor_percent = 0; - group_mentor[i].mentoree = nullptr; + for (auto& gm : group_mentor) { + gm.mentor_percent = 0; + gm.mentoree = nullptr; } leader = nullptr; memset(leadername, 0, 64); @@ -57,9 +57,9 @@ Raid::Raid(Client* nLeader) memset(members ,0, (sizeof(RaidMember)*MAX_RAID_MEMBERS)); memset(&raid_aa, 0, sizeof(RaidLeadershipAA_Struct)); memset(group_aa, 0, sizeof(GroupLeadershipAA_Struct) * MAX_RAID_GROUPS); - for (int i = 0; i < MAX_RAID_GROUPS; i++) { - group_mentor[i].mentor_percent = 0; - group_mentor[i].mentoree = nullptr; + for (auto& gm : group_mentor) { + gm.mentor_percent = 0; + gm.mentoree = nullptr; } leader = nLeader; memset(leadername, 0, 64); @@ -76,25 +76,29 @@ Raid::~Raid() bool Raid::Process() { - if(forceDisband) + if (forceDisband) { return false; - if(disbandCheck) - { + } + + if (disbandCheck) { int count = 0; - for(int x = 0; x < MAX_RAID_MEMBERS; x++) - { - if(strlen(members[x].membername) == 0) + for (const auto& m : members) { + if (strlen(m.member_name) == 0) { continue; - else + } + else { count++; + } } - if(count == 0) + if (count == 0) { return false; + } } return true; } -void Raid::AddMember(Client *c, uint32 group, bool rleader, bool groupleader, bool looter){ +void Raid::AddMember(Client *c, uint32 group, bool rleader, bool groupleader, bool looter) +{ if (!c) { return; } @@ -115,17 +119,18 @@ void Raid::AddMember(Client *c, uint32 group, bool rleader, bool groupleader, bo ); auto results = database.QueryDatabase(query); - if(!results.Success()) { + if (!results.Success()) { LogError("Error inserting into raid members: [{}]", results.ErrorMessage().c_str()); } LearnMembers(); VerifyRaid(); - if (rleader) { + if (rleader && group != RAID_GROUPLESS) { database.SetRaidGroupLeaderInfo(group, GetID()); UpdateRaidAAs(); - } else if (rleader) { + } + else if (rleader) { database.SetRaidGroupLeaderInfo(RAID_GROUPLESS, GetID()); UpdateRaidAAs(); } @@ -137,7 +142,8 @@ void Raid::AddMember(Client *c, uint32 group, bool rleader, bool groupleader, bo if (group < MAX_RAID_GROUPS) { GroupUpdate(group); - } else { // get raid AAs, GroupUpdate will handles it otherwise + } + else { // get raid AAs, GroupUpdate will handles it otherwise SendGroupLeadershipAA(c, RAID_GROUPLESS); } @@ -151,7 +157,8 @@ void Raid::AddMember(Client *c, uint32 group, bool rleader, bool groupleader, bo GetXTargetAutoMgr()->merge(*c->GetXTargetAutoMgr()); c->GetXTargetAutoMgr()->clear(); c->SetXTargetAutoMgr(GetXTargetAutoMgr()); - } else { + } + else { if (!c->GetXTargetAutoMgr()->empty()) { GetXTargetAutoMgr()->merge(*c->GetXTargetAutoMgr()); c->GetXTargetAutoMgr()->clear(); @@ -160,13 +167,13 @@ void Raid::AddMember(Client *c, uint32 group, bool rleader, bool groupleader, bo c->SetXTargetAutoMgr(GetXTargetAutoMgr()); - if (!c->GetXTargetAutoMgr()->empty()) + if (!c->GetXTargetAutoMgr()->empty()) { c->SetDirtyAutoHaters(); + } } } - auto* raid_update = c->GetRaid(); - if (raid_update) { + if (auto* raid_update = c->GetRaid()) { raid_update->SendHPManaEndPacketsTo(c); raid_update->SendHPManaEndPacketsFrom(c); } @@ -181,9 +188,8 @@ void Raid::AddMember(Client *c, uint32 group, bool rleader, bool groupleader, bo safe_delete(pack); } - - -void Raid::AddBot(Bot* b, uint32 group, bool rleader, bool groupleader, bool looter) { +void Raid::AddBot(Bot* b, uint32 group, bool raid_leader, bool group_leader, bool looter) +{ if (!b) { return; } @@ -198,8 +204,8 @@ void Raid::AddBot(Bot* b, uint32 group, bool rleader, bool groupleader, bool loo b->GetClass(), b->GetLevel(), b->GetName(), - groupleader, - rleader, + group_leader, + raid_leader, looter ); @@ -231,23 +237,23 @@ void Raid::AddBot(Bot* b, uint32 group, bool rleader, bool groupleader, bool loo } -void Raid::RemoveMember(const char *characterName) +void Raid::RemoveMember(const char *character_name) { - std::string query = StringFormat("DELETE FROM raid_members where name='%s'", characterName); + std::string query = StringFormat("DELETE FROM raid_members where name='%s'", character_name); auto results = database.QueryDatabase(query); - auto* b = entity_list.GetBotByBotName(characterName); - auto* c = entity_list.GetClientByName(characterName); + auto* b = entity_list.GetBotByBotName(character_name); + auto* c = entity_list.GetClientByName(character_name); if (RuleB(Bots, Enabled) && b) { - b = entity_list.GetBotByBotName(characterName); + b = entity_list.GetBotByBotName(character_name); b->SetFollowID(b->GetOwner()->CastToClient()->GetID()); b->SetTarget(nullptr); b->SetRaidGrouped(false); } disbandCheck = true; - SendRaidRemoveAll(characterName); + SendRaidRemoveAll(character_name); SendRaidDisband(c); LearnMembers(); VerifyRaid(); @@ -263,7 +269,7 @@ void Raid::RemoveMember(const char *characterName) rga->rid = GetID(); rga->instance_id = zone->GetInstanceID(); rga->zoneid = zone->GetZoneID(); - strn0cpy(rga->playername, characterName, sizeof(rga->playername)); + strn0cpy(rga->playername, character_name, sizeof(rga->playername)); worldserver.SendPacket(pack); safe_delete(pack); } @@ -340,12 +346,15 @@ void Raid::SetGroupLeader(const char *who, bool glFlag) Client *Raid::GetGroupLeader(uint32 group_id) { - if (group_id == RAID_GROUPLESS) + if (group_id == RAID_GROUPLESS) { return nullptr; + } - for (uint32 i = 0; i < MAX_RAID_MEMBERS; i++) - if (members[i].member && members[i].IsGroupLeader && members[i].GroupNumber == group_id) - return members[i].member; + for (const auto& m : members) { + if (m.member && m.is_group_leader && m.group_number == group_id) { + return m.member; + } + } return nullptr; } @@ -354,28 +363,32 @@ void Raid::SetRaidLeader(const char *wasLead, const char *name) { std::string query = StringFormat("UPDATE raid_members SET israidleader = 0 WHERE name = '%s'", wasLead); auto results = database.QueryDatabase(query); - if (!results.Success()) + if (!results.Success()) { LogError("Set Raid Leader error: [{}]\n", results.ErrorMessage().c_str()); + } query = StringFormat("UPDATE raid_members SET israidleader = 1 WHERE name = '%s'", name); results = database.QueryDatabase(query); - if (!results.Success()) + if (!results.Success()) { LogError("Set Raid Leader error: [{}]\n", results.ErrorMessage().c_str()); + } strn0cpy(leadername, name, 64); Client *c = entity_list.GetClientByName(name); - if(c) + if (c) { SetLeader(c); - else - SetLeader(nullptr); //sanity check, should never get hit but we want to prefer to NOT crash if we do VerifyRaid and leader never gets set there (raid without a leader?) + } + else { + SetLeader(nullptr); + } //sanity check, should never get hit but we want to prefer to NOT crash if we do VerifyRaid and leader never gets set there (raid without a leader?) LearnMembers(); VerifyRaid(); SendMakeLeaderPacket(name); auto pack = new ServerPacket(ServerOP_RaidLeader, sizeof(ServerRaidGeneralAction_Struct)); - ServerRaidGeneralAction_Struct *rga = (ServerRaidGeneralAction_Struct*)pack->pBuffer; + auto rga = (ServerRaidGeneralAction_Struct*)pack->pBuffer; rga->rid = GetID(); strn0cpy(rga->playername, name, 64); rga->zoneid = zone->GetZoneID(); @@ -394,8 +407,9 @@ void Raid::SaveGroupLeaderAA(uint32 gid) query += StringFormat("' WHERE gid = %lu AND rid = %lu LIMIT 1", gid, GetID()); safe_delete_array(queryBuffer); auto results = database.QueryDatabase(query); - if (!results.Success()) + if (!results.Success()) { LogError("Unable to store LeadershipAA: [{}]\n", results.ErrorMessage().c_str()); + } } void Raid::SaveRaidLeaderAA() @@ -408,22 +422,25 @@ void Raid::SaveRaidLeaderAA() query += StringFormat("' WHERE gid = %lu AND rid = %lu LIMIT 1", RAID_GROUPLESS, GetID()); safe_delete_array(queryBuffer); auto results = database.QueryDatabase(query); - if (!results.Success()) + if (!results.Success()) { LogError("Unable to store LeadershipAA: [{}]\n", results.ErrorMessage().c_str()); + } } void Raid::UpdateGroupAAs(uint32 gid) { - if (gid < 0 || gid > MAX_RAID_GROUPS) + if (gid > MAX_RAID_GROUPS) { return; + } Client *gl = GetGroupLeader(gid); - if (gl) + if (gl) { gl->GetGroupAAs(&group_aa[gid]); - else + } else { memset(&group_aa[gid], 0, sizeof(GroupLeadershipAA_Struct)); + } SaveGroupLeaderAA(gid); } @@ -432,10 +449,11 @@ void Raid::UpdateRaidAAs() { Client *rl = GetLeader(); - if (rl) + if (rl) { rl->GetRaidAAs(&raid_aa); - else + } else { memset(&raid_aa, 0, sizeof(RaidLeadershipAA_Struct)); + } SaveRaidLeaderAA(); } @@ -444,8 +462,8 @@ bool Raid::IsGroupLeader(const char* name) { if (name) { for (const auto &m: members) { - if (!strcmp(m.membername, name)) { - return m.IsGroupLeader; + if (!strcmp(m.member_name, name)) { + return m.is_group_leader; } } } @@ -479,16 +497,16 @@ void Raid::UpdateLevel(const char *name, int newLevel) uint32 Raid::GetFreeGroup() { //check each group return the first one with 0 members assigned... - for(int x = 0; x < MAX_RAID_GROUPS; x++) - { + for (int x = 0; x < MAX_RAID_GROUPS; x++) { int count = 0; - for(int y = 0; y < MAX_RAID_MEMBERS; y++) - { - if(members[y].GroupNumber == x && (strlen(members[y].membername)>0)) + for (const auto& m : members) { + if (m.group_number == x && (strlen(m.member_name) > 0)) { count++; + } } - if(count == 0) + if (count == 0) { return x; + } } //if we get to here then there were no free groups so we added the group as free floating members. return RAID_GROUPLESS; @@ -497,22 +515,16 @@ uint32 Raid::GetFreeGroup() uint8 Raid::GroupCount(uint32 gid) { uint8 count = 0; - if(gid < MAX_RAID_GROUPS) - { - for(int x = 0; x < MAX_RAID_MEMBERS; x++) - { - if(members[x].GroupNumber == gid && strlen(members[x].membername)>0) - { + if (gid < MAX_RAID_GROUPS) { + for (const auto& m : members) { + if (m.group_number == gid && strlen(m.member_name) > 0) { count++; } } } - else - { - for(int x = 0; x < MAX_RAID_MEMBERS; x++) - { - if(members[x].GroupNumber > 11 && strlen(members[x].membername)>0) - { + else { + for (const auto& m : members) { + if (m.group_number > 11 && strlen(m.member_name) > 0) { count++; } } @@ -523,38 +535,39 @@ uint8 Raid::GroupCount(uint32 gid) uint8 Raid::RaidCount() { int count = 0; - for(int x = 0; x < MAX_RAID_MEMBERS; x++) - { - if(strlen(members[x].membername) > 0) + for (const auto& m : members) { + if (strlen(m.member_name) > 0) { count++; + } } return count; } uint32 Raid::GetGroup(const char *name) { - for(int x = 0; x < MAX_RAID_MEMBERS; x++) - { - if(strcmp(members[x].membername, name) == 0) - return members[x].GroupNumber; + for (const auto& m : members) { + if (strcmp(m.member_name, name) == 0) { + return m.group_number; + } } return RAID_GROUPLESS; } uint32 Raid::GetGroup(Client *c) { - for(int x = 0; x < MAX_RAID_MEMBERS; x++) - { - if(members[x].member == c) - return members[x].GroupNumber; + for (const auto& m : members) { + if (m.member == c) { + return m.group_number; + } } return RAID_GROUPLESS; } void Raid::RaidSay(const char *msg, Client *c, uint8 language, uint8 lang_skill) { - if(!c) + if (!c) { return; + } auto pack = new ServerPacket(ServerOP_RaidSay, sizeof(ServerRaidMessage_Struct) + strlen(msg) + 1); ServerRaidMessage_Struct *rga = (ServerRaidMessage_Struct*)pack->pBuffer; @@ -572,18 +585,20 @@ void Raid::RaidSay(const char *msg, Client *c, uint8 language, uint8 lang_skill) void Raid::RaidGroupSay(const char *msg, Client *c, uint8 language, uint8 lang_skill) { - if(!c) + if (!c) { return; + } - uint32 groupToUse = GetGroup(c->GetName()); + uint32 group_id_to_use = GetGroup(c->GetName()); - if(groupToUse > 11) + if (group_id_to_use >= MAX_RAID_GROUPS) { return; + } auto pack = new ServerPacket(ServerOP_RaidGroupSay, sizeof(ServerRaidMessage_Struct) + strlen(msg) + 1); - ServerRaidMessage_Struct *rga = (ServerRaidMessage_Struct*)pack->pBuffer; + auto rga = (ServerRaidMessage_Struct*)pack->pBuffer; rga->rid = GetID(); - rga->gid = groupToUse; + rga->gid = group_id_to_use; rga->language = language; rga->lang_skill = lang_skill; strn0cpy(rga->from, c->GetName(), 64); @@ -594,10 +609,11 @@ void Raid::RaidGroupSay(const char *msg, Client *c, uint8 language, uint8 lang_s safe_delete(pack); } -uint32 Raid::GetPlayerIndex(const char *name){ +uint32 Raid::GetPlayerIndex(const char *name) +{ for(int x = 0; x < MAX_RAID_MEMBERS; x++) { - if(strcmp(name, members[x].membername) == 0){ + if(strcmp(name, members[x].member_name) == 0) { return x; } } @@ -606,16 +622,19 @@ uint32 Raid::GetPlayerIndex(const char *name){ uint32 Raid::GetPlayerIndex(Client *c) { - for (int i = 0; i < MAX_RAID_MEMBERS; ++i) - if (c == members[i].member) + for (int i = 0; i < MAX_RAID_MEMBERS; ++i) { + if (c == members[i].member) { return i; + } + } return 0xFFFFFFFF; // return sentinel value, make sure you check it unlike the above function } Client *Raid::GetClientByIndex(uint16 index) { - if(index > MAX_RAID_MEMBERS) + if (index > MAX_RAID_MEMBERS) { return nullptr; + } return members[index].member; } @@ -624,36 +643,37 @@ void Raid::CastGroupSpell(Mob* caster, uint16 spellid, uint32 gid) { float range, distance; - if(!caster) + if (!caster) { return; + } range = caster->GetAOERange(spellid); float range2 = range*range; - for(int x = 0; x < MAX_RAID_MEMBERS; x++) - { - if(members[x].member == caster) { + for (const auto& m : members) { + if (m.member == caster) { caster->SpellOnTarget(spellid, caster); #ifdef GROUP_BUFF_PETS - if(spells[spellid].target_type != ST_GroupNoPets && caster->GetPet() && caster->HasPetAffinity() && !caster->GetPet()->IsCharmed()) + if (spells[spellid].target_type != ST_GroupNoPets && caster->GetPet() && caster->HasPetAffinity() && !caster->GetPet()->IsCharmed()) { caster->SpellOnTarget(spellid, caster->GetPet()); + } #endif } - else if(members[x].member != nullptr) - { - if(members[x].GroupNumber == gid){ - distance = DistanceSquared(caster->GetPosition(), members[x].member->GetPosition()); - if(distance <= range2){ - caster->SpellOnTarget(spellid, members[x].member); + else if (m.member != nullptr && m.group_number == gid) { + distance = DistanceSquared(caster->GetPosition(), m.member->GetPosition()); + if (distance <= range2) { + caster->SpellOnTarget(spellid, m.member); + #ifdef GROUP_BUFF_PETS - if(spells[spellid].target_type != ST_GroupNoPets && members[x].member->GetPet() && members[x].member->HasPetAffinity() && !members[x].member->GetPet()->IsCharmed()) - caster->SpellOnTarget(spellid, members[x].member->GetPet()); + if (spells[spellid].target_type != ST_GroupNoPets && m.member->GetPet() && m.member->HasPetAffinity() && + !m.member->GetPet()->IsCharmed()) { + caster->SpellOnTarget(spellid, m.member->GetPet()); + } #endif - } - else{ - LogSpells("Raid spell: [{}] is out of range [{}] at distance [{}] from [{}]", members[x].member->GetName(), range, distance, caster->GetName()); - } + } + else { + LogSpells("Raid spell: [{}] is out of range [{}] at distance [{}] from [{}]", m.member->GetName(), range, distance, caster->GetName()); } } } @@ -664,52 +684,51 @@ uint32 Raid::GetTotalRaidDamage(Mob* other) { uint32 total = 0; - for (uint32 i = 0; i < MAX_RAID_MEMBERS; i++) { - if(!members[i].member) + for (const auto& m : members) { + if (!m.member) { continue; - if (other->CheckAggro(members[i].member)) - total += other->GetHateAmount(members[i].member,true); + } + + if (other->CheckAggro(m.member)) { + total += other->GetHateAmount(m.member, true); + } } + return total; } void Raid::HealGroup(uint32 heal_amt, Mob* caster, uint32 gid, float range) { - if (!caster) + if (!caster) { return; + } - if (!range) + if (!range) { range = 200; + } float distance; float range2 = range*range; int numMem = 0; - unsigned int gi = 0; - for(; gi < MAX_RAID_MEMBERS; gi++) - { - if(members[gi].member){ - if(members[gi].GroupNumber == gid) - { - distance = DistanceSquared(caster->GetPosition(), members[gi].member->GetPosition()); - if(distance <= range2){ - numMem += 1; - } + for (const auto& m : members) { + if (m.member && m.group_number == gid) { + distance = DistanceSquared(caster->GetPosition(), m.member->GetPosition()); + + if (distance <= range2) { + numMem += 1; } } } heal_amt /= numMem; - for(gi = 0; gi < MAX_RAID_MEMBERS; gi++) - { - if(members[gi].member){ - if(members[gi].GroupNumber == gid) - { - distance = DistanceSquared(caster->GetPosition(), members[gi].member->GetPosition()); - if(distance <= range2){ - members[gi].member->SetHP(members[gi].member->GetHP() + heal_amt); - members[gi].member->SendHPUpdate(); - } + for (const auto& m : members) { + if (m.member && m.group_number == gid) { + distance = DistanceSquared(caster->GetPosition(), m.member->GetPosition()); + + if (distance <= range2) { + m.member->SetHP(m.member->GetHP() + heal_amt); + m.member->SendHPUpdate(); } } } @@ -718,54 +737,53 @@ void Raid::HealGroup(uint32 heal_amt, Mob* caster, uint32 gid, float range) void Raid::BalanceHP(int32 penalty, uint32 gid, float range, Mob* caster, int32 limit) { - if (!caster) + if (!caster) { return; + } - if (!range) + if (!range) { range = 200; + } int dmgtaken = 0, numMem = 0, dmgtaken_tmp = 0; - int gi = 0; float distance; float range2 = range*range; - for(; gi < MAX_RAID_MEMBERS; gi++) - { - if(members[gi].member){ - if(members[gi].GroupNumber == gid) - { - distance = DistanceSquared(caster->GetPosition(), members[gi].member->GetPosition()); - if(distance <= range2){ + for (const auto& m : members) { + if (m.member && m.group_number == gid) { + distance = DistanceSquared(caster->GetPosition(), m.member->GetPosition()); - dmgtaken_tmp = members[gi].member->GetMaxHP() - members[gi].member->GetHP(); - if (limit && (dmgtaken_tmp > limit)) - dmgtaken_tmp = limit; + if (distance <= range2) { + dmgtaken_tmp = m.member->GetMaxHP() - m.member->GetHP(); - dmgtaken += (dmgtaken_tmp); - numMem += 1; + if (limit && (dmgtaken_tmp > limit)) { + dmgtaken_tmp = limit; } + + dmgtaken += dmgtaken_tmp; + numMem += 1; } } } dmgtaken += dmgtaken * penalty / 100; dmgtaken /= numMem; - for(gi = 0; gi < MAX_RAID_MEMBERS; gi++) - { - if(members[gi].member){ - if(members[gi].GroupNumber == gid) - { - distance = DistanceSquared(caster->GetPosition(), members[gi].member->GetPosition()); - if(distance <= range2){ - if((members[gi].member->GetMaxHP() - dmgtaken) < 1){//this way the ability will never kill someone - members[gi].member->SetHP(1); //but it will come darn close - members[gi].member->SendHPUpdate(); - } - else{ - members[gi].member->SetHP(members[gi].member->GetMaxHP() - dmgtaken); - members[gi].member->SendHPUpdate(); - } + for (const auto& m : members) { + if (m.member && m.group_number == gid) { + distance = DistanceSquared(caster->GetPosition(), m.member->GetPosition()); + + //this way the ability will never kill someone + //but it will come darn close + if (distance <= range2) { + if ((m.member->GetMaxHP() - dmgtaken) < 1) { + m.member->SetHP(1); + m.member->SendHPUpdate(); + } + + else { + m.member->SetHP(m.member->GetMaxHP() - dmgtaken); + m.member->SendHPUpdate(); } } } @@ -774,34 +792,38 @@ void Raid::BalanceHP(int32 penalty, uint32 gid, float range, Mob* caster, int32 void Raid::BalanceMana(int32 penalty, uint32 gid, float range, Mob* caster, int32 limit) { - if (!caster) + if (!caster) { return; + } - if (!range) + if (!range) { range = 200; + } float distance; float range2 = range*range; - int manataken = 0, numMem = 0, manataken_tmp = 0; - int gi = 0; - for(; gi < MAX_RAID_MEMBERS; gi++) - { - if (members[gi].member && !members[gi].IsBot) { - if (members[gi].GroupNumber == gid) - { - if (members[gi].member->GetMaxMana() > 0) { - distance = DistanceSquared(caster->GetPosition(), members[gi].member->GetPosition()); - if(distance <= range2){ + int manataken = 0; + int numMem = 0; + int manataken_tmp = 0; - manataken_tmp = members[gi].member->GetMaxMana() - members[gi].member->GetMana(); - if (limit && (manataken_tmp > limit)) - manataken_tmp = limit; + for (const auto& m : members) { + if (m.is_bot) { + continue; + } - manataken += (manataken_tmp); - numMem += 1; - } + if (m.member && m.group_number == gid && m.member->GetMaxMana() > 0) { + distance = DistanceSquared(caster->GetPosition(), m.member->GetPosition()); + + if (distance <= range2) { + manataken_tmp = m.member->GetMaxMana() - m.member->GetMana(); + + if (limit && (manataken_tmp > limit)) { + manataken_tmp = limit; } + + manataken += manataken_tmp; + numMem += 1; } } } @@ -809,22 +831,23 @@ void Raid::BalanceMana(int32 penalty, uint32 gid, float range, Mob* caster, int3 manataken += manataken * penalty / 100; manataken /= numMem; - for(gi = 0; gi < MAX_RAID_MEMBERS; gi++) - { - if (members[gi].member) { - if (members[gi].GroupNumber == gid) - { - distance = DistanceSquared(caster->GetPosition(), members[gi].member->GetPosition()); - if (distance <= range2){ - if ((members[gi].member->GetMaxMana() - manataken) < 1) { - members[gi].member->SetMana(1); - if (members[gi].member->IsClient()) - members[gi].member->CastToClient()->SendManaUpdate(); + for (const auto& m : members) { + if (m.member && m.group_number == gid) { + distance = DistanceSquared(caster->GetPosition(), m.member->GetPosition()); + + if (distance <= range2) { + if ((m.member->GetMaxMana() - manataken) < 1) { + m.member->SetMana(1); + + if (m.member->IsClient()) { + m.member->CastToClient()->SendManaUpdate(); } - else { - members[gi].member->SetMana(members[gi].member->GetMaxMana() - manataken); - if (members[gi].member->IsClient()) - members[gi].member->CastToClient()->SendManaUpdate(); + } + else { + m.member->SetMana(m.member->GetMaxMana() - manataken); + + if (m.member->IsClient()) { + m.member->CastToClient()->SendManaUpdate(); } } } @@ -851,8 +874,8 @@ void Raid::SplitMoney(uint32 gid, uint32 copper, uint32 silver, uint32 gold, uin } uint8 member_count = 0; - for (uint32 i = 0; i < MAX_RAID_MEMBERS; i++) { - if (members[i].member && members[i].GroupNumber == gid && members[i].member->IsClient()) { + for (const auto& m : members) { + if (m.member && m.group_number == gid && m.member->IsClient()) { member_count++; } } @@ -890,9 +913,9 @@ void Raid::SplitMoney(uint32 gid, uint32 copper, uint32 silver, uint32 gold, uin auto gold_split = gold / member_count; auto platinum_split = platinum / member_count; - for (uint32 i = 0; i < MAX_RAID_MEMBERS; i++) { - if (members[i].member && members[i].GroupNumber == gid && members[i].member->IsClient()) { // If Group Member is Client - members[i].member->AddMoneyToPP( + for (const auto& m : members) { + if (m.member && m.group_number == gid && m.member->IsClient()) { // If Group Member is Client + m.member->AddMoneyToPP( copper_split, silver_split, gold_split, @@ -906,13 +929,13 @@ void Raid::SplitMoney(uint32 gid, uint32 copper, uint32 silver, uint32 gold, uin .silver = silver_split, .gold = gold_split, .platinum = platinum_split, - .player_money_balance = members[i].member->GetCarriedMoney(), + .player_money_balance = m.member->GetCarriedMoney(), }; - RecordPlayerEventLogWithClient(members[i].member, PlayerEvent::SPLIT_MONEY, e); + RecordPlayerEventLogWithClient(m.member, PlayerEvent::SPLIT_MONEY, e); } - members[i].member->MessageString( + m.member->MessageString( Chat::MoneySplit, YOU_RECEIVE_AS_SPLIT, Strings::Money( @@ -928,9 +951,8 @@ void Raid::SplitMoney(uint32 gid, uint32 copper, uint32 silver, uint32 gold, uin void Raid::TeleportGroup(Mob* sender, uint32 zoneID, uint16 instance_id, float x, float y, float z, float heading, uint32 gid) { - for (const auto& m : members) - { - if (m.member && m.GroupNumber == gid && m.member->IsClient()) { + for (const auto& m : members) { + if (m.member && m.group_number == gid && m.member->IsClient()) { m.member->MovePC(zoneID, instance_id, x, y, z, heading, 0, ZoneSolicited); } } @@ -938,10 +960,8 @@ void Raid::TeleportGroup(Mob* sender, uint32 zoneID, uint16 instance_id, float x void Raid::TeleportRaid(Mob* sender, uint32 zoneID, uint16 instance_id, float x, float y, float z, float heading) { - for (const auto& m : members) - { - if (m.member && m.member->IsClient()) - { + for (const auto& m : members) { + if (m.member && m.member->IsClient()) { m.member->MovePC(zoneID, instance_id, x, y, z, heading, 0, ZoneSolicited); } } @@ -950,8 +970,8 @@ void Raid::TeleportRaid(Mob* sender, uint32 zoneID, uint16 instance_id, float x, void Raid::ChangeLootType(uint32 type) { std::string query = StringFormat("UPDATE raid_details SET loottype = %lu WHERE raidid = %lu", - (unsigned long)type, (unsigned long)GetID()); - auto results = database.QueryDatabase(query); + (unsigned long)type, (unsigned long)GetID()); + auto results = database.QueryDatabase(query); LootType = type; } @@ -960,16 +980,15 @@ void Raid::AddRaidLooter(const char* looter) std::string query = StringFormat("UPDATE raid_members SET islooter = 1 WHERE name = '%s'", looter); auto results = database.QueryDatabase(query); - for(int x = 0; x < MAX_RAID_MEMBERS; x++) - { - if(strcmp(looter, members[x].membername) == 0) - { - members[x].IsLooter = 1; + for (auto& m : members) { + if (strcmp(looter, m.member_name) == 0) { + m.is_looter = true; break; } } + auto pack = new ServerPacket(ServerOP_DetailsChange, sizeof(ServerRaidGeneralAction_Struct)); - ServerRaidGeneralAction_Struct *rga = (ServerRaidGeneralAction_Struct*)pack->pBuffer; + auto rga = (ServerRaidGeneralAction_Struct*)pack->pBuffer; rga->rid = GetID(); rga->zoneid = zone->GetZoneID(); rga->instance_id = zone->GetInstanceID(); @@ -982,14 +1001,15 @@ void Raid::RemoveRaidLooter(const char* looter) std::string query = StringFormat("UPDATE raid_members SET islooter = 0 WHERE name = '%s'", looter); auto results = database.QueryDatabase(query); - for(int x = 0; x < MAX_RAID_MEMBERS; x++) - if(strcmp(looter, members[x].membername) == 0) { - members[x].IsLooter = 0; + for (auto& m: members) { + if (strcmp(looter, m.member_name) == 0) { + m.is_looter = false; break; } + } auto pack = new ServerPacket(ServerOP_DetailsChange, sizeof(ServerRaidGeneralAction_Struct)); - ServerRaidGeneralAction_Struct *rga = (ServerRaidGeneralAction_Struct*)pack->pBuffer; + auto rga = (ServerRaidGeneralAction_Struct*)pack->pBuffer; rga->rid = GetID(); rga->zoneid = zone->GetZoneID(); rga->instance_id = zone->GetInstanceID(); @@ -1001,7 +1021,7 @@ bool Raid::IsRaidMember(const char *name) { if (name) { for (const auto &m: members) { - if (!strcmp(m.membername, name)) { + if (!strcmp(m.member_name, name)) { return true; } } @@ -1026,40 +1046,38 @@ bool Raid::IsRaidMember(Client* c) uint32 Raid::GetHighestLevel() { uint32 highlvl = 0; - for(int x = 0; x < MAX_RAID_MEMBERS; x++) - { - if(strlen(members[x].membername)) - { - if(members[x].level > highlvl) - highlvl = members[x].level; + for (const auto& m : members) { + if (strlen(m.member_name) && m.level > highlvl) { + highlvl = m.level; } } + return highlvl; } uint32 Raid::GetLowestLevel() { uint32 lowlvl = 1000; - for(int x = 0; x < MAX_RAID_MEMBERS; x++) - { - if(strlen(members[x].membername)) - { - if(members[x].level < lowlvl) - lowlvl = members[x].level; + for (const auto& m : members) { + if (strlen(m.member_name) && m.level < lowlvl) { + lowlvl = m.level; } } + return lowlvl; } /* * Packet Functions Start */ -void Raid::SendRaidCreate(Client *to){ - if(!to) +void Raid::SendRaidCreate(Client *to) +{ + if (!to) { return; + } auto outapp = new EQApplicationPacket(OP_RaidJoin, sizeof(RaidCreate_Struct)); - RaidCreate_Struct *rc = (RaidCreate_Struct*)outapp->pBuffer; + auto rc = (RaidCreate_Struct*)outapp->pBuffer; rc->action = raidCreate; strn0cpy(rc->leader_name, leadername, 64); rc->leader_id = (GetLeader()?GetLeader()->GetID():0); @@ -1069,24 +1087,23 @@ void Raid::SendRaidCreate(Client *to){ void Raid::SendRaidAdd(const char *who, Client *to) { - if(!to) + if (!to) { return; + } std::vector rm = GetMembers(); - for (const auto& m : rm) - { - if (strcmp(m.membername, who) == 0) - { + for (const auto& m : rm) { + if (strcmp(m.member_name, who) == 0) { auto outapp = new EQApplicationPacket(OP_RaidUpdate, sizeof(RaidAddMember_Struct)); - RaidAddMember_Struct* ram = (RaidAddMember_Struct*)outapp->pBuffer; + auto ram = (RaidAddMember_Struct*)outapp->pBuffer; ram->raidGen.action = raidAdd; - ram->raidGen.parameter = m.GroupNumber; - strn0cpy(ram->raidGen.leader_name, m.membername, 64); - strn0cpy(ram->raidGen.player_name, m.membername, 64); + ram->raidGen.parameter = m.group_number; + strn0cpy(ram->raidGen.leader_name, m.member_name, 64); + strn0cpy(ram->raidGen.player_name, m.member_name, 64); ram->_class = m._class; ram->level = m.level; - ram->isGroupLeader = m.IsGroupLeader; + ram->isGroupLeader = m.is_group_leader; to->QueuePacket(outapp); safe_delete(outapp); return; @@ -1099,15 +1116,14 @@ void Raid::SendRaidAddAll(const char *who) std::vector rm = GetMembers(); for (const auto& m : rm) { - if (strcmp(m.membername, who) == 0) - { + if (strcmp(m.member_name, who) == 0) { auto outapp = new EQApplicationPacket(OP_RaidUpdate, sizeof(RaidAddMember_Struct)); - RaidAddMember_Struct* ram = (RaidAddMember_Struct*)outapp->pBuffer; + auto ram = (RaidAddMember_Struct*)outapp->pBuffer; ram->raidGen.action = raidAdd; - ram->raidGen.parameter = m.GroupNumber; - strcpy(ram->raidGen.leader_name, m.membername); - strcpy(ram->raidGen.player_name, m.membername); - ram->isGroupLeader = m.IsGroupLeader; + ram->raidGen.parameter = m.group_number; + strcpy(ram->raidGen.leader_name, m.member_name); + strcpy(ram->raidGen.player_name, m.member_name); + ram->isGroupLeader = m.is_group_leader; ram->_class = m._class; ram->level = m.level; @@ -1120,15 +1136,14 @@ void Raid::SendRaidAddAll(const char *who) void Raid::SendRaidRemove(const char *who, Client *to) { - if(!to) + if (!to) { return; + } - for(int x = 0; x < MAX_RAID_MEMBERS; x++) - { - if(strcmp(members[x].membername, who) == 0) - { + for (const auto& m : members) { + if (strcmp(m.member_name, who) == 0) { auto outapp = new EQApplicationPacket(OP_RaidUpdate, sizeof(RaidGeneral_Struct)); - RaidGeneral_Struct *rg = (RaidGeneral_Struct*)outapp->pBuffer; + auto rg = (RaidGeneral_Struct*)outapp->pBuffer; rg->action = raidRemove2; strn0cpy(rg->leader_name, who, 64); strn0cpy(rg->player_name, who, 64); @@ -1142,12 +1157,10 @@ void Raid::SendRaidRemove(const char *who, Client *to) void Raid::SendRaidRemoveAll(const char *who) { - for(int x = 0; x < MAX_RAID_MEMBERS; x++) - { - if(strcmp(members[x].membername, who) == 0) - { + for (const auto& m : members) { + if (strcmp(m.member_name, who) == 0) { auto outapp = new EQApplicationPacket(OP_RaidUpdate, sizeof(RaidGeneral_Struct)); - RaidGeneral_Struct *rg = (RaidGeneral_Struct*)outapp->pBuffer; + auto rg = (RaidGeneral_Struct*)outapp->pBuffer; rg->action = raidRemove2; strn0cpy(rg->leader_name, who, 64); strn0cpy(rg->player_name, who, 64); @@ -1166,7 +1179,7 @@ void Raid::SendRaidDisband(Client *to) } auto outapp = new EQApplicationPacket(OP_RaidUpdate, sizeof(RaidGeneral_Struct)); - RaidGeneral_Struct *rg = (RaidGeneral_Struct*)outapp->pBuffer; + auto rg = (RaidGeneral_Struct*)outapp->pBuffer; rg->action = raidDisband; strn0cpy(rg->leader_name, to->GetName(), 64); strn0cpy(rg->player_name, to->GetName(), 64); @@ -1178,7 +1191,7 @@ void Raid::SendRaidDisband(Client *to) void Raid::SendRaidDisbandAll() { auto outapp = new EQApplicationPacket(OP_RaidUpdate, sizeof(RaidGeneral_Struct)); - RaidGeneral_Struct *rg = (RaidGeneral_Struct*)outapp->pBuffer; + auto rg = (RaidGeneral_Struct*)outapp->pBuffer; rg->action = raidDisband; strn0cpy(rg->leader_name, "RaidMember", 64); strn0cpy(rg->player_name, "RaidMember", 64); @@ -1189,19 +1202,21 @@ void Raid::SendRaidDisbandAll() void Raid::SendRaidMove(const char* who, Client *to) { - if(!to) + if (!to) { return; + } Client *c = entity_list.GetClientByName(who); - if(c && c == to){ + if (c && c == to) { SendRaidCreate(c); SendMakeLeaderPacketTo(leadername, c); } + SendRaidRemove(who, to); SendRaidAdd(who, to); - if(c && c == to){ + if (c && c == to) { SendBulkRaid(c); - if(IsLocked()) { + if (IsLocked()) { SendRaidLockTo(c); } } @@ -1211,51 +1226,53 @@ void Raid::SendRaidMoveAll(const char* who) { Client *c = entity_list.GetClientByName(who); SendRaidRemoveAll(who); - if(c) + + if (c) { SendRaidCreate(c); - if(c){ - SendBulkRaid(c); - if(IsLocked()) { SendRaidLockTo(c); } } + + if (c) { + SendBulkRaid(c); + if (IsLocked()) { + SendRaidLockTo(c); + } + } + SendRaidAddAll(who); SendMakeLeaderPacket(leadername); - } void Raid::SendBulkRaid(Client *to) { - if(!to) + if (!to) { return; + } - for(int x = 0; x < MAX_RAID_MEMBERS; x++) - { - if (strlen(members[x].membername) > 0 && (strcmp(members[x].membername, to->GetName()) != 0)) //don't send ourself - { - SendRaidAdd(members[x].membername, to); + for (const auto& m : members) { + if (strlen(m.member_name) > 0 && (strcmp(m.member_name, to->GetName()) != 0)) { + SendRaidAdd(m.member_name, to); } } } void Raid::QueuePacket(const EQApplicationPacket *app, bool ack_req) { - for (int x = 0; x < MAX_RAID_MEMBERS; x++) - { - if (members[x].member && members[x].member->IsClient()) - { - members[x].member->QueuePacket(app, ack_req); + for (const auto& m : members) { + if (m.member && m.member->IsClient()) { + m.member->QueuePacket(app, ack_req); } } } -void Raid::SendMakeLeaderPacket(const char *who) //30 +void Raid::SendMakeLeaderPacket(const char *who) { - if (RuleB(Bots, Enabled) && entity_list.GetBotByBotName(who) && members[GetPlayerIndex(who)].IsBot) { + if (RuleB(Bots, Enabled) && entity_list.GetBotByBotName(who)) { return; } auto outapp = new EQApplicationPacket(OP_RaidUpdate, sizeof(RaidLeadershipUpdate_Struct)); - RaidLeadershipUpdate_Struct *rg = (RaidLeadershipUpdate_Struct*)outapp->pBuffer; + auto rg = (RaidLeadershipUpdate_Struct*)outapp->pBuffer; rg->action = raidMakeLeader; strn0cpy(rg->leader_name, who, 64); strn0cpy(rg->player_name, who, 64); @@ -1270,12 +1287,12 @@ void Raid::SendMakeLeaderPacketTo(const char *who, Client *to) return; } - if (RuleB(Bots, Enabled) && members[GetPlayerIndex(who)].IsBot) { + if (RuleB(Bots, Enabled) && entity_list.GetBotByBotName(who)) { return; } auto outapp = new EQApplicationPacket(OP_RaidUpdate, sizeof(RaidLeadershipUpdate_Struct)); - RaidLeadershipUpdate_Struct *rg = (RaidLeadershipUpdate_Struct*)outapp->pBuffer; + auto rg = (RaidLeadershipUpdate_Struct*)outapp->pBuffer; rg->action = raidMakeLeader; strn0cpy(rg->leader_name, who, 64); strn0cpy(rg->player_name, who, 64); @@ -1295,8 +1312,9 @@ void Raid::SendMakeGroupLeaderPacket(const char *who) //13 void Raid::SendMakeGroupLeaderPacketTo(const char *who, Client *to) { - if(!to) + if (!to) { return; + } } void Raid::SendGroupUpdate(Client *to) @@ -1305,42 +1323,42 @@ void Raid::SendGroupUpdate(Client *to) return; } - if (RuleB(Bots, Enabled) && members[GetPlayerIndex(to)].IsBot) { + if (RuleB(Bots, Enabled) && entity_list.GetBotByBotName(to->GetName())) { return; } auto outapp = new EQApplicationPacket(OP_GroupUpdate, sizeof(GroupUpdate2_Struct)); - GroupUpdate2_Struct* gu = (GroupUpdate2_Struct*)outapp->pBuffer; + auto gu = (GroupUpdate2_Struct*)outapp->pBuffer; gu->action = groupActUpdate; - int index = 0; + int i = 0; uint32 grp = GetGroup(to->GetName()); - if(grp > 11) - { + if (grp >= MAX_RAID_MEMBERS) { safe_delete(outapp); return; } - for(int x = 0; x < MAX_RAID_MEMBERS; x++) - { - if(members[x].GroupNumber == grp && strlen(members[x].membername) > 0) - { - if(members[x].IsGroupLeader){ - strn0cpy(gu->leadersname, members[x].membername, 64); - if(strcmp(to->GetName(), members[x].membername) != 0){ - strn0cpy(gu->membername[index], members[x].membername, 64); - index++; + + for (const auto& m : members) { + if (m.group_number == grp && strlen(m.member_name) > 0) { + if (m.is_group_leader) { + strn0cpy(gu->leadersname, m.member_name, 64); + if (strcmp(to->GetName(), m.member_name) != 0) { + strn0cpy(gu->membername[i], m.member_name, 64); + i++; } } - else{ - if(strcmp(to->GetName(), members[x].membername) != 0){ - strn0cpy(gu->membername[index], members[x].membername, 64); - index++; + else { + if (strcmp(to->GetName(), m.member_name) != 0) { + strn0cpy(gu->membername[i], m.member_name, 64); + i++; } } } } - if(strlen(gu->leadersname) < 1){ + + if (strlen(gu->leadersname) < 1) { strn0cpy(gu->leadersname, to->GetName(), 64); } + strn0cpy(gu->yourname, to->GetName(), 64); memcpy(&gu->leader_aas, &group_aa[grp], sizeof(GroupLeadershipAA_Struct)); @@ -1349,23 +1367,20 @@ void Raid::SendGroupUpdate(Client *to) void Raid::GroupUpdate(uint32 gid, bool initial) { - if(gid > 11) {//ungrouped member doesn't need grouping. + //ungrouped member doesn't need grouping. + if (gid >= MAX_RAID_GROUPS) { return; } - for (int x = 0; x < MAX_RAID_MEMBERS; x++) - { - if(strlen(members[x].membername) > 0){ - if(members[x].GroupNumber == gid){ - if (members[x].member) { - SendGroupUpdate(members[x].member); - SendGroupLeadershipAA(members[x].member, gid); - } - } + + for (const auto& m : members) { + if (strlen(m.member_name) > 0 && m.group_number == gid && m.member) { + SendGroupUpdate(m.member); + SendGroupLeadershipAA(m.member, gid); } } - if(initial){ + if (initial) { auto pack = new ServerPacket(ServerOP_UpdateGroup, sizeof(ServerRaidGeneralAction_Struct)); - ServerRaidGeneralAction_Struct* rga = (ServerRaidGeneralAction_Struct*)pack->pBuffer; + auto rga = (ServerRaidGeneralAction_Struct*)pack->pBuffer; rga->gid = gid; rga->rid = GetID(); rga->zoneid = zone->GetZoneID(); @@ -1378,7 +1393,7 @@ void Raid::GroupUpdate(uint32 gid, bool initial) void Raid::SendRaidLock() { auto outapp = new EQApplicationPacket(OP_RaidUpdate, sizeof(RaidGeneral_Struct)); - RaidGeneral_Struct *rg = (RaidGeneral_Struct*)outapp->pBuffer; + auto rg = (RaidGeneral_Struct*)outapp->pBuffer; rg->action = raidLock; strn0cpy(rg->leader_name, leadername, 64); strn0cpy(rg->player_name, leadername, 64); @@ -1389,7 +1404,7 @@ void Raid::SendRaidLock() void Raid::SendRaidUnlock() { auto outapp = new EQApplicationPacket(OP_RaidUpdate, sizeof(RaidGeneral_Struct)); - RaidGeneral_Struct *rg = (RaidGeneral_Struct*)outapp->pBuffer; + auto rg = (RaidGeneral_Struct*)outapp->pBuffer; rg->action = raidUnlock; strn0cpy(rg->leader_name, leadername, 64); strn0cpy(rg->player_name, leadername, 64); @@ -1399,11 +1414,12 @@ void Raid::SendRaidUnlock() void Raid::SendRaidLockTo(Client *c) { - if(!c) + if (!c) { return; + } auto outapp = new EQApplicationPacket(OP_RaidUpdate, sizeof(RaidGeneral_Struct)); - RaidGeneral_Struct *rg = (RaidGeneral_Struct*)outapp->pBuffer; + auto rg = (RaidGeneral_Struct*)outapp->pBuffer; rg->action = raidLock; strn0cpy(rg->leader_name, c->GetName(), 64); strn0cpy(rg->player_name, c->GetName(), 64); @@ -1413,11 +1429,12 @@ void Raid::SendRaidLockTo(Client *c) void Raid::SendRaidUnlockTo(Client *c) { - if(!c) + if (!c) { return; + } auto outapp = new EQApplicationPacket(OP_RaidUpdate, sizeof(RaidGeneral_Struct)); - RaidGeneral_Struct *rg = (RaidGeneral_Struct*)outapp->pBuffer; + auto rg = (RaidGeneral_Struct*)outapp->pBuffer; rg->action = raidUnlock; strn0cpy(rg->leader_name, c->GetName(), 64); strn0cpy(rg->player_name, c->GetName(), 64); @@ -1427,11 +1444,12 @@ void Raid::SendRaidUnlockTo(Client *c) void Raid::SendGroupDisband(Client *to) { - if(!to) + if (!to) { return; + } auto outapp = new EQApplicationPacket(OP_GroupUpdate, sizeof(GroupUpdate_Struct)); - GroupUpdate_Struct* gu = (GroupUpdate_Struct*) outapp->pBuffer; + auto gu = (GroupUpdate_Struct*) outapp->pBuffer; gu->action = groupActDisband; strn0cpy(gu->leadersname, leadername, 64); strn0cpy(gu->yourname, to->GetName(), 64); @@ -1441,7 +1459,7 @@ void Raid::SendGroupDisband(Client *to) void Raid::SendRaidGroupAdd(const char *who, uint32 gid) { auto pack = new ServerPacket(ServerOP_RaidGroupAdd, sizeof(ServerRaidGroupAction_Struct)); - ServerRaidGroupAction_Struct * rga = (ServerRaidGroupAction_Struct*)pack->pBuffer; + auto rga = (ServerRaidGroupAction_Struct*)pack->pBuffer; rga->rid = GetID(); rga->gid = gid; strn0cpy(rga->membername, who, 64); @@ -1451,7 +1469,7 @@ void Raid::SendRaidGroupAdd(const char *who, uint32 gid) void Raid::SendRaidGroupRemove(const char *who, uint32 gid) { auto pack = new ServerPacket(ServerOP_RaidGroupRemove, sizeof(ServerRaidGroupAction_Struct)); - ServerRaidGroupAction_Struct * rga = (ServerRaidGroupAction_Struct*)pack->pBuffer; + auto rga = (ServerRaidGroupAction_Struct*)pack->pBuffer; rga->rid = GetID(); rga->gid = gid; strn0cpy(rga->membername, who, 64); @@ -1460,16 +1478,17 @@ void Raid::SendRaidGroupRemove(const char *who, uint32 gid) void Raid::SendRaidMOTD(Client *c) { - if (!c || motd.empty()) + if (!c || motd.empty()) { return; + } - if (members[GetPlayerIndex(c)].IsBot) { + if (entity_list.GetBotByBotName(c->GetName())) { return; } size_t size = motd.size() + 1; auto outapp = new EQApplicationPacket(OP_RaidUpdate, sizeof(RaidMOTD_Struct) + size); - RaidMOTD_Struct *rmotd = (RaidMOTD_Struct *)outapp->pBuffer; + auto rmotd = (RaidMOTD_Struct *)outapp->pBuffer; rmotd->general.action = raidSetMotd; strn0cpy(rmotd->general.player_name, c->GetName(), 64); strn0cpy(rmotd->motd, motd.c_str(), size); @@ -1478,22 +1497,26 @@ void Raid::SendRaidMOTD(Client *c) void Raid::SendRaidMOTD() { - if (motd.empty()) + if (motd.empty()) { return; + } - for (uint32 i = 0; i < MAX_RAID_MEMBERS; i++) - if (members[i].member) - SendRaidMOTD(members[i].member); + for (const auto& m: members) { + if (m.member) { + SendRaidMOTD(m.member); + } + } } void Raid::SendRaidMOTDToWorld() { - if (motd.empty()) + if (motd.empty()) { return; + } size_t size = motd.size() + 1; auto pack = new ServerPacket(ServerOP_RaidMOTD, sizeof(ServerRaidMOTD_Struct) + size); - ServerRaidMOTD_Struct *smotd = (ServerRaidMOTD_Struct *)pack->pBuffer; + auto smotd = (ServerRaidMOTD_Struct *)pack->pBuffer; smotd->rid = GetID(); strn0cpy(smotd->motd, motd.c_str(), size); worldserver.SendPacket(pack); @@ -1502,12 +1525,12 @@ void Raid::SendRaidMOTDToWorld() void Raid::SendGroupLeadershipAA(Client *c, uint32 gid) { - if (RuleB(Bots, Enabled) && members[GetPlayerIndex(c)].IsBot) { + if (RuleB(Bots, Enabled) && entity_list.GetBotByBotName(c->GetName())) { return; } auto outapp = new EQApplicationPacket(OP_RaidUpdate, sizeof(RaidLeadershipUpdate_Struct)); - RaidLeadershipUpdate_Struct *rlaa = (RaidLeadershipUpdate_Struct *)outapp->pBuffer; + auto rlaa = (RaidLeadershipUpdate_Struct *)outapp->pBuffer; rlaa->action = raidSetLeaderAbilities; strn0cpy(rlaa->leader_name, c->GetName(), 64); strn0cpy(rlaa->player_name, c->GetName(), 64); @@ -1521,7 +1544,11 @@ void Raid::SendGroupLeadershipAA(Client *c, uint32 gid) void Raid::SendGroupLeadershipAA(uint32 gid) { for (const auto& m : members) { - if (m.member && m.GroupNumber == gid && !m.IsBot) { + if (m.is_bot) { + continue; + } + + if (m.member && m.group_number == gid) { SendGroupLeadershipAA(m.member, gid); } } @@ -1530,8 +1557,12 @@ void Raid::SendGroupLeadershipAA(uint32 gid) void Raid::SendAllRaidLeadershipAA() { for (const auto& m : members) { - if (m.member && !m.IsBot) { - SendGroupLeadershipAA(m.member, m.GroupNumber); + if (m.is_bot) { + continue; + } + + if (m.member) { + SendGroupLeadershipAA(m.member, m.group_number); } } } @@ -1539,18 +1570,20 @@ void Raid::SendAllRaidLeadershipAA() void Raid::LockRaid(bool lockFlag) { - std::string query = StringFormat("UPDATE raid_details SET locked = %d WHERE raidid = %lu", - lockFlag, (unsigned long)GetID()); - auto results = database.QueryDatabase(query); + std::string query = StringFormat("UPDATE raid_details SET locked = %d WHERE raidid = %lu", lockFlag, (unsigned long)GetID()); + auto results = database.QueryDatabase(query); locked = lockFlag; - if(lockFlag) + + if (lockFlag) { SendRaidLock(); - else + } + else { SendRaidUnlock(); + } auto pack = new ServerPacket(ServerOP_RaidLockFlag, sizeof(ServerRaidGeneralAction_Struct)); - ServerRaidGeneralAction_Struct *rga = (ServerRaidGeneralAction_Struct*)pack->pBuffer; + auto rga = (ServerRaidGeneralAction_Struct*)pack->pBuffer; rga->rid = GetID(); rga->zoneid = zone->GetZoneID(); rga->gid = lockFlag; @@ -1562,17 +1595,19 @@ void Raid::LockRaid(bool lockFlag) void Raid::SetRaidDetails() { std::string query = StringFormat("INSERT INTO raid_details SET raidid = %lu, loottype = 4, locked = 0, motd = ''", - (unsigned long)GetID()); - auto results = database.QueryDatabase(query); + (unsigned long)GetID()); + auto results = database.QueryDatabase(query); } void Raid::GetRaidDetails() { std::string query = StringFormat("SELECT locked, loottype, motd FROM raid_details WHERE raidid = %lu", - (unsigned long)GetID()); - auto results = database.QueryDatabase(query); - if (!results.Success()) - return; + (unsigned long)GetID()); + auto results = database.QueryDatabase(query); + + if (!results.Success()) { + return; + } if (results.RowCount() == 0) { LogError( @@ -1583,10 +1618,10 @@ void Raid::GetRaidDetails() return; } - auto row = results.begin(); + auto row = results.begin(); - locked = Strings::ToInt(row[0]); - LootType = Strings::ToInt(row[1]); + locked = Strings::ToInt(row[0]); + LootType = Strings::ToInt(row[1]); motd = std::string(row[2]); } @@ -1615,69 +1650,73 @@ bool Raid::LearnMembers() } if (!results.RowCount()) { - LogError("Error getting raid members for raid [{}]: [{}]", GetID(), results.ErrorMessage()); disbandCheck = true; return false; } - int index = 0; + int i = 0; for (auto row: results) { if (!row[0]) { continue; } - members[index].member = nullptr; - strn0cpy(members[index].membername, row[0], sizeof(members[index].membername)); + members[i].member = nullptr; + strn0cpy(members[i].member_name, row[0], sizeof(members[i].member_name)); uint32 group_id = Strings::ToUnsignedInt(row[1]); - if (group_id > 11) { - members[index].GroupNumber = RAID_GROUPLESS; - } else { - members[index].GroupNumber = group_id; + if (group_id >= MAX_RAID_GROUPS) { + members[i].group_number = RAID_GROUPLESS; + } + else { + members[i].group_number = group_id; } - members[index]._class = Strings::ToUnsignedInt(row[2]); - members[index].level = Strings::ToUnsignedInt(row[3]); - members[index].IsGroupLeader = Strings::ToBool(row[4]); - members[index].IsRaidLeader = Strings::ToBool(row[5]); - members[index].IsLooter = Strings::ToBool(row[6]); - members[index].IsBot = Strings::ToBool(row[7]) > 0; - ++index; + members[i]._class = Strings::ToUnsignedInt(row[2]); + members[i].level = Strings::ToUnsignedInt(row[3]); + members[i].is_group_leader = Strings::ToBool(row[4]); + members[i].is_raid_leader = Strings::ToBool(row[5]); + members[i].is_looter = Strings::ToBool(row[6]); + members[i].is_bot = Strings::ToBool(row[7]) > 0; + ++i; } - + return true; } void Raid::VerifyRaid() { for (auto& m : members) { - if(strlen(m.membername) == 0){ + if (strlen(m.member_name) == 0) { m.member = nullptr; - } else { - auto* c = entity_list.GetClientByName(m.membername); - auto* b = entity_list.GetBotByBotName(m.membername); + } + else { + auto* c = entity_list.GetClientByName(m.member_name); + auto* b = entity_list.GetBotByBotName(m.member_name); if (c) { m.member = c; - m.IsBot = false; - } else if(RuleB(Bots, Enabled) && b){ + m.is_bot = false; + } + else if (RuleB(Bots, Enabled) && b) { //Raid requires client* we are forcing it here to be a BOT. Care is needed here as any client function that - //does not exist within the Bot Class will likely corrupt memory for the member object. Good practice to test the IsBot + //does not exist within the Bot Class will likely corrupt memory for the member object. Good practice to test the is_bot //attribute before calling a client function or casting to client. - b = entity_list.GetBotByBotName(m.membername); + b = entity_list.GetBotByBotName(m.member_name); m.member = b->CastToClient(); - m.IsBot = true; //Used to identify those members who are Bots - } else { + m.is_bot = true; //Used to identify those members who are Bots + } + else { m.member = nullptr; - m.IsBot = false; + m.is_bot = false; } } - if (m.IsRaidLeader) { - if (strlen(m.membername) > 0){ + if (m.is_raid_leader) { + if (strlen(m.member_name) > 0) { SetLeader(m.member); - strn0cpy(leadername, m.membername, sizeof(leadername)); - } else { + strn0cpy(leadername, m.member_name, sizeof(leadername)); + } + else { SetLeader(nullptr); } } @@ -1686,61 +1725,61 @@ void Raid::VerifyRaid() void Raid::MemberZoned(Client *c) { - if(!c) + if (!c) { return; + } - if (leader == c) - { + if (leader == c) { leader = nullptr; } // Raid::GetGroup() goes over the members as well, this way we go over once uint32 gid = RAID_GROUPLESS; - for(int x = 0; x < MAX_RAID_MEMBERS; x++) - { - if(members[x].member == c) - { - members[x].member = nullptr; - gid = members[x].GroupNumber; + for (auto& m : members) { + if (m.member == c) { + m.member = nullptr; + gid = m.group_number; } } - if (gid < MAX_RAID_GROUPS && group_mentor[gid].mentoree == c) + if (gid < MAX_RAID_GROUPS && group_mentor[gid].mentoree == c) { group_mentor[gid].mentoree = nullptr; + } } void Raid::SendHPManaEndPacketsTo(Client *client) { - if(!client) + if (!client) { return; + } uint32 group_id = GetGroup(client); EQApplicationPacket hp_packet; EQApplicationPacket outapp(OP_MobManaUpdate, sizeof(MobManaUpdate_Struct)); - for(int x = 0; x < MAX_RAID_MEMBERS; x++) { - if(members[x].member && !members[x].IsBot) { - if((members[x].member != client) && (members[x].GroupNumber == group_id)) { + for (const auto& m : members) { + if (m.is_bot) { + continue; + } - members[x].member->CreateHPPacket(&hp_packet); - client->QueuePacket(&hp_packet, false); - safe_delete_array(hp_packet.pBuffer); + if (m.member && (m.member != client) && (m.group_number == group_id)) { + m.member->CreateHPPacket(&hp_packet); + client->QueuePacket(&hp_packet, false); + safe_delete_array(hp_packet.pBuffer); + hp_packet.size = 0; - hp_packet.size = 0; - if (client->ClientVersion() >= EQ::versions::ClientVersion::SoD) { + if (client->ClientVersion() >= EQ::versions::ClientVersion::SoD) { + outapp.SetOpcode(OP_MobManaUpdate); + auto mana_update = (MobManaUpdate_Struct *)outapp.pBuffer; + mana_update->spawn_id = m.member->GetID(); + mana_update->mana = m.member->GetManaPercent(); + client->QueuePacket(&outapp, false); - outapp.SetOpcode(OP_MobManaUpdate); - MobManaUpdate_Struct *mana_update = (MobManaUpdate_Struct *)outapp.pBuffer; - mana_update->spawn_id = members[x].member->GetID(); - mana_update->mana = members[x].member->GetManaPercent(); - client->QueuePacket(&outapp, false); - - outapp.SetOpcode(OP_MobEnduranceUpdate); - MobEnduranceUpdate_Struct *endurance_update = (MobEnduranceUpdate_Struct *)outapp.pBuffer; - endurance_update->endurance = members[x].member->GetEndurancePercent(); - client->QueuePacket(&outapp, false); - } + outapp.SetOpcode(OP_MobEnduranceUpdate); + auto endurance_update = (MobEnduranceUpdate_Struct *)outapp.pBuffer; + endurance_update->endurance = m.member->GetEndurancePercent(); + client->QueuePacket(&outapp, false); } } } @@ -1748,35 +1787,40 @@ void Raid::SendHPManaEndPacketsTo(Client *client) void Raid::SendHPManaEndPacketsFrom(Mob *mob) { - if(!mob) + if (!mob) { return; + } uint32 group_id = 0; - if(mob->IsClient()) + if (mob->IsClient()) { group_id = GetGroup(mob->CastToClient()); + } EQApplicationPacket hpapp; EQApplicationPacket outapp(OP_MobManaUpdate, sizeof(MobManaUpdate_Struct)); mob->CreateHPPacket(&hpapp); - for(int x = 0; x < MAX_RAID_MEMBERS; x++) { - if(members[x].member && !members[x].IsBot) { - if(!mob->IsClient() || ((members[x].member != mob->CastToClient()) && (members[x].GroupNumber == group_id))) { - members[x].member->QueuePacket(&hpapp, false); - if (members[x].member->ClientVersion() >= EQ::versions::ClientVersion::SoD) { - outapp.SetOpcode(OP_MobManaUpdate); - MobManaUpdate_Struct *mana_update = (MobManaUpdate_Struct *)outapp.pBuffer; - mana_update->spawn_id = mob->GetID(); - mana_update->mana = mob->GetManaPercent(); - members[x].member->QueuePacket(&outapp, false); + for (const auto& m : members) { + if (m.is_bot) { + continue; + } - outapp.SetOpcode(OP_MobEnduranceUpdate); - MobEnduranceUpdate_Struct *endurance_update = (MobEnduranceUpdate_Struct *)outapp.pBuffer; - endurance_update->endurance = mob->GetEndurancePercent(); - members[x].member->QueuePacket(&outapp, false); - } + if (m.member && (!mob->IsClient() || ((m.member != mob->CastToClient()) && (m.group_number == group_id)))) { + m.member->QueuePacket(&hpapp, false); + + if (m.member->ClientVersion() >= EQ::versions::ClientVersion::SoD) { + outapp.SetOpcode(OP_MobManaUpdate); + MobManaUpdate_Struct *mana_update = (MobManaUpdate_Struct *)outapp.pBuffer; + mana_update->spawn_id = mob->GetID(); + mana_update->mana = mob->GetManaPercent(); + m.member->QueuePacket(&outapp, false); + + outapp.SetOpcode(OP_MobEnduranceUpdate); + MobEnduranceUpdate_Struct *endurance_update = (MobEnduranceUpdate_Struct *)outapp.pBuffer; + endurance_update->endurance = mob->GetEndurancePercent(); + m.member->QueuePacket(&outapp, false); } } } @@ -1784,54 +1828,62 @@ void Raid::SendHPManaEndPacketsFrom(Mob *mob) void Raid::SendManaPacketFrom(Mob *mob) { - if (!mob) + if (!mob) { return; + } uint32 group_id = 0; - if (mob->IsClient()) + if (mob->IsClient()) { group_id = GetGroup(mob->CastToClient()); + } EQApplicationPacket outapp(OP_MobManaUpdate, sizeof(MobManaUpdate_Struct)); - for (int x = 0; x < MAX_RAID_MEMBERS; x++) { - if (members[x].member && !members[x].IsBot) { - if (!mob->IsClient() || ((members[x].member != mob->CastToClient()) && (members[x].GroupNumber == group_id))) { - if (members[x].member->ClientVersion() >= EQ::versions::ClientVersion::SoD) { - outapp.SetOpcode(OP_MobManaUpdate); - MobManaUpdate_Struct *mana_update = (MobManaUpdate_Struct *)outapp.pBuffer; - mana_update->spawn_id = mob->GetID(); - mana_update->mana = mob->GetManaPercent(); - members[x].member->QueuePacket(&outapp, false); - } - } + for (const auto& m : members) { + if (m.is_bot) { + continue; + } + + if (m.member && (!mob->IsClient() || ((m.member != mob->CastToClient()) && (m.group_number == group_id))) && + m.member->ClientVersion() >= EQ::versions::ClientVersion::SoD + ) { + outapp.SetOpcode(OP_MobManaUpdate); + MobManaUpdate_Struct *mana_update = (MobManaUpdate_Struct *)outapp.pBuffer; + mana_update->spawn_id = mob->GetID(); + mana_update->mana = mob->GetManaPercent(); + m.member->QueuePacket(&outapp, false); } } } void Raid::SendEndurancePacketFrom(Mob *mob) { - if (!mob) + if (!mob) { return; + } uint32 group_id = 0; - if (mob->IsClient()) + if (mob->IsClient()) { group_id = GetGroup(mob->CastToClient()); + } EQApplicationPacket outapp(OP_MobManaUpdate, sizeof(MobManaUpdate_Struct)); - for (int x = 0; x < MAX_RAID_MEMBERS; x++) { - if (members[x].member && !members[x].IsBot) { - if (!mob->IsClient() || ((members[x].member != mob->CastToClient()) && (members[x].GroupNumber == group_id))) { - if (members[x].member->ClientVersion() >= EQ::versions::ClientVersion::SoD) { - outapp.SetOpcode(OP_MobEnduranceUpdate); - MobEnduranceUpdate_Struct *endurance_update = (MobEnduranceUpdate_Struct *)outapp.pBuffer; - endurance_update->spawn_id = mob->GetID(); - endurance_update->endurance = mob->GetEndurancePercent(); - members[x].member->QueuePacket(&outapp, false); - } - } + for (const auto& m : members) { + if (m.is_bot) { + continue; + } + + if (m.member && (!mob->IsClient() || ((m.member != mob->CastToClient()) && (m.group_number == group_id))) && + m.member->ClientVersion() >= EQ::versions::ClientVersion::SoD + ) { + outapp.SetOpcode(OP_MobEnduranceUpdate); + auto endurance_update = (MobEnduranceUpdate_Struct *)outapp.pBuffer; + endurance_update->spawn_id = mob->GetID(); + endurance_update->endurance = mob->GetEndurancePercent(); + m.member->QueuePacket(&outapp, false); } } } @@ -1841,30 +1893,28 @@ uint16 Raid::GetAvgLevel() double levelHolder = 0; uint8 i = 0; uint8 numMem = 0; - while(i < MAX_RAID_MEMBERS) - { - if(strlen(members[i].membername)) - { + while (i < MAX_RAID_MEMBERS) { + if (strlen(members[i].member_name)) { levelHolder = levelHolder + members[i].level; numMem++; } i++; } levelHolder = ((levelHolder/(numMem))+.5); // total levels divided by num of characters - return (uint16(levelHolder)); + return uint16(levelHolder); } const char *Raid::GetClientNameByIndex(uint8 index) { - return members[index].membername; + return members[index].member_name; } -void Raid::RaidMessageString(Mob* sender, uint32 type, uint32 string_id, const char* message,const char* message2,const char* message3,const char* message4,const char* message5,const char* message6,const char* message7,const char* message8,const char* message9, uint32 distance) { - uint32 i; - for (i = 0; i < MAX_RAID_MEMBERS; i++) { - if(members[i].member && members[i].member->IsClient()) { - if(members[i].member != sender) - members[i].member->MessageString(type, string_id, message, message2, message3, message4, message5, message6, message7, message8, message9, distance); +void Raid::RaidMessageString(Mob* sender, uint32 type, uint32 string_id, const char* message,const char* message2,const char* message3,const char* message4,const char* message5,const char* message6,const char* message7,const char* message8,const char* message9, uint32 distance) +{ + for (const auto& m : members) { + if (m.member && m.member->IsClient() && m.member != sender) { + m.member->MessageString(type, string_id, message, message2, message3, message4, message5, message6, + message7, message8, message9, distance); } } } @@ -1877,6 +1927,7 @@ void Raid::LoadLeadership() for (uint32 group_id = 0; group_id < MAX_RAID_GROUPS; group_id++) { database.GetGroupLeadershipInfo(group_id, GetID(), nullptr, nullptr, nullptr, nullptr, mentor_name, &group_mentor[group_id].mentor_percent, &group_aa[group_id]); + if (strlen(mentor_name)) { group_mentor[group_id].name = mentor_name; mentor_name[0] = '\0'; @@ -1886,8 +1937,10 @@ void Raid::LoadLeadership() void Raid::SetGroupMentor(uint32 group_id, int percent, char *name) { - if (group_id > 11) + if (group_id >= MAX_RAID_GROUPS) { return; + } + group_mentor[group_id].name = name; group_mentor[group_id].mentor_percent = percent; Client *client = entity_list.GetClientByName(name); @@ -1902,8 +1955,9 @@ void Raid::SetGroupMentor(uint32 group_id, int percent, char *name) void Raid::ClearGroupMentor(uint32 group_id) { - if (group_id > 11) + if (group_id >= MAX_RAID_GROUPS) { return; + } group_mentor[group_id].name.clear(); group_mentor[group_id].mentor_percent = 0; group_mentor[group_id].mentoree = nullptr; @@ -1911,16 +1965,18 @@ void Raid::ClearGroupMentor(uint32 group_id) std::string query = StringFormat("UPDATE raid_leaders SET mentoree = '', mentor_percent = 0 WHERE gid = %i AND rid = %i LIMIT 1", group_id, GetID()); auto results = database.QueryDatabase(query); - if (!results.Success()) + if (!results.Success()) { LogError("Unable to clear raid group mentor: [{}]\n", results.ErrorMessage().c_str()); + } } // there isn't a nice place to add this in another function, unlike groups // so we do it here instead void Raid::CheckGroupMentor(uint32 group_id, Client *c) { - if (!c || group_id > 11) + if (!c || group_id >= MAX_RAID_GROUPS) { return; + } if (group_mentor[group_id].name == c->GetName()) group_mentor[group_id].mentoree = c; @@ -1928,54 +1984,61 @@ void Raid::CheckGroupMentor(uint32 group_id, Client *c) void Raid::SetDirtyAutoHaters() { - for (int i = 0; i < MAX_RAID_MEMBERS; ++i) - if (members[i].member && members[i].IsBot) - { - members[i].member->CastToBot()->SetDirtyAutoHaters(); + for (const auto& m: members) { + if (m.member && m.is_bot) { + m.member->CastToBot()->SetDirtyAutoHaters(); } - else if (members[i].member && !members[i].IsBot) - { - members[i].member->SetDirtyAutoHaters(); + else if (m.member) { + m.member->SetDirtyAutoHaters(); } + } } -void Raid::QueueClients(Mob *sender, const EQApplicationPacket *app, bool ack_required /*= true*/, bool ignore_sender /*= true*/, float distance /*= 0*/, bool group_only /*= true*/) { +void Raid::QueueClients(Mob *sender, const EQApplicationPacket *app, bool ack_required /*= true*/, bool ignore_sender /*= true*/, float distance /*= 0*/, bool group_only /*= true*/) +{ if (sender && sender->IsClient()) { - uint32 group_id = GetGroup(sender->CastToClient()); /* If this is a group only packet and we're not in a group -- return */ - if (group_id == RAID_GROUPLESS && group_only) + if (group_id == RAID_GROUPLESS && group_only) { return; + } - for (uint32 i = 0; i < MAX_RAID_MEMBERS; i++) { - if (!members[i].member) { + for (const auto& m : members) { + if (!m.member) { continue; } - if (members[i].IsBot) { + + if (m.is_bot) { continue; } - if (!members[i].member->IsClient()) { + + if (m.member->IsClient()) { continue; } - if (ignore_sender && members[i].member == sender) { + + if (ignore_sender && m.member == sender) { continue; } - if (group_only && members[i].GroupNumber != group_id) { + + if (group_only && m.group_number != group_id) { continue; } + /* If we don't have a distance requirement - send to all members */ if (distance == 0) { - members[i].member->CastToClient()->QueuePacket(app, ack_required); + m.member->CastToClient()->QueuePacket(app, ack_required); } + else { /* If negative distance - we check if current distance is greater than X */ - if (distance <= 0 && DistanceSquared(sender->GetPosition(), members[i].member->GetPosition()) >= (distance * distance)) { - members[i].member->CastToClient()->QueuePacket(app, ack_required); + if (distance <= 0 && DistanceSquared(sender->GetPosition(), m.member->GetPosition()) >= (distance * distance)) { + m.member->CastToClient()->QueuePacket(app, ack_required); } + /* If positive distance - we check if current distance is less than X */ - else if (distance >= 0 && DistanceSquared(sender->GetPosition(), members[i].member->GetPosition()) <= (distance * distance)) { - members[i].member->CastToClient()->QueuePacket(app, ack_required); + else if (distance >= 0 && DistanceSquared(sender->GetPosition(), m.member->GetPosition()) <= (distance * distance)) { + m.member->CastToClient()->QueuePacket(app, ack_required); } } } @@ -1985,79 +2048,79 @@ void Raid::QueueClients(Mob *sender, const EQApplicationPacket *app, bool ack_re std::vector Raid::GetMembers() const { std::vector raid_members; - for (int i = 0; i < MAX_RAID_MEMBERS; ++i) - { - if (members[i].membername[0]) - { - raid_members.emplace_back(members[i]); + for (const auto& m : members) { + if (m.member_name[0]) { + raid_members.emplace_back(m); } } return raid_members; } -bool Raid::DoesAnyMemberHaveExpeditionLockout( - const std::string& expedition_name, const std::string& event_name, int max_check_count) +bool Raid::DoesAnyMemberHaveExpeditionLockout(const std::string& expedition_name, const std::string& event_name, int max_check_count) { auto raid_members = GetMembers(); - if (max_check_count > 0) - { + if (max_check_count > 0) { // priority is leader, group number, then ungrouped members std::sort(raid_members.begin(), raid_members.end(), [&](const RaidMember& lhs, const RaidMember& rhs) { - if (lhs.IsRaidLeader) { + if (lhs.is_raid_leader) { return true; - } else if (rhs.IsRaidLeader) { + } else if (rhs.is_raid_leader) { return false; } - return lhs.GroupNumber < rhs.GroupNumber; + return lhs.group_number < rhs.group_number; }); raid_members.resize(max_check_count); } return std::any_of(raid_members.begin(), raid_members.end(), [&](const RaidMember& raid_member) { - return Expedition::HasLockoutByCharacterName(raid_member.membername, expedition_name, event_name); + return Expedition::HasLockoutByCharacterName(raid_member.member_name, expedition_name, event_name); }); } -Mob* Raid::GetRaidMainAssistOneByName(const char* name) +Mob* Raid::GetRaidMainAssistOne() { - Raid* raid = entity_list.GetRaidByBotName(name); - std::vector raid_members = raid->GetMembers(); - - for (RaidMember iter : raid_members) - { - if (iter.IsRaidMainAssistOne) { - return iter.member->CastToMob(); + for (const auto& m : GetMembers()) { + if (m.is_raid_main_assist_one) { + return m.member->CastToMob(); } } return nullptr; } -bool Raid::IsEngaged() { - std::vector rm = GetMembers(); - for (const auto& m : rm) { - if (m.member && !m.IsBot && (m.member->IsEngaged() || m.member->GetAggroCount() > 0)) { - return 1; +bool Raid::IsEngaged() +{ + + for (const auto& m : GetMembers()) { + if (m.is_bot) { + continue; + } + + if (m.member && (m.member->IsEngaged() || m.member->GetAggroCount() > 0)) { + return true; } } - return 0; + return false; } + void Raid::RaidGroupSay(const char* msg, const char* from, uint8 language, uint8 lang_skill) { - if (!from) + if (!from) { return; + } - uint32 groupToUse = GetGroup(from); + uint32 group_id_to_use = GetGroup(from); - if (groupToUse > 11) + if (group_id_to_use >= MAX_RAID_GROUPS) { return; + } auto pack = new ServerPacket(ServerOP_RaidGroupSay, sizeof(ServerRaidMessage_Struct) + strlen(msg) + 1); - ServerRaidMessage_Struct* rga = (ServerRaidMessage_Struct*)pack->pBuffer; + auto rga = (ServerRaidMessage_Struct*)pack->pBuffer; rga->rid = GetID(); - rga->gid = groupToUse; + rga->gid = group_id_to_use; rga->language = language; rga->lang_skill = lang_skill; strn0cpy(rga->from, from, 64); @@ -2069,11 +2132,12 @@ void Raid::RaidGroupSay(const char* msg, const char* from, uint8 language, uint8 } void Raid::RaidSay(const char* msg, const char* from, uint8 language, uint8 lang_skill) { - if (!from) + if (!from) { return; + } auto pack = new ServerPacket(ServerOP_RaidSay, sizeof(ServerRaidMessage_Struct) + strlen(msg) + 1); - ServerRaidMessage_Struct* rga = (ServerRaidMessage_Struct*)pack->pBuffer; + auto rga = (ServerRaidMessage_Struct*)pack->pBuffer; rga->rid = GetID(); rga->gid = RAID_GROUPLESS; rga->language = language; @@ -2088,15 +2152,17 @@ void Raid::RaidSay(const char* msg, const char* from, uint8 language, uint8 lang void Raid::SetNewRaidLeader(uint32 i) { - if (members[i].IsRaidLeader) { - for (int x = 0; x < MAX_RAID_MEMBERS; x++) { - if (!members[x].IsBot) { - if (strlen(members[x].membername) > 0 && strcmp(members[x].membername, members[i].membername) != 0) { - SetRaidLeader(members[i].membername, members[x].membername); - UpdateRaidAAs(); - SendAllRaidLeadershipAA(); - break; - } + if (members[i].is_raid_leader) { + for (const auto& m : members) { + if (m.is_bot) { + continue; + } + + if (m.member && strlen(m.member_name) > 0 && strcmp(m.member_name, m.member_name) != 0) { + SetRaidLeader(members[i].member_name, m.member_name); + UpdateRaidAAs(); + SendAllRaidLeadershipAA(); + break; } } } diff --git a/zone/raids.h b/zone/raids.h index 52bbc3b3a..b8eadbc7b 100644 --- a/zone/raids.h +++ b/zone/raids.h @@ -75,21 +75,21 @@ enum { //raid command types RaidCommandSetNote = 36, }; -#define MAX_RAID_GROUPS 12 -#define MAX_RAID_MEMBERS 72 +constexpr uint8_t MAX_RAID_GROUPS = 12; +constexpr uint8_t MAX_RAID_MEMBERS = 72; const uint32 RAID_GROUPLESS = 0xFFFFFFFF; struct RaidMember{ - char membername[64]; + char member_name[64]; Client *member; - uint32 GroupNumber; + uint32 group_number; uint8 _class; uint8 level; - bool IsGroupLeader; - bool IsRaidLeader; - bool IsLooter; - bool IsBot = false; - bool IsRaidMainAssistOne = false; + bool is_group_leader; + bool is_raid_leader; + bool is_looter; + bool is_bot = false; + bool is_raid_main_assist_one = false; }; struct GroupMentor { @@ -115,12 +115,12 @@ public: bool IsRaid() { return true; } void AddMember(Client *c, uint32 group = 0xFFFFFFFF, bool rleader=false, bool groupleader=false, bool looter=false); - void AddBot(Bot* b, uint32 group = 0xFFFFFFFF, bool rleader=false, bool groupleader=false, bool looter=false); + void AddBot(Bot* b, uint32 group = 0xFFFFFFFF, bool raid_leader=false, bool group_leader=false, bool looter=false); void RaidGroupSay(const char* msg, const char* from, uint8 language, uint8 lang_skill); void RaidSay(const char* msg, const char* from, uint8 language, uint8 lang_skill); bool IsEngaged(); - Mob* GetRaidMainAssistOneByName(const char* name); - void RemoveMember(const char *c); + Mob* GetRaidMainAssistOne(); + void RemoveMember(const char *character_name); void DisbandRaid(); void MoveMember(const char *name, uint32 newGroup); void SetGroupLeader(const char *who, bool glFlag = true); diff --git a/zone/spell_effects.cpp b/zone/spell_effects.cpp index 096fa2e63..a83240480 100644 --- a/zone/spell_effects.cpp +++ b/zone/spell_effects.cpp @@ -697,7 +697,7 @@ bool Mob::SpellEffect(Mob* caster, uint16 spell_id, float partial, int level_ove uint32 gid = raid->GetGroup(caster->CastToClient()); if (gid < 12) for (int i = 0; i < MAX_RAID_MEMBERS; ++i) - if (raid->members[i].member && raid->members[i].GroupNumber == gid) + if (raid->members[i].member && raid->members[i].group_number == gid) raid->members[i].member->aa_timers[aaTimerWarcry].Start(time); } } diff --git a/zone/spells.cpp b/zone/spells.cpp index c8fdf9f08..0a63370b8 100644 --- a/zone/spells.cpp +++ b/zone/spells.cpp @@ -496,7 +496,7 @@ bool Mob::DoCastSpell(uint16 spell_id, uint16 target_id, CastingSlot slot, void Mob::DoSpellInterrupt(uint16 spell_id, int32 mana_cost, int my_curmana) { //The client will prevent spell casting if insufficient mana, this is only for serverside enforcement. - LogSpells("Spell Error not enough mana spell=[{}] mymana=[{}] cost=[{}]\n", spell_id, my_curmana, mana_cost); + LogSpells("Not enough mana spell [{}] curmana [{}] cost [{}]\n", spell_id, my_curmana, mana_cost); if (IsClient()) { //clients produce messages... npcs should not for this case MessageString(Chat::Red, INSUFFICIENT_MANA); diff --git a/zone/worldserver.cpp b/zone/worldserver.cpp index 5a5025ac4..70013c3e6 100644 --- a/zone/worldserver.cpp +++ b/zone/worldserver.cpp @@ -1121,8 +1121,9 @@ void WorldServer::HandleMessage(uint16 opcode, const EQ::Net::Packet &p) Client *client = entity_list.GetClientByName(sgfas->Name); - if (!client) + if (!client) { break; + } uint32 groupid = database.GetGroupID(client->GetName()); @@ -1445,7 +1446,7 @@ void WorldServer::HandleMessage(uint16 opcode, const EQ::Net::Packet &p) if (r->members[x].member) { if (strcmp(r->members[x].member->GetName(), rga->membername) != 0) { - if ((rga->gid < 12) && rga->gid == r->members[x].GroupNumber) + if ((rga->gid < 12) && rga->gid == r->members[x].group_number) { strn0cpy(gj->yourname, r->members[x].member->GetName(), 64); r->members[x].member->QueuePacket(outapp); @@ -1475,7 +1476,7 @@ void WorldServer::HandleMessage(uint16 opcode, const EQ::Net::Packet &p) if (r->members[x].member) { if (strcmp(r->members[x].member->GetName(), rga->membername) != 0) { - if ((rga->gid < 12) && rga->gid == r->members[x].GroupNumber) + if ((rga->gid < 12) && rga->gid == r->members[x].group_number) { strn0cpy(gj->yourname, r->members[x].member->GetName(), 64); r->members[x].member->QueuePacket(outapp); @@ -1499,8 +1500,8 @@ void WorldServer::HandleMessage(uint16 opcode, const EQ::Net::Packet &p) if (r->members[x].member) { if (strcmp(rmsg->from, r->members[x].member->GetName()) != 0) { - if (r->members[x].GroupNumber == rmsg->gid) { - if (!r->members[x].IsBot && r->members[x].member->GetFilter(FilterGroupChat) != 0) + if (r->members[x].group_number == rmsg->gid) { + if (!r->members[x].is_bot && r->members[x].member->GetFilter(FilterGroupChat) != 0) { r->members[x].member->ChannelMessageSend(rmsg->from, r->members[x].member->GetName(), ChatChannel_Group, rmsg->language, rmsg->lang_skill, rmsg->message); } @@ -1524,7 +1525,7 @@ void WorldServer::HandleMessage(uint16 opcode, const EQ::Net::Packet &p) if (r->members[x].member) { if (strcmp(rmsg->from, r->members[x].member->GetName()) != 0) { - if (!r->members[x].IsBot && r->members[x].member->GetFilter(FilterGroupChat) != 0) + if (!r->members[x].is_bot && r->members[x].member->GetFilter(FilterGroupChat) != 0) { r->members[x].member->ChannelMessageSend(rmsg->from, r->members[x].member->GetName(), ChatChannel_Raid, rmsg->language, rmsg->lang_skill, rmsg->message); } From abcb5d069f2152beb477c44aa1e3e8df9294b5cf Mon Sep 17 00:00:00 2001 From: Alex King <89047260+Kinglykrab@users.noreply.github.com> Date: Mon, 20 Mar 2023 12:06:10 -0400 Subject: [PATCH 03/22] [Cleanup] Remove FindPatch() from struct_category.cpp and struct_category.h (#3130) # Notes - This is unused. --- common/struct_strategy.cpp | 8 -------- common/struct_strategy.h | 3 --- 2 files changed, 11 deletions(-) diff --git a/common/struct_strategy.cpp b/common/struct_strategy.cpp index 52df20410..ca633143a 100644 --- a/common/struct_strategy.cpp +++ b/common/struct_strategy.cpp @@ -71,14 +71,6 @@ namespace StructStrategyFactory { strategies[first_opcode] = structs; } - const StructStrategy *FindPatch(EmuOpcode first_opcode) { - std::map::const_iterator res; - res = strategies.find(first_opcode); - if(res == strategies.end()) - return(nullptr); - return(res->second); - } - }; diff --git a/common/struct_strategy.h b/common/struct_strategy.h index da4142295..d3f7327ab 100644 --- a/common/struct_strategy.h +++ b/common/struct_strategy.h @@ -43,9 +43,6 @@ protected: //effectively a singleton, but I decided to do it this way for no apparent reason. namespace StructStrategyFactory { void RegisterPatch(EmuOpcode first_opcode, const StructStrategy *structs); - - //does NOT return ownership of the strategy. - const StructStrategy *FindPatch(EmuOpcode first_opcode); }; From 63a8d2d641084b7c208fd0670efab569c5ab1525 Mon Sep 17 00:00:00 2001 From: Alex King <89047260+Kinglykrab@users.noreply.github.com> Date: Mon, 20 Mar 2023 12:06:40 -0400 Subject: [PATCH 04/22] [Cleanup] Delete zone_numbers.h (#3129) * [Cleanup] Delete zone_numbers.h # Notes - This is unused. * Update client_packet.cpp * Update client_packet.cpp --- common/CMakeLists.txt | 1 - common/zone_numbers.h | 490 ----------------------------------------- world/worlddb.h | 1 - zone/client_packet.cpp | 3 +- 4 files changed, 1 insertion(+), 494 deletions(-) delete mode 100644 common/zone_numbers.h diff --git a/common/CMakeLists.txt b/common/CMakeLists.txt index 0f9fe6aa6..b6e9ec89d 100644 --- a/common/CMakeLists.txt +++ b/common/CMakeLists.txt @@ -608,7 +608,6 @@ SET(common_headers unix.h useperl.h version.h - zone_numbers.h zone_store.h event/event_loop.h event/task.h diff --git a/common/zone_numbers.h b/common/zone_numbers.h deleted file mode 100644 index 466ffc493..000000000 --- a/common/zone_numbers.h +++ /dev/null @@ -1,490 +0,0 @@ -#include "../common/types.h" - -inline const char* StaticGetZoneName(uint32 zoneID) { - // @merth: I did the following query to retrieve these (following by a simple find/replace) - // select concat('case ', zoneidnumber), concat(short_name, '";') from zone order by zoneidnumber; - switch (zoneID) { - case 1: return "qeynos"; - case 2: return "qeynos2"; - case 3: return "qrg"; - case 4: return "qeytoqrg"; - case 5: return "highpass"; - case 6: return "highkeep"; - case 8: return "freportn"; - case 9: return "freportw"; - case 10: return "freporte"; - case 11: return "runnyeye"; - case 12: return "qey2hh1"; - case 13: return "northkarana"; - case 14: return "southkarana"; - case 15: return "eastkarana"; - case 16: return "beholder"; - case 17: return "blackburrow"; - case 18: return "paw"; - case 19: return "rivervale"; - case 20: return "kithicor"; - case 21: return "commons"; - case 22: return "ecommons"; - case 23: return "erudnint"; - case 24: return "erudnext"; - case 25: return "nektulos"; - case 26: return "cshome"; - case 27: return "lavastorm"; - case 28: return "nektropos"; - case 29: return "halas"; - case 30: return "everfrost"; - case 31: return "soldunga"; - case 32: return "soldungb"; - case 33: return "misty"; - case 34: return "nro"; - case 35: return "sro"; - case 36: return "befallen"; - case 37: return "oasis"; - case 38: return "tox"; - case 39: return "hole"; - case 40: return "neriaka"; - case 41: return "neriakb"; - case 42: return "neriakc"; - case 43: return "neriakd"; - case 44: return "najena"; - case 45: return "qcat"; - case 46: return "innothule"; - case 47: return "feerrott"; - case 48: return "cazicthule"; - case 49: return "oggok"; - case 50: return "rathemtn"; - case 51: return "lakerathe"; - case 52: return "grobb"; - case 53: return "aviak"; - case 54: return "gfaydark"; - case 55: return "akanon"; - case 56: return "steamfont"; - case 57: return "lfaydark"; - case 58: return "crushbone"; - case 59: return "mistmoore"; - case 60: return "kaladima"; - case 61: return "felwithea"; - case 62: return "felwitheb"; - case 63: return "unrest"; - case 64: return "kedge"; - case 65: return "guktop"; - case 66: return "gukbottom"; - case 67: return "kaladimb"; - case 68: return "butcher"; - case 69: return "oot"; - case 70: return "cauldron"; - case 71: return "airplane"; - case 72: return "fearplane"; - case 73: return "permafrost"; - case 74: return "kerraridge"; - case 75: return "paineel"; - case 76: return "hateplane"; - case 77: return "arena"; - case 78: return "fieldofbone"; - case 79: return "warslikswood"; - case 80: return "soltemple"; - case 81: return "droga"; - case 82: return "cabwest"; - case 83: return "swampofnohope"; - case 84: return "firiona"; - case 85: return "lakeofillomen"; - case 86: return "dreadlands"; - case 87: return "burningwood"; - case 88: return "kaesora"; - case 89: return "sebilis"; - case 90: return "citymist"; - case 91: return "skyfire"; - case 92: return "frontiermtns"; - case 93: return "overthere"; - case 94: return "emeraldjungle"; - case 95: return "trakanon"; - case 96: return "timorous"; - case 97: return "kurn"; - case 98: return "erudsxing"; - case 100: return "stonebrunt"; - case 101: return "warrens"; - case 102: return "karnor"; - case 103: return "chardok"; - case 104: return "dalnir"; - case 105: return "charasis"; - case 106: return "cabeast"; - case 107: return "nurga"; - case 108: return "veeshan"; - case 109: return "veksar"; - case 110: return "iceclad"; - case 111: return "frozenshadow"; - case 112: return "velketor"; - case 113: return "kael"; - case 114: return "skyshrine"; - case 115: return "thurgadina"; - case 116: return "eastwastes"; - case 117: return "cobaltscar"; - case 118: return "greatdivide"; - case 119: return "wakening"; - case 120: return "westwastes"; - case 121: return "crystal"; - case 123: return "necropolis"; - case 124: return "templeveeshan"; - case 125: return "sirens"; - case 126: return "mischiefplane"; - case 127: return "growthplane"; - case 128: return "sleeper"; - case 129: return "thurgadinb"; - case 130: return "erudsxing2"; - case 150: return "shadowhaven"; - case 151: return "bazaar"; - case 152: return "nexus"; - case 153: return "echo"; - case 154: return "acrylia"; - case 155: return "sharvahl"; - case 156: return "paludal"; - case 157: return "fungusgrove"; - case 158: return "vexthal"; - case 159: return "sseru"; - case 160: return "katta"; - case 161: return "netherbian"; - case 162: return "ssratemple"; - case 163: return "griegsend"; - case 164: return "thedeep"; - case 165: return "shadeweaver"; - case 166: return "hollowshade"; - case 167: return "grimling"; - case 168: return "mseru"; - case 169: return "letalis"; - case 170: return "twilight"; - case 171: return "thegrey"; - case 172: return "tenebrous"; - case 173: return "maiden"; - case 174: return "dawnshroud"; - case 175: return "scarlet"; - case 176: return "umbral"; - case 179: return "akheva"; - case 180: return "arena2"; - case 181: return "jaggedpine"; - case 182: return "nedaria"; - case 183: return "tutorial"; - case 184: return "load"; - case 185: return "load2"; - case 186: return "hateplaneb"; - case 187: return "shadowrest"; - case 188: return "tutoriala"; - case 189: return "tutorialb"; - case 190: return "clz"; - case 200: return "codecay"; - case 201: return "pojustice"; - case 202: return "poknowledge"; - case 203: return "potranquility"; - case 204: return "ponightmare"; - case 205: return "podisease"; - case 206: return "poinnovation"; - case 207: return "potorment"; - case 208: return "povalor"; - case 209: return "bothunder"; - case 210: return "postorms"; - case 211: return "hohonora"; - case 212: return "solrotower"; - case 213: return "powar"; - case 214: return "potactics"; - case 215: return "poair"; - case 216: return "powater"; - case 217: return "pofire"; - case 218: return "poeartha"; - case 219: return "potimea"; - case 220: return "hohonorb"; - case 221: return "nightmareb"; - case 222: return "poearthb"; - case 223: return "potimeb"; - case 224: return "gunthak"; - case 225: return "dulak"; - case 226: return "torgiran"; - case 227: return "nadox"; - case 228: return "hatesfury"; - case 229: return "guka"; - case 230: return "ruja"; - case 231: return "taka"; - case 232: return "mira"; - case 233: return "mmca"; - case 234: return "gukb"; - case 235: return "rujb"; - case 236: return "takb"; - case 237: return "mirb"; - case 238: return "mmcb"; - case 239: return "gukc"; - case 240: return "rujc"; - case 241: return "takc"; - case 242: return "mirc"; - case 243: return "mmcc"; - case 244: return "gukd"; - case 245: return "rujd"; - case 246: return "takd"; - case 247: return "mird"; - case 248: return "mmcd"; - case 249: return "guke"; - case 250: return "ruje"; - case 251: return "take"; - case 252: return "mire"; - case 253: return "mmce"; - case 254: return "gukf"; - case 255: return "rujf"; - case 256: return "takf"; - case 257: return "mirf"; - case 258: return "mmcf"; - case 259: return "gukg"; - case 260: return "rujg"; - case 261: return "takg"; - case 262: return "mirg"; - case 263: return "mmcg"; - case 264: return "gukh"; - case 265: return "rujh"; - case 266: return "takh"; - case 267: return "mirh"; - case 268: return "mmch"; - case 269: return "ruji"; - case 270: return "taki"; - case 271: return "miri"; - case 272: return "mmci"; - case 273: return "rujj"; - case 274: return "takj"; - case 275: return "mirj"; - case 276: return "mmcj"; - case 277: return "chardokb"; - case 278: return "soldungc"; - case 279: return "abysmal"; - case 280: return "natimbi"; - case 281: return "qinimi"; - case 282: return "riwwi"; - case 283: return "barindu"; - case 284: return "ferubi"; - case 285: return "snpool"; - case 286: return "snlair"; - case 287: return "snplant"; - case 288: return "sncrematory"; - case 289: return "tipt"; - case 290: return "vxed"; - case 291: return "yxtta"; - case 292: return "uqua"; - case 293: return "kodtaz"; - case 294: return "ikkinz"; - case 295: return "qvic"; - case 296: return "inktuta"; - case 297: return "txevu"; - case 298: return "tacvi"; - case 299: return "qvicb"; - case 300: return "wallofslaughter"; - case 301: return "bloodfields"; - case 302: return "draniksscar"; - case 303: return "causeway"; - case 304: return "chambersa"; - case 305: return "chambersb"; - case 306: return "chambersc"; - case 307: return "chambersd"; - case 308: return "chamberse"; - case 309: return "chambersf"; - case 316: return "provinggrounds"; - case 317: return "anguish"; - case 318: return "dranikhollowsa"; - case 319: return "dranikhollowsb"; - case 320: return "dranikhollowsc"; - case 328: return "dranikcatacombsa"; - case 329: return "dranikcatacombsb"; - case 330: return "dranikcatacombsc"; - case 331: return "draniksewersa"; - case 332: return "draniksewersb"; - case 333: return "draniksewersc"; - case 334: return "riftseekers"; - case 335: return "harbingers"; - case 336: return "dranik"; - case 337: return "broodlands"; - case 338: return "stillmoona"; - case 339: return "stillmoonb"; - case 340: return "thundercrest"; - case 341: return "delvea"; - case 342: return "delveb"; - case 343: return "thenest"; - case 344: return "guildlobby"; - case 345: return "guildhall"; - case 346: return "barter"; - case 347: return "illsalin"; - case 348: return "illsalina"; - case 349: return "illsalinb"; - case 350: return "illsalinc"; - case 351: return "dreadspire"; - case 354: return "drachnidhive"; - case 355: return "drachnidhivea"; - case 356: return "drachnidhiveb"; - case 357: return "drachnidhivec"; - case 358: return "westkorlach"; - case 359: return "westkorlacha"; - case 360: return "westkorlachb"; - case 361: return "westkorlachc"; - case 362: return "eastkorlach"; - case 363: return "eastkorlacha"; - case 364: return "shadowspine"; - case 365: return "corathus"; - case 366: return "corathusa"; - case 367: return "corathusb"; - case 368: return "nektulosa"; - case 369: return "arcstone"; - case 370: return "relic"; - case 371: return "skylance"; - case 372: return "devastation"; - case 373: return "devastationa"; - case 374: return "rage"; - case 375: return "ragea"; - case 376: return "takishruins"; - case 377: return "takishruinsa"; - case 378: return "elddar"; - case 379: return "elddara"; - case 380: return "theater"; - case 381: return "theatera"; - case 382: return "freeporteast"; - case 383: return "freeportwest"; - case 384: return "freeportsewers"; - case 385: return "freeportacademy"; - case 386: return "freeporttemple"; - case 387: return "freeportmilitia"; - case 388: return "freeportarena"; - case 389: return "freeportcityhall"; - case 390: return "freeporttheater"; - case 391: return "freeporthall"; - case 392: return "northro"; - case 393: return "southro"; - case 394: return "crescent"; - case 395: return "moors"; - case 396: return "stonehive"; - case 397: return "mesa"; - case 398: return "roost"; - case 399: return "steppes"; - case 400: return "icefall"; - case 401: return "valdeholm"; - case 402: return "frostcrypt"; - case 403: return "sunderock"; - case 404: return "vergalid"; - case 405: return "direwind"; - case 406: return "ashengate"; - case 407: return "highpasshold"; - case 408: return "commonlands"; - case 409: return "oceanoftears"; - case 410: return "kithforest"; - case 411: return "befallenb"; - case 412: return "highpasskeep"; - case 413: return "innothuleb"; - case 414: return "toxxulia"; - case 415: return "mistythicket"; - case 416: return "kattacastrum"; - case 417: return "thalassius"; - case 418: return "atiiki"; - case 419: return "zhisza"; - case 420: return "silyssar"; - case 421: return "solteris"; - case 422: return "barren"; - case 423: return "buriedsea"; - case 424: return "jardelshook"; - case 425: return "monkeyrock"; - case 426: return "suncrest"; - case 427: return "deadbone"; - case 428: return "blacksail"; - case 429: return "maidensgrave"; - case 430: return "redfeather"; - case 431: return "shipmvp"; - case 432: return "shipmvu"; - case 433: return "shippvu"; - case 434: return "shipuvu"; - case 435: return "shipmvm"; - case 436: return "mechanotus"; - case 437: return "mansion"; - case 438: return "steamfactory"; - case 439: return "shipworkshop"; - case 440: return "gyrospireb"; - case 441: return "gyrospirez"; - case 442: return "dragonscale"; - case 443: return "lopingplains"; - case 444: return "hillsofshade"; - case 445: return "bloodmoon"; - case 446: return "crystallos"; - case 447: return "guardian"; - case 448: return "steamfontmts"; - case 449: return "cryptofshade"; - case 451: return "dragonscaleb"; - case 452: return "oldfieldofbone"; - case 453: return "oldkaesoraa"; - case 454: return "oldkaesorab"; - case 455: return "oldkurn"; - case 456: return "oldkithicor"; - case 457: return "oldcommons"; - case 458: return "oldhighpass"; - case 459: return "thevoida"; - case 460: return "thevoidb"; - case 461: return "thevoidc"; - case 462: return "thevoidd"; - case 463: return "thevoide"; - case 464: return "thevoidf"; - case 465: return "thevoidg"; - case 466: return "oceangreenhills"; - case 467: return "oceangreenvillage"; - case 468: return "oldblackburrow"; - case 469: return "bertoxtemple"; - case 470: return "discord"; - case 471: return "discordtower"; - case 472: return "oldbloodfield"; - case 473: return "precipiceofwar"; - case 474: return "olddranik"; - case 475: return "toskirakk"; - case 476: return "korascian"; - case 477: return "rathechamber"; - case 480: return "brellsrest"; - case 481: return "fungalforest"; - case 482: return "underquarry"; - case 483: return "coolingchamber"; - case 484: return "shiningcity"; - case 485: return "arthicrex"; - case 486: return "foundation"; - case 487: return "lichencreep"; - case 488: return "pellucid"; - case 489: return "stonesnake"; - case 490: return "brellstemple"; - case 491: return "convorteum"; - case 492: return "brellsarena"; - case 493: return "weddingchapel"; - case 494: return "weddingchapeldark"; - case 495: return "dragoncrypt"; - case 700: return "feerrott2"; - case 701: return "thulehouse1"; - case 702: return "thulehouse2"; - case 703: return "housegarden"; - case 704: return "thulelibrary"; - case 705: return "well"; - case 706: return "fallen"; - case 707: return "morellcastle"; - case 708: return "somnium"; - case 709: return "alkabormare"; - case 710: return "miragulmare"; - case 711: return "thuledream"; - case 712: return "neighborhood"; - case 724: return "argath"; - case 725: return "arelis"; - case 726: return "sarithcity"; - case 727: return "rubak"; - case 728: return "beastdomain"; - case 729: return "resplendent"; - case 730: return "pillarsalra"; - case 731: return "windsong"; - case 732: return "cityofbronze"; - case 733: return "sepulcher"; - case 734: return "eastsepulcher"; - case 735: return "westsepulcher"; - case 752: return "shardslanding"; - case 753: return "xorbb"; - case 754: return "kaelshard"; - case 755: return "eastwastesshard"; - case 756: return "crystalshard"; - case 757: return "breedinggrounds"; - case 758: return "eviltree"; - case 759: return "grelleth"; - case 760: return "chapterhouse"; - case 996: return "arttest"; - case 998: return "fhalls"; - case 999: return "apprentice"; - } - return "UNKNWN"; -} diff --git a/world/worlddb.h b/world/worlddb.h index 2b3d7ea07..9054c77ea 100644 --- a/world/worlddb.h +++ b/world/worlddb.h @@ -19,7 +19,6 @@ #define WORLDDB_H_ #include "../common/shareddb.h" -#include "../common/zone_numbers.h" #include "../common/eq_packet.h" struct PlayerProfile_Struct; diff --git a/zone/client_packet.cpp b/zone/client_packet.cpp index cc48a9844..75111a266 100644 --- a/zone/client_packet.cpp +++ b/zone/client_packet.cpp @@ -48,7 +48,6 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA #include "../common/skills.h" #include "../common/spdat.h" #include "../common/strings.h" -#include "../common/zone_numbers.h" #include "data_bucket.h" #include "event_codes.h" #include "expedition.h" @@ -6779,7 +6778,7 @@ void Client::Handle_OP_GMSearchCorpse(const EQApplicationPacket *app) bool corpseBuried = Strings::ToInt(row[7]); popupText += StringFormat("%s%s%8.0f%8.0f%8.0f%s%s%s", - charName, StaticGetZoneName(ZoneID), CorpseX, CorpseY, CorpseZ, time_of_death, + charName, zone_store.GetZoneName(ZoneID, true), CorpseX, CorpseY, CorpseZ, time_of_death, corpseRezzed ? "Yes" : "No", corpseBuried ? "Yes" : "No"); if (popupText.size() > 4000) { From 4fe44f4cb68719aea59284fc458803e5f5361309 Mon Sep 17 00:00:00 2001 From: Alex King <89047260+Kinglykrab@users.noreply.github.com> Date: Mon, 20 Mar 2023 16:18:51 -0400 Subject: [PATCH 05/22] [Quest API] Add Timer related methods to Mobs in Perl/Lua (#3133) * [Quest API] Add Timer related methods to Mobs in Perl/Lua # Perl - Add `quest::ispausedtimer(timer_name)`. - Add `quest::pausetimer(timer_name)`. - Add `quest::resumetimer(timer_name)`. - Add `$mob->GetRemainingTimeMS(timer_name)`. - Add `$mob->GetTimerDurationMS(timer_name)`. - Add `$mob->HasTimer(timer_name)`. - Add `$mob->IsPausedTimer(timer_name)`. - Add `$mob->PauseTimer(timer_name)`. - Add `$mob->ResumeTimer(timer_name)`. - Add `$mob->SetTimer(timer_name)`. - Add `$mob->SetTimerMS(timer_name)`. - Add `$mob->StopTimer(timer_name)`. # Lua - Add `mob:GetRemainingTimeMS(timer_name)`. - Add `mob:GetTimerDurationMS(timer_name)`. - Add `mob:HasTimer(timer_name)`. - Add `mob:IsPausedTimer(timer_name)`. - Add `mob:PauseTimer(timer_name)`. - Add `mob:ResumeTimer(timer_name)`. - Add `mob:SetTimer(timer_name)`. - Add `mob:SetTimerMS(timer_name)`. - Add `mob:StopTimer(timer_name)`. # Notes - The mob-based methods allow operators to loop entity list or whatever to set, stop, resume, pause, etc for timers. * StopAllTimers() * Update questmgr.cpp --- zone/embparser_api.cpp | 18 +++++++ zone/lua_mob.cpp | 60 ++++++++++++++++++++++ zone/lua_mob.h | 10 ++++ zone/perl_mob.cpp | 61 ++++++++++++++++++++++ zone/questmgr.cpp | 111 ++++++++++++++++++++--------------------- zone/questmgr.h | 26 +++++----- 6 files changed, 216 insertions(+), 70 deletions(-) diff --git a/zone/embparser_api.cpp b/zone/embparser_api.cpp index 61ce723b0..1bd461fdf 100644 --- a/zone/embparser_api.cpp +++ b/zone/embparser_api.cpp @@ -359,6 +359,11 @@ bool Perl__hastimer(const char* timer_name) return quest_manager.hastimer(timer_name); } +bool Perl__ispausedtimer(const char* timer_name) +{ + return quest_manager.ispausedtimer(timer_name); +} + uint32_t Perl__getremainingtimeMS(const char* timer_name) { return quest_manager.getremainingtimeMS(timer_name); @@ -379,6 +384,16 @@ void Perl__settimerMS(const char* timer_name, int milliseconds) quest_manager.settimerMS(timer_name, milliseconds); } +void Perl__pausetimer(const char* timer_name) +{ + quest_manager.pausetimer(timer_name); +} + +void Perl__resumetimer(const char* timer_name) +{ + quest_manager.resumetimer(timer_name); +} + void Perl__stoptimer(const char* timer_name) { quest_manager.stoptimer(timer_name); @@ -4550,6 +4565,7 @@ void perl_register_quest() package.add("isdooropen", &Perl__isdooropen); package.add("ishotzone", &Perl__ishotzone); package.add("isnpcspawned", &Perl__isnpcspawned); + package.add("ispausedtimer", &Perl__ispausedtimer); package.add("istaskactive", &Perl__istaskactive); package.add("istaskactivityactive", &Perl__istaskactivityactive); package.add("istaskappropriate", &Perl__istaskappropriate); @@ -4579,6 +4595,7 @@ void perl_register_quest() package.add("npcsize", &Perl__npcsize); package.add("npctexture", &Perl__npctexture); package.add("pause", &Perl__pause); + package.add("pausetimer", &Perl__pausetimer); package.add("permaclass", &Perl__permaclass); package.add("permagender", &Perl__permagender); package.add("permarace", &Perl__permarace); @@ -4622,6 +4639,7 @@ void perl_register_quest() package.add("resettaskactivity", &Perl__resettaskactivity); package.add("respawn", &Perl__respawn); package.add("resume", &Perl__resume); + package.add("resumetimer", &Perl__resumetimer); package.add("rewardfaction", &Perl__rewardfaction); package.add("safemove", &Perl__safemove); package.add("save", &Perl__save); diff --git a/zone/lua_mob.cpp b/zone/lua_mob.cpp index 4face4b8f..8fee8297c 100644 --- a/zone/lua_mob.cpp +++ b/zone/lua_mob.cpp @@ -2935,6 +2935,56 @@ int64 Lua_Mob::GetActReflectedSpellDamage(uint16 spell_id, int64 value, int effe return self->GetActReflectedSpellDamage(spell_id, value, effectiveness); } +uint32 Lua_Mob::GetRemainingTimeMS(const char* timer_name) { + Lua_Safe_Call_Int(); + return quest_manager.getremainingtimeMS(timer_name, self); +} + +uint32 Lua_Mob::GetTimerDurationMS(const char* timer_name) { + Lua_Safe_Call_Int(); + return quest_manager.gettimerdurationMS(timer_name, self); +} + +bool Lua_Mob::HasTimer(const char* timer_name) { + Lua_Safe_Call_Bool(); + return quest_manager.hastimer(timer_name, self); +} + +bool Lua_Mob::IsPausedTimer(const char* timer_name) { + Lua_Safe_Call_Bool(); + return quest_manager.ispausedtimer(timer_name, self); +} + +void Lua_Mob::PauseTimer(const char* timer_name) { + Lua_Safe_Call_Void(); + quest_manager.pausetimer(timer_name, self); +} + +void Lua_Mob::ResumeTimer(const char* timer_name) { + Lua_Safe_Call_Void(); + quest_manager.resumetimer(timer_name, self); +} + +void Lua_Mob::SetTimer(const char* timer_name, int seconds) { + Lua_Safe_Call_Void(); + quest_manager.settimer(timer_name, seconds, self); +} + +void Lua_Mob::SetTimerMS(const char* timer_name, int milliseconds) { + Lua_Safe_Call_Void(); + quest_manager.settimerMS(timer_name, milliseconds, self); +} + +void Lua_Mob::StopAllTimers() { + Lua_Safe_Call_Void(); + quest_manager.stopalltimers(self); +} + +void Lua_Mob::StopTimer(const char* timer_name) { + Lua_Safe_Call_Void(); + quest_manager.stoptimer(timer_name, self); +} + luabind::scope lua_register_mob() { return luabind::class_("Mob") .def(luabind::constructor<>()) @@ -3232,6 +3282,7 @@ luabind::scope lua_register_mob() { .def("GetPhR", &Lua_Mob::GetPhR) .def("GetRace", &Lua_Mob::GetRace) .def("GetRaceName", &Lua_Mob::GetRaceName) + .def("GetRemainingTimeMS", &Lua_Mob::GetRemainingTimeMS) .def("GetResist", (int(Lua_Mob::*)(int))&Lua_Mob::GetResist) .def("GetReverseFactionCon", (int(Lua_Mob::*)(Lua_Mob))&Lua_Mob::GetReverseFactionCon) .def("GetRunspeed", &Lua_Mob::GetRunspeed) @@ -3249,6 +3300,7 @@ luabind::scope lua_register_mob() { .def("GetSpellHPBonuses", &Lua_Mob::GetSpellHPBonuses) .def("GetTarget", &Lua_Mob::GetTarget) .def("GetTexture", &Lua_Mob::GetTexture) + .def("GetTimerDurationMS", &Lua_Mob::GetTimerDurationMS) .def("GetUltimateOwner", &Lua_Mob::GetUltimateOwner) .def("GetWIS", &Lua_Mob::GetWIS) .def("GetWalkspeed", &Lua_Mob::GetWalkspeed) @@ -3270,6 +3322,7 @@ luabind::scope lua_register_mob() { .def("HasPet", (bool(Lua_Mob::*)(void))&Lua_Mob::HasPet) .def("HasProcs", &Lua_Mob::HasProcs) .def("HasShieldEquiped", (bool(Lua_Mob::*)(void))&Lua_Mob::HasShieldEquiped) + .def("HasTimer", &Lua_Mob::HasTimer) .def("HasTwoHandBluntEquiped", (bool(Lua_Mob::*)(void))&Lua_Mob::HasTwoHandBluntEquiped) .def("HasTwoHanderEquipped", (bool(Lua_Mob::*)(void))&Lua_Mob::HasTwoHanderEquipped) .def("Heal", &Lua_Mob::Heal) @@ -3297,6 +3350,7 @@ luabind::scope lua_register_mob() { .def("IsMeleeDisabled", (bool(Lua_Mob::*)(void))&Lua_Mob::IsMeleeDisabled) .def("IsMezzed", (bool(Lua_Mob::*)(void))&Lua_Mob::IsMezzed) .def("IsMoving", &Lua_Mob::IsMoving) + .def("IsPausedTimer", &Lua_Mob::IsPausedTimer) .def("IsPet", (bool(Lua_Mob::*)(void))&Lua_Mob::IsPet) .def("IsRoamer", (bool(Lua_Mob::*)(void))&Lua_Mob::IsRoamer) .def("IsRooted", (bool(Lua_Mob::*)(void))&Lua_Mob::IsRooted) @@ -3318,6 +3372,7 @@ luabind::scope lua_register_mob() { .def("NPCSpecialAttacks", (void(Lua_Mob::*)(const char*,int,bool))&Lua_Mob::NPCSpecialAttacks) .def("NPCSpecialAttacks", (void(Lua_Mob::*)(const char*,int,bool,bool))&Lua_Mob::NPCSpecialAttacks) .def("NavigateTo", (void(Lua_Mob::*)(double,double,double))&Lua_Mob::NavigateTo) + .def("PauseTimer", &Lua_Mob::PauseTimer) .def("ProcessSpecialAbilities", (void(Lua_Mob::*)(std::string))&Lua_Mob::ProcessSpecialAbilities) .def("ProjectileAnimation", (void(Lua_Mob::*)(Lua_Mob,int))&Lua_Mob::ProjectileAnimation) .def("ProjectileAnimation", (void(Lua_Mob::*)(Lua_Mob,int,bool))&Lua_Mob::ProjectileAnimation) @@ -3338,6 +3393,7 @@ luabind::scope lua_register_mob() { .def("ResistSpell", (double(Lua_Mob::*)(int,int,Lua_Mob,bool))&Lua_Mob::ResistSpell) .def("ResistSpell", (double(Lua_Mob::*)(int,int,Lua_Mob,bool,int))&Lua_Mob::ResistSpell) .def("ResistSpell", (double(Lua_Mob::*)(int,int,Lua_Mob,bool,int,bool))&Lua_Mob::ResistSpell) + .def("ResumeTimer", &Lua_Mob::ResumeTimer) .def("RunTo", (void(Lua_Mob::*)(double, double, double))&Lua_Mob::RunTo) .def("Say", (void(Lua_Mob::*)(const char*))& Lua_Mob::Say) .def("Say", (void(Lua_Mob::*)(const char*, int))& Lua_Mob::Say) @@ -3401,6 +3457,10 @@ luabind::scope lua_register_mob() { .def("SetTarget", &Lua_Mob::SetTarget) .def("SetTargetable", (void(Lua_Mob::*)(bool))&Lua_Mob::SetTargetable) .def("SetTexture", (void(Lua_Mob::*)(int))&Lua_Mob::SetTexture) + .def("SetTimer", &Lua_Mob::SetTimer) + .def("SetTimerMS", &Lua_Mob::SetTimerMS) + .def("StopAllTimers", &Lua_Mob::StopAllTimers) + .def("StopTimer", &Lua_Mob::StopTimer) .def("Shout", (void(Lua_Mob::*)(const char*))& Lua_Mob::Shout) .def("Shout", (void(Lua_Mob::*)(const char*, int))& Lua_Mob::Shout) .def("Signal", (void(Lua_Mob::*)(int))&Lua_Mob::Signal) diff --git a/zone/lua_mob.h b/zone/lua_mob.h index a3bcace30..3657b3323 100644 --- a/zone/lua_mob.h +++ b/zone/lua_mob.h @@ -528,6 +528,16 @@ public: int64 GetActSpellHealing(uint16 spell_id, int64 value, Lua_Mob target); int64 GetActSpellHealing(uint16 spell_id, int64 value, Lua_Mob target, bool from_buff_tic); float GetActSpellRange(uint16 spell_id, float range); + uint32 GetRemainingTimeMS(const char* timer_name); + uint32 GetTimerDurationMS(const char* timer_name); + bool HasTimer(const char* timer_name); + bool IsPausedTimer(const char* timer_name); + void PauseTimer(const char* timer_name); + void ResumeTimer(const char* timer_name); + void SetTimer(const char* timer_name, int seconds); + void SetTimerMS(const char* timer_name, int milliseconds); + void StopAllTimers(); + void StopTimer(const char* timer_name); }; #endif diff --git a/zone/perl_mob.cpp b/zone/perl_mob.cpp index 4ce5df213..fb83bb496 100644 --- a/zone/perl_mob.cpp +++ b/zone/perl_mob.cpp @@ -9,6 +9,7 @@ #include "client.h" #include "dialogue_window.h" #include "bot.h" +#include "questmgr.h" bool Perl_Mob_IsClient(Mob* self) // @categories Script Utility { @@ -2886,6 +2887,56 @@ float Perl_Mob_GetDefaultRaceSize(Mob* self) // @categories Script Utility return self->GetDefaultRaceSize(); } +uint32 Perl_Mob_GetRemainingTimeMS(Mob* self, const char* timer_name) +{ + return quest_manager.getremainingtimeMS(timer_name, self); +} + +uint32 Perl_Mob_GetTimerDurationMS(Mob* self, const char* timer_name) +{ + return quest_manager.gettimerdurationMS(timer_name, self); +} + +bool Perl_Mob_HasTimer(Mob* self, const char* timer_name) +{ + return quest_manager.hastimer(timer_name, self); +} + +bool Perl_Mob_IsPausedTimer(Mob* self, const char* timer_name) +{ + return quest_manager.ispausedtimer(timer_name, self); +} + +void Perl_Mob_PauseTimer(Mob* self, const char* timer_name) +{ + quest_manager.pausetimer(timer_name, self); +} + +void Perl_Mob_ResumeTimer(Mob* self, const char* timer_name) +{ + quest_manager.resumetimer(timer_name, self); +} + +void Perl_Mob_SetTimer(Mob* self, const char* timer_name, int seconds) +{ + quest_manager.settimer(timer_name, seconds, self); +} + +void Perl_Mob_SetTimerMS(Mob* self, const char* timer_name, int milliseconds) +{ + quest_manager.settimerMS(timer_name, milliseconds, self); +} + +void Perl_Mob_StopAllTimers(Mob* self) +{ + quest_manager.stopalltimers(self); +} + +void Perl_Mob_StopTimer(Mob* self, const char* timer_name) +{ + quest_manager.stoptimer(timer_name, self); +} + void perl_register_mob() { perl::interpreter perl(PERL_GET_THX); @@ -3166,6 +3217,7 @@ void perl_register_mob() package.add("GetPhR", &Perl_Mob_GetPhR); package.add("GetRace", &Perl_Mob_GetRace); package.add("GetRaceName", &Perl_Mob_GetRaceName); + package.add("GetRemainingTimeMS", &Perl_Mob_GetRemainingTimeMS); package.add("GetResist", &Perl_Mob_GetResist); package.add("GetReverseFactionCon", &Perl_Mob_GetReverseFactionCon); package.add("GetRunAnimSpeed", &Perl_Mob_GetRunAnimSpeed); @@ -3185,6 +3237,7 @@ void perl_register_mob() package.add("GetSpellStat", (int(*)(Mob*, uint32, const char*, uint8))&Perl_Mob_GetSpellStat); package.add("GetTarget", &Perl_Mob_GetTarget); package.add("GetTexture", &Perl_Mob_GetTexture); + package.add("GetTimerDurationMS", &Perl_Mob_GetTimerDurationMS); package.add("GetUltimateOwner", &Perl_Mob_GetUltimateOwner); package.add("GetWIS", &Perl_Mob_GetWIS); package.add("GetWalkspeed", &Perl_Mob_GetWalkspeed); @@ -3205,6 +3258,7 @@ void perl_register_mob() package.add("HasPet", &Perl_Mob_HasPet); package.add("HasProcs", &Perl_Mob_HasProcs); package.add("HasShieldEquiped", &Perl_Mob_HasShieldEquiped); + package.add("HasTimer", &Perl_Mob_HasTimer); package.add("HasTwoHandBluntEquiped", &Perl_Mob_HasTwoHandBluntEquiped); package.add("HasTwoHanderEquipped", &Perl_Mob_HasTwoHanderEquipped); package.add("HateSummon", &Perl_Mob_HateSummon); @@ -3242,6 +3296,7 @@ void perl_register_mob() package.add("IsNPC", &Perl_Mob_IsNPC); package.add("IsNPCCorpse", &Perl_Mob_IsNPCCorpse); package.add("IsObject", &Perl_Mob_IsObject); + package.add("IsPausedTimer", &Perl_Mob_IsPausedTimer); package.add("IsPet", &Perl_Mob_IsPet); package.add("IsPlayerCorpse", &Perl_Mob_IsPlayerCorpse); package.add("IsRoamer", &Perl_Mob_IsRoamer); @@ -3272,6 +3327,7 @@ void perl_register_mob() package.add("NPCSpecialAttacks", (void(*)(Mob*, const char*, int, bool))&Perl_Mob_NPCSpecialAttacks); package.add("NPCSpecialAttacks", (void(*)(Mob*, const char*, int, bool, bool))&Perl_Mob_NPCSpecialAttacks); package.add("NavigateTo", &Perl_Mob_NavigateTo); + package.add("PauseTimer", &Perl_Mob_PauseTimer); package.add("ProcessSpecialAbilities", &Perl_Mob_ProcessSpecialAbilities); package.add("ProjectileAnim", (void(*)(Mob*, Mob*, int))&Perl_Mob_ProjectileAnim); package.add("ProjectileAnim", (void(*)(Mob*, Mob*, int, bool))&Perl_Mob_ProjectileAnim); @@ -3290,6 +3346,7 @@ void perl_register_mob() package.add("RemoveNimbusEffect", &Perl_Mob_RemoveNimbusEffect); package.add("RemovePet", &Perl_Mob_RemovePet); package.add("ResistSpell", &Perl_Mob_ResistSpell); + package.add("ResumeTimer", &Perl_Mob_ResumeTimer); package.add("RogueAssassinate", &Perl_Mob_RogueAssassinate); package.add("RunTo", &Perl_Mob_RunTo); package.add("Say", &Perl_Mob_Say); @@ -3397,6 +3454,10 @@ void perl_register_mob() package.add("SetTarget", &Perl_Mob_SetTarget); package.add("SetTargetable", &Perl_Mob_SetTargetable); package.add("SetTexture", &Perl_Mob_SetTexture); + package.add("SetTimer", &Perl_Mob_SetTimer); + package.add("SetTimerMS", &Perl_Mob_SetTimerMS); + package.add("StopAllTimers", &Perl_Mob_StopAllTimers); + package.add("StopTimer", &Perl_Mob_StopTimer); package.add("ShieldAbility", (void(*)(Mob*, uint32))&Perl_Mob_ShieldAbility); package.add("ShieldAbility", (void(*)(Mob*, uint32, int32))&Perl_Mob_ShieldAbility); package.add("ShieldAbility", (void(*)(Mob*, uint32, int32, int32))&Perl_Mob_ShieldAbility); diff --git a/zone/questmgr.cpp b/zone/questmgr.cpp index ea41f1e63..7c2898c7c 100644 --- a/zone/questmgr.cpp +++ b/zone/questmgr.cpp @@ -458,7 +458,7 @@ void QuestManager::ZoneRaid(const char *zone_name) { } } -void QuestManager::settimer(const char *timer_name, int seconds) { +void QuestManager::settimer(const char* timer_name, int seconds, Mob* mob) { QuestManagerCurrentQuestVars(); if(questitem) { @@ -469,9 +469,11 @@ void QuestManager::settimer(const char *timer_name, int seconds) { std::list::iterator cur = QTimerList.begin(), end; end = QTimerList.end(); + + const auto m = mob ? mob : owner; + while (cur != end) { - if(cur->mob && cur->mob == owner && cur->name == timer_name) - { + if (cur->mob && cur->mob == m && cur->name == timer_name) { cur->Timer_.Enable(); cur->Timer_.Start(seconds * 1000, false); return; @@ -482,7 +484,7 @@ void QuestManager::settimer(const char *timer_name, int seconds) { QTimerList.push_back(QuestTimer(seconds * 1000, owner, timer_name)); } -void QuestManager::settimerMS(const char *timer_name, int milliseconds) { +void QuestManager::settimerMS(const char* timer_name, int milliseconds) { QuestManagerCurrentQuestVars(); if(questitem) { @@ -506,13 +508,13 @@ void QuestManager::settimerMS(const char *timer_name, int milliseconds) { QTimerList.push_back(QuestTimer(milliseconds, owner, timer_name)); } -void QuestManager::settimerMS(const char *timer_name, int milliseconds, EQ::ItemInstance *inst) { +void QuestManager::settimerMS(const char* timer_name, int milliseconds, EQ::ItemInstance *inst) { if (inst) { inst->SetTimer(timer_name, milliseconds); } } -void QuestManager::settimerMS(const char *timer_name, int milliseconds, Mob *mob) { +void QuestManager::settimerMS(const char* timer_name, int milliseconds, Mob *mob) { std::list::iterator cur = QTimerList.begin(), end; end = QTimerList.end(); @@ -529,7 +531,7 @@ void QuestManager::settimerMS(const char *timer_name, int milliseconds, Mob *mob QTimerList.push_back(QuestTimer(milliseconds, mob, timer_name)); } -void QuestManager::stoptimer(const char *timer_name) { +void QuestManager::stoptimer(const char* timer_name) { QuestManagerCurrentQuestVars(); if (questitem) { @@ -549,13 +551,13 @@ void QuestManager::stoptimer(const char *timer_name) { } } -void QuestManager::stoptimer(const char *timer_name, EQ::ItemInstance *inst) { +void QuestManager::stoptimer(const char* timer_name, EQ::ItemInstance *inst) { if (inst) { inst->StopTimer(timer_name); } } -void QuestManager::stoptimer(const char *timer_name, Mob *mob) { +void QuestManager::stoptimer(const char* timer_name, Mob *mob) { std::list::iterator cur = QTimerList.begin(), end; end = QTimerList.end(); @@ -605,7 +607,7 @@ void QuestManager::stopalltimers(Mob *mob) { } } -void QuestManager::pausetimer(const char *timer_name) { +void QuestManager::pausetimer(const char* timer_name, Mob* mob) { QuestManagerCurrentQuestVars(); std::list::iterator cur = QTimerList.begin(), end; @@ -613,11 +615,11 @@ void QuestManager::pausetimer(const char *timer_name) { PausedTimer pt; uint32 milliseconds = 0; + const auto m = mob ? mob : owner; + pend = PTimerList.end(); - while (pcur != pend) - { - if (pcur->owner && pcur->owner == owner && pcur->name == timer_name) - { + while (pcur != pend) { + if (pcur->owner && pcur->owner == m && pcur->name == timer_name) { LogQuests("Timer [{}] is already paused for [{}]. Returning", timer_name, owner->GetName()); return; } @@ -625,10 +627,8 @@ void QuestManager::pausetimer(const char *timer_name) { } end = QTimerList.end(); - while (cur != end) - { - if (cur->mob && cur->mob == owner && cur->name == timer_name) - { + while (cur != end) { + if (cur->mob && cur->mob == m && cur->name == timer_name) { milliseconds = cur->Timer_.GetRemainingTime(); QTimerList.erase(cur); break; @@ -644,7 +644,7 @@ void QuestManager::pausetimer(const char *timer_name) { PTimerList.push_back(pt); } -void QuestManager::resumetimer(const char *timer_name) { +void QuestManager::resumetimer(const char* timer_name, Mob* mob) { QuestManagerCurrentQuestVars(); std::list::iterator cur = QTimerList.begin(), end; @@ -652,11 +652,11 @@ void QuestManager::resumetimer(const char *timer_name) { PausedTimer pt; uint32 milliseconds = 0; + const auto m = mob ? mob : owner; + pend = PTimerList.end(); - while (pcur != pend) - { - if (pcur->owner && pcur->owner == owner && pcur->name == timer_name) - { + while (pcur != pend) { + if (pcur->owner && pcur->owner == m && pcur->name == timer_name) { milliseconds = pcur->time; PTimerList.erase(pcur); break; @@ -664,40 +664,40 @@ void QuestManager::resumetimer(const char *timer_name) { ++pcur; } - if (milliseconds == 0) - { + if (milliseconds == 0) { LogQuests("Paused timer [{}] not found or has expired. Returning", timer_name); return; } end = QTimerList.end(); - while (cur != end) - { - if (cur->mob && cur->mob == owner && cur->name == timer_name) - { + while (cur != end) { + if (cur->mob && cur->mob == m && cur->name == timer_name) { cur->Timer_.Enable(); cur->Timer_.Start(milliseconds, false); - LogQuests("Resuming timer [{}] for [{}] with [{}] ms remaining", timer_name, owner->GetName(), milliseconds); + LogQuests("Resuming timer [{}] for [{}] with [{}] ms remaining", + timer_name, + owner->GetName(), + milliseconds); return; } ++cur; } - QTimerList.push_back(QuestTimer(milliseconds, owner, timer_name)); + QTimerList.push_back(QuestTimer(milliseconds, m, timer_name)); LogQuests("Creating a new timer and resuming [{}] for [{}] with [{}] ms remaining", timer_name, owner->GetName(), milliseconds); } -bool QuestManager::ispausedtimer(const char *timer_name) { +bool QuestManager::ispausedtimer(const char* timer_name, Mob* mob) { QuestManagerCurrentQuestVars(); std::list::iterator pcur = PTimerList.begin(), pend; + const auto m = mob ? mob : owner; + pend = PTimerList.end(); - while (pcur != pend) - { - if (pcur->owner && pcur->owner == owner && pcur->name == timer_name) - { + while (pcur != pend) { + if (pcur->owner && pcur->owner == m && pcur->name == timer_name) { return true; } ++pcur; @@ -706,18 +706,17 @@ bool QuestManager::ispausedtimer(const char *timer_name) { return false; } -bool QuestManager::hastimer(const char *timer_name) { +bool QuestManager::hastimer(const char* timer_name, Mob* mob) { QuestManagerCurrentQuestVars(); std::list::iterator cur = QTimerList.begin(), end; + const auto m = mob ? mob : owner; + end = QTimerList.end(); - while (cur != end) - { - if (cur->mob && cur->mob == owner && cur->name == timer_name) - { - if (cur->Timer_.Enabled()) - { + while (cur != end) { + if (cur->mob && cur->mob == m && cur->name == timer_name) { + if (cur->Timer_.Enabled()) { return true; } } @@ -726,18 +725,17 @@ bool QuestManager::hastimer(const char *timer_name) { return false; } -uint32 QuestManager::getremainingtimeMS(const char *timer_name) { +uint32 QuestManager::getremainingtimeMS(const char* timer_name, Mob* mob) { QuestManagerCurrentQuestVars(); std::list::iterator cur = QTimerList.begin(), end; + const auto m = mob ? mob : owner; + end = QTimerList.end(); - while (cur != end) - { - if (cur->mob && cur->mob == owner && cur->name == timer_name) - { - if (cur->Timer_.Enabled()) - { + while (cur != end) { + if (cur->mob && cur->mob == m && cur->name == timer_name) { + if (cur->Timer_.Enabled()) { return cur->Timer_.GetRemainingTime(); } } @@ -746,18 +744,17 @@ uint32 QuestManager::getremainingtimeMS(const char *timer_name) { return 0; } -uint32 QuestManager::gettimerdurationMS(const char *timer_name) { +uint32 QuestManager::gettimerdurationMS(const char* timer_name, Mob* mob) { QuestManagerCurrentQuestVars(); std::list::iterator cur = QTimerList.begin(), end; + const auto m = mob ? mob : owner; + end = QTimerList.end(); - while (cur != end) - { - if (cur->mob && cur->mob == owner && cur->name == timer_name) - { - if (cur->Timer_.Enabled()) - { + while (cur != end) { + if (cur->mob && cur->mob == m && cur->name == timer_name) { + if (cur->Timer_.Enabled()) { return cur->Timer_.GetDuration(); } } diff --git a/zone/questmgr.h b/zone/questmgr.h index 5d9f81636..cdf1051f2 100644 --- a/zone/questmgr.h +++ b/zone/questmgr.h @@ -81,22 +81,22 @@ public: void Zone(const char *zone_name); void ZoneGroup(const char *zone_name); void ZoneRaid(const char *zone_name); - void settimer(const char *timer_name, int seconds); - void settimerMS(const char *timer_name, int milliseconds); - void settimerMS(const char *timer_name, int milliseconds, EQ::ItemInstance *inst); - void settimerMS(const char *timer_name, int milliseconds, Mob *mob); - void stoptimer(const char *timer_name); - void stoptimer(const char *timer_name, EQ::ItemInstance *inst); - void stoptimer(const char *timer_name, Mob *mob); + void settimer(const char* timer_name, int seconds, Mob* mob = nullptr); + void settimerMS(const char* timer_name, int milliseconds); + void settimerMS(const char* timer_name, int milliseconds, EQ::ItemInstance *inst); + void settimerMS(const char* timer_name, int milliseconds, Mob *mob); + void stoptimer(const char* timer_name); + void stoptimer(const char* timer_name, EQ::ItemInstance *inst); + void stoptimer(const char* timer_name, Mob *mob); void stopalltimers(); void stopalltimers(EQ::ItemInstance *inst); void stopalltimers(Mob *mob); - void pausetimer(const char *timer_name); - void resumetimer(const char *timer_name); - bool ispausedtimer(const char *timer_name); - bool hastimer(const char *timer_name); - uint32 getremainingtimeMS(const char *timer_name); - uint32 gettimerdurationMS(const char *timer_name); + void pausetimer(const char* timer_name, Mob* mob = nullptr); + void resumetimer(const char* timer_name, Mob* mob = nullptr); + bool ispausedtimer(const char* timer_name, Mob* mob = nullptr); + bool hastimer(const char* timer_name, Mob* mob = nullptr); + uint32 getremainingtimeMS(const char* timer_name, Mob* mob = nullptr); + uint32 gettimerdurationMS(const char* timer_name, Mob* mob = nullptr); void emote(const char *str); void shout(const char *str); void shout2(const char *str); From fe2dcb6544b4c74bea4bfeff3d2fb72937e518b0 Mon Sep 17 00:00:00 2001 From: Aeadoin <109764533+Aeadoin@users.noreply.github.com> Date: Tue, 21 Mar 2023 11:57:04 -0400 Subject: [PATCH 06/22] [Crash] Fix dangling Group member pointers for Bots. (#3134) * [Crash] Fix dangling Group member pointers for Bots. * fixes for edge cases --- zone/bot.cpp | 126 ++++++++++++++++++++++++++++-------------------- zone/bot.h | 1 + zone/entity.cpp | 12 +++++ zone/entity.h | 1 + zone/groups.cpp | 18 ++++--- 5 files changed, 100 insertions(+), 58 deletions(-) diff --git a/zone/bot.cpp b/zone/bot.cpp index 81981d01d..44f40c692 100644 --- a/zone/bot.cpp +++ b/zone/bot.cpp @@ -425,11 +425,6 @@ Bot::Bot(uint32 botID, uint32 botOwnerCharacterID, uint32 botSpellsID, double to cur_end = max_end; - // Safety Check to confirm we have a valid group - if (HasGroup() && !GetGroup()->IsGroupMember(GetBotOwner())) { - Bot::RemoveBotFromGroup(this, GetGroup()); - } - // Safety Check to confirm we have a valid raid if (HasRaid() && !GetRaid()->IsRaidMember(GetBotOwner()->CastToClient())) { Bot::RemoveBotFromRaid(this); @@ -3111,7 +3106,6 @@ Client* Bot::SetLeashOwner(Client* bot_owner, Group* bot_group, Raid* raid, uint raid->GetGroupLeader(r_group)->CastToClient() : bot_owner; } else if (bot_group) { - bot_group->VerifyGroup(); leash_owner = (bot_group->GetLeader() && bot_group->GetLeader()->IsClient() ? bot_group->GetLeader()->CastToClient() : bot_owner); } else { @@ -3321,11 +3315,18 @@ bool Bot::Spawn(Client* botCharacterOwner) { } } - if (Raid* raid = entity_list.GetRaidByBotName(GetName())) - { + Raid* raid = nullptr; + Group* group = nullptr; + + if (raid = entity_list.GetRaidByBotName(GetName())) { raid->VerifyRaid(); SetRaidGrouped(true); } + else if (group = entity_list.GetGroupByMobName(GetName())) { + group->VerifyGroup(); + SetGrouped(true); + } + return true; } @@ -3863,21 +3864,18 @@ bool Bot::RemoveBotFromGroup(Bot* bot, Group* group) { bool Bot::AddBotToGroup(Bot* bot, Group* group) { bool Result = false; - if (bot && group) { - // Add bot to this group - if (group->AddMember(bot)) { - if (group->GetLeader()) { - bot->SetFollowID(group->GetLeader()->GetID()); - // Need to send this only once when a group is formed with a bot so the client knows it is also the group leader - if (group->GroupCount() == 2 && group->GetLeader()->IsClient()) { - group->UpdateGroupAAs(); - Mob *TempLeader = group->GetLeader(); - group->SendUpdate(groupActUpdate, TempLeader); - } + if (bot && group && group->AddMember(bot)) { + if (group->GetLeader()) { + bot->SetFollowID(group->GetLeader()->GetID()); + // Need to send this only once when a group is formed with a bot so the client knows it is also the group leader + if (group->GroupCount() == 2 && group->GetLeader()->IsClient()) { + group->UpdateGroupAAs(); + Mob *TempLeader = group->GetLeader(); + group->SendUpdate(groupActUpdate, TempLeader); } - group->VerifyGroup(); - Result = true; } + group->VerifyGroup(); + Result = true; } return Result; } @@ -6680,7 +6678,11 @@ void Bot::Camp(bool save_to_database) { Save(); } - Depop(); + if (HasGroup() || HasRaid()) { + Zone(); + } else { + Depop(); + } } void Bot::Zone() { @@ -8582,24 +8584,34 @@ void Bot::SpawnBotGroupByName(Client* c, const std::string& botgroup_name, uint3 return; } - if (!leader->Spawn(c)) { - c->Message( - Chat::White, - fmt::format( - "Could not spawn bot-group leader {} for '{}'.", - leader->GetName(), - botgroup_name - ).c_str() - ); - safe_delete(leader); - return; + if (!leader->spawned) { + if (!leader->Spawn(c)) { + c->Message( + Chat::White, + fmt::format( + "Could not spawn bot-group leader {} for '{}'.", + leader->GetName(), + botgroup_name + ).c_str() + ); + safe_delete(leader); + return; + } } - auto* g = new Group(leader); + auto group = leader->GetGroupByLeaderName(); + auto raid = leader->GetRaid(); + + if (!raid && group) { + group->SetLeader(leader); + } + else if (!raid) { + group = new Group(leader); + entity_list.AddGroup(group); + database.SetGroupID(leader->GetCleanName(), group->GetID(), leader->GetBotID()); + database.SetGroupLeaderName(group->GetID(), leader->GetCleanName()); + } - entity_list.AddGroup(g); - database.SetGroupID(leader->GetCleanName(), g->GetID(), leader->GetBotID()); - database.SetGroupLeaderName(g->GetID(), leader->GetCleanName()); leader->SetFollowID(c->GetID()); uint32 botgroup_id = 0; @@ -8686,23 +8698,33 @@ void Bot::SpawnBotGroupByName(Client* c, const std::string& botgroup_name, uint3 continue; } - if (!member->Spawn(c)) { - c->Message( - Chat::White, - fmt::format( - "Could not spawn bot '{}' (ID {}).", - member->GetName(), - member_iter - ).c_str() - ); - safe_delete(member); - return; + if (!member->spawned) { + if (!member->Spawn(c)) { + c->Message( + Chat::White, + fmt::format( + "Could not spawn bot '{}' (ID {}).", + member->GetName(), + member_iter + ).c_str() + ); + safe_delete(member); + return; + } + + spawned_bot_count++; + bot_class_spawned_count[member->GetClass() - 1]++; + + if (group) { + Bot::AddBotToGroup(member, group); + } } + } - spawned_bot_count++; - bot_class_spawned_count[member->GetClass() - 1]++; - - Bot::AddBotToGroup(member, g); + if (group) { + group->VerifyGroup(); + } else if (raid) { + raid->VerifyRaid(); } c->Message( diff --git a/zone/bot.h b/zone/bot.h index f383304ce..b77e0f919 100644 --- a/zone/bot.h +++ b/zone/bot.h @@ -141,6 +141,7 @@ public: bool HasGroup() final { return GetGroup() != nullptr; } Raid* GetRaid() final { return entity_list.GetRaidByBot(this); } Group* GetGroup() final { return entity_list.GetGroupByMob(this); } + Group* GetGroupByLeaderName() { return entity_list.GetGroupByLeaderName(GetName()); } // Common, but informal "interfaces" with Client object uint32 CharacterID() const { return GetBotID(); } diff --git a/zone/entity.cpp b/zone/entity.cpp index 49c21a1da..9ded585bf 100644 --- a/zone/entity.cpp +++ b/zone/entity.cpp @@ -2119,6 +2119,18 @@ Group *EntityList::GetGroupByMob(Mob *mob) return nullptr; } +Group *EntityList::GetGroupByMobName(const char* name) +{ + for (const auto& g : group_list) { + for (const auto& m : g->membername) { + if (strcmp(m, name) == 0) { + return g; + } + } + } + return nullptr; +} + Group *EntityList::GetGroupByLeaderName(const char *leader) { std::list::iterator iterator; diff --git a/zone/entity.h b/zone/entity.h index 5a2939e60..079a33a0a 100644 --- a/zone/entity.h +++ b/zone/entity.h @@ -193,6 +193,7 @@ public: NPC* GetRandomNPC(const glm::vec3& location = glm::vec3(0.f), float distance = 0, NPC* exclude_npc = nullptr); Mob* GetRandomMob(const glm::vec3& location = glm::vec3(0.f), float distance = 0, Mob* exclude_mob = nullptr); Group* GetGroupByMob(Mob* mob); + Group* GetGroupByMobName(const char* name); Group* GetGroupByBot(Bot* bot); bool IsInSameGroupOrRaidGroup(Client *client1, Client *client2); Group *GetGroupByClient(Client* client); diff --git a/zone/groups.cpp b/zone/groups.cpp index d803904d6..58db3edf9 100644 --- a/zone/groups.cpp +++ b/zone/groups.cpp @@ -547,11 +547,13 @@ bool Group::UpdatePlayer(Mob* update) { void Group::MemberZoned(Mob* removemob) { uint32 i; - if (removemob == nullptr) + if (!removemob) { return; + } - if(removemob == GetLeader()) + if (removemob == GetLeader()) { SetLeader(nullptr); + } //should NOT clear the name, it is used for world communication. for (auto & m : members) { @@ -560,17 +562,21 @@ void Group::MemberZoned(Mob* removemob) { } } - if(removemob->IsClient() && HasRole(removemob, RoleAssist)) + if (removemob->IsClient() && HasRole(removemob, RoleAssist)) { SetGroupAssistTarget(0); + } - if(removemob->IsClient() && HasRole(removemob, RoleTank)) + if (removemob->IsClient() && HasRole(removemob, RoleTank)) { SetGroupTankTarget(0); + } - if(removemob->IsClient() && HasRole(removemob, RolePuller)) + if (removemob->IsClient() && HasRole(removemob, RolePuller)) { SetGroupPullerTarget(0); + } - if (removemob->IsClient() && removemob == mentoree) + if (removemob->IsClient() && removemob == mentoree) { mentoree = nullptr; + } if (RuleB(Bots, Enabled)) { Bot::UpdateGroupCastingRoles(this); From c5add503ab7f199ccd4bc1a5d710adafa925be32 Mon Sep 17 00:00:00 2001 From: Aeadoin <109764533+Aeadoin@users.noreply.github.com> Date: Tue, 21 Mar 2023 19:16:01 -0400 Subject: [PATCH 07/22] [Bug Fix] Fix for Raid Disband if leader not in same zone. (#3135) --- zone/client_packet.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/zone/client_packet.cpp b/zone/client_packet.cpp index 75111a266..1208d6a62 100644 --- a/zone/client_packet.cpp +++ b/zone/client_packet.cpp @@ -12185,7 +12185,7 @@ void Client::Handle_OP_RaidCommand(const EQApplicationPacket* app) } raid->SendGroupDisband(c_to_disband); raid->GroupUpdate(group); - if (!raid->RaidCount() || !raid->GetLeader()) { + if (!raid->RaidCount()) { raid->DisbandRaid(); } break; From 2e2c4d64feb0172958bd36a0e8fcb44c184118fe Mon Sep 17 00:00:00 2001 From: Aeadoin <109764533+Aeadoin@users.noreply.github.com> Date: Wed, 22 Mar 2023 12:22:03 -0400 Subject: [PATCH 08/22] [Cleanup] Cleanup uses of Strings::ToInt to match correct type. (#3054) * [Cleanup] Cleanup uses of Strings::ToInt to match correct type. * cleanup --- common/database.cpp | 78 +++++----- common/database_conversions.cpp | 24 ++-- common/eqemu_config.cpp | 26 ++-- common/guild_base.cpp | 32 ++--- common/item_instance.cpp | 2 +- common/misc.cpp | 2 +- common/misc_functions.cpp | 2 +- common/ptimer.cpp | 6 +- common/shareddb.cpp | 244 ++++++++++++++++---------------- common/strings.cpp | 16 +-- common/strings.h | 16 +-- loginserver/database.cpp | 6 +- world/worlddb.cpp | 14 +- 13 files changed, 232 insertions(+), 236 deletions(-) diff --git a/common/database.cpp b/common/database.cpp index 407268c89..a25667995 100644 --- a/common/database.cpp +++ b/common/database.cpp @@ -387,7 +387,7 @@ bool Database::DeleteCharacter(char *character_name) std::string query = StringFormat("SELECT `id` from `character_data` WHERE `name` = '%s'", character_name); auto results = QueryDatabase(query); for (auto row = results.begin(); row != results.end(); ++row) { - character_id = Strings::ToInt(row[0]); + character_id = Strings::ToUnsignedInt(row[0]); } if (character_id <= 0) { @@ -787,7 +787,7 @@ uint32 Database::GetCharacterID(const char *name) { auto row = results.begin(); if (results.RowCount() == 1) { - return Strings::ToInt(row[0]); + return Strings::ToUnsignedInt(row[0]); } return 0; } @@ -815,7 +815,7 @@ uint32 Database::GetAccountIDByChar(const char* charname, uint32* oCharID) { uint32 accountId = Strings::ToInt(row[0]); if (oCharID) - *oCharID = Strings::ToInt(row[1]); + *oCharID = Strings::ToUnsignedInt(row[1]); return accountId; } @@ -832,7 +832,7 @@ uint32 Database::GetAccountIDByChar(uint32 char_id) { return 0; auto row = results.begin(); - return Strings::ToInt(row[0]); + return Strings::ToUnsignedInt(row[0]); } uint32 Database::GetAccountIDByName(std::string account_name, std::string loginserver, int16* status, uint32* lsid) { @@ -880,7 +880,7 @@ void Database::GetAccountName(uint32 accountid, char* name, uint32* oLSAccountID strcpy(name, row[0]); if (row[1] && oLSAccountID) { - *oLSAccountID = Strings::ToInt(row[1]); + *oLSAccountID = Strings::ToUnsignedInt(row[1]); } } @@ -968,7 +968,7 @@ bool Database::LoadVariables() { std::string key, value; for (auto row = results.begin(); row != results.end(); ++row) { - varcache.last_update = Strings::ToInt(row[2]); // ahh should we be comparing if this is newer? + varcache.last_update = Strings::ToUnsignedInt(row[2]); // ahh should we be comparing if this is newer? key = row[0]; value = row[1]; std::transform(std::begin(key), std::end(key), std::begin(key), ::tolower); // keys are lower case, DB doesn't have to be @@ -1052,7 +1052,7 @@ bool Database::GetZoneGraveyard(const uint32 graveyard_id, uint32* graveyard_zon auto row = results.begin(); if(graveyard_zoneid != nullptr) - *graveyard_zoneid = Strings::ToInt(row[0]); + *graveyard_zoneid = Strings::ToUnsignedInt(row[0]); if(graveyard_x != nullptr) *graveyard_x = Strings::ToFloat(row[1]); if(graveyard_y != nullptr) @@ -1168,7 +1168,7 @@ uint32 Database::GetAccountIDFromLSID( } for (auto row = results.begin(); row != results.end(); ++row) { - account_id = Strings::ToInt(row[0]); + account_id = Strings::ToUnsignedInt(row[0]); if (in_account_name) { strcpy(in_account_name, row[1]); @@ -1244,7 +1244,7 @@ uint8 Database::GetServerType() { return 0; auto row = results.begin(); - return Strings::ToInt(row[0]); + return Strings::ToUnsignedInt(row[0]); } bool Database::MoveCharacterToZone(uint32 character_id, uint32 zone_id) @@ -1296,7 +1296,7 @@ uint8 Database::GetRaceSkill(uint8 skillid, uint8 in_race) return 0; auto row = results.begin(); - return Strings::ToInt(row[0]); + return Strings::ToUnsignedInt(row[0]); } uint8 Database::GetSkillCap(uint8 skillid, uint8 in_race, uint8 in_class, uint16 in_level) @@ -1312,12 +1312,12 @@ uint8 Database::GetSkillCap(uint8 skillid, uint8 in_race, uint8 in_class, uint16 if (results.Success() && results.RowsAffected() != 0) { auto row = results.begin(); - skill_level = Strings::ToInt(row[0]); - skill_formula = Strings::ToInt(row[1]); - skill_cap = Strings::ToInt(row[2]); - if (Strings::ToInt(row[3]) > skill_cap) - skill_cap2 = (Strings::ToInt(row[3])-skill_cap)/10; //Split the post-50 skill cap into difference between pre-50 cap and post-50 cap / 10 to determine amount of points per level. - skill_cap3 = Strings::ToInt(row[4]); + skill_level = Strings::ToUnsignedInt(row[0]); + skill_formula = Strings::ToUnsignedInt(row[1]); + skill_cap = Strings::ToUnsignedInt(row[2]); + if (Strings::ToUnsignedInt(row[3]) > skill_cap) + skill_cap2 = (Strings::ToUnsignedInt(row[3])-skill_cap)/10; //Split the post-50 skill cap into difference between pre-50 cap and post-50 cap / 10 to determine amount of points per level. + skill_cap3 = Strings::ToUnsignedInt(row[4]); } int race_skill = GetRaceSkill(skillid,in_race); @@ -1488,7 +1488,7 @@ uint32 Database::GetGroupID(const char* name){ auto row = results.begin(); - return Strings::ToInt(row[0]); + return Strings::ToUnsignedInt(row[0]); } std::string Database::GetGroupLeaderForLogin(std::string character_name) { @@ -1638,7 +1638,7 @@ uint8 Database::GetAgreementFlag(uint32 acctid) { auto row = results.begin(); - return Strings::ToInt(row[0]); + return Strings::ToUnsignedInt(row[0]); } void Database::SetAgreementFlag(uint32 acctid) { @@ -1724,7 +1724,7 @@ uint32 Database::GetRaidID(const char* name) } if (row[0]) // would it ever be possible to have a null here? - return Strings::ToInt(row[0]); + return Strings::ToUnsignedInt(row[0]); return 0; } @@ -1980,16 +1980,16 @@ bool Database::GetAdventureStats(uint32 char_id, AdventureStats_Struct *as) auto row = results.begin(); - as->success.guk = Strings::ToInt(row[0]); - as->success.mir = Strings::ToInt(row[1]); - as->success.mmc = Strings::ToInt(row[2]); - as->success.ruj = Strings::ToInt(row[3]); - as->success.tak = Strings::ToInt(row[4]); - as->failure.guk = Strings::ToInt(row[5]); - as->failure.mir = Strings::ToInt(row[6]); - as->failure.mmc = Strings::ToInt(row[7]); - as->failure.ruj = Strings::ToInt(row[8]); - as->failure.tak = Strings::ToInt(row[9]); + as->success.guk = Strings::ToUnsignedInt(row[0]); + as->success.mir = Strings::ToUnsignedInt(row[1]); + as->success.mmc = Strings::ToUnsignedInt(row[2]); + as->success.ruj = Strings::ToUnsignedInt(row[3]); + as->success.tak = Strings::ToUnsignedInt(row[4]); + as->failure.guk = Strings::ToUnsignedInt(row[5]); + as->failure.mir = Strings::ToUnsignedInt(row[6]); + as->failure.mmc = Strings::ToUnsignedInt(row[7]); + as->failure.ruj = Strings::ToUnsignedInt(row[8]); + as->failure.tak = Strings::ToUnsignedInt(row[9]); as->failure.total = as->failure.guk + as->failure.mir + as->failure.mmc + as->failure.ruj + as->failure.tak; as->success.total = as->success.guk + as->success.mir + as->success.mmc + as->success.ruj + as->success.tak; @@ -2008,7 +2008,7 @@ uint32 Database::GetGuildIDByCharID(uint32 character_id) return 0; auto row = results.begin(); - return Strings::ToInt(row[0]); + return Strings::ToUnsignedInt(row[0]); } uint32 Database::GetGroupIDByCharID(uint32 character_id) @@ -2030,7 +2030,7 @@ uint32 Database::GetGroupIDByCharID(uint32 character_id) return 0; auto row = results.begin(); - return Strings::ToInt(row[0]); + return Strings::ToUnsignedInt(row[0]); } uint32 Database::GetRaidIDByCharID(uint32 character_id) { @@ -2044,7 +2044,7 @@ uint32 Database::GetRaidIDByCharID(uint32 character_id) { ); auto results = QueryDatabase(query); for (auto row = results.begin(); row != results.end(); ++row) { - return Strings::ToInt(row[0]); + return Strings::ToUnsignedInt(row[0]); } return 0; } @@ -2089,17 +2089,17 @@ struct TimeOfDay_Struct Database::LoadTime(time_t &realtime) eqTime.day = 1; eqTime.month = 1; eqTime.year = 3100; - realtime = time(0); + realtime = time(nullptr); } else{ auto row = results.begin(); - eqTime.minute = Strings::ToInt(row[0]); - eqTime.hour = Strings::ToInt(row[1]); - eqTime.day = Strings::ToInt(row[2]); - eqTime.month = Strings::ToInt(row[3]); - eqTime.year = Strings::ToInt(row[4]); - realtime = Strings::ToInt(row[5]); + eqTime.minute = Strings::ToUnsignedInt(row[0]); + eqTime.hour = Strings::ToUnsignedInt(row[1]); + eqTime.day = Strings::ToUnsignedInt(row[2]); + eqTime.month = Strings::ToUnsignedInt(row[3]); + eqTime.year = Strings::ToUnsignedInt(row[4]); + realtime = Strings::ToBigInt(row[5]); } return eqTime; diff --git a/common/database_conversions.cpp b/common/database_conversions.cpp index bcb987107..d78e43fff 100644 --- a/common/database_conversions.cpp +++ b/common/database_conversions.cpp @@ -937,11 +937,11 @@ bool Database::CheckDatabaseConvertPPDeblob(){ character_id = Strings::ToInt(row[0]); account_id = Strings::ToInt(row2[4]); /* Convert some data from the character_ table that is still relevant */ - firstlogon = Strings::ToInt(row2[5]); - lfg = Strings::ToInt(row2[6]); - lfp = Strings::ToInt(row2[7]); + firstlogon = Strings::ToUnsignedInt(row2[5]); + lfg = Strings::ToUnsignedInt(row2[6]); + lfp = Strings::ToUnsignedInt(row2[7]); mailkey = row2[8]; - xtargets = Strings::ToInt(row2[9]); + xtargets = Strings::ToUnsignedInt(row2[9]); inspectmessage = row2[10]; /* Verify PP Integrity */ @@ -1567,7 +1567,7 @@ bool Database::CheckDatabaseConvertCorpseDeblob(){ rquery = StringFormat("SELECT DISTINCT charid FROM character_corpses"); results = QueryDatabase(rquery); for (auto row = results.begin(); row != results.end(); ++row) { - std::string squery = StringFormat("SELECT id, charname, data, time_of_death, is_rezzed FROM character_corpses WHERE `charid` = %i", Strings::ToInt(row[0])); + std::string squery = StringFormat("SELECT id, charname, data, time_of_death, is_rezzed FROM character_corpses WHERE `charid` = %i", Strings::ToUnsignedInt(row[0])); auto results2 = QueryDatabase(squery); for (auto row2 = results2.begin(); row2 != results2.end(); ++row2) { in_datasize = results2.LengthOfColumn(2); @@ -1599,7 +1599,7 @@ bool Database::CheckDatabaseConvertCorpseDeblob(){ c_type = "NULL"; continue; } - std::cout << "Converting Corpse: [OK] [" << c_type << "]: " << "ID: " << Strings::ToInt(row2[0]) << std::endl; + std::cout << "Converting Corpse: [OK] [" << c_type << "]: " << "ID: " << Strings::ToUnsignedInt(row2[0]) << std::endl; if (is_sof){ scquery = StringFormat("UPDATE `character_corpses` SET \n" @@ -1670,7 +1670,7 @@ bool Database::CheckDatabaseConvertCorpseDeblob(){ dbpc->item_tint[6].color, dbpc->item_tint[7].color, dbpc->item_tint[8].color, - Strings::ToInt(row2[0]) + Strings::ToUnsignedInt(row2[0]) ); if (scquery != ""){ auto sc_results = QueryDatabase(scquery); } @@ -1682,7 +1682,7 @@ bool Database::CheckDatabaseConvertCorpseDeblob(){ scquery = StringFormat("REPLACE INTO `character_corpse_items` \n" " (corpse_id, equip_slot, item_id, charges, aug_1, aug_2, aug_3, aug_4, aug_5, aug_6, attuned) \n" " VALUES (%u, %u, %u, %u, %u, %u, %u, %u, %u, %u, %u) \n", - Strings::ToInt(row2[0]), + Strings::ToUnsignedInt(row2[0]), dbpc->items[i].equipSlot, dbpc->items[i].item_id, dbpc->items[i].charges, @@ -1698,7 +1698,7 @@ bool Database::CheckDatabaseConvertCorpseDeblob(){ } else{ scquery = scquery + StringFormat(", (%u, %u, %u, %u, %u, %u, %u, %u, %u, %u, %u) \n", - Strings::ToInt(row2[0]), + Strings::ToUnsignedInt(row2[0]), dbpc->items[i].equipSlot, dbpc->items[i].item_id, dbpc->items[i].charges, @@ -1778,7 +1778,7 @@ bool Database::CheckDatabaseConvertCorpseDeblob(){ dbpc_c->item_tint[6].color, dbpc_c->item_tint[7].color, dbpc_c->item_tint[8].color, - Strings::ToInt(row2[0]) + Strings::ToUnsignedInt(row2[0]) ); if (scquery != ""){ auto sc_results = QueryDatabase(scquery); } @@ -1791,7 +1791,7 @@ bool Database::CheckDatabaseConvertCorpseDeblob(){ scquery = StringFormat("REPLACE INTO `character_corpse_items` \n" " (corpse_id, equip_slot, item_id, charges, aug_1, aug_2, aug_3, aug_4, aug_5, aug_6, attuned) \n" " VALUES (%u, %u, %u, %u, %u, %u, %u, %u, %u, %u, %u) \n", - Strings::ToInt(row2[0]), + Strings::ToUnsignedInt(row2[0]), dbpc_c->items[i].equipSlot, dbpc_c->items[i].item_id, dbpc_c->items[i].charges, @@ -1807,7 +1807,7 @@ bool Database::CheckDatabaseConvertCorpseDeblob(){ } else{ scquery = scquery + StringFormat(", (%u, %u, %u, %u, %u, %u, %u, %u, %u, %u, %u) \n", - Strings::ToInt(row2[0]), + Strings::ToUnsignedInt(row2[0]), dbpc_c->items[i].equipSlot, dbpc_c->items[i].item_id, dbpc_c->items[i].charges, diff --git a/common/eqemu_config.cpp b/common/eqemu_config.cpp index b258be2e3..becae656e 100644 --- a/common/eqemu_config.cpp +++ b/common/eqemu_config.cpp @@ -40,7 +40,7 @@ void EQEmuConfig::parse_config() if (_root["server"]["world"]["loginserver"].isObject()) { LoginHost = _root["server"]["world"]["loginserver"].get("host", "login.eqemulator.net").asString(); - LoginPort = Strings::ToInt(_root["server"]["world"]["loginserver"].get("port", "5998").asString().c_str()); + LoginPort = Strings::ToUnsignedInt(_root["server"]["world"]["loginserver"].get("port", "5998").asString().c_str()); LoginLegacy = false; if (_root["server"]["world"]["loginserver"].get("legacy", "0").asString() == "1") { LoginLegacy = true; } LoginAccount = _root["server"]["world"]["loginserver"].get("account", "").asString(); @@ -63,7 +63,7 @@ void EQEmuConfig::parse_config() auto loginconfig = new LoginConfig; loginconfig->LoginHost = _root["server"]["world"][str].get("host", "login.eqemulator.net").asString(); - loginconfig->LoginPort = Strings::ToInt(_root["server"]["world"][str].get("port", "5998").asString().c_str()); + loginconfig->LoginPort = Strings::ToUnsignedInt(_root["server"]["world"][str].get("port", "5998").asString().c_str()); loginconfig->LoginAccount = _root["server"]["world"][str].get("account", "").asString(); loginconfig->LoginPassword = _root["server"]["world"][str].get("password", "").asString(); @@ -86,15 +86,15 @@ void EQEmuConfig::parse_config() Locked = false; if (_root["server"]["world"].get("locked", "false").asString() == "true") { Locked = true; } WorldIP = _root["server"]["world"]["tcp"].get("host", "127.0.0.1").asString(); - WorldTCPPort = Strings::ToInt(_root["server"]["world"]["tcp"].get("port", "9000").asString().c_str()); + WorldTCPPort = Strings::ToUnsignedInt(_root["server"]["world"]["tcp"].get("port", "9000").asString().c_str()); TelnetIP = _root["server"]["world"]["telnet"].get("ip", "127.0.0.1").asString(); - TelnetTCPPort = Strings::ToInt(_root["server"]["world"]["telnet"].get("port", "9001").asString().c_str()); + TelnetTCPPort = Strings::ToUnsignedInt(_root["server"]["world"]["telnet"].get("port", "9001").asString().c_str()); TelnetEnabled = false; if (_root["server"]["world"]["telnet"].get("enabled", "false").asString() == "true") { TelnetEnabled = true; } WorldHTTPMimeFile = _root["server"]["world"]["http"].get("mimefile", "mime.types").asString(); - WorldHTTPPort = Strings::ToInt(_root["server"]["world"]["http"].get("port", "9080").asString().c_str()); + WorldHTTPPort = Strings::ToUnsignedInt(_root["server"]["world"]["http"].get("port", "9080").asString().c_str()); WorldHTTPEnabled = false; if (_root["server"]["world"]["http"].get("enabled", "false").asString() == "true") { @@ -109,9 +109,9 @@ void EQEmuConfig::parse_config() * UCS */ ChatHost = _root["server"]["chatserver"].get("host", "eqchat.eqemulator.net").asString(); - ChatPort = Strings::ToInt(_root["server"]["chatserver"].get("port", "7778").asString().c_str()); + ChatPort = Strings::ToUnsignedInt(_root["server"]["chatserver"].get("port", "7778").asString().c_str()); MailHost = _root["server"]["mailserver"].get("host", "eqmail.eqemulator.net").asString(); - MailPort = Strings::ToInt(_root["server"]["mailserver"].get("port", "7778").asString().c_str()); + MailPort = Strings::ToUnsignedInt(_root["server"]["mailserver"].get("port", "7778").asString().c_str()); /** * Database @@ -119,7 +119,7 @@ void EQEmuConfig::parse_config() DatabaseUsername = _root["server"]["database"].get("username", "eq").asString(); DatabasePassword = _root["server"]["database"].get("password", "eq").asString(); DatabaseHost = _root["server"]["database"].get("host", "localhost").asString(); - DatabasePort = Strings::ToInt(_root["server"]["database"].get("port", "3306").asString().c_str()); + DatabasePort = Strings::ToUnsignedInt(_root["server"]["database"].get("port", "3306").asString().c_str()); DatabaseDB = _root["server"]["database"].get("db", "eq").asString(); /** @@ -128,14 +128,14 @@ void EQEmuConfig::parse_config() ContentDbUsername = _root["server"]["content_database"].get("username", "").asString(); ContentDbPassword = _root["server"]["content_database"].get("password", "").asString(); ContentDbHost = _root["server"]["content_database"].get("host", "").asString(); - ContentDbPort = Strings::ToInt(_root["server"]["content_database"].get("port", 0).asString().c_str()); + ContentDbPort = Strings::ToUnsignedInt(_root["server"]["content_database"].get("port", 0).asString().c_str()); ContentDbName = _root["server"]["content_database"].get("db", "").asString(); /** * QS */ QSDatabaseHost = _root["server"]["qsdatabase"].get("host", "localhost").asString(); - QSDatabasePort = Strings::ToInt(_root["server"]["qsdatabase"].get("port", "3306").asString().c_str()); + QSDatabasePort = Strings::ToUnsignedInt(_root["server"]["qsdatabase"].get("port", "3306").asString().c_str()); QSDatabaseUsername = _root["server"]["qsdatabase"].get("username", "eq").asString(); QSDatabasePassword = _root["server"]["qsdatabase"].get("password", "eq").asString(); QSDatabaseDB = _root["server"]["qsdatabase"].get("db", "eq").asString(); @@ -143,9 +143,9 @@ void EQEmuConfig::parse_config() /** * Zones */ - DefaultStatus = Strings::ToInt(_root["server"]["zones"].get("defaultstatus", 0).asString().c_str()); - ZonePortLow = Strings::ToInt(_root["server"]["zones"]["ports"].get("low", "7000").asString().c_str()); - ZonePortHigh = Strings::ToInt(_root["server"]["zones"]["ports"].get("high", "7999").asString().c_str()); + DefaultStatus = Strings::ToUnsignedInt(_root["server"]["zones"].get("defaultstatus", 0).asString().c_str()); + ZonePortLow = Strings::ToUnsignedInt(_root["server"]["zones"]["ports"].get("low", "7000").asString().c_str()); + ZonePortHigh = Strings::ToUnsignedInt(_root["server"]["zones"]["ports"].get("high", "7999").asString().c_str()); /** * Files diff --git a/common/guild_base.cpp b/common/guild_base.cpp index 911f28651..1278d48ac 100644 --- a/common/guild_base.cpp +++ b/common/guild_base.cpp @@ -61,7 +61,7 @@ bool BaseGuildManager::LoadGuilds() { } for (auto row=results.begin();row!=results.end();++row) - _CreateGuild(Strings::ToInt(row[0]), row[1], Strings::ToInt(row[2]), Strings::ToInt(row[3]), row[4], row[5], row[6], row[7]); + _CreateGuild(Strings::ToUnsignedInt(row[0]), row[1], Strings::ToUnsignedInt(row[2]), Strings::ToUnsignedInt(row[3]), row[4], row[5], row[6], row[7]); LogInfo("Loaded [{}] Guilds", Strings::Commify(std::to_string(results.RowCount()))); @@ -75,8 +75,8 @@ bool BaseGuildManager::LoadGuilds() { for (auto row=results.begin();row!=results.end();++row) { - uint32 guild_id = Strings::ToInt(row[0]); - uint8 rankn = Strings::ToInt(row[1]); + uint32 guild_id = Strings::ToUnsignedInt(row[0]); + uint8 rankn = Strings::ToUnsignedInt(row[1]); if(rankn > GUILD_MAX_RANK) { LogGuilds("Found invalid (too high) rank [{}] for guild [{}], skipping", rankn, guild_id); @@ -131,7 +131,7 @@ bool BaseGuildManager::RefreshGuild(uint32 guild_id) { auto row = results.begin(); - info = _CreateGuild(guild_id, row[0], Strings::ToInt(row[1]), Strings::ToInt(row[2]), row[3], row[4], row[5], row[6]); + info = _CreateGuild(guild_id, row[0], Strings::ToUnsignedInt(row[1]), Strings::ToUnsignedInt(row[2]), row[3], row[4], row[5], row[6]); query = StringFormat("SELECT guild_id, `rank`, title, can_hear, can_speak, can_invite, can_remove, can_promote, can_demote, can_motd, can_warpeace " "FROM guild_ranks WHERE guild_id=%lu", (unsigned long)guild_id); @@ -144,7 +144,7 @@ bool BaseGuildManager::RefreshGuild(uint32 guild_id) { for (auto row=results.begin();row!=results.end();++row) { - uint8 rankn = Strings::ToInt(row[1]); + uint8 rankn = Strings::ToUnsignedInt(row[1]); if(rankn > GUILD_MAX_RANK) { LogGuilds("Found invalid (too high) rank [{}] for guild [{}], skipping", rankn, guild_id); @@ -787,9 +787,7 @@ bool BaseGuildManager::GetBankerFlag(uint32 CharID) auto row = results.begin(); - bool IsBanker = Strings::ToInt(row[0]); - - return IsBanker; + return Strings::ToBool(row[0]); } bool BaseGuildManager::DBSetAltFlag(uint32 charid, bool is_alt) @@ -817,9 +815,7 @@ bool BaseGuildManager::GetAltFlag(uint32 CharID) auto row = results.begin(); - bool IsAlt = Strings::ToInt(row[0]); - - return IsAlt; + return Strings::ToBool(row[0]); } bool BaseGuildManager::DBSetTributeFlag(uint32 charid, bool enabled) { @@ -873,18 +869,18 @@ bool BaseGuildManager::QueryWithLogging(std::string query, const char *errmsg) { " FROM `character_data` AS c LEFT JOIN `guild_members` AS g ON c.`id` = g.`char_id` " static void ProcessGuildMember(MySQLRequestRow row, CharGuildInfo &into) { //fields from `characer_` - into.char_id = Strings::ToInt(row[0]); + into.char_id = Strings::ToUnsignedInt(row[0]); into.char_name = row[1]; - into.class_ = Strings::ToInt(row[2]); - into.level = Strings::ToInt(row[3]); + into.class_ = Strings::ToUnsignedInt(row[2]); + into.level = Strings::ToUnsignedInt(row[3]); into.time_last_on = Strings::ToUnsignedInt(row[4]); - into.zone_id = Strings::ToInt(row[5]); + into.zone_id = Strings::ToUnsignedInt(row[5]); //fields from `guild_members`, leave at defaults if missing - into.guild_id = row[6] ? Strings::ToInt(row[6]) : GUILD_NONE; - into.rank = row[7] ? Strings::ToInt(row[7]) : (GUILD_MAX_RANK+1); + into.guild_id = row[6] ? Strings::ToUnsignedInt(row[6]) : GUILD_NONE; + into.rank = row[7] ? Strings::ToUnsignedInt(row[7]) : (GUILD_MAX_RANK+1); into.tribute_enable = row[8] ? (row[8][0] == '0'?false:true) : false; - into.total_tribute = row[9] ? Strings::ToInt(row[9]) : 0; + into.total_tribute = row[9] ? Strings::ToUnsignedInt(row[9]) : 0; into.last_tribute = row[10]? Strings::ToUnsignedInt(row[10]) : 0; //timestamp into.banker = row[11]? (row[11][0] == '0'?false:true) : false; into.public_note = row[12]? row[12] : ""; diff --git a/common/item_instance.cpp b/common/item_instance.cpp index 319e37ad2..eb025ee98 100644 --- a/common/item_instance.cpp +++ b/common/item_instance.cpp @@ -610,7 +610,7 @@ bool EQ::ItemInstance::UpdateOrnamentationInfo() { SetOrnamentHeroModel(ornamentItem->HerosForgeModel); if (strlen(ornamentItem->IDFile) > 2) { - SetOrnamentationIDFile(Strings::ToInt(&ornamentItem->IDFile[2])); + SetOrnamentationIDFile(Strings::ToUnsignedInt(&ornamentItem->IDFile[2])); } else { diff --git a/common/misc.cpp b/common/misc.cpp index 61f21a589..83f5e7827 100644 --- a/common/misc.cpp +++ b/common/misc.cpp @@ -151,7 +151,7 @@ static char *temp=nullptr; return false; } ptr++; - uint32 id = Strings::ToInt(field[id_pos].c_str()); + uint32 id = Strings::ToUnsignedInt(field[id_pos].c_str()); items[id]=field; for(i=0;i<10;i++) { diff --git a/common/misc_functions.cpp b/common/misc_functions.cpp index 5c1584193..dfa034944 100644 --- a/common/misc_functions.cpp +++ b/common/misc_functions.cpp @@ -131,7 +131,7 @@ bool ParseAddress(const char* iAddress, uint32* oIP, uint16* oPort, char* errbuf if (*oIP == 0) return false; if (oPort) - *oPort = Strings::ToInt(sep.arg[1]); + *oPort = Strings::ToUnsignedInt(sep.arg[1]); return true; } return false; diff --git a/common/ptimer.cpp b/common/ptimer.cpp index 437f82f86..d5f6ca162 100644 --- a/common/ptimer.cpp +++ b/common/ptimer.cpp @@ -288,9 +288,9 @@ bool PTimerList::Load(Database *db) { PersistentTimer *cur; for (auto row = results.begin(); row != results.end(); ++row) { - type = Strings::ToInt(row[0]); - start_time = strtoul(row[1], nullptr, 10); - timer_time = strtoul(row[2], nullptr, 10); + type = Strings::ToUnsignedInt(row[0]); + start_time = Strings::ToUnsignedInt(row[1]); + timer_time = Strings::ToUnsignedInt(row[2]); enabled = (row[3][0] == '1'); //if it expired allready, dont bother. diff --git a/common/shareddb.cpp b/common/shareddb.cpp index 755978287..08c82fb1e 100644 --- a/common/shareddb.cpp +++ b/common/shareddb.cpp @@ -126,7 +126,7 @@ uint32 SharedDatabase::GetTotalTimeEntitledOnAccount(uint32 AccountID) { const std::string query = StringFormat("SELECT `time_played` FROM `character_data` WHERE `account_id` = %u", AccountID); auto results = QueryDatabase(query); for (auto& row = results.begin(); row != results.end(); ++row) { - EntitledTime += Strings::ToInt(row[0]); + EntitledTime += Strings::ToUnsignedInt(row[0]); } return EntitledTime; } @@ -228,8 +228,8 @@ bool SharedDatabase::VerifyInventory(uint32 account_id, int16 slot_id, const EQ: auto& row = results.begin(); - const uint32 id = Strings::ToInt(row[0]); - const uint16 charges = Strings::ToInt(row[1]); + const uint32 id = Strings::ToUnsignedInt(row[0]); + const uint16 charges = Strings::ToUnsignedInt(row[1]); uint16 expect_charges; @@ -519,16 +519,16 @@ bool SharedDatabase::GetSharedBank(uint32 id, EQ::InventoryProfile *inv, bool is for (auto& row = results.begin(); row != results.end(); ++row) { int16 slot_id = static_cast(Strings::ToInt(row[0])); - uint32 item_id = static_cast(Strings::ToInt(row[1])); + uint32 item_id = Strings::ToUnsignedInt(row[1]); const int16 charges = static_cast(Strings::ToInt(row[2])); uint32 aug[EQ::invaug::SOCKET_COUNT]; - aug[0] = static_cast(Strings::ToInt(row[3])); - aug[1] = static_cast(Strings::ToInt(row[4])); - aug[2] = static_cast(Strings::ToInt(row[5])); - aug[3] = static_cast(Strings::ToInt(row[6])); - aug[4] = static_cast(Strings::ToInt(row[7])); - aug[5] = static_cast(Strings::ToInt(row[8])); + aug[0] = Strings::ToUnsignedInt(row[3]); + aug[1] = Strings::ToUnsignedInt(row[4]); + aug[2] = Strings::ToUnsignedInt(row[5]); + aug[3] = Strings::ToUnsignedInt(row[6]); + aug[4] = Strings::ToUnsignedInt(row[7]); + aug[5] = Strings::ToUnsignedInt(row[8]); const EQ::ItemData *item = GetItem(item_id); @@ -645,8 +645,8 @@ bool SharedDatabase::GetInventory(uint32 char_id, EQ::InventoryProfile *inv) } } - uint32 item_id = Strings::ToInt(row[1]); - const uint16 charges = Strings::ToInt(row[2]); + uint32 item_id = Strings::ToUnsignedInt(row[1]); + const uint16 charges = Strings::ToUnsignedInt(row[2]); const uint32 color = Strings::ToUnsignedInt(row[3]); uint32 aug[EQ::invaug::SOCKET_COUNT]; @@ -658,7 +658,7 @@ bool SharedDatabase::GetInventory(uint32 char_id, EQ::InventoryProfile *inv) aug[4] = Strings::ToUnsignedInt(row[8]); aug[5] = Strings::ToUnsignedInt(row[9]); - const bool instnodrop = (row[10] && static_cast(Strings::ToInt(row[10]))) ? true : false; + const bool instnodrop = (row[10] && static_cast(Strings::ToUnsignedInt(row[10]))); const uint32 ornament_icon = Strings::ToUnsignedInt(row[12]); const uint32 ornament_idfile = Strings::ToUnsignedInt(row[13]); @@ -795,19 +795,19 @@ bool SharedDatabase::GetInventory(uint32 account_id, char *name, EQ::InventoryPr for (auto& row = results.begin(); row != results.end(); ++row) { int16 slot_id = Strings::ToInt(row[0]); - uint32 item_id = Strings::ToInt(row[1]); + uint32 item_id = Strings::ToUnsignedInt(row[1]); const int8 charges = Strings::ToInt(row[2]); const uint32 color = Strings::ToUnsignedInt(row[3]); uint32 aug[EQ::invaug::SOCKET_COUNT]; - aug[0] = static_cast(Strings::ToInt(row[4])); - aug[1] = static_cast(Strings::ToInt(row[5])); - aug[2] = static_cast(Strings::ToInt(row[6])); - aug[3] = static_cast(Strings::ToInt(row[7])); - aug[4] = static_cast(Strings::ToInt(row[8])); - aug[5] = static_cast(Strings::ToInt(row[9])); + aug[0] = Strings::ToUnsignedInt(row[4]); + aug[1] = Strings::ToUnsignedInt(row[5]); + aug[2] = Strings::ToUnsignedInt(row[6]); + aug[3] = Strings::ToUnsignedInt(row[7]); + aug[4] = Strings::ToUnsignedInt(row[8]); + aug[5] = Strings::ToUnsignedInt(row[9]); - const bool instnodrop = (row[10] && static_cast(Strings::ToInt(row[10]))) ? true : false; + const bool instnodrop = (row[10] && static_cast(Strings::ToUnsignedInt(row[10]))); const uint32 ornament_icon = Strings::ToUnsignedInt(row[12]); const uint32 ornament_idfile = Strings::ToUnsignedInt(row[13]); uint32 ornament_hero_model = Strings::ToUnsignedInt(row[14]); @@ -905,7 +905,7 @@ uint32 SharedDatabase::GetItemRecastTimestamp(uint32 char_id, uint32 recast_type return 0; auto& row = results.begin(); - return static_cast(Strings::ToUnsignedInt(row[0])); + return Strings::ToUnsignedInt(row[0]); } void SharedDatabase::ClearOldRecastTimestamps(uint32 char_id) @@ -933,10 +933,10 @@ void SharedDatabase::GetItemsCount(int32 &item_count, uint32 &max_id) auto& row = results.begin(); if (row[0]) - max_id = Strings::ToInt(row[0]); + max_id = Strings::ToUnsignedInt(row[0]); if (row[1]) - item_count = Strings::ToInt(row[1]); + item_count = Strings::ToUnsignedInt(row[1]); } bool SharedDatabase::LoadItems(const std::string &prefix) { @@ -1025,24 +1025,24 @@ void SharedDatabase::LoadItems(void *data, uint32 size, int32 items, uint32 max_ strn0cpy(item.Lore, row[ItemField::lore], sizeof(item.Lore)); // Flags - item.ArtifactFlag = Strings::ToInt(row[ItemField::artifactflag]) ? true : false; - item.Attuneable = disable_attuneable ? false : Strings::ToInt(row[ItemField::attuneable]) ? true : false; - item.BenefitFlag = Strings::ToInt(row[ItemField::benefitflag]) ? true : false; - item.FVNoDrop = Strings::ToInt(row[ItemField::fvnodrop]) ? true : false; - item.Magic = Strings::ToInt(row[ItemField::magic]) ? true : false; + item.ArtifactFlag = Strings::ToBool(row[ItemField::artifactflag]); + item.Attuneable = !disable_attuneable && Strings::ToInt(row[ItemField::attuneable]) != 0; + item.BenefitFlag = Strings::ToBool(row[ItemField::benefitflag]) != 0; + item.FVNoDrop = Strings::ToInt(row[ItemField::fvnodrop]) != 0; + item.Magic = Strings::ToBool(row[ItemField::magic]) != 0; item.NoDrop = disable_no_drop ? static_cast(255) : static_cast(Strings::ToUnsignedInt(row[ItemField::nodrop])); - item.NoPet = disable_no_pet ? false : Strings::ToInt(row[ItemField::nopet]) ? true : false; + item.NoPet = !disable_no_pet && Strings::ToBool(row[ItemField::nopet]); item.NoRent = disable_no_rent ? static_cast(255) : static_cast(Strings::ToUnsignedInt(row[ItemField::norent])); - item.NoTransfer = disable_no_transfer ? false : Strings::ToInt(row[ItemField::notransfer]) ? true : false; - item.PendingLoreFlag = Strings::ToInt(row[ItemField::pendingloreflag]) ? true : false; - item.QuestItemFlag = Strings::ToInt(row[ItemField::questitemflag]) ? true : false; - item.Stackable = Strings::ToInt(row[ItemField::stackable]) ? true : false; - item.Tradeskills = Strings::ToInt(row[ItemField::tradeskills]) ? true : false; - item.SummonedFlag = Strings::ToInt(row[ItemField::summonedflag]) ? true : false; + item.NoTransfer = !disable_no_transfer && Strings::ToBool(row[ItemField::notransfer]); + item.PendingLoreFlag = Strings::ToBool(row[ItemField::pendingloreflag]); + item.QuestItemFlag = Strings::ToBool(row[ItemField::questitemflag]); + item.Stackable = Strings::ToBool(row[ItemField::stackable]); + item.Tradeskills = Strings::ToBool(row[ItemField::tradeskills]); + item.SummonedFlag = Strings::ToBool(row[ItemField::summonedflag]); // Lore item.LoreGroup = disable_lore ? 0 : Strings::ToInt(row[ItemField::loregroup]); - item.LoreFlag = disable_lore ? false : item.LoreGroup != 0; + item.LoreFlag = !disable_lore && item.LoreGroup != 0; // Type item.AugType = Strings::ToUnsignedInt(row[ItemField::augtype]); @@ -1058,7 +1058,7 @@ void SharedDatabase::LoadItems(void *data, uint32 size, int32 items, uint32 max_ item.Weight = Strings::ToInt(row[ItemField::weight]); // Potion Belt - item.PotionBelt = disable_potion_belt ? false : Strings::ToInt(row[ItemField::potionbelt]) ? true : false; + item.PotionBelt = !disable_potion_belt && Strings::ToBool(row[ItemField::potionbelt]); item.PotionBeltSlots = disable_potion_belt ? 0 : static_cast(Strings::ToUnsignedInt(row[ItemField::potionbeltslots])); // Merchant @@ -1369,8 +1369,8 @@ void SharedDatabase::GetFactionListInfo(uint32 &list_count, uint32 &max_lists) { auto& row = results.begin(); - list_count = static_cast(Strings::ToUnsignedInt(row[0])); - max_lists = static_cast(Strings::ToUnsignedInt(row[1] ? row[1] : "0")); + list_count = Strings::ToUnsignedInt(row[0]); + max_lists = Strings::ToUnsignedInt(row[1] ? row[1] : "0"); } const NPCFactionList* SharedDatabase::GetNPCFactionEntry(uint32 id) const @@ -1403,7 +1403,7 @@ void SharedDatabase::LoadNPCFactionLists(void *data, uint32 size, uint32 list_co uint32 current_entry = 0; for(auto& row = results.begin(); row != results.end(); ++row) { - const uint32 id = static_cast(Strings::ToUnsignedInt(row[0])); + const uint32 id = Strings::ToUnsignedInt(row[0]); if(id != current_id) { if(current_id != 0) { hash.insert(current_id, faction); @@ -1413,7 +1413,7 @@ void SharedDatabase::LoadNPCFactionLists(void *data, uint32 size, uint32 list_co current_entry = 0; current_id = id; faction.id = id; - faction.primaryfaction = static_cast(Strings::ToUnsignedInt(row[1])); + faction.primaryfaction = Strings::ToUnsignedInt(row[1]); faction.assistprimaryfaction = (Strings::ToInt(row[2]) == 0); } @@ -1423,10 +1423,10 @@ void SharedDatabase::LoadNPCFactionLists(void *data, uint32 size, uint32 list_co if(current_entry >= MAX_NPC_FACTIONS) continue; - faction.factionid[current_entry] = static_cast(Strings::ToUnsignedInt(row[3])); - faction.factionvalue[current_entry] = static_cast(Strings::ToInt(row[4])); + faction.factionid[current_entry] = Strings::ToUnsignedInt(row[3]); + faction.factionvalue[current_entry] = Strings::ToInt(row[4]); faction.factionnpcvalue[current_entry] = static_cast(Strings::ToInt(row[5])); - faction.factiontemp[current_entry] = static_cast(Strings::ToInt(row[6])); + faction.factiontemp[current_entry] = static_cast(Strings::ToUnsignedInt(row[6])); ++current_entry; } @@ -1664,7 +1664,7 @@ bool SharedDatabase::GetCommandSettings(std::map= skill_count || class_ >= class_count || level >= level_count) continue; @@ -1866,7 +1866,7 @@ void SharedDatabase::LoadDamageShieldTypes(SPDat_Spell_Struct* sp, int32 iMaxSpe for(auto& row = results.begin(); row != results.end(); ++row) { const int spellID = Strings::ToInt(row[0]); if((spellID > 0) && (spellID <= iMaxSpellID)) - sp[spellID].damage_shield_type = Strings::ToInt(row[1]); + sp[spellID].damage_shield_type = Strings::ToUnsignedInt(row[1]); } } @@ -1947,16 +1947,16 @@ void SharedDatabase::LoadSpells(void *data, int max_spells) { strn0cpy(sp[tempid].cast_on_other, row[7], sizeof(sp[tempid].cast_on_other)); strn0cpy(sp[tempid].spell_fades, row[8], sizeof(sp[tempid].spell_fades)); - sp[tempid].range=static_cast(Strings::ToFloat(row[9])); - sp[tempid].aoe_range=static_cast(Strings::ToFloat(row[10])); - sp[tempid].push_back=static_cast(Strings::ToFloat(row[11])); - sp[tempid].push_up=static_cast(Strings::ToFloat(row[12])); - sp[tempid].cast_time=Strings::ToInt(row[13]); - sp[tempid].recovery_time=Strings::ToInt(row[14]); - sp[tempid].recast_time=Strings::ToInt(row[15]); - sp[tempid].buff_duration_formula=Strings::ToInt(row[16]); - sp[tempid].buff_duration=Strings::ToInt(row[17]); - sp[tempid].aoe_duration=Strings::ToInt(row[18]); + sp[tempid].range = Strings::ToFloat(row[9]); + sp[tempid].aoe_range = Strings::ToFloat(row[10]); + sp[tempid].push_back = Strings::ToFloat(row[11]); + sp[tempid].push_up = Strings::ToFloat(row[12]); + sp[tempid].cast_time=Strings::ToUnsignedInt(row[13]); + sp[tempid].recovery_time=Strings::ToUnsignedInt(row[14]); + sp[tempid].recast_time=Strings::ToUnsignedInt(row[15]); + sp[tempid].buff_duration_formula=Strings::ToUnsignedInt(row[16]); + sp[tempid].buff_duration=Strings::ToUnsignedInt(row[17]); + sp[tempid].aoe_duration=Strings::ToUnsignedInt(row[18]); sp[tempid].mana=Strings::ToInt(row[19]); int y=0; @@ -1979,7 +1979,7 @@ void SharedDatabase::LoadSpells(void *data, int max_spells) { sp[tempid].no_expend_reagent[y]=Strings::ToInt(row[66+y]); for(y=0; y< EFFECT_COUNT;y++) - sp[tempid].formula[y]=Strings::ToInt(row[70+y]); + sp[tempid].formula[y]=Strings::ToUnsignedInt(row[70+y]); sp[tempid].good_effect=Strings::ToInt(row[83]); sp[tempid].activated=Strings::ToInt(row[84]); @@ -2014,51 +2014,51 @@ void SharedDatabase::LoadSpells(void *data, int max_spells) { sp[tempid].deities[y]=Strings::ToInt(row[126+y]); sp[tempid].new_icon=Strings::ToInt(row[144]); - sp[tempid].uninterruptable=Strings::ToInt(row[146]) != 0; + sp[tempid].uninterruptable=Strings::ToBool(row[146]); sp[tempid].resist_difficulty=Strings::ToInt(row[147]); - sp[tempid].unstackable_dot = Strings::ToInt(row[148]) != 0; - sp[tempid].recourse_link = Strings::ToInt(row[150]); - sp[tempid].no_partial_resist = Strings::ToInt(row[151]) != 0; + sp[tempid].unstackable_dot = Strings::ToBool(row[148]); + sp[tempid].recourse_link = Strings::ToUnsignedInt(row[150]); + sp[tempid].no_partial_resist = Strings::ToBool(row[151]); sp[tempid].short_buff_box = Strings::ToInt(row[154]); sp[tempid].description_id = Strings::ToInt(row[155]); sp[tempid].type_description_id = Strings::ToInt(row[156]); sp[tempid].effect_description_id = Strings::ToInt(row[157]); - sp[tempid].npc_no_los = Strings::ToInt(row[159]) != 0; - sp[tempid].feedbackable = Strings::ToInt(row[160]) != 0; - sp[tempid].reflectable = Strings::ToInt(row[161]) != 0; + sp[tempid].npc_no_los = Strings::ToBool(row[159]); + sp[tempid].feedbackable = Strings::ToBool(row[160]); + sp[tempid].reflectable = Strings::ToBool(row[161]); sp[tempid].bonus_hate=Strings::ToInt(row[162]); - sp[tempid].ldon_trap = Strings::ToInt(row[165]) != 0; - sp[tempid].endurance_cost=Strings::ToInt(row[166]); - sp[tempid].timer_id=Strings::ToInt(row[167]); - sp[tempid].is_discipline = Strings::ToInt(row[168]) != 0; - sp[tempid].hate_added=Strings::ToInt(row[173]); + sp[tempid].ldon_trap = Strings::ToBool(row[165]); + sp[tempid].endurance_cost= Strings::ToInt(row[166]); + sp[tempid].timer_id= Strings::ToInt(row[167]); + sp[tempid].is_discipline = Strings::ToBool(row[168]); + sp[tempid].hate_added= Strings::ToInt(row[173]); sp[tempid].endurance_upkeep=Strings::ToInt(row[174]); sp[tempid].hit_number_type = Strings::ToInt(row[175]); sp[tempid].hit_number = Strings::ToInt(row[176]); - sp[tempid].pvp_resist_base=Strings::ToInt(row[177]); - sp[tempid].pvp_resist_per_level=Strings::ToInt(row[178]); - sp[tempid].pvp_resist_cap=Strings::ToInt(row[179]); - sp[tempid].spell_category=Strings::ToInt(row[180]); + sp[tempid].pvp_resist_base= Strings::ToInt(row[177]); + sp[tempid].pvp_resist_per_level= Strings::ToInt(row[178]); + sp[tempid].pvp_resist_cap= Strings::ToInt(row[179]); + sp[tempid].spell_category= Strings::ToInt(row[180]); sp[tempid].pvp_duration = Strings::ToInt(row[181]); sp[tempid].pvp_duration_cap = Strings::ToInt(row[182]); - sp[tempid].pcnpc_only_flag=Strings::ToInt(row[183]); + sp[tempid].pcnpc_only_flag= Strings::ToInt(row[183]); sp[tempid].cast_not_standing = Strings::ToInt(row[184]) != 0; - sp[tempid].can_mgb=Strings::ToInt(row[185]); + sp[tempid].can_mgb= Strings::ToBool(row[185]); sp[tempid].dispel_flag = Strings::ToInt(row[186]); sp[tempid].min_resist = Strings::ToInt(row[189]); sp[tempid].max_resist = Strings::ToInt(row[190]); sp[tempid].viral_targets = Strings::ToInt(row[191]); sp[tempid].viral_timer = Strings::ToInt(row[192]); sp[tempid].nimbus_effect = Strings::ToInt(row[193]); - sp[tempid].directional_start = static_cast(Strings::ToInt(row[194])); - sp[tempid].directional_end = static_cast(Strings::ToInt(row[195])); - sp[tempid].sneak = Strings::ToInt(row[196]) != 0; - sp[tempid].not_focusable = Strings::ToInt(row[197]) != 0; - sp[tempid].no_detrimental_spell_aggro = Strings::ToInt(row[198]) != 0; - sp[tempid].suspendable = Strings::ToInt(row[200]) != 0; + sp[tempid].directional_start = Strings::ToFloat(row[194]); + sp[tempid].directional_end = Strings::ToFloat(row[195]); + sp[tempid].sneak = Strings::ToBool(row[196]); + sp[tempid].not_focusable = Strings::ToBool(row[197]); + sp[tempid].no_detrimental_spell_aggro = Strings::ToBool(row[198]); + sp[tempid].suspendable = Strings::ToBool(row[200]); sp[tempid].viral_range = Strings::ToInt(row[201]); sp[tempid].song_cap = Strings::ToInt(row[202]); sp[tempid].no_block = Strings::ToInt(row[205]); @@ -2066,22 +2066,22 @@ void SharedDatabase::LoadSpells(void *data, int max_spells) { sp[tempid].rank = Strings::ToInt(row[208]); sp[tempid].no_resist=Strings::ToInt(row[209]); sp[tempid].cast_restriction = Strings::ToInt(row[211]); - sp[tempid].allow_rest = Strings::ToInt(row[212]) != 0; - sp[tempid].can_cast_in_combat = Strings::ToInt(row[213]) != 0; - sp[tempid].can_cast_out_of_combat = Strings::ToInt(row[214]) != 0; + sp[tempid].allow_rest = Strings::ToBool(row[212]); + sp[tempid].can_cast_in_combat = Strings::ToBool(row[213]); + sp[tempid].can_cast_out_of_combat = Strings::ToBool(row[214]); sp[tempid].override_crit_chance = Strings::ToInt(row[217]); sp[tempid].aoe_max_targets = Strings::ToInt(row[218]); sp[tempid].no_heal_damage_item_mod = Strings::ToInt(row[219]); sp[tempid].caster_requirement_id = Strings::ToInt(row[220]); sp[tempid].spell_class = Strings::ToInt(row[221]); sp[tempid].spell_subclass = Strings::ToInt(row[222]); - sp[tempid].persist_death = Strings::ToInt(row[224]) != 0; - sp[tempid].min_distance = static_cast(Strings::ToFloat(row[227])); - sp[tempid].min_distance_mod = static_cast(Strings::ToFloat(row[228])); - sp[tempid].max_distance = static_cast(Strings::ToFloat(row[229])); - sp[tempid].max_distance_mod = static_cast(Strings::ToFloat(row[230])); - sp[tempid].min_range = static_cast(Strings::ToInt(row[231])); - sp[tempid].no_remove = Strings::ToInt(row[232]) != 0; + sp[tempid].persist_death = Strings::ToBool(row[224]); + sp[tempid].min_distance = Strings::ToFloat(row[227]); + sp[tempid].min_distance_mod = Strings::ToFloat(row[228]); + sp[tempid].max_distance = Strings::ToFloat(row[229]); + sp[tempid].max_distance_mod = Strings::ToFloat(row[230]); + sp[tempid].min_range = Strings::ToFloat(row[231]); + sp[tempid].no_remove = Strings::ToBool(row[232]); sp[tempid].damage_shield_type = 0; } @@ -2218,9 +2218,9 @@ void SharedDatabase::GetLootTableInfo(uint32 &loot_table_count, uint32 &max_loot auto& row = results.begin(); - loot_table_count = static_cast(Strings::ToUnsignedInt(row[0])); - max_loot_table = static_cast(Strings::ToUnsignedInt(row[1] ? row[1] : "0")); - loot_table_entries = static_cast(Strings::ToUnsignedInt(row[2])); + loot_table_count = Strings::ToUnsignedInt(row[0]); + max_loot_table = Strings::ToUnsignedInt(row[1] ? row[1] : "0"); + loot_table_entries = Strings::ToUnsignedInt(row[2]); } void SharedDatabase::GetLootDropInfo(uint32 &loot_drop_count, uint32 &max_loot_drop, uint32 &loot_drop_entries) { @@ -2243,9 +2243,9 @@ void SharedDatabase::GetLootDropInfo(uint32 &loot_drop_count, uint32 &max_loot_d auto& row =results.begin(); - loot_drop_count = static_cast(Strings::ToUnsignedInt(row[0])); - max_loot_drop = static_cast(Strings::ToUnsignedInt(row[1] ? row[1] : "0")); - loot_drop_entries = static_cast(Strings::ToUnsignedInt(row[2])); + loot_drop_count = Strings::ToUnsignedInt(row[0]); + max_loot_drop = Strings::ToUnsignedInt(row[1] ? row[1] : "0"); + loot_drop_entries = Strings::ToUnsignedInt(row[2]); } void SharedDatabase::LoadLootTables(void *data, uint32 size) { @@ -2289,7 +2289,7 @@ void SharedDatabase::LoadLootTables(void *data, uint32 size) { uint32 current_entry = 0; for (auto& row = results.begin(); row != results.end(); ++row) { - const uint32 id = static_cast(Strings::ToUnsignedInt(row[0])); + const uint32 id = Strings::ToUnsignedInt(row[0]); if (id != current_id) { if (current_id != 0) { hash.insert( @@ -2301,9 +2301,9 @@ void SharedDatabase::LoadLootTables(void *data, uint32 size) { memset(loot_table, 0, sizeof(LootTable_Struct) + (sizeof(LootTableEntries_Struct) * 128)); current_entry = 0; current_id = id; - lt->mincash = static_cast(Strings::ToUnsignedInt(row[1])); - lt->maxcash = static_cast(Strings::ToUnsignedInt(row[2])); - lt->avgcoin = static_cast(Strings::ToUnsignedInt(row[3])); + lt->mincash = Strings::ToUnsignedInt(row[1]); + lt->maxcash = Strings::ToUnsignedInt(row[2]); + lt->avgcoin = Strings::ToUnsignedInt(row[3]); lt->content_flags.min_expansion = static_cast(Strings::ToInt(row[9])); lt->content_flags.max_expansion = static_cast(Strings::ToInt(row[10])); @@ -2320,11 +2320,11 @@ void SharedDatabase::LoadLootTables(void *data, uint32 size) { continue; } - lt->Entries[current_entry].lootdrop_id = static_cast(Strings::ToUnsignedInt(row[4])); - lt->Entries[current_entry].multiplier = static_cast(Strings::ToInt(row[5])); - lt->Entries[current_entry].droplimit = static_cast(Strings::ToInt(row[6])); - lt->Entries[current_entry].mindrop = static_cast(Strings::ToInt(row[7])); - lt->Entries[current_entry].probability = static_cast(Strings::ToFloat(row[8])); + lt->Entries[current_entry].lootdrop_id = Strings::ToUnsignedInt(row[4]); + lt->Entries[current_entry].multiplier = static_cast(Strings::ToUnsignedInt(row[5])); + lt->Entries[current_entry].droplimit = static_cast(Strings::ToUnsignedInt(row[6])); + lt->Entries[current_entry].mindrop = static_cast(Strings::ToUnsignedInt(row[7])); + lt->Entries[current_entry].probability = Strings::ToFloat(row[8]); ++(lt->NumEntries); ++current_entry; @@ -2383,7 +2383,7 @@ void SharedDatabase::LoadLootDrops(void *data, uint32 size) { uint32 current_entry = 0; for (auto& row = results.begin(); row != results.end(); ++row) { - const auto id = static_cast(Strings::ToUnsignedInt(row[0])); + const auto id = Strings::ToUnsignedInt(row[0]); if (id != current_id) { if (current_id != 0) { hash.insert( @@ -2397,7 +2397,7 @@ void SharedDatabase::LoadLootDrops(void *data, uint32 size) { current_id = id; p_loot_drop_struct->content_flags.min_expansion = static_cast(Strings::ToInt(row[10])); - p_loot_drop_struct->content_flags.max_expansion = static_cast(Strings::ToInt(row[11])); + p_loot_drop_struct->content_flags.max_expansion = static_cast(Strings::ToUnsignedInt(row[11])); strn0cpy(p_loot_drop_struct->content_flags.content_flags, row[12], sizeof(p_loot_drop_struct->content_flags.content_flags)); strn0cpy(p_loot_drop_struct->content_flags.content_flags_disabled, row[13], sizeof(p_loot_drop_struct->content_flags.content_flags_disabled)); @@ -2407,15 +2407,15 @@ void SharedDatabase::LoadLootDrops(void *data, uint32 size) { continue; } - p_loot_drop_struct->Entries[current_entry].item_id = static_cast(Strings::ToUnsignedInt(row[1])); - p_loot_drop_struct->Entries[current_entry].item_charges = static_cast(Strings::ToInt(row[2])); - p_loot_drop_struct->Entries[current_entry].equip_item = static_cast(Strings::ToInt(row[3])); - p_loot_drop_struct->Entries[current_entry].chance = static_cast(Strings::ToFloat(row[4])); - p_loot_drop_struct->Entries[current_entry].trivial_min_level = static_cast(Strings::ToInt(row[5])); - p_loot_drop_struct->Entries[current_entry].trivial_max_level = static_cast(Strings::ToInt(row[6])); - p_loot_drop_struct->Entries[current_entry].npc_min_level = static_cast(Strings::ToInt(row[7])); - p_loot_drop_struct->Entries[current_entry].npc_max_level = static_cast(Strings::ToInt(row[8])); - p_loot_drop_struct->Entries[current_entry].multiplier = static_cast(Strings::ToInt(row[9])); + p_loot_drop_struct->Entries[current_entry].item_id = Strings::ToUnsignedInt(row[1]); + p_loot_drop_struct->Entries[current_entry].item_charges = static_cast(Strings::ToUnsignedInt(row[2])); + p_loot_drop_struct->Entries[current_entry].equip_item = static_cast(Strings::ToUnsignedInt(row[3])); + p_loot_drop_struct->Entries[current_entry].chance = Strings::ToFloat(row[4]); + p_loot_drop_struct->Entries[current_entry].trivial_min_level = static_cast(Strings::ToUnsignedInt(row[5])); + p_loot_drop_struct->Entries[current_entry].trivial_max_level = static_cast(Strings::ToUnsignedInt(row[6])); + p_loot_drop_struct->Entries[current_entry].npc_min_level = static_cast(Strings::ToUnsignedInt(row[7])); + p_loot_drop_struct->Entries[current_entry].npc_max_level = static_cast(Strings::ToUnsignedInt(row[8])); + p_loot_drop_struct->Entries[current_entry].multiplier = static_cast(Strings::ToUnsignedInt(row[9])); ++(p_loot_drop_struct->NumEntries); ++current_entry; diff --git a/common/strings.cpp b/common/strings.cpp index 5a37b7659..dc50b0020 100644 --- a/common/strings.cpp +++ b/common/strings.cpp @@ -115,7 +115,7 @@ Strings::SearchDelim(const std::string &haystack, const std::string &needle, con } -std::string Strings::Implode(std::string glue, std::vector src) +std::string Strings::Implode(const std::string& glue, std::vector src) { if (src.empty()) { return {}; @@ -272,7 +272,7 @@ std::string Strings::Repeat(std::string s, int n) return s; } -bool Strings::Contains(std::vector container, std::string element) +bool Strings::Contains(std::vector container, const std::string& element) { return std::find(container.begin(), container.end(), element) != container.end(); } @@ -316,7 +316,7 @@ const std::string Strings::ToUpper(std::string s) ); return s; } -const std::string Strings::UcFirst(std::string s) +const std::string Strings::UcFirst(const std::string& s) { std::string output = s; if (!s.empty()) { @@ -327,7 +327,7 @@ const std::string Strings::UcFirst(std::string s) } -std::vector Strings::Wrap(std::vector &src, std::string character) +std::vector Strings::Wrap(std::vector &src, const std::string& character) { std::vector new_vector; new_vector.reserve(src.size()); @@ -659,7 +659,7 @@ std::string Strings::SecondsToTime(int duration, bool is_milliseconds) return time_string; } -std::string &Strings::LTrim(std::string &str, const std::string &chars) +std::string &Strings::LTrim(std::string &str, std::string_view chars) { str.erase(0, str.find_first_not_of(chars)); return str; @@ -670,7 +670,7 @@ std::string Strings::MillisecondsToTime(int duration) return SecondsToTime(duration, true); } -std::string &Strings::RTrim(std::string &str, const std::string &chars) +std::string &Strings::RTrim(std::string &str, std::string_view chars) { str.erase(str.find_last_not_of(chars) + 1); return str; @@ -682,7 +682,7 @@ std::string &Strings::Trim(std::string &str, const std::string &chars) } // Function to convert single digit or two digit number into words -std::string Strings::ConvertToDigit(int n, std::string suffix) +std::string Strings::ConvertToDigit(int n, const std::string& suffix) { // if n is zero if (n == 0) { @@ -745,7 +745,7 @@ uint32 Strings::TimeToSeconds(std::string time_string) return duration; } -bool Strings::ToBool(std::string bool_string) +bool Strings::ToBool(const std::string& bool_string) { if ( Strings::Contains(bool_string, "true") || diff --git a/common/strings.h b/common/strings.h index d454b90b9..f74da2407 100644 --- a/common/strings.h +++ b/common/strings.h @@ -84,7 +84,7 @@ namespace EQ { class Strings { public: - static bool Contains(std::vector container, std::string element); + static bool Contains(std::vector container, const std::string& element); static bool Contains(const std::string& subject, const std::string& search); static int ToInt(const std::string &s, int fallback = 0); static int64 ToBigInt(const std::string &s, int64 fallback = 0); @@ -96,9 +96,9 @@ public: static bool IsFloat(const std::string &s); static const std::string ToLower(std::string s); static const std::string ToUpper(std::string s); - static const std::string UcFirst(std::string s); - static std::string <rim(std::string &str, const std::string &chars = "\t\n\v\f\r "); - static std::string &RTrim(std::string &str, const std::string &chars = "\t\n\v\f\r "); + static const std::string UcFirst(const std::string& s); + static std::string <rim(std::string &str, std::string_view chars = "\t\n\v\f\r "); + static std::string &RTrim(std::string &str, std::string_view chars = "\t\n\v\f\r "); static std::string &Trim(std::string &str, const std::string &chars = "\t\n\v\f\r "); static std::string Commify(const std::string &number); static std::string Commify(uint16 number) { return Strings::Commify(std::to_string(number)); }; @@ -107,10 +107,10 @@ public: static std::string Commify(int16 number) { return Strings::Commify(std::to_string(number)); }; static std::string Commify(int32 number) { return Strings::Commify(std::to_string(number)); }; static std::string Commify(int64 number) { return Strings::Commify(std::to_string(number)); }; - static std::string ConvertToDigit(int n, std::string suffix); + static std::string ConvertToDigit(int n, const std::string& suffix); static std::string Escape(const std::string &s); static std::string GetBetween(const std::string &s, std::string start_delim, std::string stop_delim); - static std::string Implode(std::string glue, std::vector src); + static std::string Implode(const std::string& glue, std::vector src); static std::string Join(const std::vector &ar, const std::string &delim); static std::string Join(const std::vector &ar, const std::string &delim); static std::string MillisecondsToTime(int duration); @@ -122,10 +122,10 @@ public: static std::string::size_type SearchDelim(const std::string &haystack, const std::string &needle, const char deliminator = ','); static std::vector Split(const std::string &s, const char delim = ','); static std::vector Split(const std::string& s, const std::string& delimiter); - static std::vector Wrap(std::vector &src, std::string character); + static std::vector Wrap(std::vector &src, const std::string& character); static void FindReplace(std::string &string_subject, const std::string &search_string, const std::string &replace_string); static uint32 TimeToSeconds(std::string time_string); - static bool ToBool(std::string bool_string); + static bool ToBool(const std::string& bool_string); static inline bool EqualFold(const std::string &string_one, const std::string &string_two) { return strcasecmp(string_one.c_str(), string_two.c_str()) == 0; } static std::string Random(size_t length); diff --git a/loginserver/database.cpp b/loginserver/database.cpp index 25ea28aa6..08c5855a3 100644 --- a/loginserver/database.cpp +++ b/loginserver/database.cpp @@ -178,7 +178,7 @@ unsigned int Database::GetFreeID(const std::string &loginserver) auto row = results.begin(); - return Strings::ToInt(row[0]); + return Strings::ToUnsignedInt(row[0]); } /** @@ -647,7 +647,7 @@ Database::DbLoginServerAdmin Database::GetLoginServerAdmin(const std::string &ac if (results.RowCount() == 1) { auto row = results.begin(); r.loaded = true; - r.id = Strings::ToInt(row[0]); + r.id = Strings::ToUnsignedInt(row[0]); r.account_name = row[1]; r.account_password = row[2]; r.first_name = row[3]; @@ -683,7 +683,7 @@ Database::DbLoginServerAccount Database::GetLoginServerAccountByAccountName( if (results.RowCount() == 1) { auto row = results.begin(); r.loaded = true; - r.id = Strings::ToInt(row[0]); + r.id = Strings::ToUnsignedInt(row[0]); r.account_name = row[1]; r.account_password = row[2]; r.account_email = row[3]; diff --git a/world/worlddb.cpp b/world/worlddb.cpp index 4cac30d86..a6186907e 100644 --- a/world/worlddb.cpp +++ b/world/worlddb.cpp @@ -120,22 +120,22 @@ void WorldDatabase::GetCharSelectInfo(uint32 account_id, EQApplicationPacket **o inventory_profile.SetInventoryVersion(client_version); inventory_profile.SetGMInventory(true); // charsel can not interact with items..but, no harm in setting to full expansion support - uint32 character_id = (uint32) Strings::ToInt(row[0]); + uint32 character_id = Strings::ToUnsignedInt(row[0]); uint8 has_home = 0; uint8 has_bind = 0; memset(&pp, 0, sizeof(PlayerProfile_Struct)); memset(p_character_select_entry_struct->Name, 0, sizeof(p_character_select_entry_struct->Name)); strcpy(p_character_select_entry_struct->Name, row[1]); - p_character_select_entry_struct->Class = (uint8) Strings::ToInt(row[4]); - p_character_select_entry_struct->Race = (uint32) Strings::ToInt(row[3]); - p_character_select_entry_struct->Level = (uint8) Strings::ToInt(row[5]); + p_character_select_entry_struct->Class = (uint8) Strings::ToUnsignedInt(row[4]); + p_character_select_entry_struct->Race = (uint32) Strings::ToUnsignedInt(row[3]); + p_character_select_entry_struct->Level = (uint8) Strings::ToUnsignedInt(row[5]); p_character_select_entry_struct->ShroudClass = p_character_select_entry_struct->Class; p_character_select_entry_struct->ShroudRace = p_character_select_entry_struct->Race; - p_character_select_entry_struct->Zone = (uint16) Strings::ToInt(row[19]); + p_character_select_entry_struct->Zone = (uint16) Strings::ToUnsignedInt(row[19]); p_character_select_entry_struct->Instance = 0; - p_character_select_entry_struct->Gender = (uint8) Strings::ToInt(row[2]); - p_character_select_entry_struct->Face = (uint8) Strings::ToInt(row[15]); + p_character_select_entry_struct->Gender = (uint8) Strings::ToUnsignedInt(row[2]); + p_character_select_entry_struct->Face = (uint8) Strings::ToUnsignedInt(row[15]); for (uint32 material_slot = 0; material_slot < EQ::textures::materialCount; material_slot++) { p_character_select_entry_struct->Equip[material_slot].Material = 0; From dc45e0d2809679a92686e7a346283894f2a8ad56 Mon Sep 17 00:00:00 2001 From: Aeadoin <109764533+Aeadoin@users.noreply.github.com> Date: Thu, 23 Mar 2023 02:06:51 -0400 Subject: [PATCH 09/22] [Fix] Change SPA 193 Weapon Damage to allow values over 65,535 (#3138) --- zone/mob.h | 6 +-- zone/special_attacks.cpp | 99 ++++++++++++++++++++++------------------ 2 files changed, 57 insertions(+), 48 deletions(-) diff --git a/zone/mob.h b/zone/mob.h index 1508e2998..efe069058 100644 --- a/zone/mob.h +++ b/zone/mob.h @@ -1107,9 +1107,9 @@ public: int64 ReduceAllDamage(int64 damage); void DoSpecialAttackDamage(Mob *who, EQ::skills::SkillType skill, int base_damage, int min_damage = 0, int32 hate_override = -1, int ReuseTime = 10); - virtual void DoThrowingAttackDmg(Mob* other, const EQ::ItemInstance* RangeWeapon = nullptr, const EQ::ItemData* AmmoItem = nullptr, uint16 weapon_damage = 0, int16 chance_mod = 0, int16 focus = 0, int ReuseTime = 0, uint32 range_id = 0, int AmmoSlot = 0, float speed = 4.0f, bool DisableProcs = false); - void DoMeleeSkillAttackDmg(Mob* other, uint16 weapon_damage, EQ::skills::SkillType skillinuse, int16 chance_mod = 0, int16 focus = 0, bool CanRiposte = false, int ReuseTime = 0); - virtual void DoArcheryAttackDmg(Mob* other, const EQ::ItemInstance* RangeWeapon = nullptr, const EQ::ItemInstance* Ammo = nullptr, uint16 weapon_damage = 0, int16 chance_mod = 0, int16 focus = 0, int ReuseTime = 0, uint32 range_id = 0, uint32 ammo_id = 0, const EQ::ItemData *AmmoItem = nullptr, int AmmoSlot = 0, float speed = 4.0f, bool DisableProcs = false); + void DoThrowingAttackDmg(Mob* other, const EQ::ItemInstance* RangeWeapon = nullptr, const EQ::ItemData* AmmoItem = nullptr, int32 weapon_damage = 0, int16 chance_mod = 0, int16 focus = 0, int ReuseTime = 0, uint32 range_id = 0, int AmmoSlot = 0, float speed = 4.0f, bool DisableProcs = false); + void DoMeleeSkillAttackDmg(Mob* other, int32 weapon_damage, EQ::skills::SkillType skillinuse, int16 chance_mod = 0, int16 focus = 0, bool CanRiposte = false, int ReuseTime = 0); + void DoArcheryAttackDmg(Mob* other, const EQ::ItemInstance* RangeWeapon = nullptr, const EQ::ItemInstance* Ammo = nullptr, int32 weapon_damage = 0, int16 chance_mod = 0, int16 focus = 0, int ReuseTime = 0, uint32 range_id = 0, uint32 ammo_id = 0, const EQ::ItemData *AmmoItem = nullptr, int AmmoSlot = 0, float speed = 4.0f, bool DisableProcs = false); bool TryProjectileAttack(Mob* other, const EQ::ItemData *item, EQ::skills::SkillType skillInUse, uint64 weapon_dmg, const EQ::ItemInstance* RangeWeapon, const EQ::ItemInstance* Ammo, int AmmoSlot, float speed, bool DisableProcs = false); void ProjectileAttack(); inline bool HasProjectileAttack() const { return ActiveProjectileATK; } diff --git a/zone/special_attacks.cpp b/zone/special_attacks.cpp index 1243d0eb6..59048c765 100644 --- a/zone/special_attacks.cpp +++ b/zone/special_attacks.cpp @@ -747,11 +747,10 @@ void Client::RangedAttack(Mob* other, bool CanDoubleAttack) { LogCombat("Shooting [{}] with bow [{}] ([{}]) and arrow [{}] ([{}])", other->GetName(), RangeItem->Name, RangeItem->ID, AmmoItem->Name, AmmoItem->ID); //look for ammo in inventory if we only have 1 left... - if(Ammo->GetCharges() == 1) { + if (Ammo->GetCharges() == 1) { //first look for quivers - int r; bool found = false; - for (r = EQ::invslot::GENERAL_BEGIN; r <= EQ::invslot::GENERAL_END; r++) { + for (int r = EQ::invslot::GENERAL_BEGIN; r <= EQ::invslot::GENERAL_END; r++) { const EQ::ItemInstance *pi = m_inv[r]; if (pi == nullptr || !pi->IsClassBag()) continue; @@ -760,16 +759,17 @@ void Client::RangedAttack(Mob* other, bool CanDoubleAttack) { continue; //we found a quiver, look for the ammo in it - int i; - for (i = 0; i < bagitem->BagSlots; i++) { - EQ::ItemInstance* baginst = pi->GetItem(i); - if(!baginst) - continue; //empty - if(baginst->GetID() == Ammo->GetID()) { + for (int i = 0; i < bagitem->BagSlots; i++) { + const EQ::ItemInstance* baginst = pi->GetItem(i); + if (!baginst) { + continue; + } + + if (baginst->GetID() == Ammo->GetID()) { //we found it... use this stack //the item wont change, but the instance does Ammo = baginst; - ammo_slot = m_inv.CalcSlotId(r, i); + ammo_slot = EQ::InventoryProfile::CalcSlotId(r, i); found = true; LogCombat("Using ammo from quiver stack at slot [{}]. [{}] in stack", ammo_slot, Ammo->GetCharges()); break; @@ -794,18 +794,17 @@ void Client::RangedAttack(Mob* other, bool CanDoubleAttack) { float range = RangeItem->Range + AmmoItem->Range + GetRangeDistTargetSizeMod(GetTarget()); LogCombat("Calculated bow range to be [{}]", range); range *= range; - float dist = DistanceSquared(m_Position, other->GetPosition()); - if(dist > range) { + if (float dist = DistanceSquared(m_Position, other->GetPosition()); dist > range) { LogCombat("Ranged attack out of range client should catch this. ([{}] > [{}]).\n", dist, range); MessageString(Chat::Red,TARGET_OUT_OF_RANGE);//Client enforces range and sends the message, this is a backup just incase. return; } - else if(dist < (RuleI(Combat, MinRangedAttackDist)*RuleI(Combat, MinRangedAttackDist))){ + else if (dist < (RuleI(Combat, MinRangedAttackDist)*RuleI(Combat, MinRangedAttackDist))){ MessageString(Chat::Yellow,RANGED_TOO_CLOSE);//Client enforces range and sends the message, this is a backup just incase. return; } - if(!IsAttackAllowed(other) || + if (!IsAttackAllowed(other) || IsCasting() || IsSitting() || (DivineAura() && !GetGM()) || @@ -845,12 +844,12 @@ void Client::RangedAttack(Mob* other, bool CanDoubleAttack) { } void Mob::DoArcheryAttackDmg(Mob *other, const EQ::ItemInstance *RangeWeapon, const EQ::ItemInstance *Ammo, - uint16 weapon_damage, int16 chance_mod, int16 focus, int ReuseTime, uint32 range_id, - uint32 ammo_id, const EQ::ItemData *AmmoItem, int AmmoSlot, float speed, bool DisableProcs) + int32 weapon_damage, int16 chance_mod, int16 focus, int ReuseTime, uint32 range_id, + uint32 ammo_id, const EQ::ItemData *AmmoItem, int AmmoSlot, float speed, bool DisableProcs) { if ((other == nullptr || - ((IsClient() && CastToClient()->dead) || (other->IsClient() && other->CastToClient()->dead)) || - HasDied() || (!IsAttackAllowed(other)) || (other->GetInvul() || other->GetSpecialAbility(IMMUNE_MELEE)))) { + ((IsClient() && CastToClient()->dead) || (other->IsClient() && other->CastToClient()->dead)) || + HasDied() || (!IsAttackAllowed(other)) || (other->GetInvul() || other->GetSpecialAbility(IMMUNE_MELEE)))) { return; } @@ -911,7 +910,7 @@ void Mob::DoArcheryAttackDmg(Mob *other, const EQ::ItemInstance *RangeWeapon, co if (LaunchProjectile) { // 1: Shoot the Projectile once we calculate weapon damage. TryProjectileAttack(other, AmmoItem, EQ::skills::SkillArchery, (WDmg + ADmg), RangeWeapon, - Ammo, AmmoSlot, speed, DisableProcs); + Ammo, AmmoSlot, speed, DisableProcs); return; } @@ -920,10 +919,14 @@ void Mob::DoArcheryAttackDmg(Mob *other, const EQ::ItemInstance *RangeWeapon, co } if (WDmg > 0 || ADmg > 0) { - if (WDmg < 0) + if (WDmg < 0) { WDmg = 0; - if (ADmg < 0) + } + + if (ADmg < 0) { ADmg = 0; + } + int MaxDmg = WDmg + ADmg; hate = ((WDmg + ADmg)); @@ -934,10 +937,11 @@ void Mob::DoArcheryAttackDmg(Mob *other, const EQ::ItemInstance *RangeWeapon, co LogCombat("Bow DMG [{}], Arrow DMG [{}], Max Damage [{}]", WDmg, ADmg, MaxDmg); } - if (MaxDmg == 0) + if (MaxDmg == 0) { MaxDmg = 1; + } - DamageHitInfo my_hit; + DamageHitInfo my_hit {}; my_hit.base_damage = MaxDmg; my_hit.min_damage = 0; my_hit.damage_done = 1; @@ -953,8 +957,9 @@ void Mob::DoArcheryAttackDmg(Mob *other, const EQ::ItemInstance *RangeWeapon, co TotalDmg = DMG_INVULNERABLE; } - if (IsClient() && !CastToClient()->GetFeigned()) + if (IsClient() && !CastToClient()->GetFeigned()) { other->AddToHateList(this, hate, 0); + } other->Damage(this, TotalDmg, SPELL_UNKNOWN, EQ::skills::SkillArchery); @@ -1443,7 +1448,7 @@ void Client::ThrowingAttack(Mob* other, bool CanDoubleAttack) { //old was 51 } void Mob::DoThrowingAttackDmg(Mob *other, const EQ::ItemInstance *RangeWeapon, const EQ::ItemData *AmmoItem, - uint16 weapon_damage, int16 chance_mod, int16 focus, int ReuseTime, uint32 range_id, + int32 weapon_damage, int16 chance_mod, int16 focus, int ReuseTime, uint32 range_id, int AmmoSlot, float speed, bool DisableProcs) { if ((other == nullptr || @@ -1490,7 +1495,7 @@ void Mob::DoThrowingAttackDmg(Mob *other, const EQ::ItemInstance *RangeWeapon, c int WDmg = 0; if (!weapon_damage) { - if (IsClient() && RangeWeapon) { + if (IsOfClientBot() && RangeWeapon) { WDmg = GetWeaponDamage(other, RangeWeapon); } else if (AmmoItem) { @@ -1514,7 +1519,7 @@ void Mob::DoThrowingAttackDmg(Mob *other, const EQ::ItemInstance *RangeWeapon, c int TotalDmg = 0; if (WDmg > 0) { - DamageHitInfo my_hit; + DamageHitInfo my_hit {}; my_hit.base_damage = WDmg; my_hit.min_damage = 0; my_hit.damage_done = 1; @@ -1533,8 +1538,9 @@ void Mob::DoThrowingAttackDmg(Mob *other, const EQ::ItemInstance *RangeWeapon, c TotalDmg = DMG_INVULNERABLE; } - if (IsClient() && !CastToClient()->GetFeigned()) + if (IsClient() && !CastToClient()->GetFeigned()) { other->AddToHateList(this, WDmg, 0); + } other->Damage(this, TotalDmg, SPELL_UNKNOWN, EQ::skills::SkillThrowing); @@ -2299,11 +2305,12 @@ int Mob::TryAssassinate(Mob *defender, EQ::skills::SkillType skillInUse) return 0; } -void Mob::DoMeleeSkillAttackDmg(Mob *other, uint16 weapon_damage, EQ::skills::SkillType skillinuse, int16 chance_mod, +void Mob::DoMeleeSkillAttackDmg(Mob *other, int32 weapon_damage, EQ::skills::SkillType skillinuse, int16 chance_mod, int16 focus, bool CanRiposte, int ReuseTime) { - if (!CanDoSpecialAttack(other)) + if (!CanDoSpecialAttack(other)) { return; + } /* For spells using skill value 98 (feral swipe ect) server sets this to 67 automatically. @@ -2311,34 +2318,34 @@ void Mob::DoMeleeSkillAttackDmg(Mob *other, uint16 weapon_damage, EQ::skills::Sk TODO: We need to stop moving skill 98, it's suppose to just be a dummy skill AFAIK Spells using offense should use the skill of your primary, if you can use it, otherwise h2h */ - if (skillinuse == EQ::skills::SkillBegging) + if (skillinuse == EQ::skills::SkillBegging) { skillinuse = EQ::skills::SkillOffense; + } int64 damage = 0; int64 hate = 0; - if (hate == 0 && weapon_damage > 1) + if (hate == 0 && weapon_damage > 1) { hate = weapon_damage; + } if (weapon_damage > 0) { if (focus) { weapon_damage += weapon_damage * focus / 100; } - if (skillinuse == EQ::skills::SkillBash) { - if (IsClient()) { - EQ::ItemInstance *item = - CastToClient()->GetInv().GetItem(EQ::invslot::slotSecondary); - if (item) { - if (item->GetItem()->ItemType == EQ::item::ItemTypeShield) { - hate += item->GetItem()->AC; - } - const EQ::ItemData *itm = item->GetItem(); - hate = hate * (100 + GetFuriousBash(itm->Focus.Effect)) / 100; + if (skillinuse == EQ::skills::SkillBash && IsClient()) { + EQ::ItemInstance *item = + CastToClient()->GetInv().GetItem(EQ::invslot::slotSecondary); + if (item) { + if (item->GetItem()->ItemType == EQ::item::ItemTypeShield) { + hate += item->GetItem()->AC; } + const EQ::ItemData *itm = item->GetItem(); + hate = hate * (100 + GetFuriousBash(itm->Focus.Effect)) / 100; } } - DamageHitInfo my_hit; + DamageHitInfo my_hit {}; my_hit.base_damage = weapon_damage; my_hit.min_damage = 0; my_hit.damage_done = 1; @@ -2349,8 +2356,9 @@ void Mob::DoMeleeSkillAttackDmg(Mob *other, uint16 weapon_damage, EQ::skills::Sk // slot range exclude ripe etc ... my_hit.hand = CanRiposte ? EQ::invslot::slotRange : EQ::invslot::slotPrimary; - if (IsNPC()) + if (IsNPC()) { my_hit.min_damage = CastToNPC()->GetMinDamage(); + } DoAttack(other, my_hit); damage = my_hit.damage_done; @@ -2365,8 +2373,9 @@ void Mob::DoMeleeSkillAttackDmg(Mob *other, uint16 weapon_damage, EQ::skills::Sk other->AddToHateList(this, hate, 0); other->Damage(this, damage, SPELL_UNKNOWN, skillinuse); - if (HasDied()) + if (HasDied()) { return; + } TryCastOnSkillUse(other, skillinuse); } From 5a6314e1a9612ee10d2e26068c16e4635708e681 Mon Sep 17 00:00:00 2001 From: Alex Date: Wed, 22 Mar 2023 23:16:52 -0700 Subject: [PATCH 10/22] [Fix] Fixes for corpses not properly saving some item instance data correctly. (#3123) * Convert ZoneDb::LoadCharacterCorpseData to use a cleaner api that has a better layout. * Update corpse save methods to use a new cleaner api. * Add item to corpse will use a few new fields that don't yet save. * Fix for some issues moving data to corpses. * Make CreateItem more explicit to avoid overlooking places it's used and add more arguments. * DB changes * Revert of the changes to the database.CreateItem api change. * Missed one. * Fixes for mr Krab * Small formatting --------- Co-authored-by: KimLS Co-authored-by: Akkadius --- common/eq_packet_structs.h | 6 +- common/inventory_profile.h | 12 +- common/item_instance.cpp | 25 +- common/item_instance.h | 13 +- common/shareddb.cpp | 88 ++---- common/shareddb.h | 12 +- common/version.h | 2 +- utils/sql/db_update_manifest.txt | 1 + .../git/required/2023_03_17_corpse_fields.sql | 5 + world/worlddb.cpp | 23 +- zone/bot_database.cpp | 23 +- zone/client.cpp | 6 +- zone/corpse.cpp | 272 +++++++++++------- zone/corpse.h | 15 +- zone/inventory.cpp | 18 +- zone/lua_iteminst.cpp | 24 +- zone/lua_iteminst.h | 12 +- zone/questmgr.cpp | 12 +- zone/zonedb.cpp | 268 +++++++++-------- zone/zonedb.h | 56 +++- zone/zonedump.h | 50 ---- 21 files changed, 491 insertions(+), 452 deletions(-) create mode 100644 utils/sql/git/required/2023_03_17_corpse_fields.sql diff --git a/common/eq_packet_structs.h b/common/eq_packet_structs.h index cd26fe79a..8d1b3f13e 100644 --- a/common/eq_packet_structs.h +++ b/common/eq_packet_structs.h @@ -5522,7 +5522,11 @@ struct ServerLootItem_Struct { uint32 aug_4; // uint32 aug_4; uint32 aug_5; // uint32 aug_5; uint32 aug_6; // uint32 aug_5; - uint8 attuned; + bool attuned; + std::string custom_data; + uint32 ornamenticon; + uint32 ornamentidfile; + uint32 ornament_hero_model; uint16 trivial_min_level; uint16 trivial_max_level; uint16 npc_min_level; diff --git a/common/inventory_profile.h b/common/inventory_profile.h index 43f4a88f4..c1a82e407 100644 --- a/common/inventory_profile.h +++ b/common/inventory_profile.h @@ -203,12 +203,12 @@ namespace EQ void dumpBankItems(); void dumpSharedBankItems(); - void SetCustomItemData(uint32 character_id, int16 slot_id, std::string identifier, std::string value); - void SetCustomItemData(uint32 character_id, int16 slot_id, std::string identifier, int value); - void SetCustomItemData(uint32 character_id, int16 slot_id, std::string identifier, float value); - void SetCustomItemData(uint32 character_id, int16 slot_id, std::string identifier, bool value); - std::string GetCustomItemData(int16 slot_id, std::string identifier); - static const int GetItemStatValue(uint32 item_id, std::string identifier); + void SetCustomItemData(uint32 character_id, int16 slot_id, const std::string &identifier, const std::string& value); + void SetCustomItemData(uint32 character_id, int16 slot_id, const std::string &identifier, int value); + void SetCustomItemData(uint32 character_id, int16 slot_id, const std::string &identifier, float value); + void SetCustomItemData(uint32 character_id, int16 slot_id, const std::string &identifier, bool value); + std::string GetCustomItemData(int16 slot_id, const std::string& identifier); + static const int GetItemStatValue(uint32 item_id, const std::string& identifier); protected: /////////////////////////////// // Protected Methods diff --git a/common/item_instance.cpp b/common/item_instance.cpp index eb025ee98..696a34b6f 100644 --- a/common/item_instance.cpp +++ b/common/item_instance.cpp @@ -840,7 +840,20 @@ std::string EQ::ItemInstance::GetCustomDataString() const { return ret_val; } -std::string EQ::ItemInstance::GetCustomData(std::string identifier) { +void EQ::ItemInstance::SetCustomDataString(const std::string& str) +{ + auto components = Strings::Split(str, "^"); + auto value_count = components.size() / 2; + + for (auto i = 0; i < value_count; i++) { + auto identifier = components[i * 2]; + auto value = components[(i * 2) + 1]; + + SetCustomData(identifier, value); + } +} + +std::string EQ::ItemInstance::GetCustomData(const std::string& identifier) { std::map::const_iterator iter = m_custom_data.find(identifier); if (iter != m_custom_data.end()) { return iter->second; @@ -849,33 +862,33 @@ std::string EQ::ItemInstance::GetCustomData(std::string identifier) { return ""; } -void EQ::ItemInstance::SetCustomData(std::string identifier, std::string value) { +void EQ::ItemInstance::SetCustomData(const std::string& identifier, const std::string& value) { DeleteCustomData(identifier); m_custom_data[identifier] = value; } -void EQ::ItemInstance::SetCustomData(std::string identifier, int value) { +void EQ::ItemInstance::SetCustomData(const std::string& identifier, int value) { DeleteCustomData(identifier); std::stringstream ss; ss << value; m_custom_data[identifier] = ss.str(); } -void EQ::ItemInstance::SetCustomData(std::string identifier, float value) { +void EQ::ItemInstance::SetCustomData(const std::string& identifier, float value) { DeleteCustomData(identifier); std::stringstream ss; ss << value; m_custom_data[identifier] = ss.str(); } -void EQ::ItemInstance::SetCustomData(std::string identifier, bool value) { +void EQ::ItemInstance::SetCustomData(const std::string& identifier, bool value) { DeleteCustomData(identifier); std::stringstream ss; ss << value; m_custom_data[identifier] = ss.str(); } -void EQ::ItemInstance::DeleteCustomData(std::string identifier) { +void EQ::ItemInstance::DeleteCustomData(const std::string& identifier) { auto iter = m_custom_data.find(identifier); if (iter != m_custom_data.end()) { m_custom_data.erase(iter); diff --git a/common/item_instance.h b/common/item_instance.h index 89620d0b5..d1a8e021e 100644 --- a/common/item_instance.h +++ b/common/item_instance.h @@ -175,12 +175,13 @@ namespace EQ void SetAttuned(bool flag) { m_attuned = flag; } std::string GetCustomDataString() const; - std::string GetCustomData(std::string identifier); - void SetCustomData(std::string identifier, std::string value); - void SetCustomData(std::string identifier, int value); - void SetCustomData(std::string identifier, float value); - void SetCustomData(std::string identifier, bool value); - void DeleteCustomData(std::string identifier); + std::string GetCustomData(const std::string &identifier); + void SetCustomDataString(const std::string& str); + void SetCustomData(const std::string &identifier, const std::string& value); + void SetCustomData(const std::string &identifier, int value); + void SetCustomData(const std::string &identifier, float value); + void SetCustomData(const std::string &identifier, bool value); + void DeleteCustomData(const std::string& identifier); // Allows treatment of this object as though it were a pointer to m_item operator bool() const { return (m_item != nullptr); } diff --git a/common/shareddb.cpp b/common/shareddb.cpp index 08c82fb1e..b37cb8127 100644 --- a/common/shareddb.cpp +++ b/common/shareddb.cpp @@ -548,27 +548,7 @@ bool SharedDatabase::GetSharedBank(uint32 id, EQ::InventoryProfile *inv, bool is if (inst && row[9]) { std::string data_str(row[9]); - std::string idAsString; - std::string value; - bool use_id = true; - - for (int i = 0; i < data_str.length(); ++i) { - if (data_str[i] == '^') { - if (!use_id) { - inst->SetCustomData(idAsString, value); - idAsString.clear(); - value.clear(); - } - use_id = !use_id; - continue; - } - - const char v = data_str[i]; - if (use_id) - idAsString.push_back(v); - else - value.push_back(v); - } + inst->SetCustomDataString(data_str); } // theoretically inst can be nullptr ... this would be very bad ... @@ -679,28 +659,7 @@ bool SharedDatabase::GetInventory(uint32 char_id, EQ::InventoryProfile *inv) if (row[11]) { std::string data_str(row[11]); - std::string idAsString; - std::string value; - bool use_id = true; - - for (int i = 0; i < data_str.length(); ++i) { - if (data_str[i] == '^') { - if (!use_id) { - inst->SetCustomData(idAsString, value); - idAsString.clear(); - value.clear(); - } - - use_id = !use_id; - continue; - } - - const char v = data_str[i]; - if (use_id) - idAsString.push_back(v); - else - value.push_back(v); - } + inst->SetCustomDataString(data_str); } inst->SetOrnamentIcon(ornament_icon); @@ -825,28 +784,7 @@ bool SharedDatabase::GetInventory(uint32 account_id, char *name, EQ::InventoryPr if (row[11]) { std::string data_str(row[11]); - std::string idAsString; - std::string value; - bool use_id = true; - - for (int i = 0; i < data_str.length(); ++i) { - if (data_str[i] == '^') { - if (!use_id) { - inst->SetCustomData(idAsString, value); - idAsString.clear(); - value.clear(); - } - - use_id = !use_id; - continue; - } - - const char v = data_str[i]; - if (use_id) - idAsString.push_back(v); - else - value.push_back(v); - } + inst->SetCustomDataString(data_str); } inst->SetOrnamentIcon(ornament_icon); @@ -1544,7 +1482,11 @@ EQ::ItemInstance* SharedDatabase::CreateItem( uint32 aug4, uint32 aug5, uint32 aug6, - bool attuned + bool attuned, + const std::string& custom_data, + uint32 ornamenticon, + uint32 ornamentidfile, + uint32 ornament_hero_model ) { EQ::ItemInstance* inst = nullptr; @@ -1565,6 +1507,10 @@ EQ::ItemInstance* SharedDatabase::CreateItem( inst->PutAugment(this, 4, aug5); inst->PutAugment(this, 5, aug6); inst->SetAttuned(attuned); + inst->SetCustomDataString(custom_data); + inst->SetOrnamentIcon(ornamenticon); + inst->SetOrnamentationIDFile(ornamentidfile); + inst->SetOrnamentHeroModel(ornament_hero_model); } return inst; @@ -1581,7 +1527,11 @@ EQ::ItemInstance* SharedDatabase::CreateItem( uint32 aug4, uint32 aug5, uint32 aug6, - bool attuned + bool attuned, + const std::string& custom_data, + uint32 ornamenticon, + uint32 ornamentidfile, + uint32 ornament_hero_model ) { EQ::ItemInstance* inst = nullptr; if (item) { @@ -1600,6 +1550,10 @@ EQ::ItemInstance* SharedDatabase::CreateItem( inst->PutAugment(this, 4, aug5); inst->PutAugment(this, 5, aug6); inst->SetAttuned(attuned); + inst->SetCustomDataString(custom_data); + inst->SetOrnamentIcon(ornamenticon); + inst->SetOrnamentationIDFile(ornamentidfile); + inst->SetOrnamentHeroModel(ornament_hero_model); } return inst; diff --git a/common/shareddb.h b/common/shareddb.h index fc5f89932..7139b17fd 100644 --- a/common/shareddb.h +++ b/common/shareddb.h @@ -126,7 +126,11 @@ public: uint32 aug4 = 0, uint32 aug5 = 0, uint32 aug6 = 0, - bool attuned = 0 + bool attuned = false, + const std::string& custom_data = "", + uint32 ornamenticon = 0, + uint32 ornamentidfile = 0, + uint32 ornament_hero_model = 0 ); EQ::ItemInstance *CreateItem( const EQ::ItemData *item, @@ -137,7 +141,11 @@ public: uint32 aug4 = 0, uint32 aug5 = 0, uint32 aug6 = 0, - bool attuned = 0 + bool attuned = false, + const std::string &custom_data = "", + uint32 ornamenticon = 0, + uint32 ornamentidfile = 0, + uint32 ornament_hero_model = 0 ); EQ::ItemInstance *CreateBaseItem(const EQ::ItemData *item, int16 charges = 0); diff --git a/common/version.h b/common/version.h index 3941cce9d..6f6179db5 100644 --- a/common/version.h +++ b/common/version.h @@ -42,7 +42,7 @@ * Manifest: https://github.com/EQEmu/Server/blob/master/utils/sql/db_update_manifest.txt */ -#define CURRENT_BINARY_DATABASE_VERSION 9225 +#define CURRENT_BINARY_DATABASE_VERSION 9226 #define CURRENT_BINARY_BOTS_DATABASE_VERSION 9038 diff --git a/utils/sql/db_update_manifest.txt b/utils/sql/db_update_manifest.txt index 14f6b208e..c7aaab906 100644 --- a/utils/sql/db_update_manifest.txt +++ b/utils/sql/db_update_manifest.txt @@ -479,6 +479,7 @@ 9223|2023_03_04_npc_scale_global_base_heroic_strikethrough.sql|SHOW COLUMNS FROM `npc_scale_global_base` LIKE 'heroic_strikethrough'|empty| 9224|2023_03_08_npc_scale_global_base_avoidance.sql|SHOW COLUMNS FROM `npc_scale_global_base` LIKE 'hp_regen_per_second'|empty| 9225|2023_01_21_bots_raid_members.sql|SHOW COLUMNS FROM `raid_members` LIKE 'bot_id'|empty| +9226|2023_03_17_corpse_fields.sql|SHOW COLUMNS FROM `character_corpse_items` LIKE 'custom_data'|empty| # Upgrade conditions: # This won't be needed after this system is implemented, but it is used database that are not diff --git a/utils/sql/git/required/2023_03_17_corpse_fields.sql b/utils/sql/git/required/2023_03_17_corpse_fields.sql new file mode 100644 index 000000000..0552deb9b --- /dev/null +++ b/utils/sql/git/required/2023_03_17_corpse_fields.sql @@ -0,0 +1,5 @@ +ALTER TABLE `character_corpse_items` + ADD COLUMN `custom_data` TEXT NULL AFTER `attuned`, + ADD COLUMN `ornamenticon` INT UNSIGNED NOT NULL DEFAULT '0' AFTER `custom_data`, + ADD COLUMN `ornamentidfile` INT UNSIGNED NOT NULL DEFAULT '0' AFTER `ornamenticon`, + ADD COLUMN `ornament_hero_model` INT UNSIGNED NOT NULL DEFAULT '0' AFTER `ornamentidfile`; diff --git a/world/worlddb.cpp b/world/worlddb.cpp index a6186907e..dcf03bc5b 100644 --- a/world/worlddb.cpp +++ b/world/worlddb.cpp @@ -946,28 +946,7 @@ bool WorldDatabase::GetCharSelInventory(uint32 account_id, char *name, EQ::Inven if (row[11]) { std::string data_str(row[11]); - std::string idAsString; - std::string value; - bool use_id = true; - - for (int i = 0; i < data_str.length(); ++i) { - if (data_str[i] == '^') { - if (!use_id) { - inst->SetCustomData(idAsString, value); - idAsString.clear(); - value.clear(); - } - - use_id = !use_id; - continue; - } - - char v = data_str[i]; - if (use_id) - idAsString.push_back(v); - else - value.push_back(v); - } + inst->SetCustomDataString(data_str); } inst->SetOrnamentIcon(ornament_icon); diff --git a/zone/bot_database.cpp b/zone/bot_database.cpp index a12e4e6dd..6057ce8aa 100644 --- a/zone/bot_database.cpp +++ b/zone/bot_database.cpp @@ -1101,28 +1101,7 @@ bool BotDatabase::LoadItems(const uint32 bot_id, EQ::InventoryProfile& inventory if (row[5]) { std::string data_str(row[5]); - std::string idAsString; - std::string value; - bool use_id = true; - - for (int i = 0; i < data_str.length(); ++i) { - if (data_str[i] == '^') { - if (!use_id) { - item_inst->SetCustomData(idAsString, value); - idAsString.clear(); - value.clear(); - } - - use_id = !use_id; - continue; - } - - char v = data_str[i]; - if (use_id) - idAsString.push_back(v); - else - value.push_back(v); - } + item_inst->SetCustomDataString(data_str); } item_inst->SetOrnamentIcon((uint32)Strings::ToUnsignedInt(row[6])); diff --git a/zone/client.cpp b/zone/client.cpp index 36d1334b5..5781fce25 100644 --- a/zone/client.cpp +++ b/zone/client.cpp @@ -11050,7 +11050,11 @@ void Client::SummonBaggedItems(uint32 bag_item_id, const std::vectoritemcount; i++) { - tmp = new ServerLootItem_Struct; - memcpy(tmp, &pcs->items[i], sizeof(player_lootitem::ServerLootItem_Struct)); + for (auto &item: ce.items) { + auto tmp = new ServerLootItem_Struct; + + tmp->equip_slot = item.equip_slot; + tmp->item_id = item.item_id; + tmp->charges = item.charges; + tmp->lootslot = item.lootslot; + tmp->aug_1 = item.aug_1; + tmp->aug_2 = item.aug_2; + tmp->aug_3 = item.aug_3; + tmp->aug_4 = item.aug_4; + tmp->aug_5 = item.aug_5; + tmp->aug_6 = item.aug_6; + tmp->attuned = item.attuned; + itemlist.push_back(tmp); } /* Create Corpse Entity */ - auto pc = new Corpse(in_dbid, // uint32 in_dbid - in_charid, // uint32 in_charid - in_charname.c_str(), // char* in_charname - &itemlist, // ItemList* in_itemlist - pcs->copper, // uint32 in_copper - pcs->silver, // uint32 in_silver - pcs->gold, // uint32 in_gold - pcs->plat, // uint32 in_plat - position, - pcs->size, // float in_size - pcs->gender, // uint8 in_gender - pcs->race, // uint16 in_race - pcs->class_, // uint8 in_class - pcs->deity, // uint8 in_deity - pcs->level, // uint8 in_level - pcs->texture, // uint8 in_texture - pcs->helmtexture, // uint8 in_helmtexture - pcs->exp, // uint32 in_rezexp - was_at_graveyard // bool wasAtGraveyard - ); + auto pc = new Corpse( + in_dbid, // uint32 in_dbid + in_charid, // uint32 in_charid + in_charname.c_str(), // char* in_charname + &itemlist, // ItemList* in_itemlist + ce.copper, // uint32 in_copper + ce.silver, // uint32 in_silver + ce.gold, // uint32 in_gold + ce.plat, // uint32 in_plat + position, + ce.size, // float in_size + ce.gender, // uint8 in_gender + ce.race, // uint16 in_race + ce.class_, // uint8 in_class + ce.deity, // uint8 in_deity + ce.level, // uint8 in_level + ce.texture, // uint8 in_texture + ce.helmtexture, // uint8 in_helmtexture + ce.exp, // uint32 in_rezexp + was_at_graveyard // bool wasAtGraveyard + ); - if (pcs->locked) + if (ce.locked) pc->Lock(); /* Load Item Tints */ - pc->item_tint.Head.Color = pcs->item_tint.Head.Color; - pc->item_tint.Chest.Color = pcs->item_tint.Chest.Color; - pc->item_tint.Arms.Color = pcs->item_tint.Arms.Color; - pc->item_tint.Wrist.Color = pcs->item_tint.Wrist.Color; - pc->item_tint.Hands.Color = pcs->item_tint.Hands.Color; - pc->item_tint.Legs.Color = pcs->item_tint.Legs.Color; - pc->item_tint.Feet.Color = pcs->item_tint.Feet.Color; - pc->item_tint.Primary.Color = pcs->item_tint.Primary.Color; - pc->item_tint.Secondary.Color = pcs->item_tint.Secondary.Color; + pc->item_tint.Head.Color = ce.item_tint.Head.Color; + pc->item_tint.Chest.Color = ce.item_tint.Chest.Color; + pc->item_tint.Arms.Color = ce.item_tint.Arms.Color; + pc->item_tint.Wrist.Color = ce.item_tint.Wrist.Color; + pc->item_tint.Hands.Color = ce.item_tint.Hands.Color; + pc->item_tint.Legs.Color = ce.item_tint.Legs.Color; + pc->item_tint.Feet.Color = ce.item_tint.Feet.Color; + pc->item_tint.Primary.Color = ce.item_tint.Primary.Color; + pc->item_tint.Secondary.Color = ce.item_tint.Secondary.Color; /* Load Physical Appearance */ - pc->haircolor = pcs->haircolor; - pc->beardcolor = pcs->beardcolor; - pc->eyecolor1 = pcs->eyecolor1; - pc->eyecolor2 = pcs->eyecolor2; - pc->hairstyle = pcs->hairstyle; - pc->luclinface = pcs->face; - pc->beard = pcs->beard; - pc->drakkin_heritage = pcs->drakkin_heritage; - pc->drakkin_tattoo = pcs->drakkin_tattoo; - pc->drakkin_details = pcs->drakkin_details; + pc->haircolor = ce.haircolor; + pc->beardcolor = ce.beardcolor; + pc->eyecolor1 = ce.eyecolor1; + pc->eyecolor2 = ce.eyecolor2; + pc->hairstyle = ce.hairstyle; + pc->luclinface = ce.face; + pc->beard = ce.beard; + pc->drakkin_heritage = ce.drakkin_heritage; + pc->drakkin_tattoo = ce.drakkin_tattoo; + pc->drakkin_details = ce.drakkin_details; pc->IsRezzed(rezzed); - pc->become_npc = false; + pc->become_npc = false; pc->consented_guild_id = guild_consent_id; pc->UpdateEquipmentLight(); // itemlist populated above..need to determine actual values - safe_delete_array(pcs); - return pc; } @@ -509,8 +518,13 @@ void Corpse::MoveItemToCorpse(Client *client, EQ::ItemInstance *inst, int16 equi inst->GetAugmentItemID(3), inst->GetAugmentItemID(4), inst->GetAugmentItemID(5), - inst->IsAttuned() - ); + inst->IsAttuned(), + inst->GetCustomDataString(), + inst->GetOrnamentationIcon(), + inst->GetOrnamentationIDFile(), + inst->GetOrnamentHeroModel() + ); + removedList.push_back(equipSlot); while (true) { @@ -532,8 +546,13 @@ void Corpse::MoveItemToCorpse(Client *client, EQ::ItemInstance *inst, int16 equi bag_inst->GetAugmentItemID(3), bag_inst->GetAugmentItemID(4), bag_inst->GetAugmentItemID(5), - bag_inst->IsAttuned() - ); + bag_inst->IsAttuned(), + bag_inst->GetCustomDataString(), + bag_inst->GetOrnamentationIcon(), + bag_inst->GetOrnamentationIDFile(), + bag_inst->GetOrnamentHeroModel() + ); + removedList.push_back(real_bag_slot); client->DeleteItemInInventory(real_bag_slot, 0, true, false); } @@ -677,63 +696,72 @@ void Corpse::CalcCorpseName() { } bool Corpse::Save() { - if (!is_player_corpse) + if (!is_player_corpse) { return true; - if (!is_corpse_changed) + } + + if (!is_corpse_changed) { return true; + } - uint32 tmp = CountItems(); - uint32 tmpsize = sizeof(PlayerCorpse_Struct) + (tmp * sizeof(player_lootitem::ServerLootItem_Struct)); + CharacterCorpseEntry ce; - PlayerCorpse_Struct* dbpc = (PlayerCorpse_Struct*) new uchar[tmpsize]; - memset(dbpc, 0, tmpsize); - dbpc->itemcount = tmp; - dbpc->size = size; - dbpc->locked = is_locked; - dbpc->copper = copper; - dbpc->silver = silver; - dbpc->gold = gold; - dbpc->plat = platinum; - dbpc->race = race; - dbpc->class_ = class_; - dbpc->gender = gender; - dbpc->deity = deity; - dbpc->level = level; - dbpc->texture = texture; - dbpc->helmtexture = helmtexture; - dbpc->exp = rez_experience; + ce.size = size; + ce.locked = is_locked; + ce.copper = copper; + ce.silver = silver; + ce.gold = gold; + ce.plat = platinum; + ce.race = race; + ce.class_ = class_; + ce.gender = gender; + ce.deity = deity; + ce.level = level; + ce.texture = texture; + ce.helmtexture = helmtexture; + ce.exp = rez_experience; + ce.item_tint = item_tint; + ce.haircolor = haircolor; + ce.beardcolor = beardcolor; + ce.eyecolor2 = eyecolor1; + ce.hairstyle = hairstyle; + ce.face = luclinface; + ce.beard = beard; + ce.drakkin_heritage = drakkin_heritage; + ce.drakkin_tattoo = drakkin_tattoo; + ce.drakkin_details = drakkin_details; - memcpy(&dbpc->item_tint.Slot, &item_tint.Slot, sizeof(dbpc->item_tint)); - dbpc->haircolor = haircolor; - dbpc->beardcolor = beardcolor; - dbpc->eyecolor2 = eyecolor1; - dbpc->hairstyle = hairstyle; - dbpc->face = luclinface; - dbpc->beard = beard; - dbpc->drakkin_heritage = drakkin_heritage; - dbpc->drakkin_tattoo = drakkin_tattoo; - dbpc->drakkin_details = drakkin_details; + for (auto &item: itemlist) { + CharacterCorpseItemEntry e; - uint32 x = 0; - ItemList::iterator cur, end; - cur = itemlist.begin(); - end = itemlist.end(); - for (; cur != end; ++cur) { - ServerLootItem_Struct* item = *cur; - memcpy((char*)&dbpc->items[x++], (char*)item, sizeof(player_lootitem::ServerLootItem_Struct)); + e.item_id = item->item_id; + e.equip_slot = item->equip_slot; + e.charges = item->charges; + e.lootslot = item->lootslot; + e.aug_1 = item->aug_1; + e.aug_2 = item->aug_2; + e.aug_3 = item->aug_3; + e.aug_4 = item->aug_4; + e.aug_5 = item->aug_5; + e.aug_6 = item->aug_6; + e.attuned = item->attuned; + e.custom_data = item->custom_data; + e.ornamenticon = item->ornamenticon; + e.ornamentidfile = item->ornamentidfile; + e.ornament_hero_model = item->ornament_hero_model; + + ce.items.push_back(std::move(e)); } /* Create New Corpse*/ if (corpse_db_id == 0) { - corpse_db_id = database.SaveCharacterCorpse(char_id, corpse_name, zone->GetZoneID(), zone->GetInstanceID(), dbpc, m_Position, consented_guild_id); + corpse_db_id = database.SaveCharacterCorpse(char_id, corpse_name, zone->GetZoneID(), zone->GetInstanceID(), ce, m_Position, consented_guild_id); } /* Update Corpse Data */ else{ - corpse_db_id = database.UpdateCharacterCorpse(corpse_db_id, char_id, corpse_name, zone->GetZoneID(), zone->GetInstanceID(), dbpc, m_Position, consented_guild_id, IsRezzed()); + corpse_db_id = database.UpdateCharacterCorpse(corpse_db_id, char_id, corpse_name, zone->GetZoneID(), zone->GetInstanceID(), ce, m_Position, consented_guild_id, IsRezzed()); } - safe_delete_array(dbpc); - return true; } @@ -784,7 +812,21 @@ uint32 Corpse::CountItems() { return itemlist.size(); } -void Corpse::AddItem(uint32 itemnum, uint16 charges, int16 slot, uint32 aug1, uint32 aug2, uint32 aug3, uint32 aug4, uint32 aug5, uint32 aug6, uint8 attuned) { +void Corpse::AddItem(uint32 itemnum, + uint16 charges, + int16 slot, + uint32 aug1, + uint32 aug2, + uint32 aug3, + uint32 aug4, + uint32 aug5, + uint32 aug6, + bool attuned, + const std::string& custom_data, + uint32 ornamenticon, + uint32 ornamentidfile, + uint32 ornament_hero_model) { + if (!database.GetItem(itemnum)) return; @@ -792,17 +834,21 @@ void Corpse::AddItem(uint32 itemnum, uint16 charges, int16 slot, uint32 aug1, ui auto item = new ServerLootItem_Struct; - memset(item, 0, sizeof(ServerLootItem_Struct)); item->item_id = itemnum; item->charges = charges; item->equip_slot = slot; - item->aug_1=aug1; - item->aug_2=aug2; - item->aug_3=aug3; - item->aug_4=aug4; - item->aug_5=aug5; - item->aug_6=aug6; - item->attuned=attuned; + item->aug_1 = aug1; + item->aug_2 = aug2; + item->aug_3 = aug3; + item->aug_4 = aug4; + item->aug_5 = aug5; + item->aug_6 = aug6; + item->attuned = attuned; + item->custom_data = custom_data; + item->ornamenticon = ornamenticon; + item->ornamentidfile = ornamentidfile; + item->ornament_hero_model = ornament_hero_model; + itemlist.push_back(item); UpdateEquipmentLight(); @@ -1291,7 +1337,11 @@ void Corpse::MakeLootRequestPackets(Client* client, const EQApplicationPacket* a item_data->aug_4, item_data->aug_5, item_data->aug_6, - item_data->attuned + item_data->attuned, + item_data->custom_data, + item_data->ornamenticon, + item_data->ornamentidfile, + item_data->ornament_hero_model ); if (!inst) continue; @@ -1418,7 +1468,9 @@ void Corpse::LootItem(Client *client, const EQApplicationPacket *app) if (item_data) { inst = database.CreateItem(item, item_data ? item_data->charges : 0, item_data->aug_1, item_data->aug_2, item_data->aug_3, item_data->aug_4, - item_data->aug_5, item_data->aug_6, item_data->attuned); + item_data->aug_5, item_data->aug_6, item_data->attuned, + item_data->custom_data, item_data->ornamenticon, + item_data->ornamentidfile, item_data->ornament_hero_model); } else { inst = database.CreateItem(item); diff --git a/zone/corpse.h b/zone/corpse.h index ac76f9b85..c9f7b4652 100644 --- a/zone/corpse.h +++ b/zone/corpse.h @@ -100,7 +100,20 @@ class Corpse : public Mob { void RemoveItem(uint16 lootslot); void RemoveItem(ServerLootItem_Struct* item_data); void RemoveItemByID(uint32 item_id, int quantity = 1); - void AddItem(uint32 itemnum, uint16 charges, int16 slot = 0, uint32 aug1 = 0, uint32 aug2 = 0, uint32 aug3 = 0, uint32 aug4 = 0, uint32 aug5 = 0, uint32 aug6 = 0, uint8 attuned = 0); + void AddItem(uint32 itemnum, + uint16 charges, + int16 slot = 0, + uint32 aug1 = 0, + uint32 aug2 = 0, + uint32 aug3 = 0, + uint32 aug4 = 0, + uint32 aug5 = 0, + uint32 aug6 = 0, + bool attuned = false, + const std::string &custom_data = std::string(), + uint32 ornamenticon = 0, + uint32 ornamentidfile = 0, + uint32 ornament_hero_model = 0); /* Corpse: Coin */ void SetCash(uint32 in_copper, uint32 in_silver, uint32 in_gold, uint32 in_platinum); diff --git a/zone/inventory.cpp b/zone/inventory.cpp index 6f8854b3f..f71b34fce 100644 --- a/zone/inventory.cpp +++ b/zone/inventory.cpp @@ -1387,7 +1387,11 @@ void Client::PutLootInInventory(int16 slot_id, const EQ::ItemInstance &inst, Ser bag_item_data[index]->aug_4, bag_item_data[index]->aug_5, bag_item_data[index]->aug_6, - bag_item_data[index]->attuned + bag_item_data[index]->attuned, + bag_item_data[index]->custom_data, + bag_item_data[index]->ornamenticon, + bag_item_data[index]->ornamentidfile, + bag_item_data[index]->ornament_hero_model ); // Dump bag contents to cursor in the event that owning bag is not the first cursor item @@ -3958,7 +3962,7 @@ bool Client::InterrogateInventory_error(int16 head, int16 index, const EQ::ItemI return false; } -void EQ::InventoryProfile::SetCustomItemData(uint32 character_id, int16 slot_id, std::string identifier, std::string value) { +void EQ::InventoryProfile::SetCustomItemData(uint32 character_id, int16 slot_id, const std::string &identifier, const std::string &value) { EQ::ItemInstance *inst = GetItem(slot_id); if(inst) { inst->SetCustomData(identifier, value); @@ -3966,7 +3970,7 @@ void EQ::InventoryProfile::SetCustomItemData(uint32 character_id, int16 slot_id, } } -void EQ::InventoryProfile::SetCustomItemData(uint32 character_id, int16 slot_id, std::string identifier, int value) { +void EQ::InventoryProfile::SetCustomItemData(uint32 character_id, int16 slot_id, const std::string &identifier, int value) { EQ::ItemInstance *inst = GetItem(slot_id); if(inst) { inst->SetCustomData(identifier, value); @@ -3974,7 +3978,7 @@ void EQ::InventoryProfile::SetCustomItemData(uint32 character_id, int16 slot_id, } } -void EQ::InventoryProfile::SetCustomItemData(uint32 character_id, int16 slot_id, std::string identifier, float value) { +void EQ::InventoryProfile::SetCustomItemData(uint32 character_id, int16 slot_id, const std::string &identifier, float value) { EQ::ItemInstance *inst = GetItem(slot_id); if(inst) { inst->SetCustomData(identifier, value); @@ -3982,7 +3986,7 @@ void EQ::InventoryProfile::SetCustomItemData(uint32 character_id, int16 slot_id, } } -void EQ::InventoryProfile::SetCustomItemData(uint32 character_id, int16 slot_id, std::string identifier, bool value) { +void EQ::InventoryProfile::SetCustomItemData(uint32 character_id, int16 slot_id, const std::string &identifier, bool value) { EQ::ItemInstance *inst = GetItem(slot_id); if(inst) { inst->SetCustomData(identifier, value); @@ -3990,7 +3994,7 @@ void EQ::InventoryProfile::SetCustomItemData(uint32 character_id, int16 slot_id, } } -std::string EQ::InventoryProfile::GetCustomItemData(int16 slot_id, std::string identifier) { +std::string EQ::InventoryProfile::GetCustomItemData(int16 slot_id, const std::string &identifier) { EQ::ItemInstance *inst = GetItem(slot_id); if(inst) { return inst->GetCustomData(identifier); @@ -3998,7 +4002,7 @@ std::string EQ::InventoryProfile::GetCustomItemData(int16 slot_id, std::string i return ""; } -const int EQ::InventoryProfile::GetItemStatValue(uint32 item_id, std::string identifier) { +const int EQ::InventoryProfile::GetItemStatValue(uint32 item_id, const std::string &identifier) { if (identifier.empty()) { return 0; } diff --git a/zone/lua_iteminst.cpp b/zone/lua_iteminst.cpp index 54f7deef4..180856f66 100644 --- a/zone/lua_iteminst.cpp +++ b/zone/lua_iteminst.cpp @@ -179,32 +179,32 @@ std::string Lua_ItemInst::GetCustomDataString() { return self->GetCustomDataString(); } -void Lua_ItemInst::SetCustomData(std::string identifier, std::string value) { +void Lua_ItemInst::SetCustomData(const std::string &identifier, const std::string& value) { Lua_Safe_Call_Void(); self->SetCustomData(identifier, value); } -void Lua_ItemInst::SetCustomData(std::string identifier, int value) { +void Lua_ItemInst::SetCustomData(const std::string& identifier, int value) { Lua_Safe_Call_Void(); self->SetCustomData(identifier, value); } -void Lua_ItemInst::SetCustomData(std::string identifier, float value) { +void Lua_ItemInst::SetCustomData(const std::string& identifier, float value) { Lua_Safe_Call_Void(); self->SetCustomData(identifier, value); } -void Lua_ItemInst::SetCustomData(std::string identifier, bool value) { +void Lua_ItemInst::SetCustomData(const std::string& identifier, bool value) { Lua_Safe_Call_Void(); self->SetCustomData(identifier, value); } -std::string Lua_ItemInst::GetCustomData(std::string identifier) { +std::string Lua_ItemInst::GetCustomData(const std::string& identifier) { Lua_Safe_Call_String(); return self->GetCustomData(identifier); } -void Lua_ItemInst::DeleteCustomData(std::string identifier) { +void Lua_ItemInst::DeleteCustomData(const std::string& identifier) { Lua_Safe_Call_Void(); self->DeleteCustomData(identifier); } @@ -296,13 +296,13 @@ luabind::scope lua_register_iteminst() { .def("Clone", (Lua_ItemInst(Lua_ItemInst::*)(void))&Lua_ItemInst::Clone) .def("ContainsAugmentByID", (bool(Lua_ItemInst::*)(uint32))&Lua_ItemInst::ContainsAugmentByID) .def("CountAugmentByID", (int(Lua_ItemInst::*)(uint32))&Lua_ItemInst::CountAugmentByID) - .def("DeleteCustomData", (void(Lua_ItemInst::*)(std::string))&Lua_ItemInst::DeleteCustomData) + .def("DeleteCustomData", (void(Lua_ItemInst::*)(const std::string &))&Lua_ItemInst::DeleteCustomData) .def("GetAugment", (Lua_ItemInst(Lua_ItemInst::*)(int))&Lua_ItemInst::GetAugment) .def("GetAugmentItemID", (uint32(Lua_ItemInst::*)(int))&Lua_ItemInst::GetAugmentItemID) .def("GetAugmentType", (int(Lua_ItemInst::*)(void))&Lua_ItemInst::GetAugmentType) .def("GetCharges", (int(Lua_ItemInst::*)(void))&Lua_ItemInst::GetCharges) .def("GetColor", (uint32(Lua_ItemInst::*)(void))&Lua_ItemInst::GetColor) - .def("GetCustomData", (std::string(Lua_ItemInst::*)(std::string))&Lua_ItemInst::GetCustomData) + .def("GetCustomData", (std::string(Lua_ItemInst::*)(const std::string &))&Lua_ItemInst::GetCustomData) .def("GetCustomDataString", (std::string(Lua_ItemInst::*)(void))&Lua_ItemInst::GetCustomDataString) .def("GetExp", (uint32(Lua_ItemInst::*)(void))&Lua_ItemInst::GetExp) .def("GetID", (uint32(Lua_ItemInst::*)(void))&Lua_ItemInst::GetID) @@ -329,10 +329,10 @@ luabind::scope lua_register_iteminst() { .def("RemoveTaskDeliveredItems", &Lua_ItemInst::RemoveTaskDeliveredItems) .def("SetCharges", (void(Lua_ItemInst::*)(int))&Lua_ItemInst::SetCharges) .def("SetColor", (void(Lua_ItemInst::*)(uint32))&Lua_ItemInst::SetColor) - .def("SetCustomData", (void(Lua_ItemInst::*)(std::string,bool))&Lua_ItemInst::SetCustomData) - .def("SetCustomData", (void(Lua_ItemInst::*)(std::string,float))&Lua_ItemInst::SetCustomData) - .def("SetCustomData", (void(Lua_ItemInst::*)(std::string,int))&Lua_ItemInst::SetCustomData) - .def("SetCustomData", (void(Lua_ItemInst::*)(std::string,std::string))&Lua_ItemInst::SetCustomData) + .def("SetCustomData", (void(Lua_ItemInst::*)(const std::string&,bool))&Lua_ItemInst::SetCustomData) + .def("SetCustomData", (void(Lua_ItemInst::*)(const std::string&,float))&Lua_ItemInst::SetCustomData) + .def("SetCustomData", (void(Lua_ItemInst::*)(const std::string&,int))&Lua_ItemInst::SetCustomData) + .def("SetCustomData", (void(Lua_ItemInst::*)(const std::string&,const std::string&))&Lua_ItemInst::SetCustomData) .def("SetExp", (void(Lua_ItemInst::*)(uint32))&Lua_ItemInst::SetExp) .def("SetInstNoDrop", (void(Lua_ItemInst::*)(bool))&Lua_ItemInst::SetInstNoDrop) .def("SetPrice", (void(Lua_ItemInst::*)(uint32))&Lua_ItemInst::SetPrice) diff --git a/zone/lua_iteminst.h b/zone/lua_iteminst.h index 04138dafd..ea8e98e37 100644 --- a/zone/lua_iteminst.h +++ b/zone/lua_iteminst.h @@ -63,12 +63,12 @@ public: bool IsInstNoDrop(); void SetInstNoDrop(bool flag); std::string GetCustomDataString(); - void SetCustomData(std::string identifier, std::string value); - void SetCustomData(std::string identifier, int value); - void SetCustomData(std::string identifier, float value); - void SetCustomData(std::string identifier, bool value); - std::string GetCustomData(std::string identifier); - void DeleteCustomData(std::string identifier); + void SetCustomData(const std::string &identifier, const std::string &value); + void SetCustomData(const std::string &identifier, int value); + void SetCustomData(const std::string &identifier, float value); + void SetCustomData(const std::string &identifier, bool value); + std::string GetCustomData(const std::string& identifier); + void DeleteCustomData(const std::string& identifier); void SetScaling(bool v); void SetScale(double scale_factor); uint32 GetExp(); diff --git a/zone/questmgr.cpp b/zone/questmgr.cpp index 7c2898c7c..027df7e0b 100644 --- a/zone/questmgr.cpp +++ b/zone/questmgr.cpp @@ -3606,7 +3606,17 @@ void QuestManager::UpdateZoneHeader(std::string type, std::string value) { EQ::ItemInstance *QuestManager::CreateItem(uint32 item_id, int16 charges, uint32 augment_one, uint32 augment_two, uint32 augment_three, uint32 augment_four, uint32 augment_five, uint32 augment_six, bool attuned) const { if (database.GetItem(item_id)) { - return database.CreateItem(item_id, charges, augment_one, augment_two, augment_three, augment_four, augment_five, augment_six, attuned); + return database.CreateItem( + item_id, + charges, + augment_one, + augment_two, + augment_three, + augment_four, + augment_five, + augment_six, + attuned + ); } return nullptr; } diff --git a/zone/zonedb.cpp b/zone/zonedb.cpp index 734b70677..62e984f4d 100755 --- a/zone/zonedb.cpp +++ b/zone/zonedb.cpp @@ -3780,7 +3780,7 @@ uint32 ZoneDatabase::GetCharacterCorpseDecayTimer(uint32 corpse_db_id){ return 0; } -uint32 ZoneDatabase::UpdateCharacterCorpse(uint32 db_id, uint32 char_id, const char* char_name, uint32 zone_id, uint16 instance_id, PlayerCorpse_Struct* dbpc, const glm::vec4& position, uint32 guild_id, bool is_rezzed) { +uint32 ZoneDatabase::UpdateCharacterCorpse(uint32 db_id, uint32 char_id, const char* char_name, uint32 zone_id, uint16 instance_id, const CharacterCorpseEntry& corpse, const glm::vec4& position, uint32 guild_id, bool is_rezzed) { std::string query = StringFormat("UPDATE `character_corpses` " "SET `charname` = '%s', `zone_id` = %u, `instance_id` = %u, `charid` = %d, " "`x` = %1.1f,`y` = %1.1f,`z` = %1.1f, `heading` = %1.1f, `guild_consent_id` = %u, " @@ -3796,15 +3796,15 @@ uint32 ZoneDatabase::UpdateCharacterCorpse(uint32 db_id, uint32 char_id, const c "WHERE `id` = %u", Strings::Escape(char_name).c_str(), zone_id, instance_id, char_id, position.x, position.y, position.z, position.w, guild_id, - dbpc->locked, dbpc->exp, dbpc->size, dbpc->level, dbpc->race, - dbpc->gender, dbpc->class_, dbpc->deity, dbpc->texture, - dbpc->helmtexture, dbpc->copper, dbpc->silver, dbpc->gold, - dbpc->plat, dbpc->haircolor, dbpc->beardcolor, dbpc->eyecolor1, - dbpc->eyecolor2, dbpc->hairstyle, dbpc->face, dbpc->beard, - dbpc->drakkin_heritage, dbpc->drakkin_tattoo, dbpc->drakkin_details, - dbpc->item_tint.Head.Color, dbpc->item_tint.Chest.Color, dbpc->item_tint.Arms.Color, - dbpc->item_tint.Wrist.Color, dbpc->item_tint.Hands.Color, dbpc->item_tint.Legs.Color, - dbpc->item_tint.Feet.Color, dbpc->item_tint.Primary.Color, dbpc->item_tint.Secondary.Color, + corpse.locked, corpse.exp, corpse.size, corpse.level, corpse.race, + corpse.gender, corpse.class_, corpse.deity, corpse.texture, + corpse.helmtexture, corpse.copper, corpse.silver, corpse.gold, + corpse.plat, corpse.haircolor, corpse.beardcolor, corpse.eyecolor1, + corpse.eyecolor2, corpse.hairstyle, corpse.face, corpse.beard, + corpse.drakkin_heritage, corpse.drakkin_tattoo, corpse.drakkin_details, + corpse.item_tint.Head.Color, corpse.item_tint.Chest.Color, corpse.item_tint.Arms.Color, + corpse.item_tint.Wrist.Color, corpse.item_tint.Hands.Color, corpse.item_tint.Legs.Color, + corpse.item_tint.Feet.Color, corpse.item_tint.Primary.Color, corpse.item_tint.Secondary.Color, db_id); auto results = QueryDatabase(query); @@ -3823,7 +3823,7 @@ void ZoneDatabase::MarkCorpseAsRezzed(uint32 db_id) { auto results = QueryDatabase(query); } -uint32 ZoneDatabase::SaveCharacterCorpse(uint32 charid, const char* charname, uint32 zoneid, uint16 instanceid, PlayerCorpse_Struct* dbpc, const glm::vec4& position, uint32 guildid) { +uint32 ZoneDatabase::SaveCharacterCorpse(uint32 charid, const char* charname, uint32 zoneid, uint16 instanceid, const CharacterCorpseEntry& corpse, const glm::vec4& position, uint32 guildid) { /* Dump Basic Corpse Data */ std::string query = StringFormat( "INSERT INTO `character_corpses` " @@ -3880,39 +3880,39 @@ uint32 ZoneDatabase::SaveCharacterCorpse(uint32 charid, const char* charname, ui position.z, position.w, guildid, - dbpc->locked, - dbpc->exp, - dbpc->size, - dbpc->level, - dbpc->race, - dbpc->gender, - dbpc->class_, - dbpc->deity, - dbpc->texture, - dbpc->helmtexture, - dbpc->copper, - dbpc->silver, - dbpc->gold, - dbpc->plat, - dbpc->haircolor, - dbpc->beardcolor, - dbpc->eyecolor1, - dbpc->eyecolor2, - dbpc->hairstyle, - dbpc->face, - dbpc->beard, - dbpc->drakkin_heritage, - dbpc->drakkin_tattoo, - dbpc->drakkin_details, - dbpc->item_tint.Head.Color, - dbpc->item_tint.Chest.Color, - dbpc->item_tint.Arms.Color, - dbpc->item_tint.Wrist.Color, - dbpc->item_tint.Hands.Color, - dbpc->item_tint.Legs.Color, - dbpc->item_tint.Feet.Color, - dbpc->item_tint.Primary.Color, - dbpc->item_tint.Secondary.Color + corpse.locked, + corpse.exp, + corpse.size, + corpse.level, + corpse.race, + corpse.gender, + corpse.class_, + corpse.deity, + corpse.texture, + corpse.helmtexture, + corpse.copper, + corpse.silver, + corpse.gold, + corpse.plat, + corpse.haircolor, + corpse.beardcolor, + corpse.eyecolor1, + corpse.eyecolor2, + corpse.hairstyle, + corpse.face, + corpse.beard, + corpse.drakkin_heritage, + corpse.drakkin_tattoo, + corpse.drakkin_details, + corpse.item_tint.Head.Color, + corpse.item_tint.Chest.Color, + corpse.item_tint.Arms.Color, + corpse.item_tint.Wrist.Color, + corpse.item_tint.Hands.Color, + corpse.item_tint.Legs.Color, + corpse.item_tint.Feet.Color, + corpse.item_tint.Primary.Color, + corpse.item_tint.Secondary.Color ); auto results = QueryDatabase(query); uint32 last_insert_id = results.LastInsertedID(); @@ -3920,41 +3920,51 @@ uint32 ZoneDatabase::SaveCharacterCorpse(uint32 charid, const char* charname, ui std::string corpse_items_query; /* Dump Items from Inventory */ uint8 first_entry = 0; - for (unsigned int i = 0; i < dbpc->itemcount; i++) { + for(auto &item : corpse.items) + { if (first_entry != 1){ corpse_items_query = StringFormat("REPLACE INTO `character_corpse_items` \n" - " (corpse_id, equip_slot, item_id, charges, aug_1, aug_2, aug_3, aug_4, aug_5, aug_6, attuned) \n" - " VALUES (%u, %u, %u, %u, %u, %u, %u, %u, %u, %u, %u) \n", + " (corpse_id, equip_slot, item_id, charges, aug_1, aug_2, aug_3, aug_4, aug_5, aug_6, attuned, custom_data, ornamenticon, ornamentidfile, ornament_hero_model) \n" + " VALUES (%u, %u, %u, %u, %u, %u, %u, %u, %u, %u, %u, '%s', %u, %u, %u) \n", last_insert_id, - dbpc->items[i].equip_slot, - dbpc->items[i].item_id, - dbpc->items[i].charges, - dbpc->items[i].aug_1, - dbpc->items[i].aug_2, - dbpc->items[i].aug_3, - dbpc->items[i].aug_4, - dbpc->items[i].aug_5, - dbpc->items[i].aug_6, - dbpc->items[i].attuned + item.equip_slot, + item.item_id, + item.charges, + item.aug_1, + item.aug_2, + item.aug_3, + item.aug_4, + item.aug_5, + item.aug_6, + item.attuned, + item.custom_data.c_str(), + item.ornamenticon, + item.ornamentidfile, + item.ornament_hero_model ); first_entry = 1; } else{ - corpse_items_query = corpse_items_query + StringFormat(", (%u, %u, %u, %u, %u, %u, %u, %u, %u, %u, %u) \n", + corpse_items_query = corpse_items_query + StringFormat(", (%u, %u, %u, %u, %u, %u, %u, %u, %u, %u, %u, '%s', %u, %u, %u) \n", last_insert_id, - dbpc->items[i].equip_slot, - dbpc->items[i].item_id, - dbpc->items[i].charges, - dbpc->items[i].aug_1, - dbpc->items[i].aug_2, - dbpc->items[i].aug_3, - dbpc->items[i].aug_4, - dbpc->items[i].aug_5, - dbpc->items[i].aug_6, - dbpc->items[i].attuned + item.equip_slot, + item.item_id, + item.charges, + item.aug_1, + item.aug_2, + item.aug_3, + item.aug_4, + item.aug_5, + item.aug_6, + item.attuned, + item.custom_data.c_str(), + item.ornamenticon, + item.ornamentidfile, + item.ornament_hero_model ); } } + if (!corpse_items_query.empty()) QueryDatabase(corpse_items_query); @@ -3993,18 +4003,6 @@ uint32 ZoneDatabase::GetCharacterCorpseID(uint32 char_id, uint8 corpse) { return 0; } -uint32 ZoneDatabase::GetCharacterCorpseItemCount(uint32 corpse_id){ - std::string query = StringFormat("SELECT COUNT(*) FROM character_corpse_items WHERE `corpse_id` = %u", - corpse_id - ); - auto results = QueryDatabase(query); - auto& row = results.begin(); - if (results.Success() && results.RowsAffected() != 0){ - return Strings::ToInt(row[0]); - } - return 0; -} - uint32 ZoneDatabase::GetCharacterCorpseItemAt(uint32 corpse_id, uint16 slotid) { Corpse* tmp = LoadCharacterCorpse(corpse_id); uint32 itemid = 0; @@ -4016,7 +4014,7 @@ uint32 ZoneDatabase::GetCharacterCorpseItemAt(uint32 corpse_id, uint16 slotid) { return itemid; } -bool ZoneDatabase::LoadCharacterCorpseData(uint32 corpse_id, PlayerCorpse_Struct* pcs){ +bool ZoneDatabase::LoadCharacterCorpseData(uint32 corpse_id, CharacterCorpseEntry& corpse){ std::string query = StringFormat( "SELECT \n" "is_locked, \n" @@ -4060,39 +4058,39 @@ bool ZoneDatabase::LoadCharacterCorpseData(uint32 corpse_id, PlayerCorpse_Struct auto results = QueryDatabase(query); uint16 i = 0; for (auto& row = results.begin(); row != results.end(); ++row) { - pcs->locked = Strings::ToInt(row[i++]); // is_locked, - pcs->exp = Strings::ToUnsignedInt(row[i++]); // exp, - pcs->size = Strings::ToInt(row[i++]); // size, - pcs->level = Strings::ToInt(row[i++]); // `level`, - pcs->race = Strings::ToInt(row[i++]); // race, - pcs->gender = Strings::ToInt(row[i++]); // gender, - pcs->class_ = Strings::ToInt(row[i++]); // class, - pcs->deity = Strings::ToInt(row[i++]); // deity, - pcs->texture = Strings::ToInt(row[i++]); // texture, - pcs->helmtexture = Strings::ToInt(row[i++]); // helm_texture, - pcs->copper = Strings::ToUnsignedInt(row[i++]); // copper, - pcs->silver = Strings::ToUnsignedInt(row[i++]); // silver, - pcs->gold = Strings::ToUnsignedInt(row[i++]); // gold, - pcs->plat = Strings::ToUnsignedInt(row[i++]); // platinum, - pcs->haircolor = Strings::ToInt(row[i++]); // hair_color, - pcs->beardcolor = Strings::ToInt(row[i++]); // beard_color, - pcs->eyecolor1 = Strings::ToInt(row[i++]); // eye_color_1, - pcs->eyecolor2 = Strings::ToInt(row[i++]); // eye_color_2, - pcs->hairstyle = Strings::ToInt(row[i++]); // hair_style, - pcs->face = Strings::ToInt(row[i++]); // face, - pcs->beard = Strings::ToInt(row[i++]); // beard, - pcs->drakkin_heritage = Strings::ToUnsignedInt(row[i++]); // drakkin_heritage, - pcs->drakkin_tattoo = Strings::ToUnsignedInt(row[i++]); // drakkin_tattoo, - pcs->drakkin_details = Strings::ToUnsignedInt(row[i++]); // drakkin_details, - pcs->item_tint.Head.Color = Strings::ToUnsignedInt(row[i++]); // wc_1, - pcs->item_tint.Chest.Color = Strings::ToUnsignedInt(row[i++]); // wc_2, - pcs->item_tint.Arms.Color = Strings::ToUnsignedInt(row[i++]); // wc_3, - pcs->item_tint.Wrist.Color = Strings::ToUnsignedInt(row[i++]); // wc_4, - pcs->item_tint.Hands.Color = Strings::ToUnsignedInt(row[i++]); // wc_5, - pcs->item_tint.Legs.Color = Strings::ToUnsignedInt(row[i++]); // wc_6, - pcs->item_tint.Feet.Color = Strings::ToUnsignedInt(row[i++]); // wc_7, - pcs->item_tint.Primary.Color = Strings::ToUnsignedInt(row[i++]); // wc_8, - pcs->item_tint.Secondary.Color = Strings::ToUnsignedInt(row[i++]); // wc_9 + corpse.locked = Strings::ToInt(row[i++]); // is_locked, + corpse.exp = Strings::ToUnsignedInt(row[i++]); // exp, + corpse.size = Strings::ToInt(row[i++]); // size, + corpse.level = Strings::ToInt(row[i++]); // `level`, + corpse.race = Strings::ToInt(row[i++]); // race, + corpse.gender = Strings::ToInt(row[i++]); // gender, + corpse.class_ = Strings::ToInt(row[i++]); // class, + corpse.deity = Strings::ToInt(row[i++]); // deity, + corpse.texture = Strings::ToInt(row[i++]); // texture, + corpse.helmtexture = Strings::ToInt(row[i++]); // helm_texture, + corpse.copper = Strings::ToUnsignedInt(row[i++]); // copper, + corpse.silver = Strings::ToUnsignedInt(row[i++]); // silver, + corpse.gold = Strings::ToUnsignedInt(row[i++]); // gold, + corpse.plat = Strings::ToUnsignedInt(row[i++]); // platinum, + corpse.haircolor = Strings::ToInt(row[i++]); // hair_color, + corpse.beardcolor = Strings::ToInt(row[i++]); // beard_color, + corpse.eyecolor1 = Strings::ToInt(row[i++]); // eye_color_1, + corpse.eyecolor2 = Strings::ToInt(row[i++]); // eye_color_2, + corpse.hairstyle = Strings::ToInt(row[i++]); // hair_style, + corpse.face = Strings::ToInt(row[i++]); // face, + corpse.beard = Strings::ToInt(row[i++]); // beard, + corpse.drakkin_heritage = Strings::ToUnsignedInt(row[i++]); // drakkin_heritage, + corpse.drakkin_tattoo = Strings::ToUnsignedInt(row[i++]); // drakkin_tattoo, + corpse.drakkin_details = Strings::ToUnsignedInt(row[i++]); // drakkin_details, + corpse.item_tint.Head.Color = Strings::ToUnsignedInt(row[i++]); // wc_1, + corpse.item_tint.Chest.Color = Strings::ToUnsignedInt(row[i++]); // wc_2, + corpse.item_tint.Arms.Color = Strings::ToUnsignedInt(row[i++]); // wc_3, + corpse.item_tint.Wrist.Color = Strings::ToUnsignedInt(row[i++]); // wc_4, + corpse.item_tint.Hands.Color = Strings::ToUnsignedInt(row[i++]); // wc_5, + corpse.item_tint.Legs.Color = Strings::ToUnsignedInt(row[i++]); // wc_6, + corpse.item_tint.Feet.Color = Strings::ToUnsignedInt(row[i++]); // wc_7, + corpse.item_tint.Primary.Color = Strings::ToUnsignedInt(row[i++]); // wc_8, + corpse.item_tint.Secondary.Color = Strings::ToUnsignedInt(row[i++]); // wc_9 } query = StringFormat( "SELECT \n" @@ -4105,7 +4103,11 @@ bool ZoneDatabase::LoadCharacterCorpseData(uint32 corpse_id, PlayerCorpse_Struct "aug_4, \n" "aug_5, \n" "aug_6, \n" - "attuned \n" + "attuned, \n" + "custom_data, \n" + "ornamenticon, \n" + "ornamentidfile, \n" + "ornament_hero_model \n" "FROM \n" "character_corpse_items \n" "WHERE `corpse_id` = %u\n" @@ -4115,20 +4117,32 @@ bool ZoneDatabase::LoadCharacterCorpseData(uint32 corpse_id, PlayerCorpse_Struct results = QueryDatabase(query); i = 0; - pcs->itemcount = results.RowCount(); uint16 r = 0; for (auto& row = results.begin(); row != results.end(); ++row) { - memset(&pcs->items[i], 0, sizeof (player_lootitem::ServerLootItem_Struct)); - pcs->items[i].equip_slot = Strings::ToInt(row[r++]); // equip_slot, - pcs->items[i].item_id = Strings::ToUnsignedInt(row[r++]); // item_id, - pcs->items[i].charges = Strings::ToInt(row[r++]); // charges, - pcs->items[i].aug_1 = Strings::ToInt(row[r++]); // aug_1, - pcs->items[i].aug_2 = Strings::ToInt(row[r++]); // aug_2, - pcs->items[i].aug_3 = Strings::ToInt(row[r++]); // aug_3, - pcs->items[i].aug_4 = Strings::ToInt(row[r++]); // aug_4, - pcs->items[i].aug_5 = Strings::ToInt(row[r++]); // aug_5, - pcs->items[i].aug_6 = Strings::ToInt(row[r++]); // aug_6, - pcs->items[i].attuned = Strings::ToInt(row[r++]); // attuned, + CharacterCorpseItemEntry item; + item.equip_slot = Strings::ToInt(row[r++]); // equip_slot, + item.item_id = Strings::ToUnsignedInt(row[r++]); // item_id, + item.charges = Strings::ToInt(row[r++]); // charges, + item.aug_1 = Strings::ToInt(row[r++]); // aug_1, + item.aug_2 = Strings::ToInt(row[r++]); // aug_2, + item.aug_3 = Strings::ToInt(row[r++]); // aug_3, + item.aug_4 = Strings::ToInt(row[r++]); // aug_4, + item.aug_5 = Strings::ToInt(row[r++]); // aug_5, + item.aug_6 = Strings::ToInt(row[r++]); // aug_6, + item.attuned = Strings::ToInt(row[r++]) > 0 ? true : false; // attuned, + + if (row[r]) { + item.custom_data = row[r++]; + } + else { + r++; + } + + item.ornamenticon = Strings::ToUnsignedInt(row[r++]); + item.ornamentidfile = Strings::ToUnsignedInt(row[r++]); + item.ornament_hero_model = Strings::ToUnsignedInt(row[r++]); + + corpse.items.push_back(std::move(item)); r = 0; i++; } diff --git a/zone/zonedb.h b/zone/zonedb.h index b7c196a78..23309128c 100644 --- a/zone/zonedb.h +++ b/zone/zonedb.h @@ -285,6 +285,55 @@ struct ClientMercEntry { uint32 npcid; }; +struct CharacterCorpseItemEntry +{ + uint32 item_id; + int16 equip_slot; + uint16 charges; + uint16 lootslot; + uint32 aug_1; + uint32 aug_2; + uint32 aug_3; + uint32 aug_4; + uint32 aug_5; + uint32 aug_6; + bool attuned; + std::string custom_data; + uint32 ornamenticon; + uint32 ornamentidfile; + uint32 ornament_hero_model; +}; + +struct CharacterCorpseEntry +{ + bool locked; + uint32 exp; + float size; + uint8 level; + uint32 race; + uint8 gender; + uint8 class_; + uint8 deity; + uint8 texture; + uint8 helmtexture; + uint32 copper; + uint32 silver; + uint32 gold; + uint32 plat; + EQ::TintProfile item_tint; + uint8 haircolor; + uint8 beardcolor; + uint8 eyecolor1; + uint8 eyecolor2; + uint8 hairstyle; + uint8 face; + uint8 beard; + uint32 drakkin_heritage; + uint32 drakkin_tattoo; + uint32 drakkin_details; + std::vector items; +}; + namespace BeastlordPetData { struct PetStruct { uint16 race_id = WOLF; @@ -429,8 +478,7 @@ public: /* Corpses */ bool DeleteItemOffCharacterCorpse(uint32 db_id, uint32 equip_slot, uint32 item_id); - uint32 GetCharacterCorpseItemCount(uint32 corpse_id); - bool LoadCharacterCorpseData(uint32 corpse_id, PlayerCorpse_Struct* pcs); + bool LoadCharacterCorpseData(uint32 corpse_id, CharacterCorpseEntry &corpse); Corpse* LoadCharacterCorpse(uint32 player_corpse_id); Corpse* SummonBuriedCharacterCorpses(uint32 char_id, uint32 dest_zoneid, uint16 dest_instanceid, const glm::vec4& position); void MarkCorpseAsRezzed(uint32 dbid); @@ -446,8 +494,8 @@ public: uint32 GetCharacterCorpseDecayTimer(uint32 corpse_db_id); uint32 GetCharacterBuriedCorpseCount(uint32 char_id); uint32 SendCharacterCorpseToGraveyard(uint32 dbid, uint32 zoneid, uint16 instanceid, const glm::vec4& position); - uint32 SaveCharacterCorpse(uint32 charid, const char* charname, uint32 zoneid, uint16 instanceid, PlayerCorpse_Struct* dbpc, const glm::vec4& position, uint32 guildid); - uint32 UpdateCharacterCorpse(uint32 dbid, uint32 charid, const char* charname, uint32 zoneid, uint16 instanceid, PlayerCorpse_Struct* dbpc, const glm::vec4& position, uint32 guildid, bool rezzed = false); + uint32 SaveCharacterCorpse(uint32 charid, const char* charname, uint32 zoneid, uint16 instanceid, const CharacterCorpseEntry& corpse, const glm::vec4& position, uint32 guildid); + uint32 UpdateCharacterCorpse(uint32 dbid, uint32 charid, const char* charname, uint32 zoneid, uint16 instanceid, const CharacterCorpseEntry& corpse, const glm::vec4& position, uint32 guildid, bool rezzed = false); uint32 UpdateCharacterCorpseConsent(uint32 charid, uint32 guildid); uint32 GetFirstCorpseID(uint32 char_id); uint32 GetCharacterCorpseCount(uint32 char_id); diff --git a/zone/zonedump.h b/zone/zonedump.h index 51b21ee31..7de07c0fd 100644 --- a/zone/zonedump.h +++ b/zone/zonedump.h @@ -155,56 +155,6 @@ struct NPCType bool keeps_sold_items; }; -namespace player_lootitem { - struct ServerLootItem_Struct { - uint32 item_id; - int16 equip_slot; - uint16 charges; - uint16 lootslot; - uint32 aug_1; - uint32 aug_2; - uint32 aug_3; - uint32 aug_4; - uint32 aug_5; - uint32 aug_6; - int8 attuned; - uint8 min_level; // - uint8 max_level; // - }; -} - -struct PlayerCorpse_Struct { - uint32 crc; - bool locked; - uint32 itemcount; - uint32 exp; - float size; - uint8 level; - uint32 race; - uint8 gender; - uint8 class_; - uint8 deity; - uint8 texture; - uint8 helmtexture; - uint32 copper; - uint32 silver; - uint32 gold; - uint32 plat; - EQ::TintProfile item_tint; - uint8 haircolor; - uint8 beardcolor; - uint8 eyecolor1; - uint8 eyecolor2; - uint8 hairstyle; - uint8 face; - uint8 beard; - uint32 drakkin_heritage; - uint32 drakkin_tattoo; - uint32 drakkin_details; - player_lootitem::ServerLootItem_Struct items[0]; - //std::list items; -}; - #pragma pack() #endif From e085f271f5065230dc4ca52da545a1a27cf35ad3 Mon Sep 17 00:00:00 2001 From: Aeadoin <109764533+Aeadoin@users.noreply.github.com> Date: Thu, 23 Mar 2023 18:55:56 -0400 Subject: [PATCH 11/22] [Bug Fix] Fix for incorrect bindpoint x,y,z,headings (#3141) --- zone/zonedb.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/zone/zonedb.cpp b/zone/zonedb.cpp index 62e984f4d..f57c45daf 100755 --- a/zone/zonedb.cpp +++ b/zone/zonedb.cpp @@ -1017,10 +1017,10 @@ bool ZoneDatabase::LoadCharacterBindPoint(uint32 character_id, PlayerProfile_Str pp->binds[index].zone_id = Strings::ToInt(row[1]); pp->binds[index].instance_id = Strings::ToInt(row[2]); - pp->binds[index].x = Strings::ToInt(row[3]); - pp->binds[index].y = Strings::ToInt(row[4]); - pp->binds[index].z = Strings::ToInt(row[5]); - pp->binds[index].heading = Strings::ToInt(row[6]); + pp->binds[index].x = Strings::ToFloat(row[3]); + pp->binds[index].y = Strings::ToFloat(row[4]); + pp->binds[index].z = Strings::ToFloat(row[5]); + pp->binds[index].heading = Strings::ToFloat(row[6]); } return true; From c975dc241284120efb8f892b736622d730c85357 Mon Sep 17 00:00:00 2001 From: Aeadoin <109764533+Aeadoin@users.noreply.github.com> Date: Thu, 23 Mar 2023 19:04:59 -0400 Subject: [PATCH 12/22] [Bug Fix] Fix for transferring Raid Leader (#3140) --- zone/client_packet.cpp | 10 ++++------ zone/raids.cpp | 2 +- 2 files changed, 5 insertions(+), 7 deletions(-) diff --git a/zone/client_packet.cpp b/zone/client_packet.cpp index 1208d6a62..4e67608f5 100644 --- a/zone/client_packet.cpp +++ b/zone/client_packet.cpp @@ -12177,12 +12177,10 @@ void Client::Handle_OP_RaidCommand(const EQApplicationPacket* app) //Added to remove all bots if the Bot_Owner is removed from the Raid //Does not camp the Bots, just removes from the raid if (c_to_disband) { + uint32 i = raid->GetPlayerIndex(raid_command_packet->leader_name); + raid->SetNewRaidLeader(i); raid->HandleBotGroupDisband(c_to_disband->CharacterID()); raid->RemoveMember(raid_command_packet->leader_name); - if (raid->IsLeader(c_to_disband->GetName())) { - uint32 i = raid->GetPlayerIndex(raid_command_packet->leader_name); - raid->SetNewRaidLeader(i); - } raid->SendGroupDisband(c_to_disband); raid->GroupUpdate(group); if (!raid->RaidCount()) { @@ -12213,8 +12211,8 @@ void Client::Handle_OP_RaidCommand(const EQApplicationPacket* app) break; } } + uint32 i = raid->GetPlayerIndex(raid_command_packet->leader_name); if (group < 12) { - uint32 i = raid->GetPlayerIndex(raid_command_packet->leader_name); if (raid->members[i].is_group_leader) { //assign group leader to someone else for (int x = 0; x < MAX_RAID_MEMBERS; x++) { if (strlen(raid->members[x].member_name) > 0 && i != x) { @@ -12227,8 +12225,8 @@ void Client::Handle_OP_RaidCommand(const EQApplicationPacket* app) } } } - raid->SetNewRaidLeader(i); } + raid->SetNewRaidLeader(i); raid->RemoveMember(raid_command_packet->leader_name); Client* c = entity_list.GetClientByName(raid_command_packet->leader_name); if (c) { diff --git a/zone/raids.cpp b/zone/raids.cpp index c64d0ea42..bd28bbfe4 100644 --- a/zone/raids.cpp +++ b/zone/raids.cpp @@ -2158,7 +2158,7 @@ void Raid::SetNewRaidLeader(uint32 i) continue; } - if (m.member && strlen(m.member_name) > 0 && strcmp(m.member_name, m.member_name) != 0) { + if (m.member && strlen(m.member_name) > 0 && strcmp(m.member_name, members[i].member_name) != 0) { SetRaidLeader(members[i].member_name, m.member_name); UpdateRaidAAs(); SendAllRaidLeadershipAA(); From abc27ab4230aae9b3180ce711a999972b30410fc Mon Sep 17 00:00:00 2001 From: Aeadoin <109764533+Aeadoin@users.noreply.github.com> Date: Thu, 23 Mar 2023 19:23:34 -0400 Subject: [PATCH 13/22] [Bug Fix] Fix edge cases where camped bots would be left in a raid (#3139) * [Bug Fix] Fix edge cases where camped bots would be left in a raid * formatting --- zone/bot_raid.cpp | 31 +++++++++++++++++++++++++++++-- zone/client_packet.cpp | 1 + zone/raids.cpp | 3 +-- zone/raids.h | 1 + 4 files changed, 32 insertions(+), 4 deletions(-) diff --git a/zone/bot_raid.cpp b/zone/bot_raid.cpp index 13537e0e8..a0ba2c8c6 100644 --- a/zone/bot_raid.cpp +++ b/zone/bot_raid.cpp @@ -116,6 +116,30 @@ void Raid::HandleBotGroupDisband(uint32 owner, uint32 gid) } } +// we need to cleanup any camped/offline bots when the owner leaves the Raid +void Raid::HandleOfflineBots(uint32 owner) { + std::list bots_list; + if (!database.botdb.LoadBotsList(owner, bots_list)) { + return; + } + + for (const auto& b: bots_list) { + if (IsRaidMember(b.Name)) { + for (const auto& m: members) { + if (m.is_bot && strcmp(m.member_name, b.Name) == 0) { + uint32 gid = GetGroup(m.member_name); + SendRaidGroupRemove(m.member_name, gid); + RemoveMember(m.member_name); + GroupUpdate(gid); + if (!RaidCount()) { + DisbandRaid(); + } + } + } + } + } +} + uint8 Bot::GetNumberNeedingHealedInRaidGroup(uint8& need_healed, uint8 hpr, bool includePets, Raid* raid) { if (raid) { @@ -170,8 +194,8 @@ void Bot::CreateBotRaid(Mob* invitee, Client* invitor, bool group_invite, Raid* Group* g_invitee = invitee->GetGroup(); Group* g_invitor = invitor->GetGroup(); - if (g_invitee && invitor->IsClient()) { - if (!g_invitee->IsLeader(invitee)) { + if (g_invitee && invitor->IsClient() && !g_invitee->IsLeader(invitee)) { + if (g_invitee->GetLeader()) { invitor->Message( Chat::Red, fmt::format( @@ -180,6 +204,9 @@ void Bot::CreateBotRaid(Mob* invitee, Client* invitor, bool group_invite, Raid* ).c_str() ); return; + } else { + invitor->Message(Chat::Red, "You can only invite group leaders or ungrouped bots."); + return; } } diff --git a/zone/client_packet.cpp b/zone/client_packet.cpp index 4e67608f5..1980926c0 100644 --- a/zone/client_packet.cpp +++ b/zone/client_packet.cpp @@ -12180,6 +12180,7 @@ void Client::Handle_OP_RaidCommand(const EQApplicationPacket* app) uint32 i = raid->GetPlayerIndex(raid_command_packet->leader_name); raid->SetNewRaidLeader(i); raid->HandleBotGroupDisband(c_to_disband->CharacterID()); + raid->HandleOfflineBots(c_to_disband->CharacterID()); raid->RemoveMember(raid_command_packet->leader_name); raid->SendGroupDisband(c_to_disband); raid->GroupUpdate(group); diff --git a/zone/raids.cpp b/zone/raids.cpp index bd28bbfe4..54250e680 100644 --- a/zone/raids.cpp +++ b/zone/raids.cpp @@ -1703,11 +1703,10 @@ void Raid::VerifyRaid() //attribute before calling a client function or casting to client. b = entity_list.GetBotByBotName(m.member_name); m.member = b->CastToClient(); - m.is_bot = true; //Used to identify those members who are Bots + m.is_bot = true; } else { m.member = nullptr; - m.is_bot = false; } } diff --git a/zone/raids.h b/zone/raids.h index b8eadbc7b..d3fd1fe3c 100644 --- a/zone/raids.h +++ b/zone/raids.h @@ -256,6 +256,7 @@ public: std::vector GetRaidGroupBotMembers(uint32 gid); std::vector GetRaidBotMembers(uint32 owner = 0); void HandleBotGroupDisband(uint32 owner, uint32 gid = RAID_GROUPLESS); + void HandleOfflineBots(uint32 owner); RaidMember members[MAX_RAID_MEMBERS]; char leadername[64]; From 59ad91a1400f8219a59509cf7d3d46393571f49c Mon Sep 17 00:00:00 2001 From: Aeadoin <109764533+Aeadoin@users.noreply.github.com> Date: Thu, 23 Mar 2023 21:42:13 -0400 Subject: [PATCH 14/22] [Feature] Add Data Bucket support for scaling of Heroic Stats. (#3058) * [Feature] Add Data Bucket support for scaling of Heroic Stats. * update * fixes, still reworking logic * fixes, still reworking logic * logic done * logic done * fixes * Cleanup * Cleanup * Cleanup naming, verify behaviors * formatting * formatting * fix issue with endurance and mana. * update rule desc * cleanup * DataBucket Struct * Cleanup data_bucket.cpp and add constants * cleanup * changes * formatting * fix from merge * escape keyword `key` * Add `key` to generator, run repository-generator.pl * fix for change to key * cleanup * formatting * formatting * typo --- common/emu_constants.h | 25 +++ .../base/base_data_buckets_repository.h | 24 +-- common/ruletypes.h | 3 + .../generators/repository-generator.pl | 3 +- zone/attack.cpp | 8 +- zone/bonuses.cpp | 143 +++++++++++++++++- zone/bot.cpp | 113 +++----------- zone/bot.h | 19 +-- zone/client.cpp | 37 +---- zone/client.h | 16 +- zone/client_mods.cpp | 38 +---- zone/client_packet.cpp | 3 + zone/client_process.cpp | 10 +- zone/common.h | 18 +++ zone/data_bucket.cpp | 55 ++++++- zone/data_bucket.h | 19 ++- zone/effects.cpp | 77 +++++++--- zone/lua_bot.cpp | 4 +- zone/lua_client.cpp | 6 + zone/lua_client.h | 2 + zone/merc.h | 4 +- zone/mob.cpp | 2 +- zone/mob.h | 25 ++- zone/perl_bot.cpp | 4 +- zone/perl_client.cpp | 6 + zone/tune.cpp | 8 +- zone/zone.cpp | 2 +- zone/zone.h | 2 +- 28 files changed, 433 insertions(+), 243 deletions(-) diff --git a/common/emu_constants.h b/common/emu_constants.h index 0d18f1179..8a432e471 100644 --- a/common/emu_constants.h +++ b/common/emu_constants.h @@ -593,4 +593,29 @@ enum class ApplySpellType { Raid }; + +namespace HeroicBonusBucket +{ + const std::string WisMaxMana = "HWIS-MaxMana"; + const std::string WisManaRegen = "HWIS-ManaRegen"; + const std::string WisHealAmt = "HWIS-HealAmt"; + const std::string IntMaxMana = "HINT-MaxMana"; + const std::string IntManaRegen = "HINT-ManaRegen"; + const std::string IntSpellDmg = "HINT-SpellDmg"; + const std::string StrMeleeDamage = "HSTR-MeleeDamage"; + const std::string StrShieldAC = "HSTR-ShieldAC"; + const std::string StrMaxEndurance = "HSTR-MaxEndurance"; + const std::string StrEnduranceRegen = "HSTR-EnduranceRegen"; + const std::string StaMaxHP = "HSTA-MaxHP"; + const std::string StaHPRegen = "HSTA-HPRegen"; + const std::string StaMaxEndurance = "HSTA-MaxEndurance"; + const std::string StaEnduranceRegen = "HSTA-EnduranceRegen"; + const std::string AgiAvoidance = "HAGI-Avoidance"; + const std::string AgiMaxEndurance = "HAGI-MaxEndurance"; + const std::string AgiEnduranceRegen = "HAGI-EnduranceRegen"; + const std::string DexRangedDamage = "HDEX-RangedDamage"; + const std::string DexMaxEndurance = "HDEX-MaxEndurance"; + const std::string DexEnduranceRegen = "HDEX-EnduranceRegen"; +} + #endif /*COMMON_EMU_CONSTANTS_H*/ diff --git a/common/repositories/base/base_data_buckets_repository.h b/common/repositories/base/base_data_buckets_repository.h index 3c7ad5a0a..0c4709315 100644 --- a/common/repositories/base/base_data_buckets_repository.h +++ b/common/repositories/base/base_data_buckets_repository.h @@ -16,11 +16,12 @@ #include "../../strings.h" #include + class BaseDataBucketsRepository { public: struct DataBuckets { uint64_t id; - std::string key; + std::string key_; std::string value; uint32_t expires; }; @@ -34,7 +35,7 @@ public: { return { "id", - "key", + "`key`", "value", "expires", }; @@ -44,7 +45,7 @@ public: { return { "id", - "key", + "`key`", "value", "expires", }; @@ -88,7 +89,7 @@ public: DataBuckets e{}; e.id = 0; - e.key = ""; + e.key_ = ""; e.value = ""; e.expires = 0; @@ -116,8 +117,9 @@ public: { auto results = db.QueryDatabase( fmt::format( - "{} WHERE id = {} LIMIT 1", + "{} WHERE {} = {} LIMIT 1", BaseSelect(), + PrimaryKey(), data_buckets_id ) ); @@ -127,7 +129,7 @@ public: DataBuckets e{}; e.id = strtoull(row[0], nullptr, 10); - e.key = row[1] ? row[1] : ""; + e.key_ = row[1] ? row[1] : ""; e.value = row[2] ? row[2] : ""; e.expires = static_cast(strtoul(row[3], nullptr, 10)); @@ -163,7 +165,7 @@ public: auto columns = Columns(); - v.push_back(columns[1] + " = '" + Strings::Escape(e.key) + "'"); + v.push_back(columns[1] + " = '" + Strings::Escape(e.key_) + "'"); v.push_back(columns[2] + " = '" + Strings::Escape(e.value) + "'"); v.push_back(columns[3] + " = " + std::to_string(e.expires)); @@ -188,7 +190,7 @@ public: std::vector v; v.push_back(std::to_string(e.id)); - v.push_back("'" + Strings::Escape(e.key) + "'"); + v.push_back("'" + Strings::Escape(e.key_) + "'"); v.push_back("'" + Strings::Escape(e.value) + "'"); v.push_back(std::to_string(e.expires)); @@ -221,7 +223,7 @@ public: std::vector v; v.push_back(std::to_string(e.id)); - v.push_back("'" + Strings::Escape(e.key) + "'"); + v.push_back("'" + Strings::Escape(e.key_) + "'"); v.push_back("'" + Strings::Escape(e.value) + "'"); v.push_back(std::to_string(e.expires)); @@ -258,7 +260,7 @@ public: DataBuckets e{}; e.id = strtoull(row[0], nullptr, 10); - e.key = row[1] ? row[1] : ""; + e.key_ = row[1] ? row[1] : ""; e.value = row[2] ? row[2] : ""; e.expires = static_cast(strtoul(row[3], nullptr, 10)); @@ -286,7 +288,7 @@ public: DataBuckets e{}; e.id = strtoull(row[0], nullptr, 10); - e.key = row[1] ? row[1] : ""; + e.key_ = row[1] ? row[1] : ""; e.value = row[2] ? row[2] : ""; e.expires = static_cast(strtoul(row[3], nullptr, 10)); diff --git a/common/ruletypes.h b/common/ruletypes.h index b597cfc2c..fdef35ecd 100644 --- a/common/ruletypes.h +++ b/common/ruletypes.h @@ -93,6 +93,9 @@ RULE_INT(Character, ItemEnduranceRegenCap, 15, "Limit on endurance regeneration RULE_INT(Character, ItemExtraDmgCap, 150, "Cap for bonuses to melee skills like Bash, Frenzy, etc.") RULE_INT(Character, HasteCap, 100, "Haste cap for non-v3(over haste) haste") RULE_INT(Character, Hastev3Cap, 25, "Haste cap for v3(over haste) haste") +RULE_BOOL(Character, HeroicStatsUseDataBucketsToScale, false, "Allows scaling the benefits a character receives from Heroic Stats using Data Buckets. Stacks with other Heroic Stats Mulitplier Rules.") +RULE_REAL(Character, HeroicIntelligenceIncreaseSpellDmgMultiplier, 0.00, "Allows Heroic Intelligence to increase a Players Worn Spell Damage Stat from Equipment, for example, setting this rule to 1.00 will always grant 1 Spell Damage per 1 Heroic Intelligence") +RULE_REAL(Character, HeroicWisdomIncreaseHealAmtMultiplier, 0.00, "Allows Heroic Wisdom to increase a Players Worn Heal Amount Stat from Equipment, for example, setting this rule to 1.00 will always grant 1 Heal Amount per 1 Heroic Wisdom") RULE_REAL(Character, HeroicStrengthMultiplier, 1.00, "Multplier scales benefits from Heroic Strength. Grants 25 Base Endurance, 0.05 Endurance Regen, 1 Melee Damage each Hit, and 1 Shield AC per 10 Heroic Strength.") RULE_REAL(Character, HeroicStaminaMultiplier, 1.00, "Multplier scales benefits from Heroic Stamina. Grants 25 Base Endurance, 0.05 Endurance Regen, 100 Base HP, and 0.5 HP Regen per 10 Heroic Stamina.") RULE_REAL(Character, HeroicAgilityMultiplier, 1.00, "Multplier scales benefits from Heroic Agility. Grants 25 Base Endurance, 0.05 Endurance Regen, and 1 Avoidance AC per 10 Heroic Agility. (Rule does not change Dodge Chance)") diff --git a/utils/scripts/generators/repository-generator.pl b/utils/scripts/generators/repository-generator.pl index 438323d66..a943613ba 100644 --- a/utils/scripts/generators/repository-generator.pl +++ b/utils/scripts/generators/repository-generator.pl @@ -585,7 +585,8 @@ sub translate_mysql_data_type_to_c { sub get_reserved_cpp_variable_names { return ( "class", - "int" + "int", + "key" ); } diff --git a/zone/attack.cpp b/zone/attack.cpp index d7978e6d1..d567985b7 100644 --- a/zone/attack.cpp +++ b/zone/attack.cpp @@ -250,7 +250,7 @@ int Mob::compute_defense() int defense = GetSkill(EQ::skills::SkillDefense) * 400 / 225; defense += (8000 * (GetAGI() - 40)) / 36000; if (IsOfClientBot()) { - defense += GetHeroicAGI() * RuleR(Character, HeroicAgilityMultiplier) / 10; + defense += itembonuses.heroic_agi_avoidance; } //516 SE_AC_Mitigation_Max_Percent @@ -883,7 +883,7 @@ int Mob::ACSum(bool skip_caps) shield_ac = CalcRecommendedLevelBonus(GetLevel(), inst->GetItemRecommendedLevel(true), inst->GetItemArmorClass(true)); } } - shield_ac += GetHeroicSTR() * RuleR(Character, HeroicStrengthMultiplier) / 10; + shield_ac += itembonuses.heroic_str_shield_ac; } // EQ math ac = (ac * 4) / 3; @@ -5909,10 +5909,10 @@ void Mob::CommonOutgoingHitSuccess(Mob* defender, DamageHitInfo &hit, ExtraAttac switch (hit.skill) { case EQ::skills::SkillThrowing: case EQ::skills::SkillArchery: - extra = GetHeroicDEX() * RuleR(Character, HeroicDexterityMultiplier) / 10; + extra = itembonuses.heroic_dex_ranged_damage; break; default: - extra = GetHeroicSTR() * RuleR(Character, HeroicStrengthMultiplier) / 10; + extra = itembonuses.heroic_str_melee_damage; break; } hit.damage_done += extra; diff --git a/zone/bonuses.cpp b/zone/bonuses.cpp index 9ee25918e..fdedc1383 100644 --- a/zone/bonuses.cpp +++ b/zone/bonuses.cpp @@ -77,6 +77,7 @@ void Client::CalcBonuses() { memset(&itembonuses, 0, sizeof(StatBonuses)); CalcItemBonuses(&itembonuses); + CalcHeroicBonuses(&itembonuses); CalcEdibleBonuses(&itembonuses); CalcSpellBonuses(&spellbonuses); CalcAABonuses(&aabonuses); @@ -204,7 +205,7 @@ void Client::CalcItemBonuses(StatBonuses* newbon) { } // These item stat caps depend on spells/AAs so we process them after those are processed -void Client::ProcessItemCaps() +void Mob::ProcessItemCaps() { itembonuses.HPRegen = std::min(itembonuses.HPRegen, CalcHPRegenCap()); itembonuses.ManaRegen = std::min(itembonuses.ManaRegen, CalcManaRegenCap()); @@ -219,6 +220,15 @@ void Client::ProcessItemCaps() } itembonuses.ATK = std::min(itembonuses.ATK, CalcItemATKCap()); + + if (itembonuses.SpellDmg > RuleI(Character, ItemSpellDmgCap)) { + itembonuses.SpellDmg = RuleI(Character, ItemSpellDmgCap); + } + + if (itembonuses.HealAmt > RuleI(Character, ItemHealAmtCap)) { + itembonuses.HealAmt = RuleI(Character, ItemHealAmtCap); + } + } void Client::AddItemBonuses(const EQ::ItemInstance *inst, StatBonuses *newbon, bool isAug, bool isTribute, int rec_override, bool ammo_slot_item) @@ -5634,3 +5644,134 @@ void Mob::NegateSpellEffectBonuses(uint16 spell_id) } } } + +void Mob::CalcHeroicBonuses(StatBonuses* newbon) +{ + if (GetHeroicSTR()) { + SetHeroicStrBonuses(newbon); + } + + if (GetHeroicSTA()) { + SetHeroicStaBonuses(newbon); + } + + if (GetHeroicAGI()) { + SetHeroicAgiBonuses(newbon); + } + + if (GetHeroicDEX()) { + SetHeroicDexBonuses(newbon); + } + + if (GetHeroicINT()) { + SetHeroicIntBonuses(newbon); + } + + if (GetHeroicWIS()) { + SetHeroicWisBonuses(newbon); + } +} + +void Mob::SetHeroicWisBonuses(StatBonuses* n) +{ + n->heroic_max_mana += IsWISCasterClass(GetClass()) ? GetHeroicWIS() * RuleR(Character, HeroicWisdomMultiplier) * 10 : 0; + n->heroic_mana_regen += IsWISCasterClass(GetClass()) ? GetHeroicWIS() * RuleR(Character, HeroicWisdomMultiplier) / 25 : 0; + n->HealAmt += GetHeroicWIS() * RuleR(Character, HeroicWisdomIncreaseHealAmtMultiplier); + + if (RuleB(Character, HeroicStatsUseDataBucketsToScale)) { + n->heroic_max_mana += IsWISCasterClass(GetClass()) ? GetHeroicWIS() * CheckHeroicBonusesDataBuckets(HeroicBonusBucket::WisMaxMana) * 10 : 0; + n->heroic_mana_regen += IsWISCasterClass(GetClass()) ? GetHeroicWIS() * CheckHeroicBonusesDataBuckets(HeroicBonusBucket::WisManaRegen) / 25 : 0; + n->HealAmt += GetHeroicWIS() * CheckHeroicBonusesDataBuckets(HeroicBonusBucket::WisHealAmt); + } +} + +void Mob::SetHeroicIntBonuses(StatBonuses* n) +{ + n->heroic_max_mana += IsINTCasterClass(GetClass()) ? GetHeroicINT() * RuleR(Character, HeroicIntelligenceMultiplier) * 10 : 0; + n->heroic_mana_regen += IsINTCasterClass(GetClass()) ? GetHeroicINT() * RuleR(Character, HeroicIntelligenceMultiplier) / 25 : 0; + n->SpellDmg += GetHeroicINT() * RuleR(Character, HeroicIntelligenceIncreaseSpellDmgMultiplier); + + if (RuleB(Character, HeroicStatsUseDataBucketsToScale)) { + n->heroic_max_mana += IsINTCasterClass(GetClass()) ? GetHeroicINT() * CheckHeroicBonusesDataBuckets(HeroicBonusBucket::IntMaxMana) * 10 : 0; + n->heroic_mana_regen += IsINTCasterClass(GetClass()) ? GetHeroicINT() * CheckHeroicBonusesDataBuckets(HeroicBonusBucket::IntManaRegen) / 25 : 0; + n->SpellDmg += GetHeroicINT() * CheckHeroicBonusesDataBuckets(HeroicBonusBucket::IntSpellDmg); + } +} + +void Mob::SetHeroicDexBonuses(StatBonuses* n) +{ + n->heroic_dex_ranged_damage += GetHeroicDEX() * RuleR(Character, HeroicDexterityMultiplier) / 10; + n->heroic_max_end += GetHeroicDEX() * RuleR(Character, HeroicDexterityMultiplier) / 4 * 10.0f; + n->heroic_end_regen += GetHeroicDEX() * RuleR(Character, HeroicDexterityMultiplier) / 4 / 50; + + if (RuleB(Character, HeroicStatsUseDataBucketsToScale)) { + n->heroic_dex_ranged_damage += GetHeroicDEX() * CheckHeroicBonusesDataBuckets(HeroicBonusBucket::DexRangedDamage) / 10; + n->heroic_max_end += GetHeroicDEX() * CheckHeroicBonusesDataBuckets(HeroicBonusBucket::DexMaxEndurance) / 4 * 10.0f; + n->heroic_end_regen += GetHeroicDEX() * CheckHeroicBonusesDataBuckets(HeroicBonusBucket::DexEnduranceRegen) / 4 / 50; + } +} + +void Mob::SetHeroicAgiBonuses(StatBonuses* n) +{ + n->heroic_agi_avoidance += GetHeroicAGI() * RuleR(Character, HeroicAgilityMultiplier) / 10; + n->heroic_max_end += GetHeroicAGI() * RuleR(Character, HeroicAgilityMultiplier) / 4 * 10.0f; + n->heroic_end_regen += GetHeroicAGI() * RuleR(Character, HeroicAgilityMultiplier) / 4 / 50; + + if (RuleB(Character, HeroicStatsUseDataBucketsToScale)) { + n->heroic_agi_avoidance += GetHeroicAGI() * CheckHeroicBonusesDataBuckets(HeroicBonusBucket::AgiAvoidance) / 10; + n->heroic_max_end += GetHeroicAGI() * CheckHeroicBonusesDataBuckets(HeroicBonusBucket::AgiMaxEndurance) / 4 * 10.0f; + n->heroic_end_regen += GetHeroicAGI() * CheckHeroicBonusesDataBuckets(HeroicBonusBucket::AgiEnduranceRegen) / 4 / 50; + } +} + +void Mob::SetHeroicStaBonuses(StatBonuses* n) +{ + n->heroic_max_hp += GetHeroicSTA() * RuleR(Character, HeroicStaminaMultiplier) * 10; + n->heroic_hp_regen += GetHeroicSTA() * RuleR(Character, HeroicStaminaMultiplier) / 20; + n->heroic_max_end += GetHeroicSTA() * RuleR(Character, HeroicStaminaMultiplier) / 4 * 10.0f; + n->heroic_end_regen += GetHeroicSTA() * RuleR(Character, HeroicStaminaMultiplier) / 4 / 50; + + if (RuleB(Character, HeroicStatsUseDataBucketsToScale)) { + n->heroic_max_hp += GetHeroicSTA() * CheckHeroicBonusesDataBuckets(HeroicBonusBucket::StaMaxHP) * 10; + n->heroic_hp_regen += GetHeroicSTA() * CheckHeroicBonusesDataBuckets(HeroicBonusBucket::StaHPRegen) / 20; + n->heroic_max_end += GetHeroicSTA() * CheckHeroicBonusesDataBuckets(HeroicBonusBucket::StaMaxEndurance) / 4 * 10.0f; + n->heroic_end_regen += GetHeroicSTA() * CheckHeroicBonusesDataBuckets(HeroicBonusBucket::StaEnduranceRegen) / 4 / 50; + } +} + +void Mob::SetHeroicStrBonuses(StatBonuses* n) +{ + n->heroic_str_shield_ac += GetHeroicSTR() * RuleR(Character, HeroicStrengthMultiplier) / 10; + n->heroic_str_melee_damage += GetHeroicSTR() * RuleR(Character, HeroicStrengthMultiplier) / 10; + n->heroic_max_end += GetHeroicSTR() * RuleR(Character, HeroicStrengthMultiplier) / 4 * 10.0f; + n->heroic_end_regen += GetHeroicSTR() * RuleR(Character, HeroicStrengthMultiplier) / 4 / 50; + + if (RuleB(Character, HeroicStatsUseDataBucketsToScale)) { + n->heroic_str_shield_ac += GetHeroicSTR() * CheckHeroicBonusesDataBuckets(HeroicBonusBucket::StrShieldAC) / 10; + n->heroic_str_melee_damage += GetHeroicSTR() * CheckHeroicBonusesDataBuckets(HeroicBonusBucket::StrMeleeDamage) / 10; + n->heroic_max_end += GetHeroicSTR() * CheckHeroicBonusesDataBuckets(HeroicBonusBucket::StrMaxEndurance) / 4 * 10.0f; + n->heroic_end_regen += GetHeroicSTR() * CheckHeroicBonusesDataBuckets(HeroicBonusBucket::StrEnduranceRegen) / 4 / 50; + } +} + +float Mob::CheckHeroicBonusesDataBuckets(std::string bucket_name) +{ + std::string bucket_value; + if (!bucket_name.empty()) { + const auto full_name = fmt::format( + "{}-{}", + GetBucketKey(), + bucket_name + ); + + if (IsOfClientBot()) { + bucket_value = DataBucket::CheckBucketKey(this, full_name); + } + + if (bucket_value.empty() || !Strings::IsNumber(bucket_value)) { + return 0.00f; + } + } + + return Strings::ToFloat(bucket_value); +} \ No newline at end of file diff --git a/zone/bot.cpp b/zone/bot.cpp index 44f40c692..af8584f5d 100644 --- a/zone/bot.cpp +++ b/zone/bot.cpp @@ -3284,8 +3284,7 @@ bool Bot::Spawn(Client* botCharacterOwner) { m_targetable = true; entity_list.AddBot(this, true, true); - GetBotOwnerDataBuckets(); - GetBotDataBuckets(); + DataBucket::GetDataBuckets(this); LoadBotSpellSettings(); if (!AI_AddBotSpells(GetBotSpellID())) { GetBotOwner()->CastToClient()->Message( @@ -5461,10 +5460,10 @@ int64 Bot::CalcMaxMana() { switch(GetCasterClass()) { case 'I': max_mana = (GenerateBaseManaPoints() + itembonuses.Mana + spellbonuses.Mana + GroupLeadershipAAManaEnhancement()); - max_mana += (GetHeroicINT() * 10); + max_mana += itembonuses.heroic_max_mana; case 'W': { max_mana = (GenerateBaseManaPoints() + itembonuses.Mana + spellbonuses.Mana + GroupLeadershipAAManaEnhancement()); - max_mana += (GetHeroicWIS() * 10); + max_mana += itembonuses.heroic_max_mana; break; } case 'N': { @@ -6001,11 +6000,13 @@ void Bot::CalcBonuses() { memset(&itembonuses, 0, sizeof(StatBonuses)); GenerateBaseStats(); CalcItemBonuses(&itembonuses); + CalcHeroicBonuses(&itembonuses); CalcSpellBonuses(&spellbonuses); CalcAABonuses(&aabonuses); SetAttackTimer(); CalcSeeInvisibleLevel(); CalcInvisibleLevel(); + ProcessItemCaps(); CalcATK(); CalcSTR(); CalcSTA(); @@ -6037,15 +6038,7 @@ int64 Bot::CalcHPRegenCap() { } int64 Bot::CalcManaRegenCap() { - int64 cap = RuleI(Character, ItemManaRegenCap) + aabonuses.ItemManaRegenCap; - switch(GetCasterClass()) { - case 'I': - cap += itembonuses.HeroicINT * RuleR(Character, HeroicIntelligenceMultiplier) / 25; - break; - case 'W': - cap += itembonuses.HeroicWIS * RuleR(Character, HeroicWisdomMultiplier) / 25; - break; - } + int64 cap = RuleI(Character, ItemManaRegenCap) + aabonuses.ItemManaRegenCap + itembonuses.heroic_mana_regen; return (cap * RuleI(Character, ManaRegenMultiplier) / 100); } @@ -6435,7 +6428,7 @@ int32 Bot::LevelRegen() { int64 Bot::CalcHPRegen() { int32 regen = (LevelRegen() + itembonuses.HPRegen + spellbonuses.HPRegen); - regen += GetHeroicSTA() * RuleR(Character, HeroicStaminaMultiplier) / 20; + regen += itembonuses.heroic_hp_regen; regen += (aabonuses.HPRegen + GroupLeadershipAAHealthRegeneration()); regen = ((regen * RuleI(Character, HPRegenMultiplier)) / 100); @@ -6456,15 +6449,8 @@ int64 Bot::CalcManaRegen() { } else regen = (2 + spellbonuses.ManaRegen + itembonuses.ManaRegen); - if(GetCasterClass() == 'I') - regen += itembonuses.HeroicINT * RuleR(Character, HeroicIntelligenceMultiplier) / 25; - else if(GetCasterClass() == 'W') - regen += itembonuses.HeroicWIS * RuleR(Character, HeroicWisdomMultiplier) / 25; + regen += aabonuses.ManaRegen + itembonuses.heroic_mana_regen; - else - regen = 0; - - regen += aabonuses.ManaRegen; regen = ((regen * RuleI(Character, ManaRegenMultiplier)) / 100); float mana_regen_rate = RuleR(Bots, ManaRegen); if (mana_regen_rate < 0.0f) @@ -6509,7 +6495,7 @@ int64 Bot::CalcMaxHP() { int32 bot_hp = 0; uint32 nd = 10000; bot_hp += (GenerateBaseHitPoints() + itembonuses.HP); - bot_hp += GetHeroicSTA() * RuleR(Character, HeroicStaminaMultiplier) * 10; + bot_hp += itembonuses.heroic_max_hp; nd += aabonuses.MaxHP; bot_hp = ((float)bot_hp * (float)nd / (float)10000); bot_hp += (spellbonuses.HP + aabonuses.HP); @@ -6553,13 +6539,7 @@ int64 Bot::CalcBaseEndurance() { int32 sta_end = 0; int stats = 0; if (GetOwner() && GetOwner()->CastToClient() && GetOwner()->CastToClient()->ClientVersion() >= EQ::versions::ClientVersion::SoD && RuleB(Character, SoDClientUseSoDHPManaEnd)) { - double heroic_stats = 0; stats = ((GetSTR() + GetSTA() + GetDEX() + GetAGI()) / 4); - double heroic_str = GetHeroicSTR() * RuleR(Character, HeroicStrengthMultiplier); - double heroic_sta = GetHeroicSTA() * RuleR(Character, HeroicStaminaMultiplier); - double heroic_dex = GetHeroicDEX() * RuleR(Character, HeroicDexterityMultiplier); - double heroic_agi = GetHeroicAGI() * RuleR(Character, HeroicAgilityMultiplier); - heroic_stats = (heroic_str + heroic_sta + heroic_dex + heroic_agi) / 4; if (stats > 100) { converted_stats = (((stats - 100) * 5 / 2) + 100); @@ -6580,7 +6560,7 @@ int64 Bot::CalcBaseEndurance() { sta_end = (9 * converted_stats); base_endurance = (1800 + ((GetLevel() - 80) * 18)); } - base_end = (base_endurance + sta_end + (heroic_stats * 10)); + base_end = base_endurance + sta_end + itembonuses.heroic_max_end; } else { stats = (GetSTR() + GetSTA() + GetDEX() + GetAGI()); @@ -6593,7 +6573,8 @@ int64 Bot::CalcBaseEndurance() { int HalfBonus400to800 = 0; int Bonus800plus = 0; int HalfBonus800plus = 0; - int BonusUpto800 = int(at_most_800 / 4) ; + + auto BonusUpto800 = int(at_most_800 / 4) ; if(stats > 400) { Bonus400to800 = int((at_most_800 - 400) / 4); @@ -8768,62 +8749,7 @@ void Bot::OwnerMessage(const std::string& message) ); } -bool Bot::GetBotOwnerDataBuckets() -{ - auto bot_owner = GetBotOwner(); - if (!bot_owner) { - return false; - } - - const auto query = fmt::format( - "SELECT `key`, `value` FROM data_buckets WHERE `key` LIKE '{}-%'", - Strings::Escape(bot_owner->GetBucketKey()) - ); - - auto results = database.QueryDatabase(query); - if (!results.Success()) { - return false; - } - - bot_owner_data_buckets.clear(); - - if (!results.RowCount()) { - return true; - } - - for (auto row : results) { - bot_owner_data_buckets.insert(std::pair(row[0], row[1])); - } - - return true; -} - -bool Bot::GetBotDataBuckets() -{ - const auto query = fmt::format( - "SELECT `key`, `value` FROM data_buckets WHERE `key` LIKE '{}-%'", - Strings::Escape(GetBucketKey()) - ); - - auto results = database.QueryDatabase(query); - if (!results.Success()) { - return false; - } - - bot_data_buckets.clear(); - - if (!results.RowCount()) { - return true; - } - - for (auto row : results) { - bot_data_buckets.insert(std::pair(row[0], row[1])); - } - - return true; -} - -bool Bot::CheckDataBucket(const std::string& bucket_name, const std::string& bucket_value, uint8 bucket_comparison) +bool Bot::CheckDataBucket(std::string bucket_name, const std::string& bucket_value, uint8 bucket_comparison) { if (!bucket_name.empty() && !bucket_value.empty()) { auto full_name = fmt::format( @@ -8832,7 +8758,7 @@ bool Bot::CheckDataBucket(const std::string& bucket_name, const std::string& buc bucket_name ); - auto player_value = bot_data_buckets[full_name]; + auto player_value = DataBucket::CheckBucketKey(this, full_name); if (player_value.empty() && GetBotOwner()) { full_name = fmt::format( "{}-{}", @@ -8840,13 +8766,13 @@ bool Bot::CheckDataBucket(const std::string& bucket_name, const std::string& buc bucket_name ); - player_value = bot_owner_data_buckets[full_name]; + player_value = DataBucket::CheckBucketKey(GetBotOwner(), full_name); if (player_value.empty()) { return false; } } - if (zone->CheckDataBucket(bucket_comparison, bucket_value, player_value)) { + if (zone->CompareDataBucket(bucket_comparison, bucket_value, player_value)) { return true; } } @@ -9351,6 +9277,12 @@ float Bot::GetBotCasterMaxRange(float melee_distance_max) {// Calculate caster d return caster_distance_max; } + +int32 Bot::CalcItemATKCap() +{ + return RuleI(Character, ItemATKCap) + itembonuses.ItemATKCap + spellbonuses.ItemATKCap + aabonuses.ItemATKCap; +} + bool Bot::CheckSpawnConditions(Client* c) { if (c->GetFeigned()) { @@ -9386,5 +9318,4 @@ bool Bot::CheckSpawnConditions(Client* c) { return true; } - uint8 Bot::spell_casting_chances[SPELL_TYPE_COUNT][PLAYER_CLASS_COUNT][EQ::constants::STANCE_TYPE_COUNT][cntHSND] = { 0 }; diff --git a/zone/bot.h b/zone/bot.h index b77e0f919..3f31f451d 100644 --- a/zone/bot.h +++ b/zone/bot.h @@ -269,8 +269,8 @@ public: int32 CalcPR(); int32 CalcCR(); int32 CalcCorrup(); - int64 CalcHPRegenCap(); - int64 CalcManaRegenCap(); + int64 CalcHPRegenCap() final; + int64 CalcManaRegenCap() final; int32 LevelRegen(); int64 CalcHPRegen(); int64 CalcManaRegen(); @@ -280,6 +280,7 @@ public: int GroupLeadershipAAHealthRegeneration(); int GroupLeadershipAAOffenseEnhancement(); void CalcRestState(); + int64 CalcMaxEndurance(); int64 CalcBaseEndurance(); int64 CalcEnduranceRegen(); @@ -382,9 +383,7 @@ public: [[nodiscard]] int GetMaxDiscSlots() const final { return EQ::spells::DISC_BUFFS; } [[nodiscard]] int GetMaxTotalSlots() const final { return EQ::spells::TOTAL_BUFFS; } - bool GetBotOwnerDataBuckets(); - bool GetBotDataBuckets(); - bool CheckDataBucket(const std::string& bucket_name, const std::string& bucket_value, uint8 bucket_comparison); + bool CheckDataBucket(std::string bucket_name, const std::string& bucket_value, uint8 bucket_comparison); // Bot Equipment & Inventory Class Methods void BotTradeAddItem(const EQ::ItemInstance* inst, uint16 slot_id, std::string* error_message, bool save_to_database = true); @@ -571,8 +570,8 @@ public: inline virtual int32 GetCombatEffects() const { return itembonuses.ProcChance; } inline virtual int32 GetDS() const { return itembonuses.DamageShield; } // Mod3 - inline virtual int32 GetHealAmt() const { return itembonuses.HealAmt; } - inline virtual int32 GetSpellDmg() const { return itembonuses.SpellDmg; } + inline int32 GetHealAmt() const override { return itembonuses.HealAmt; } + inline int32 GetSpellDmg() const override { return itembonuses.SpellDmg; } inline virtual int32 GetClair() const { return itembonuses.Clairvoyance; } inline virtual int32 GetDSMit() const { return itembonuses.DSMitigation; } @@ -883,8 +882,6 @@ private: eStandingPetOrder m_previous_pet_order; uint32 m_bot_caster_range; BotCastingRoles m_CastingRoles; - std::map bot_data_buckets; - std::map bot_owner_data_buckets; std::map bot_spell_settings; @@ -937,6 +934,10 @@ private: bool LoadPet(); // Load and spawn bot pet if there is one bool SavePet(); // Save and depop bot pet if there is one bool DeletePet(); + + public: + + int32 CalcItemATKCap() final; }; bool IsSpellInBotList(DBbotspells_Struct* spell_list, uint16 iSpellID); diff --git a/zone/client.cpp b/zone/client.cpp index 5781fce25..d820328df 100644 --- a/zone/client.cpp +++ b/zone/client.cpp @@ -6437,8 +6437,7 @@ void Client::SendStatsWindow(Client* client, bool use_window) regen_row_color = color_red; base_regen_field = itoa(LevelRegen()); - item_regen_field = itoa( - itembonuses.HPRegen +(GetHeroicSTA() * RuleR(Character, HeroicStaminaMultiplier) / 20)); + item_regen_field = itoa(itembonuses.HPRegen + itembonuses.heroic_hp_regen); cap_regen_field = itoa(CalcHPRegenCap()); spell_regen_field = itoa(spellbonuses.HPRegen); aa_regen_field = itoa(aabonuses.HPRegen); @@ -6451,9 +6450,7 @@ void Client::SendStatsWindow(Client* client, bool use_window) regen_row_color = color_blue; base_regen_field = itoa(CalcBaseManaRegen()); - int32 heroic_mana_regen = (GetCasterClass() == 'W') ? - GetHeroicWIS() * RuleR(Character, HeroicWisdomMultiplier) / 25 : - GetHeroicINT() * RuleR(Character, HeroicIntelligenceMultiplier) / 25; + int32 heroic_mana_regen = itembonuses.heroic_mana_regen; item_regen_field = itoa(itembonuses.ManaRegen + heroic_mana_regen); cap_regen_field = itoa(CalcManaRegenCap()); spell_regen_field = itoa(spellbonuses.ManaRegen); @@ -6468,12 +6465,7 @@ void Client::SendStatsWindow(Client* client, bool use_window) regen_row_color = color_green; base_regen_field = itoa(((GetLevel() * 4 / 10) + 2)); - double heroic_str = GetHeroicSTR() * RuleR(Character, HeroicStrengthMultiplier); - double heroic_sta = GetHeroicSTA() * RuleR(Character, HeroicStaminaMultiplier); - double heroic_dex = GetHeroicDEX() * RuleR(Character, HeroicDexterityMultiplier); - double heroic_agi = GetHeroicAGI() * RuleR(Character, HeroicAgilityMultiplier); - double heroic_stats = (heroic_str + heroic_sta + heroic_dex + heroic_agi) / 4; - item_regen_field = itoa(itembonuses.EnduranceRegen + heroic_stats); + item_regen_field = itoa(itembonuses.EnduranceRegen + itembonuses.heroic_end_regen); cap_regen_field = itoa(CalcEnduranceRegenCap()); spell_regen_field = itoa(spellbonuses.EnduranceRegen); aa_regen_field = itoa(aabonuses.EnduranceRegen); @@ -11584,27 +11576,6 @@ void Client::SendReloadCommandMessages() { SendChatLineBreak(); } -std::map Client::GetMerchantDataBuckets() -{ - std::map merchant_data_buckets; - - auto query = fmt::format( - "SELECT `key`, `value` FROM data_buckets WHERE `key` LIKE '{}-%'", - Strings::Escape(GetBucketKey()) - ); - auto results = database.QueryDatabase(query); - - if (!results.Success() || !results.RowCount()) { - return merchant_data_buckets; - } - - for (auto row : results) { - merchant_data_buckets.insert(std::pair(row[0], row[1])); - } - - return merchant_data_buckets; -} - void Client::Undye() { for (uint8 slot = EQ::textures::textureBegin; slot <= EQ::textures::LastTexture; slot++) { @@ -12215,4 +12186,4 @@ void Client::PlayerTradeEventLog(Trade *t, Trade *t2) RecordPlayerEventLogWithClient(trader, PlayerEvent::TRADE, e); RecordPlayerEventLogWithClient(trader2, PlayerEvent::TRADE, e); -} +} \ No newline at end of file diff --git a/zone/client.h b/zone/client.h index 7d02d4fe2..9362bca60 100644 --- a/zone/client.h +++ b/zone/client.h @@ -430,7 +430,7 @@ public: int64 CalcMaxMana(); int64 CalcBaseMana(); const int64& SetMana(int64 amount); - int64 CalcManaRegenCap(); + int64 CalcManaRegenCap() final; // guild pool regen shit. Sends a SpawnAppearance with a value that regens to value * 0.001 void EnableAreaHPRegen(int value); @@ -535,8 +535,8 @@ public: inline virtual int32 GetCombatEffects() const { return itembonuses.ProcChance; } inline virtual int32 GetDS() const { return itembonuses.DamageShield; } // Mod3 - inline virtual int32 GetHealAmt() const { return itembonuses.HealAmt; } - inline virtual int32 GetSpellDmg() const { return itembonuses.SpellDmg; } + inline int32 GetHealAmt() const override { return itembonuses.HealAmt; } + inline int32 GetSpellDmg() const final { return itembonuses.SpellDmg; } inline virtual int32 GetClair() const { return itembonuses.Clairvoyance; } inline virtual int32 GetDSMit() const { return itembonuses.DSMitigation; } @@ -578,8 +578,8 @@ public: int64 CalcEnduranceRegen(bool bCombat = false); //Calculates endurance regen used in DoEnduranceRegen() int64 GetEndurance() const {return current_endurance;} //This gets our current endurance int64 GetMaxEndurance() const {return max_end;} //This gets our endurance from the last CalcMaxEndurance() call - int64 CalcEnduranceRegenCap(); - int64 CalcHPRegenCap(); + int64 CalcEnduranceRegenCap() final; + int64 CalcHPRegenCap() final; inline uint8 GetEndurancePercent() { return (uint8)((float)current_endurance / (float)max_end * 100.0f); } void SetEndurance(int32 newEnd); //This sets the current endurance to the new value void DoEnduranceRegen(); //This Regenerates endurance @@ -1638,19 +1638,17 @@ public: // rate limit Timer m_list_task_timers_rate_limit = {}; - std::map GetMerchantDataBuckets(); - std::string GetGuildPublicNote(); PlayerEvent::PlayerEvent GetPlayerEvent(); void RecordKilledNPCEvent(NPC *n); + protected: friend class Mob; void CalcItemBonuses(StatBonuses* newbon); void AddItemBonuses(const EQ::ItemInstance *inst, StatBonuses* newbon, bool isAug = false, bool isTribute = false, int rec_override = 0, bool ammo_slot_item = false); void AdditiveWornBonuses(const EQ::ItemInstance *inst, StatBonuses* newbon, bool isAug = false); void CalcEdibleBonuses(StatBonuses* newbon); - void ProcessItemCaps(); void MakeBuffFadePacket(uint16 spell_id, int slot_id, bool send_message = true); bool client_data_loaded; @@ -1701,7 +1699,7 @@ private: void HandleTraderPriceUpdate(const EQApplicationPacket *app); - int32 CalcItemATKCap(); + int32 CalcItemATKCap() final; int32 CalcHaste(); int32 CalcAlcoholPhysicalEffect(); diff --git a/zone/client_mods.cpp b/zone/client_mods.cpp index a9b70d453..4adaee619 100644 --- a/zone/client_mods.cpp +++ b/zone/client_mods.cpp @@ -234,7 +234,7 @@ int32 Client::LevelRegen() int64 Client::CalcHPRegen(bool bCombat) { int64 item_regen = itembonuses.HPRegen; // worn spells and +regen, already capped - item_regen += GetHeroicSTA() * RuleR(Character, HeroicStaminaMultiplier) / 20; + item_regen += itembonuses.heroic_hp_regen; item_regen += aabonuses.HPRegen; @@ -491,7 +491,7 @@ int64 Client::CalcBaseHP() auto base_data = database.GetBaseData(GetLevel(), GetClass()); if (base_data) { base_hp += base_data->base_hp + (base_data->hp_factor * stats); - base_hp += GetHeroicSTA() * RuleR(Character, HeroicStaminaMultiplier) * 10; + base_hp += itembonuses.heroic_max_hp; } } else { @@ -624,8 +624,7 @@ int64 Client::CalcBaseMana() auto base_data = database.GetBaseData(GetLevel(), GetClass()); if (base_data) { max_m = base_data->base_mana + - (ConvertedWisInt * base_data->mana_factor) + - (GetHeroicINT() * RuleR(Character, HeroicIntelligenceMultiplier) * 10); + (ConvertedWisInt * base_data->mana_factor) + itembonuses.heroic_max_mana; } } else { @@ -658,8 +657,7 @@ int64 Client::CalcBaseMana() auto base_data = database.GetBaseData(GetLevel(), GetClass()); if (base_data) { max_m = base_data->base_mana + - (ConvertedWisInt * base_data->mana_factor) + - ((GetHeroicWIS() * RuleR(Character, HeroicWisdomMultiplier)) * 10); + (ConvertedWisInt * base_data->mana_factor) + itembonuses.heroic_max_mana; } } else { @@ -752,18 +750,7 @@ int64 Client::CalcManaRegen(bool bCombat) // add in + 1 bonus for SE_CompleteHeal, but we don't do anything for it yet? int item_bonus = itembonuses.ManaRegen; // this is capped already - int heroic_bonus = 0; - - switch (GetCasterClass()) { - case 'W': - heroic_bonus = GetHeroicWIS() * RuleR(Character, HeroicWisdomMultiplier); - break; - default: - heroic_bonus = GetHeroicINT() * RuleR(Character, HeroicIntelligenceMultiplier); - break; - } - - item_bonus += heroic_bonus / 25; + item_bonus += itembonuses.heroic_mana_regen; regen += item_bonus; if (level <= 70 && regen > 65) @@ -1690,11 +1677,6 @@ int64 Client::CalcBaseEndurance() { int64 base_end = 0; if (ClientVersion() >= EQ::versions::ClientVersion::SoF && RuleB(Character, SoDClientUseSoDHPManaEnd)) { - double heroic_str = GetHeroicSTR() * RuleR(Character, HeroicStrengthMultiplier); - double heroic_sta = GetHeroicSTA() * RuleR(Character, HeroicStaminaMultiplier); - double heroic_dex = GetHeroicDEX() * RuleR(Character, HeroicDexterityMultiplier); - double heroic_agi = GetHeroicAGI() * RuleR(Character, HeroicAgilityMultiplier); - double heroic_stats = (heroic_str + heroic_sta + heroic_dex + heroic_agi) / 4; double stats = (GetSTR() + GetSTA() + GetDEX() + GetAGI()) / 4.0f; if (stats > 201.0f) { @@ -1705,7 +1687,7 @@ int64 Client::CalcBaseEndurance() } auto base_data = database.GetBaseData(GetLevel(), GetClass()); if (base_data) { - base_end = base_data->base_end + (heroic_stats * 10.0f) + (base_data->endurance_factor * static_cast(stats)); + base_end = base_data->base_end + itembonuses.heroic_max_end + (base_data->endurance_factor * static_cast(stats)); } } else { @@ -1794,13 +1776,7 @@ int64 Client::CalcEnduranceRegen(bool bCombat) if (encumbered) base += level / -15; - double heroic_str = GetHeroicSTR() * RuleR(Character, HeroicStrengthMultiplier); - double heroic_sta = GetHeroicSTA() * RuleR(Character, HeroicStaminaMultiplier); - double heroic_dex = GetHeroicDEX() * RuleR(Character, HeroicDexterityMultiplier); - double heroic_agi = GetHeroicAGI() * RuleR(Character, HeroicAgilityMultiplier); - int32 item_bonus = heroic_str + heroic_sta + heroic_dex + heroic_agi; - item_bonus = item_bonus / 4 / 50; - item_bonus += itembonuses.EnduranceRegen; // this is capped already + auto item_bonus = itembonuses.EnduranceRegen + itembonuses.heroic_end_regen; // this is capped already base += item_bonus; base = base * AreaEndRegen + 0.5f; diff --git a/zone/client_packet.cpp b/zone/client_packet.cpp index 1980926c0..1ea1a85c8 100644 --- a/zone/client_packet.cpp +++ b/zone/client_packet.cpp @@ -1380,6 +1380,9 @@ void Client::Handle_Connect_OP_ZoneEntry(const EQApplicationPacket *app) drakkin_tattoo = m_pp.drakkin_tattoo; drakkin_details = m_pp.drakkin_details; + // Load Data Buckets + DataBucket::GetDataBuckets(this); + // Max Level for Character:PerCharacterQglobalMaxLevel and Character:PerCharacterBucketMaxLevel uint8 client_max_level = 0; if (RuleB(Character, PerCharacterQglobalMaxLevel)) { diff --git a/zone/client_process.cpp b/zone/client_process.cpp index 087e05fe5..748fd80f5 100644 --- a/zone/client_process.cpp +++ b/zone/client_process.cpp @@ -845,18 +845,16 @@ void Client::BulkSendMerchantInventory(int merchant_id, int npcid) { } } - auto client_data_buckets = GetMerchantDataBuckets(); - auto temporary_merchant_list = zone->tmpmerchanttable[npcid]; uint32 slot_id = 1; uint8 handy_chance = 0; - for (auto ml : merchant_list) { + for (const auto& ml : merchant_list) { if (slot_id > merchant_slots) { break; } auto bucket_name = ml.bucket_name; - auto bucket_value = ml.bucket_value; + auto const& bucket_value = ml.bucket_value; if (!bucket_name.empty() && !bucket_value.empty()) { auto full_name = fmt::format( "{}-{}", @@ -864,12 +862,12 @@ void Client::BulkSendMerchantInventory(int merchant_id, int npcid) { bucket_name ); - auto player_value = client_data_buckets[full_name]; + auto const& player_value = DataBucket::CheckBucketKey(this, full_name); if (player_value.empty()) { continue; } - if (!zone->CheckDataBucket(ml.bucket_comparison, bucket_value, player_value)) { + if (!zone->CompareDataBucket(ml.bucket_comparison, bucket_value, player_value)) { continue; } } diff --git a/zone/common.h b/zone/common.h index 08c9e078c..f932da9da 100644 --- a/zone/common.h +++ b/zone/common.h @@ -639,6 +639,16 @@ struct StatBonuses { int aura_slots; int trap_slots; bool hunger; // Song of Sustenance -- min caps to 3500 + int64 heroic_max_hp; + int64 heroic_max_mana; + int64 heroic_max_end; + int64 heroic_hp_regen; + int64 heroic_mana_regen; + int64 heroic_end_regen; + int32 heroic_str_shield_ac; + int32 heroic_str_melee_damage; + int32 heroic_agi_avoidance; + int32 heroic_dex_ranged_damage; }; // StatBonus Indexes @@ -915,5 +925,13 @@ struct ExpeditionInvite std::string swap_remove_name; }; +struct DataBucketCache +{ + uint64_t bucket_id; + std::string bucket_key; + std::string bucket_value; + uint32_t bucket_expires; +}; + #endif diff --git a/zone/data_bucket.cpp b/zone/data_bucket.cpp index fd05f8795..c96d417b4 100644 --- a/zone/data_bucket.cpp +++ b/zone/data_bucket.cpp @@ -13,7 +13,7 @@ * @param bucket_value * @param expires_time */ -void DataBucket::SetData(std::string bucket_key, std::string bucket_value, std::string expires_time) { +void DataBucket::SetData(const std::string& bucket_key, const std::string& bucket_value, std::string expires_time) { uint64 bucket_id = DataBucket::DoesBucketExist(bucket_key); std::string query; @@ -57,7 +57,7 @@ void DataBucket::SetData(std::string bucket_key, std::string bucket_value, std:: * @param bucket_key * @return */ -std::string DataBucket::GetData(std::string bucket_key) { +std::string DataBucket::GetData(const std::string& bucket_key) { std::string query = StringFormat( "SELECT `value` from `data_buckets` WHERE `key` = '%s' AND (`expires` > %lld OR `expires` = 0) LIMIT 1", bucket_key.c_str(), @@ -82,7 +82,7 @@ std::string DataBucket::GetData(std::string bucket_key) { * @param bucket_key * @return */ -std::string DataBucket::GetDataExpires(std::string bucket_key) { +std::string DataBucket::GetDataExpires(const std::string& bucket_key) { std::string query = StringFormat( "SELECT `expires` from `data_buckets` WHERE `key` = '%s' AND (`expires` > %lld OR `expires` = 0) LIMIT 1", bucket_key.c_str(), @@ -102,7 +102,7 @@ std::string DataBucket::GetDataExpires(std::string bucket_key) { return std::string(row[0]); } -std::string DataBucket::GetDataRemaining(std::string bucket_key) { +std::string DataBucket::GetDataRemaining(const std::string& bucket_key) { if (DataBucket::GetDataExpires(bucket_key).empty()) { return "0"; } @@ -130,7 +130,7 @@ std::string DataBucket::GetDataRemaining(std::string bucket_key) { * @param bucket_key * @return */ -uint64 DataBucket::DoesBucketExist(std::string bucket_key) { +uint64 DataBucket::DoesBucketExist(const std::string& bucket_key) { std::string query = StringFormat( "SELECT `id` from `data_buckets` WHERE `key` = '%s' AND (`expires` > %lld OR `expires` = 0) LIMIT 1", Strings::Escape(bucket_key).c_str(), @@ -154,7 +154,7 @@ uint64 DataBucket::DoesBucketExist(std::string bucket_key) { * @param bucket_key * @return */ -bool DataBucket::DeleteData(std::string bucket_key) { +bool DataBucket::DeleteData(const std::string& bucket_key) { std::string query = StringFormat( "DELETE FROM `data_buckets` WHERE `key` = '%s'", Strings::Escape(bucket_key).c_str() @@ -164,3 +164,46 @@ bool DataBucket::DeleteData(std::string bucket_key) { return results.Success(); } + +bool DataBucket::GetDataBuckets(Mob* mob) +{ + auto l = BaseDataBucketsRepository::GetWhere( + database, + fmt::format( + "`key` LIKE '{}-%'", + Strings::Escape(mob->GetBucketKey()) + ) + ); + + if (l.empty()) { + return false; + } + + mob->m_data_bucket_cache.clear(); + + DataBucketCache d; + + for (const auto& e : l) { + d.bucket_id = e.id; + d.bucket_key = e.key_; + d.bucket_value = e.value; + d.bucket_expires = e.expires; + + mob->m_data_bucket_cache.emplace_back(d); + } + + return true; +} + +std::string DataBucket::CheckBucketKey(const Mob* mob, std::string_view full_name) +{ + std::string bucket_value; + for (const auto &d : mob->m_data_bucket_cache) { + if (d.bucket_key == full_name) { + bucket_value = d.bucket_value; + break; + } + } + return bucket_value; +} + diff --git a/zone/data_bucket.h b/zone/data_bucket.h index c06a77c6c..78a55cc16 100644 --- a/zone/data_bucket.h +++ b/zone/data_bucket.h @@ -5,20 +5,23 @@ #ifndef EQEMU_DATABUCKET_H #define EQEMU_DATABUCKET_H - #include #include "../common/types.h" +#include "../common/repositories/data_buckets_repository.h" +#include "mob.h" class DataBucket { public: - static void SetData(std::string bucket_key, std::string bucket_value, std::string expires_time = ""); - static bool DeleteData(std::string bucket_key); - static std::string GetData(std::string bucket_key); - static std::string GetDataExpires(std::string bucket_key); - static std::string GetDataRemaining(std::string bucket_key); + static void SetData(const std::string& bucket_key, const std::string& bucket_value, std::string expires_time = ""); + static bool DeleteData(const std::string& bucket_key); + static std::string GetData(const std::string& bucket_key); + static std::string GetDataExpires(const std::string& bucket_key); + static std::string GetDataRemaining(const std::string& bucket_key); + static bool GetDataBuckets(Mob* mob); + static std::string CheckBucketKey(const Mob* mob, std::string_view full_name); + private: - static uint64 DoesBucketExist(std::string bucket_key); + static uint64 DoesBucketExist(const std::string& bucket_key); }; - #endif //EQEMU_DATABUCKET_H diff --git a/zone/effects.cpp b/zone/effects.cpp index 9883b5368..87374cf3b 100644 --- a/zone/effects.cpp +++ b/zone/effects.cpp @@ -132,6 +132,7 @@ int64 Mob::GetActSpellDamage(uint16 spell_id, int64 value, Mob* target) { if (RuleB(Spells, IgnoreSpellDmgLvlRestriction) && !spells[spell_id].no_heal_damage_item_mod && itembonuses.SpellDmg) { value -= GetExtraSpellAmt(spell_id, itembonuses.SpellDmg, base_value) * ratio / 100; + } else if (!spells[spell_id].no_heal_damage_item_mod && itembonuses.SpellDmg && spells[spell_id].classes[(GetClass() % 17) - 1] >= GetLevel() - 5) { @@ -140,7 +141,7 @@ int64 Mob::GetActSpellDamage(uint16 spell_id, int64 value, Mob* target) { entity_list.FilteredMessageCloseString( this, true, 100, Chat::SpellCrit, FilterSpellCrits, - OTHER_CRIT_BLAST, 0, GetName(), itoa(-value)); + OTHER_CRIT_BLAST, nullptr, GetName(), itoa(-value)); if (IsClient()) MessageString(Chat::SpellCrit, YOU_CRIT_BLAST, itoa(-value)); @@ -175,8 +176,13 @@ int64 Mob::GetActSpellDamage(uint16 spell_id, int64 value, Mob* target) { if (RuleB(Spells, IgnoreSpellDmgLvlRestriction) && !spells[spell_id].no_heal_damage_item_mod && itembonuses.SpellDmg) value -= GetExtraSpellAmt(spell_id, itembonuses.SpellDmg, base_value); - else if (!spells[spell_id].no_heal_damage_item_mod && itembonuses.SpellDmg && spells[spell_id].classes[(GetClass() % 17) - 1] >= GetLevel() - 5) - value -= GetExtraSpellAmt(spell_id, itembonuses.SpellDmg, base_value); + else if ( + !spells[spell_id].no_heal_damage_item_mod && + GetSpellDmg() && + spells[spell_id].classes[(GetClass() % 17) - 1] >= GetLevel() - 5 + ) { + value -= GetExtraSpellAmt(spell_id, GetSpellDmg(), base_value); + } return value; } @@ -260,11 +266,19 @@ int64 Mob::GetActDoTDamage(uint16 spell_id, int64 value, Mob* target, bool from_ GetFocusEffect(focusFcAmplifyAmt, spell_id, nullptr, from_buff_tic); if (RuleB(Spells, DOTsScaleWithSpellDmg)) { - if (RuleB(Spells, IgnoreSpellDmgLvlRestriction) && !spells[spell_id].no_heal_damage_item_mod && itembonuses.SpellDmg) { - extra_dmg += GetExtraSpellAmt(spell_id, itembonuses.SpellDmg, base_value)*ratio/100; + if ( + RuleB(Spells, IgnoreSpellDmgLvlRestriction) && + !spells[spell_id].no_heal_damage_item_mod && + GetSpellDmg() + ) { + extra_dmg += GetExtraSpellAmt(spell_id, GetSpellDmg(), base_value)*ratio/100; } - else if(!spells[spell_id].no_heal_damage_item_mod && itembonuses.SpellDmg && spells[spell_id].classes[(GetClass() % 17) - 1] >= GetLevel() - 5) { - extra_dmg += GetExtraSpellAmt(spell_id, itembonuses.SpellDmg, base_value)*ratio/100; + else if ( + !spells[spell_id].no_heal_damage_item_mod && + GetSpellDmg() && + spells[spell_id].classes[(GetClass() % 17) - 1] >= GetLevel() - 5 + ) { + extra_dmg += GetExtraSpellAmt(spell_id, GetSpellDmg(), base_value)*ratio/100; } } @@ -295,11 +309,19 @@ int64 Mob::GetActDoTDamage(uint16 spell_id, int64 value, Mob* target, bool from_ GetFocusEffect(focusFcAmplifyAmt, spell_id, nullptr, from_buff_tic); if (RuleB(Spells, DOTsScaleWithSpellDmg)) { - if (RuleB(Spells, IgnoreSpellDmgLvlRestriction) && !spells[spell_id].no_heal_damage_item_mod && itembonuses.SpellDmg) { - extra_dmg += GetExtraSpellAmt(spell_id, itembonuses.SpellDmg, base_value); + if ( + RuleB(Spells, IgnoreSpellDmgLvlRestriction) && + !spells[spell_id].no_heal_damage_item_mod && + GetSpellDmg() + ) { + extra_dmg += GetExtraSpellAmt(spell_id, GetSpellDmg(), base_value); } - else if(!spells[spell_id].no_heal_damage_item_mod && itembonuses.SpellDmg && spells[spell_id].classes[(GetClass() % 17) - 1] >= GetLevel() - 5) { - extra_dmg += GetExtraSpellAmt(spell_id, itembonuses.SpellDmg, base_value); + else if ( + !spells[spell_id].no_heal_damage_item_mod && + GetSpellDmg() && + spells[spell_id].classes[(GetClass() % 17) - 1] >= GetLevel() - 5 + ) { + extra_dmg += GetExtraSpellAmt(spell_id, GetSpellDmg(), base_value); } } @@ -321,6 +343,7 @@ int64 Mob::GetActDoTDamage(uint16 spell_id, int64 value, Mob* target, bool from_ int64 Mob::GetExtraSpellAmt(uint16 spell_id, int64 extra_spell_amt, int64 base_spell_dmg) { + if (RuleB(Spells, FlatItemExtraSpellAmt)) { if (RuleB(Spells, ItemExtraSpellAmtCalcAsPercent)) { return std::abs(base_spell_dmg) * extra_spell_amt / 100; @@ -425,11 +448,19 @@ int64 Mob::GetActSpellHealing(uint16 spell_id, int64 value, Mob* target, bool fr value += GetFocusEffect(focusFcHealAmtCrit, spell_id); //SPA 396 Add before critical //Using IgnoreSpellDmgLvlRestriction to also allow healing to scale - if (RuleB(Spells, IgnoreSpellDmgLvlRestriction) && !spells[spell_id].no_heal_damage_item_mod && itembonuses.HealAmt) { - value += GetExtraSpellAmt(spell_id, itembonuses.HealAmt, base_value);//Item Heal Amt Add before critical + if ( + RuleB(Spells, IgnoreSpellDmgLvlRestriction) && + !spells[spell_id].no_heal_damage_item_mod && + GetHealAmt() + ) { + value += GetExtraSpellAmt(spell_id, GetHealAmt(), base_value); //Item Heal Amt Add before critical } - else if (!spells[spell_id].no_heal_damage_item_mod && itembonuses.HealAmt && spells[spell_id].classes[(GetClass() % 17) - 1] >= GetLevel() - 5) { - value += GetExtraSpellAmt(spell_id, itembonuses.HealAmt, base_value);//Item Heal Amt Add before critical + else if ( + !spells[spell_id].no_heal_damage_item_mod && + GetHealAmt() && + spells[spell_id].classes[(GetClass() % 17) - 1] >= GetLevel() - 5 + ) { + value += GetExtraSpellAmt(spell_id, GetHealAmt(), base_value); //Item Heal Amt Add before critical } if (target) { @@ -471,11 +502,19 @@ int64 Mob::GetActSpellHealing(uint16 spell_id, int64 value, Mob* target, bool fr } if (RuleB(Spells, HOTsScaleWithHealAmt)) { - if (RuleB(Spells, IgnoreSpellDmgLvlRestriction) && !spells[spell_id].no_heal_damage_item_mod && itembonuses.HealAmt) { - extra_heal += GetExtraSpellAmt(spell_id, itembonuses.HealAmt, base_value); + if ( + RuleB(Spells, IgnoreSpellDmgLvlRestriction) && + !spells[spell_id].no_heal_damage_item_mod && + GetHealAmt() + ) { + extra_heal += GetExtraSpellAmt(spell_id, GetHealAmt(), base_value); } - else if(!spells[spell_id].no_heal_damage_item_mod && itembonuses.HealAmt && spells[spell_id].classes[(GetClass() % 17) - 1] >= GetLevel() - 5) { - extra_heal += GetExtraSpellAmt(spell_id, itembonuses.HealAmt, base_value); + else if ( + !spells[spell_id].no_heal_damage_item_mod && + GetHealAmt() && + spells[spell_id].classes[(GetClass() % 17) - 1] >= GetLevel() - 5 + ) { + extra_heal += GetExtraSpellAmt(spell_id, GetHealAmt(), base_value); } } diff --git a/zone/lua_bot.cpp b/zone/lua_bot.cpp index 7b63e3844..a5955d207 100644 --- a/zone/lua_bot.cpp +++ b/zone/lua_bot.cpp @@ -112,12 +112,12 @@ void Lua_Bot::SetExpansionBitmask(int expansion_bitmask, bool save) { bool Lua_Bot::ReloadBotDataBuckets() { Lua_Safe_Call_Bool(); - return self->GetBotDataBuckets(); + return DataBucket::GetDataBuckets(self); } bool Lua_Bot::ReloadBotOwnerDataBuckets() { Lua_Safe_Call_Bool(); - return self->GetBotOwnerDataBuckets(); + return self->HasOwner() && DataBucket::GetDataBuckets(self->GetBotOwner()); } bool Lua_Bot::ReloadBotSpells() { diff --git a/zone/lua_client.cpp b/zone/lua_client.cpp index 0ae70ee66..1540bceb4 100644 --- a/zone/lua_client.cpp +++ b/zone/lua_client.cpp @@ -3046,6 +3046,11 @@ bool Lua_Client::IsAutoFireEnabled() return self->AutoFireEnabled(); } +bool Lua_Client::ReloadDataBuckets() { + Lua_Safe_Call_Bool(); + return DataBucket::GetDataBuckets(self); +} + luabind::scope lua_register_client() { return luabind::class_("Client") .def(luabind::constructor<>()) @@ -3394,6 +3399,7 @@ luabind::scope lua_register_client() { .def("QueuePacket", (void(Lua_Client::*)(Lua_Packet,bool,int,int))&Lua_Client::QueuePacket) .def("ReadBookByName", (void(Lua_Client::*)(std::string,uint8))&Lua_Client::ReadBookByName) .def("RefundAA", (void(Lua_Client::*)(void))&Lua_Client::RefundAA) + .def("ReloadDataBuckets", (bool(Lua_Client::*)(void))&Lua_Client::ReloadDataBuckets) .def("RemoveAllExpeditionLockouts", (void(Lua_Client::*)(std::string))&Lua_Client::RemoveAllExpeditionLockouts) .def("RemoveAllExpeditionLockouts", (void(Lua_Client::*)(void))&Lua_Client::RemoveAllExpeditionLockouts) .def("RemoveExpeditionLockout", (void(Lua_Client::*)(std::string, std::string))&Lua_Client::RemoveExpeditionLockout) diff --git a/zone/lua_client.h b/zone/lua_client.h index a5d0c8409..0d5c58bad 100644 --- a/zone/lua_client.h +++ b/zone/lua_client.h @@ -534,6 +534,8 @@ public: void DialogueWindow(std::string markdown); + bool ReloadDataBuckets(); + Lua_Expedition CreateExpedition(luabind::object expedition_info); Lua_Expedition CreateExpedition(std::string zone_name, uint32 version, uint32 duration, std::string expedition_name, uint32 min_players, uint32 max_players); Lua_Expedition CreateExpedition(std::string zone_name, uint32 version, uint32 duration, std::string expedition_name, uint32 min_players, uint32 max_players, bool disable_messages); diff --git a/zone/merc.h b/zone/merc.h index 42fba3098..57ffe3438 100644 --- a/zone/merc.h +++ b/zone/merc.h @@ -226,8 +226,8 @@ public: inline virtual int32 GetCombatEffects() const { return itembonuses.ProcChance; } inline virtual int32 GetDS() const { return itembonuses.DamageShield; } // Mod3 - inline virtual int32 GetHealAmt() const { return itembonuses.HealAmt; } - inline virtual int32 GetSpellDmg() const { return itembonuses.SpellDmg; } + inline int32 GetHealAmt() const override { return itembonuses.HealAmt; } + inline int32 GetSpellDmg() const override { return itembonuses.SpellDmg; } inline virtual int32 GetClair() const { return itembonuses.Clairvoyance; } inline virtual int32 GetDSMit() const { return itembonuses.DSMitigation; } diff --git a/zone/mob.cpp b/zone/mob.cpp index 2c20fc05e..17f680a8a 100644 --- a/zone/mob.cpp +++ b/zone/mob.cpp @@ -7115,4 +7115,4 @@ int Mob::DispatchZoneControllerEvent( } return ret; -} +} \ No newline at end of file diff --git a/zone/mob.h b/zone/mob.h index efe069058..bbd4ce944 100644 --- a/zone/mob.h +++ b/zone/mob.h @@ -20,6 +20,7 @@ #define MOB_H #include "common.h" +#include "data_bucket.h" #include "entity.h" #include "hate_list.h" #include "pathfinder_interface.h" @@ -618,10 +619,13 @@ public: inline int64 GetHP() const { return current_hp; } inline int64 GetMaxHP() const { return max_hp; } virtual int64 CalcMaxHP(); + virtual int64 CalcHPRegenCap() { return 0; } inline int64 GetMaxMana() const { return max_mana; } + virtual int64 CalcManaRegenCap() { return 0; } inline int64 GetMana() const { return current_mana; } virtual int64 GetEndurance() const { return 0; } virtual int64 GetMaxEndurance() const { return 0; } + virtual int64 CalcEnduranceRegenCap() { return 0; } virtual void SetEndurance(int32 newEnd) { return; } int64 GetItemHPBonuses(); int64 GetSpellHPBonuses(); @@ -654,7 +658,10 @@ public: inline int32 GetHeroicStrikethrough() const { return heroic_strikethrough; } inline const bool GetKeepsSoldItems() const { return keeps_sold_items; } inline void SetKeepsSoldItems(bool in_keeps_sold_items) { keeps_sold_items = in_keeps_sold_items; } - + virtual int32 GetHealAmt() const { return 0; } + virtual int32 GetSpellDmg() const { return 0; } + void ProcessItemCaps(); + virtual int32 CalcItemATKCap() { return 0; } virtual bool IsSitting() const { return false; } int CalcRecommendedLevelBonus(uint8 level, uint8 reclevel, int basestat); @@ -1390,6 +1397,9 @@ public: /// this cures timing issues cuz dead animation isn't done but server side feigning is? inline bool GetFeigned() const { return(feigned); } + std::vector m_data_bucket_cache; + + // Data Bucket Methods void DeleteBucket(std::string bucket_name); std::string GetBucket(std::string bucket_name); std::string GetBucketExpires(std::string bucket_name); @@ -1397,6 +1407,9 @@ public: std::string GetBucketRemaining(std::string bucket_name); void SetBucket(std::string bucket_name, std::string bucket_value, std::string expiration = ""); + // Heroic Stat Benefits + float CheckHeroicBonusesDataBuckets(std::string bucket_name); + int DispatchZoneControllerEvent(QuestEventID evt, Mob* init, const std::string& data, uint32 extra, std::vector* pointers); // Bots HealRotation methods @@ -1418,6 +1431,8 @@ public: void DrawDebugCoordinateNode(std::string node_name, const glm::vec4 vec); + void CalcHeroicBonuses(StatBonuses* newbon); + protected: void CommonDamage(Mob* other, int64 &damage, const uint16 spell_id, const EQ::skills::SkillType attack_skill, bool &avoidable, const int8 buffslot, const bool iBuffTic, eSpecialAttacks specal = eSpecialAttacks::None); static uint16 GetProcID(uint16 spell_id, uint8 effect_index); @@ -1701,6 +1716,7 @@ protected: bool is_boat; CombatRecord m_combat_record{}; + public: const CombatRecord &GetCombatRecord() const; @@ -1833,6 +1849,13 @@ private: std::shared_ptr m_target_of_heal_rotation; bool m_manual_follow; + void SetHeroicStrBonuses(StatBonuses* n); + void SetHeroicStaBonuses(StatBonuses* n); + void SetHeroicAgiBonuses(StatBonuses* n); + void SetHeroicDexBonuses(StatBonuses* n); + void SetHeroicIntBonuses(StatBonuses* n); + void SetHeroicWisBonuses(StatBonuses* n); + void DoSpellInterrupt(uint16 spell_id, int32 mana_cost, int my_curmana); }; diff --git a/zone/perl_bot.cpp b/zone/perl_bot.cpp index 99f37b3ef..f8e0e956e 100644 --- a/zone/perl_bot.cpp +++ b/zone/perl_bot.cpp @@ -337,12 +337,12 @@ void Perl_Bot_SetSpellDurationGroup(Bot* self, int spell_id, int duration, bool bool Perl_Bot_ReloadBotDataBuckets(Bot* self) { - return self->GetBotDataBuckets(); + return DataBucket::GetDataBuckets(self); } bool Perl_Bot_ReloadBotOwnerDataBuckets(Bot* self) { - return self->GetBotOwnerDataBuckets(); + return self->HasOwner() && DataBucket::GetDataBuckets(self->GetBotOwner()); } bool Perl_Bot_ReloadBotSpells(Bot* self) diff --git a/zone/perl_client.cpp b/zone/perl_client.cpp index 2f2ccaa46..16c57f321 100644 --- a/zone/perl_client.cpp +++ b/zone/perl_client.cpp @@ -2902,6 +2902,11 @@ bool Perl_Client_IsAutoFireEnabled(Client* self) return self->AutoFireEnabled(); } +bool Perl_Client_ReloadDataBuckets(Client* self) +{ + return DataBucket::GetDataBuckets(self); +} + void perl_register_client() { perl::interpreter perl(PERL_GET_THX); @@ -3248,6 +3253,7 @@ void perl_register_client() package.add("ReadBook", &Perl_Client_ReadBook); package.add("ReadBookByName", &Perl_Client_ReadBookByName); package.add("RefundAA", &Perl_Client_RefundAA); + package.add("ReloadDataBuckets", &Perl_Client_ReloadDataBuckets); package.add("RemoveAllExpeditionLockouts", (void(*)(Client*))&Perl_Client_RemoveAllExpeditionLockouts); package.add("RemoveAllExpeditionLockouts", (void(*)(Client*, std::string))&Perl_Client_RemoveAllExpeditionLockouts); package.add("RemoveExpeditionLockout", &Perl_Client_RemoveExpeditionLockout); diff --git a/zone/tune.cpp b/zone/tune.cpp index beb428f10..ad427146e 100644 --- a/zone/tune.cpp +++ b/zone/tune.cpp @@ -1049,7 +1049,7 @@ int64 Mob::TuneACSum(bool skip_caps, int ac_override, int add_ac) shield_ac = CalcRecommendedLevelBonus(GetLevel(), inst->GetItemRecommendedLevel(true),inst->GetItemArmorClass(true)); } } - shield_ac += GetHeroicSTR() * RuleR(Character, HeroicStrengthMultiplier) / 10; + shield_ac += itembonuses.heroic_str_shield_ac; } // EQ math ac = (ac * 4) / 3; @@ -1353,7 +1353,7 @@ int64 Mob::Tunecompute_defense(int avoidance_override, int add_avoidance) defense = avoidance_override; } else { - defense += GetHeroicAGI() * RuleR(Character, HeroicAgilityMultiplier) / 10; + defense += itembonuses.heroic_agi_avoidance; } defense += add_avoidance; //1 pt = 10 heroic agi } @@ -1495,10 +1495,10 @@ void Mob::TuneCommonOutgoingHitSuccess(Mob* defender, DamageHitInfo &hit, ExtraA switch (hit.skill) { case EQ::skills::SkillThrowing: case EQ::skills::SkillArchery: - extra = GetHeroicDEX() * RuleR(Character, HeroicDexterityMultiplier) / 10; + extra = itembonuses.heroic_dex_ranged_damage; break; default: - extra = GetHeroicSTR() * RuleR(Character, HeroicStrengthMultiplier) / 10; + extra = itembonuses.heroic_str_melee_damage; break; } hit.damage_done += extra; diff --git a/zone/zone.cpp b/zone/zone.cpp index 287856f82..3ddcc1894 100644 --- a/zone/zone.cpp +++ b/zone/zone.cpp @@ -2986,7 +2986,7 @@ std::string Zone::GetAAName(int aa_id) return std::string(); } -bool Zone::CheckDataBucket(uint8 bucket_comparison, std::string bucket_value, std::string player_value) +bool Zone::CompareDataBucket(uint8 bucket_comparison, const std::string& bucket_value, const std::string& player_value) { std::vector bucket_checks; bool found = false; diff --git a/zone/zone.h b/zone/zone.h index aa95a0e6c..6a6906684 100755 --- a/zone/zone.h +++ b/zone/zone.h @@ -311,7 +311,7 @@ public: bool IsQuestHotReloadQueued() const; void SetQuestHotReloadQueued(bool in_quest_hot_reload_queued); - bool CheckDataBucket(uint8 bucket_comparison, std::string bucket_value, std::string player_value); + bool CompareDataBucket(uint8 bucket_comparison, const std::string& bucket_value, const std::string& player_value); WaterMap *watermap; ZonePoint *GetClosestZonePoint(const glm::vec3 &location, uint32 to, Client *client, float max_distance = 40000.0f); From dc475a1bd7cf882b0b119aea0f5a0d52520bac2e Mon Sep 17 00:00:00 2001 From: Aeadoin <109764533+Aeadoin@users.noreply.github.com> Date: Fri, 24 Mar 2023 16:11:42 -0400 Subject: [PATCH 15/22] [Release] 22.7.0 (#3143) --- CHANGELOG.md | 157 +++++++++++++++++++++++++++++++++++++++++++++++ common/version.h | 2 +- package.json | 2 +- 3 files changed, 159 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 7089f4ea4..6627e5d23 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,160 @@ +## [22.7.0] - 03/24/2023 + +### Bots + +* Place BOT_COMMAND_CHAR inside messages ([#3027](https://github.com/EQEmu/Server/pull/3027)) @trentdm 2023-03-05 +* Prevent interrupt spam when OOM ([#3011](https://github.com/EQEmu/Server/pull/3011)) @nytmyr 2023-03-07 + +### Code + +* Cleaning up Raid.cpp ([#3125](https://github.com/EQEmu/Server/pull/3125)) @Aeadoin 2023-03-20 +* Cleanup unused methods and variables in world/main.cpp and world/main.h ([#3105](https://github.com/EQEmu/Server/pull/3105)) @Kinglykrab 2023-03-17 +* Cleanup uses of Strings::ToInt to match correct type. ([#3054](https://github.com/EQEmu/Server/pull/3054)) @Aeadoin 2023-03-22 +* Delete deprecated/perlxs folder ([#3110](https://github.com/EQEmu/Server/pull/3110)) @Kinglykrab 2023-03-17 +* Delete queues.h ([#3089](https://github.com/EQEmu/Server/pull/3089)) @Kinglykrab 2023-03-17 +* Delete world/console.old.cpp ([#3099](https://github.com/EQEmu/Server/pull/3099)) @Kinglykrab 2023-03-17 +* Delete zone_numbers.h ([#3129](https://github.com/EQEmu/Server/pull/3129)) @Kinglykrab 2023-03-20 +* Remove AllConnected(), CanUpdate(), and SendInfo() from login_server_list.cpp and login_server_list.h ([#3104](https://github.com/EQEmu/Server/pull/3104)) @Kinglykrab 2023-03-17 +* Remove CLIENT_TIMEOUT from world/client.h and zone/client.h ([#3071](https://github.com/EQEmu/Server/pull/3071)) @Kinglykrab 2023-03-17 +* Remove ChangeHP() from mob.h ([#3128](https://github.com/EQEmu/Server/pull/3128)) @Kinglykrab 2023-03-19 +* Remove CheckAuth(), SetOnline(), and pMD5Pass from cliententry.h ([#3095](https://github.com/EQEmu/Server/pull/3095)) @Kinglykrab 2023-03-17 +* Remove CommandRequirement() from zonedb.h ([#3094](https://github.com/EQEmu/Server/pull/3094)) @Kinglykrab 2023-03-17 +* Remove CountZones() from launcher_link.h ([#3100](https://github.com/EQEmu/Server/pull/3100)) @Kinglykrab 2023-03-17 +* Remove DBInitVars() and HandleMysqlError() from queryserv/database.h ([#3114](https://github.com/EQEmu/Server/pull/3114)) @Kinglykrab 2023-03-17 +* Remove DBInitVars(), HandleMysqlError(), and IsChatChannelInDB() in ucs/database.h ([#3113](https://github.com/EQEmu/Server/pull/3113)) @Kinglykrab 2023-03-17 +* Remove DisableStats(), EnableStats(), DisableLoginserver(), and EnableLoginserver() from world_config.h ([#3107](https://github.com/EQEmu/Server/pull/3107)) @Kinglykrab 2023-03-17 +* Remove DoBuffWearOffEffect() from mob.h ([#3062](https://github.com/EQEmu/Server/pull/3062)) @Kinglykrab 2023-03-17 +* Remove FindByName(charname) from clientlist.h ([#3096](https://github.com/EQEmu/Server/pull/3096)) @Kinglykrab 2023-03-17 +* Remove FindCLEByLSID(), GetCLE(), GetCLEIPCount(), and RemoveCLEByLSID() from clientlist.h ([#3098](https://github.com/EQEmu/Server/pull/3098)) @Kinglykrab 2023-03-17 +* Remove FindPatch() from struct_category.cpp and struct_category.h ([#3130](https://github.com/EQEmu/Server/pull/3130)) @Kinglykrab 2023-03-20 +* Remove FlushLootStats() from npc.h ([#3079](https://github.com/EQEmu/Server/pull/3079)) @Kinglykrab 2023-03-17 +* Remove GetAILevel() from npc.h ([#3080](https://github.com/EQEmu/Server/pull/3080)) @Kinglykrab 2023-03-17 +* Remove GetDestination() from doors.h ([#3078](https://github.com/EQEmu/Server/pull/3078)) @Kinglykrab 2023-03-17 +* Remove GetServerByAddress() from server_manager.h ([#3119](https://github.com/EQEmu/Server/pull/3119)) @Kinglykrab 2023-03-17 +* Remove GetStartCount() and InitStartTimer() from zone_launch.cpp and zone_launch.h ([#3121](https://github.com/EQEmu/Server/pull/3121)) @Kinglykrab 2023-03-17 +* Remove GetTransformation() and GetInvertedTransformation() from oriented_bounding_box.h ([#3084](https://github.com/EQEmu/Server/pull/3084)) @Kinglykrab 2023-03-17 +* Remove IsAffectedByBuff() ([#3068](https://github.com/EQEmu/Server/pull/3068)) @Kinglykrab 2023-03-17 +* Remove IsConnected() from loginserver/database.h ([#3117](https://github.com/EQEmu/Server/pull/3117)) @Kinglykrab 2023-03-17 +* Remove IsOrigin(glm::vec2) from position.h ([#3088](https://github.com/EQEmu/Server/pull/3088)) @Kinglykrab 2023-03-17 +* Remove MakeGuildMembers() from wguild_mgr.h ([#3106](https://github.com/EQEmu/Server/pull/3106)) @Kinglykrab 2023-03-17 +* Remove PlayerLogin_Struct from login_types.h ([#3118](https://github.com/EQEmu/Server/pull/3118)) @Kinglykrab 2023-03-17 +* Remove RemoveSpawnGroup() from spawngroup.h ([#3090](https://github.com/EQEmu/Server/pull/3090)) @Kinglykrab 2023-03-17 +* Remove SendGuildPacket() from clientlist.cpp, clientlist.h, and wguild_mgr.cpp ([#3097](https://github.com/EQEmu/Server/pull/3097)) @Kinglykrab 2023-03-17 +* Remove SetConnection() from loginserver/world_server.h ([#3120](https://github.com/EQEmu/Server/pull/3120)) @Kinglykrab 2023-03-17 +* Remove SetDBID() from object.h ([#3082](https://github.com/EQEmu/Server/pull/3082)) @Kinglykrab 2023-03-17 +* Remove SetSentTime2 in petitions.h ([#3086](https://github.com/EQEmu/Server/pull/3086)) @Kinglykrab 2023-03-17 +* Remove StoreCharacter() from worlddb.h ([#3108](https://github.com/EQEmu/Server/pull/3108)) @Kinglykrab 2023-03-17 +* Remove UpdateLoginserverWorldAdminAccountPasswordById() from account_management.cpp ([#3115](https://github.com/EQEmu/Server/pull/3115)) @Kinglykrab 2023-03-17 +* Remove _baseBotStance from bot.h ([#3076](https://github.com/EQEmu/Server/pull/3076)) @Kinglykrab 2023-03-17 +* Remove _botRole from bot.h ([#3075](https://github.com/EQEmu/Server/pull/3075)) @Kinglykrab 2023-03-17 +* Remove _previousTarget from bot.h ([#3074](https://github.com/EQEmu/Server/pull/3074)) @Kinglykrab 2023-03-17 +* Remove authenticated from launcher_link.cpp and launcher_link.h ([#3101](https://github.com/EQEmu/Server/pull/3101)) @Kinglykrab 2023-03-17 +* Remove can_corpse_be_rezzed from corpse.h ([#3077](https://github.com/EQEmu/Server/pull/3077)) @Kinglykrab 2023-03-17 +* Remove casting_spell_type from mob.h ([#3064](https://github.com/EQEmu/Server/pull/3064)) @Kinglykrab 2023-03-17 +* Remove class EQStream from client.h ([#3070](https://github.com/EQEmu/Server/pull/3070)) @Kinglykrab 2023-03-17 +* Remove current_buff_count ([#3067](https://github.com/EQEmu/Server/pull/3067)) @Kinglykrab 2023-03-17 +* Remove firstlogin and realfirstlogin from world/client.h ([#3072](https://github.com/EQEmu/Server/pull/3072)) @Kinglykrab 2023-03-17 +* Remove fixedZ from mob.h ([#3065](https://github.com/EQEmu/Server/pull/3065)) @Kinglykrab 2023-03-17 +* Remove inWater from mob.h ([#3069](https://github.com/EQEmu/Server/pull/3069)) @Kinglykrab 2023-03-17 +* Remove is_authenticatd, LSShutDownUpdate(), and SetInstanceID() from zoneserver.h ([#3109](https://github.com/EQEmu/Server/pull/3109)) @Kinglykrab 2023-03-17 +* Remove last_insert_id from petitions.h ([#3087](https://github.com/EQEmu/Server/pull/3087)) @Kinglykrab 2023-03-17 +* Remove last_max_hp from mob.h ([#3063](https://github.com/EQEmu/Server/pull/3063)) @Kinglykrab 2023-03-17 +* Remove m_inuse, m_z, and m_heading from object.h ([#3083](https://github.com/EQEmu/Server/pull/3083)) @Kinglykrab 2023-03-17 +* Remove npc_ai.cpp/npc_ai.cpp ([#3081](https://github.com/EQEmu/Server/pull/3081)) @Kinglykrab 2023-03-17 +* Remove ownHiddenTrigger from trap.cpp and trap.h ([#3092](https://github.com/EQEmu/Server/pull/3092)) @Kinglykrab 2023-03-17 +* Remove perlparser.h ([#3085](https://github.com/EQEmu/Server/pull/3085)) @Kinglykrab 2023-03-17 +* Remove unused AbilityTimer variable in client.h ([#3035](https://github.com/EQEmu/Server/pull/3035)) @Kinglykrab 2023-03-05 +* Remove unused BotAA struct in bot_structs.h ([#3038](https://github.com/EQEmu/Server/pull/3038)) @Kinglykrab 2023-03-05 +* Remove unused HandleUpdateTasksOnKill in client.h ([#3032](https://github.com/EQEmu/Server/pull/3032)) @Kinglykrab 2023-03-05 +* Remove unused SaveBackup in client.h ([#3030](https://github.com/EQEmu/Server/pull/3030)) @Kinglykrab 2023-03-05 +* Remove unused ^evacuate and ^succor subcommands from bot_command.h ([#3039](https://github.com/EQEmu/Server/pull/3039)) @Kinglykrab 2023-03-05 +* Remove unused bot structs in bot_structs.h ([#3037](https://github.com/EQEmu/Server/pull/3037)) @Kinglykrab 2023-03-05 +* Remove unused client queued work variable in client.cpp/client.h ([#3034](https://github.com/EQEmu/Server/pull/3034)) @Kinglykrab 2023-03-05 +* Remove unused command variables in client.cpp ([#3031](https://github.com/EQEmu/Server/pull/3031)) @Kinglykrab 2023-03-05 +* Remove unused lua_hate_entry.cpp ([#3057](https://github.com/EQEmu/Server/pull/3057)) @Kinglykrab 2023-03-12 +* Remove unused methods in eql_config.cpp, eql_config.h, launcher_list.cpp, and launcher_list.h ([#3103](https://github.com/EQEmu/Server/pull/3103)) @Kinglykrab 2023-03-17 +* Remove unused methods in loginserver/client.h ([#3116](https://github.com/EQEmu/Server/pull/3116)) @Kinglykrab 2023-03-17 +* Remove unused player update variables in client.cpp/client.h ([#3033](https://github.com/EQEmu/Server/pull/3033)) @Kinglykrab 2023-03-05 +* Utilize GetPlayerState() in mob methods ([#3066](https://github.com/EQEmu/Server/pull/3066)) @Kinglykrab 2023-03-17 +* Utilize GetScheduler() in zone/worldserver.cpp ([#3093](https://github.com/EQEmu/Server/pull/3093)) @Kinglykrab 2023-03-17 +* Utilize SetFilter in client.cpp ([#3036](https://github.com/EQEmu/Server/pull/3036)) @Kinglykrab 2023-03-05 +* Utilize SetHiddenTrigger in trap.cpp ([#3091](https://github.com/EQEmu/Server/pull/3091)) @Kinglykrab 2023-03-17 +* remove _botOrderAttack from bot.h ([#3073](https://github.com/EQEmu/Server/pull/3073)) @Kinglykrab 2023-03-17 + +### Commands + +* Cleanup #haste Command ([#3042](https://github.com/EQEmu/Server/pull/3042)) @Kinglykrab 2023-03-06 +* Cleanup #hideme Command ([#3043](https://github.com/EQEmu/Server/pull/3043)) @Kinglykrab 2023-03-06 +* Cleanup #interrupt Command ([#3044](https://github.com/EQEmu/Server/pull/3044)) @Kinglykrab 2023-03-06 +* Cleanup #level Command ([#3045](https://github.com/EQEmu/Server/pull/3045)) @Kinglykrab 2023-03-06 +* Cleanup #picklock Command ([#3046](https://github.com/EQEmu/Server/pull/3046)) @Kinglykrab 2023-03-06 +* Cleanup #resetaa and #resetaa_timer ([#3047](https://github.com/EQEmu/Server/pull/3047)) @Kinglykrab 2023-03-06 +* Cleanup #wc Command ([#3049](https://github.com/EQEmu/Server/pull/3049)) @Kinglykrab 2023-03-06 +* Remove #equipitem Command ([#3040](https://github.com/EQEmu/Server/pull/3040)) @Kinglykrab 2023-03-06 + +### Console + +* Add IS_TTY to force terminal coloring output ([#3021](https://github.com/EQEmu/Server/pull/3021)) @Akkadius 2023-03-04 + +### Crash + +* Fix dangling Group member pointers for Bots. ([#3134](https://github.com/EQEmu/Server/pull/3134)) @Aeadoin 2023-03-21 +* Fixes Crash when Zoning with XTarget when Bots are in group. ([#3126](https://github.com/EQEmu/Server/pull/3126)) @Aeadoin 2023-03-19 + +### Feature + +* Add Basic Bot Raiding Functionality ([#2782](https://github.com/EQEmu/Server/pull/2782)) @neckkola 2023-03-17 +* Add Data Bucket support for scaling of Heroic Stats. ([#3058](https://github.com/EQEmu/Server/pull/3058)) @Aeadoin 2023-03-24 +* Add Item Extra Skill Damage Percent Modifier ([#3127](https://github.com/EQEmu/Server/pull/3127)) @Kinglykrab 2023-03-19 + +### Fixes + +* Add Avoidance and HP Regen Per Second too NPC Scaling. ([#3050](https://github.com/EQEmu/Server/pull/3050)) @Aeadoin 2023-03-09 +* Add Heroic Strikethrough & HP Regen Per Second to GM Entity Info ([#3055](https://github.com/EQEmu/Server/pull/3055)) @Aeadoin 2023-03-12 +* Add Heroic Strikethrough to NPC Scaling ([#3028](https://github.com/EQEmu/Server/pull/3028)) @Kinglykrab 2023-03-06 +* Change SPA 193 Weapon Damage to allow values over 65,535 ([#3138](https://github.com/EQEmu/Server/pull/3138)) @Aeadoin 2023-03-23 +* Checkmarks and X characters in popup messages ([#3041](https://github.com/EQEmu/Server/pull/3041)) @Kinglykrab 2023-03-06 +* Cursor Coin Upon Death ([#3020](https://github.com/EQEmu/Server/pull/3020)) @cybernine186 2023-03-04 +* Ensure synchronization of pet taunt state with UI ([#3025](https://github.com/EQEmu/Server/pull/3025)) @catapultam-habeo 2023-03-04 +* Fix Bard Bot Casting ([#3122](https://github.com/EQEmu/Server/pull/3122)) @Aeadoin 2023-03-17 +* Fix Discovered Items with Alternate Currency and LDoN Adventure Merchants ([#3026](https://github.com/EQEmu/Server/pull/3026)) @Kinglykrab 2023-03-04 +* Fix Heal Scale and Spell Scale in NPC Scaling ([#3051](https://github.com/EQEmu/Server/pull/3051)) @Kinglykrab 2023-03-10 +* Fix Raid Invites causing client desync issues ([#3053](https://github.com/EQEmu/Server/pull/3053)) @Aeadoin 2023-03-11 +* Fix Raid methods that could cause crashes with Bots in raid ([#3111](https://github.com/EQEmu/Server/pull/3111)) @Aeadoin 2023-03-17 +* Fix edge cases where camped bots would be left in a raid ([#3139](https://github.com/EQEmu/Server/pull/3139)) @Aeadoin 2023-03-23 +* Fix for Raid Disband if leader not in same zone. ([#3135](https://github.com/EQEmu/Server/pull/3135)) @Aeadoin 2023-03-21 +* Fix for incorrect bindpoint x,y,z,headings ([#3141](https://github.com/EQEmu/Server/pull/3141)) @Aeadoin 2023-03-23 +* Fix for transferring Raid Leader ([#3140](https://github.com/EQEmu/Server/pull/3140)) @Aeadoin 2023-03-23 +* Fix issue with overflow on min/max hit dmg in npc scaling calculations ([#3052](https://github.com/EQEmu/Server/pull/3052)) @Aeadoin 2023-03-10 +* Fix typo for bot_id raid_members column in db_update_manifest.txt ([#3132](https://github.com/EQEmu/Server/pull/3132)) @Kinglykrab 2023-03-20 +* Fixes for corpses not properly saving some item instance data correctly. ([#3123](https://github.com/EQEmu/Server/pull/3123)) @KimLS 2023-03-23 + +### Illusions + +* Fix bug where spells like Ignite Bones left NPC size incorrect. ([#3061](https://github.com/EQEmu/Server/pull/3061)) @noudess 2023-03-16 + +### Quest API + +* Add SendIllusion overloads/parameters to Perl/Lua ([#3059](https://github.com/EQEmu/Server/pull/3059)) @Kinglykrab 2023-03-16 +* Add Spell GetActX methods to Perl/Lua ([#3056](https://github.com/EQEmu/Server/pull/3056)) @Kinglykrab 2023-03-12 +* Add Timer related methods to Mobs in Perl/Lua ([#3133](https://github.com/EQEmu/Server/pull/3133)) @Kinglykrab 2023-03-20 + +### Rules + +* Add Multiplier for Heroic Stats. ([#3014](https://github.com/EQEmu/Server/pull/3014)) @Aeadoin 2023-03-04 +* Add ResurrectionEffectsBlock ([#2990](https://github.com/EQEmu/Server/pull/2990)) @nytmyr 2023-03-04 +* Add Rule to allow ExtraDmgSkill/SPA 220 to effect Spell Skills ([#3124](https://github.com/EQEmu/Server/pull/3124)) @Aeadoin 2023-03-19 +* Add Task System Rule ExpRewardsIgnoreLevelBasedEXPMods ([#3112](https://github.com/EQEmu/Server/pull/3112)) @Aeadoin 2023-03-17 + +### Scaling + +* Add support for pipe-separated zone IDs and versions ([#3015](https://github.com/EQEmu/Server/pull/3015)) @Kinglykrab 2023-03-04 + +### Strings + +* Add exception handling to converters themselves ([#3029](https://github.com/EQEmu/Server/pull/3029)) @Akkadius 2023-03-05 +* Add more number formatters ([#2873](https://github.com/EQEmu/Server/pull/2873)) @Kinglykrab 2023-03-04 + ## [22.4.5] - 03/03/2023 ### Bots diff --git a/common/version.h b/common/version.h index 6f6179db5..bb067bfb4 100644 --- a/common/version.h +++ b/common/version.h @@ -25,7 +25,7 @@ // Build variables // these get injected during the build pipeline -#define CURRENT_VERSION "22.4.5-dev" // always append -dev to the current version for custom-builds +#define CURRENT_VERSION "22.7.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__ diff --git a/package.json b/package.json index 8617ab870..47da5ac06 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "eqemu-server", - "version": "22.4.5", + "version": "22.7.0", "repository": { "type": "git", "url": "https://github.com/EQEmu/Server.git" From 2e4071cdcf41979a835f7623178d27c597f7d702 Mon Sep 17 00:00:00 2001 From: Alex King <89047260+Kinglykrab@users.noreply.github.com> Date: Sat, 25 Mar 2023 17:48:40 -0400 Subject: [PATCH 16/22] [Cleanup] Remove extern bool Critical (#3146) # Notes - This is unused. --- zone/main.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/zone/main.cpp b/zone/main.cpp index cb16f13aa..083c2ff07 100644 --- a/zone/main.cpp +++ b/zone/main.cpp @@ -85,7 +85,6 @@ volatile bool RunLoops = true; #endif extern volatile bool is_zone_loaded; -extern bool Critical = false; #include "zone_event_scheduler.h" #include "../common/file.h" From 7f415479634af0145a5e843d35b01ee45151c78b Mon Sep 17 00:00:00 2001 From: Aeadoin <109764533+Aeadoin@users.noreply.github.com> Date: Sat, 25 Mar 2023 18:02:05 -0400 Subject: [PATCH 17/22] [Crash] Fix for crash in Raid::QueuePacket (#3145) * [Crash] Fix for crash in Raid::QueuePacket * bots can't be a part of BalanceMana * corrected additions * adding additional is_bot gates * updating raid for loops to be range based. * typo * formatting * formatting --- zone/attack.cpp | 62 +++++++---- zone/bot.cpp | 16 +-- zone/client.cpp | 82 ++++++-------- zone/client_packet.cpp | 2 +- zone/questmgr.cpp | 10 +- zone/raids.cpp | 47 +++++++- zone/worldserver.cpp | 241 +++++++++++++++++++++++------------------ 7 files changed, 271 insertions(+), 189 deletions(-) diff --git a/zone/attack.cpp b/zone/attack.cpp index d567985b7..a87862506 100644 --- a/zone/attack.cpp +++ b/zone/attack.cpp @@ -2505,8 +2505,10 @@ bool NPC::Death(Mob* killer_mob, int64 damage, uint16 spell, EQ::skills::SkillTy bool ownerInGroup = false; if ((give_exp->HasGroup() && give_exp->GetGroup()->IsGroupMember(give_exp->GetUltimateOwner())) || (give_exp->IsPet() && (give_exp->GetOwner()->IsClient() - || (give_exp->GetOwner()->HasGroup() && give_exp->GetOwner()->GetGroup()->IsGroupMember(give_exp->GetOwner()->GetUltimateOwner()))))) + || (give_exp->GetOwner()->HasGroup() && give_exp->GetOwner()->GetGroup()->IsGroupMember(give_exp->GetOwner()->GetUltimateOwner())))) + ) { ownerInGroup = true; + } give_exp = give_exp->GetUltimateOwner(); @@ -2518,20 +2520,23 @@ bool NPC::Death(Mob* killer_mob, int64 damage, uint16 spell, EQ::skills::SkillTy if (give_exp && give_exp->IsTempPet() && give_exp->IsPetOwnerClient()) { if (give_exp->IsNPC() && give_exp->CastToNPC()->GetSwarmOwner()) { Mob* temp_owner = entity_list.GetMobID(give_exp->CastToNPC()->GetSwarmOwner()); - if (temp_owner) + if (temp_owner) { give_exp = temp_owner; + } } } int PlayerCount = 0; // QueryServ Player Counting Client *give_exp_client = nullptr; - if (give_exp && give_exp->IsClient()) + if (give_exp && give_exp->IsClient()) { give_exp_client = give_exp->CastToClient(); + } //do faction hits even if we are a merchant, so long as a player killed us - if (!IsCharmed() && give_exp_client && !RuleB(NPC, EnableMeritBasedFaction)) + if (!IsCharmed() && give_exp_client && !RuleB(NPC, EnableMeritBasedFaction)) { hate_list.DoFactionHits(GetNPCFactionID(), GetPrimaryFaction(), GetFactionAmount()); + } bool IsLdonTreasure = (GetClass() == LDON_TREASURE); @@ -2559,17 +2564,22 @@ bool NPC::Death(Mob* killer_mob, int64 damage, uint16 spell, EQ::skills::SkillTy } /* Send the EVENT_KILLED_MERIT event for all raid members */ - for (int i = 0; i < MAX_RAID_MEMBERS; i++) { - if (kr->members[i].member != nullptr && kr->members[i].member->IsClient()) { // If Group Member is Client - Client *c = kr->members[i].member; + for (const auto& m : kr->members) { + if (m.is_bot) { + continue; + } + + if (m.member && m.member->IsClient()) { // If Group Member is Client + Client *c = m.member; c->RecordKilledNPCEvent(this); if (parse->HasQuestSub(GetNPCTypeID(), EVENT_KILLED_MERIT)) { parse->EventNPC(EVENT_KILLED_MERIT, this, c, "killed", 0); } - if (RuleB(NPC, EnableMeritBasedFaction)) + if (RuleB(NPC, EnableMeritBasedFaction)) { c->SetFactionLevel(c->CharacterID(), GetNPCFactionID(), c->GetBaseClass(), c->GetBaseRace(), c->GetDeity()); + } PlayerCount++; } @@ -2586,9 +2596,13 @@ bool NPC::Death(Mob* killer_mob, int64 damage, uint16 spell, EQ::skills::SkillTy QS->s1.NPCID = GetNPCTypeID(); QS->s1.ZoneID = GetZoneID(); QS->s1.Type = 2; // Raid Fight - for (int i = 0; i < MAX_RAID_MEMBERS; i++) { - if (kr->members[i].member != nullptr && kr->members[i].member->IsClient()) { // If Group Member is Client - Client *c = kr->members[i].member; + for (const auto& m : kr->members) { + if (m.is_bot) { + continue; + } + + if (m.member && m.member->IsClient()) { // If Group Member is Client + Client *c = m.member; QS->Chars[PlayerCount].char_id = c->CharacterID(); PlayerCount++; } @@ -2742,34 +2756,34 @@ bool NPC::Death(Mob* killer_mob, int64 damage, uint16 spell, EQ::skills::SkillTy Raid* r = entity_list.GetRaidByClient(killer->CastToClient()); if (r) { int i = 0; - for (int x = 0; x < MAX_RAID_MEMBERS; x++) { + for (const auto& m : r->members) { + if (m.is_bot) { + continue; + } + switch (r->GetLootType()) { case 0: case 1: - if (r->members[x].member && r->members[x].is_raid_leader) { - corpse->AllowPlayerLoot(r->members[x].member, i); + if (m.member && m.is_raid_leader) { + corpse->AllowPlayerLoot(m.member, i); i++; } break; case 2: - if (r->members[x].member && r->members[x].is_raid_leader) { - corpse->AllowPlayerLoot(r->members[x].member, i); - i++; - } - else if (r->members[x].member && r->members[x].is_group_leader) { - corpse->AllowPlayerLoot(r->members[x].member, i); + if (m.member && (m.is_raid_leader || m.is_group_leader)) { + corpse->AllowPlayerLoot(m.member, i); i++; } break; case 3: - if (r->members[x].member && r->members[x].is_looter) { - corpse->AllowPlayerLoot(r->members[x].member, i); + if (m.member && m.is_looter) { + corpse->AllowPlayerLoot(m.member, i); i++; } break; case 4: - if (r->members[x].member) { - corpse->AllowPlayerLoot(r->members[x].member, i); + if (m.member) { + corpse->AllowPlayerLoot(m.member, i); i++; } break; diff --git a/zone/bot.cpp b/zone/bot.cpp index af8584f5d..e68789e07 100644 --- a/zone/bot.cpp +++ b/zone/bot.cpp @@ -9105,16 +9105,18 @@ std::vector Bot::GetApplySpellList( auto* r = GetRaid(); auto group_id = r->GetGroup(GetCleanName()); if (r && EQ::ValueWithin(group_id, 0, (MAX_RAID_GROUPS - 1))) { - for (auto i = 0; i < MAX_RAID_MEMBERS; i++) { - auto* m = r->members[i].member; - if (m && m->IsClient() && (!is_raid_group_only || r->GetGroup(m) == group_id)) { - l.push_back(m); + for (const auto& m : r->members) { + if (m.is_bot) { + continue; + } + 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->HasPet()) { - l.push_back(m->GetPet()); + if (allow_pets && m.member->HasPet()) { + l.push_back(m.member->GetPet()); } - const auto& sbl = entity_list.GetBotListByCharacterID(m->CharacterID()); + const auto& sbl = entity_list.GetBotListByCharacterID(m.member->CharacterID()); for (const auto& b : sbl) { l.push_back(b); } diff --git a/zone/client.cpp b/zone/client.cpp index d820328df..7b87af474 100644 --- a/zone/client.cpp +++ b/zone/client.cpp @@ -798,24 +798,21 @@ bool Client::SendAllPackets() { } void Client::QueuePacket(const EQApplicationPacket* app, bool ack_req, CLIENT_CONN_STATUS required_state, eqFilterType filter) { - if(filter!=FilterNone){ - //this is incomplete... no support for FilterShowGroupOnly or FilterShowSelfOnly - if(GetFilter(filter) == FilterHide) - return; //Client has this filter on, no need to send packet + if (filter != FilterNone && GetFilter(filter) == FilterHide) { + return; } - if(client_state != CLIENT_CONNECTED && required_state == CLIENT_CONNECTED){ + + if (client_state != CLIENT_CONNECTED && required_state == CLIENT_CONNECTED) { AddPacket(app, ack_req); return; } // if the program doesnt care about the status or if the status isnt what we requested - if (required_state != CLIENT_CONNECTINGALL && client_state != required_state) - { + if (required_state != CLIENT_CONNECTINGALL && client_state != required_state) { // todo: save packets for later use AddPacket(app, ack_req); } - else if (eqs) - { + else if (eqs) { eqs->QueuePacket(app, ack_req); } } @@ -4143,42 +4140,32 @@ void Client::UpdateLFP() { bool Client::GroupFollow(Client* inviter) { - if (inviter) - { + if (inviter) { isgrouped = true; Raid* raid = entity_list.GetRaidByClient(inviter); Raid* iraid = entity_list.GetRaidByClient(this); //inviter has a raid don't do group stuff instead do raid stuff! - if (raid) - { + if (raid) { // Suspend the merc while in a raid (maybe a rule could be added for this) - if (GetMerc()) + if (GetMerc()) { GetMerc()->Suspend(); + } uint32 groupToUse = 0xFFFFFFFF; - for (int x = 0; x < MAX_RAID_MEMBERS; x++) - { - if (raid->members[x].member) - { - //this assumes the inviter is in the zone - if (raid->members[x].member == inviter){ - groupToUse = raid->members[x].group_number; - break; - } + for (const auto& m : raid->members) { + if (m.member && m.member == inviter) { + groupToUse = m.group_number; + break; } } - if (iraid == raid) - { + if (iraid == raid) { //both in same raid uint32 ngid = raid->GetGroup(inviter->GetName()); - if (raid->GroupCount(ngid) < 6) - { + if (raid->GroupCount(ngid) < 6) { raid->MoveMember(GetName(), ngid); raid->SendGroupDisband(this); - //raid->SendRaidGroupAdd(GetName(), ngid); - //raid->SendGroupUpdate(this); - raid->GroupUpdate(ngid); //break + raid->GroupUpdate(ngid); } return false; } @@ -8866,16 +8853,15 @@ void Client::ProcessAggroMeter() if (m_aggrometer.set_pct(AggroMeter::AT_Secondary, has_aggro ? cur_tar->GetHateRatio(this, secondary) : secondary ? 100 : 0)) add_entry(AggroMeter::AT_Secondary); - // fuuuuuuuuuuuuuuuuuuuuuuuucckkkkkkkkkkkkkkk raids if (IsRaidGrouped()) { auto raid = GetRaid(); if (raid) { auto gid = raid->GetGroup(this); - if (gid < 12) { + if (gid < MAX_RAID_GROUPS) { int at_id = AggroMeter::AT_Group1; - for (int i = 0; i < MAX_RAID_MEMBERS; ++i) { - if (raid->members[i].member && raid->members[i].member != this && raid->members[i].group_number == gid) { - if (m_aggrometer.set_pct(static_cast(at_id), cur_tar->GetHateRatio(cur_tar->GetTarget(), raid->members[i].member))) + for (const auto& m : raid->members) { + if (m.member && m.member != this && m.group_number == gid) { + if (m_aggrometer.set_pct(static_cast(at_id), cur_tar->GetHateRatio(cur_tar->GetTarget(), m.member))) add_entry(static_cast(at_id)); at_id++; if (at_id > AggroMeter::AT_Group5) @@ -10956,11 +10942,14 @@ std::vector Client::GetPartyMembers() std::vector clients_to_update = {}; // raid - Raid *raid = entity_list.GetRaidByClient(this); - if (raid) { - for (auto &e : raid->members) { - if (e.member && e.member->IsClient()) { - clients_to_update.push_back(e.member->CastToClient()); + if (const auto raid = entity_list.GetRaidByClient(this)) { + for (auto &m : raid->members) { + if (m.is_bot) { + continue; + } + + if (m.member && m.member->IsClient()) { + clients_to_update.push_back(m.member->CastToClient()); } } } @@ -11747,17 +11736,16 @@ std::vector Client::GetApplySpellList( auto* r = GetRaid(); auto group_id = r->GetGroup(this); if (r && EQ::ValueWithin(group_id, 0, (MAX_RAID_GROUPS - 1))) { - for (auto i = 0; i < MAX_RAID_MEMBERS; i++) { - auto* m = r->members[i].member; - if (m && m->IsClient() && (!is_raid_group_only || r->GetGroup(m) == group_id)) { - l.push_back(m); + 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->HasPet()) { - l.push_back(m->GetPet()); + if (allow_pets && m.member->HasPet()) { + l.push_back(m.member->GetPet()); } if (allow_bots) { - const auto& sbl = entity_list.GetBotListByCharacterID(m->CharacterID()); + const auto& sbl = entity_list.GetBotListByCharacterID(m.member->CharacterID()); for (const auto& b : sbl) { l.push_back(b); } diff --git a/zone/client_packet.cpp b/zone/client_packet.cpp index 1ea1a85c8..85fb68804 100644 --- a/zone/client_packet.cpp +++ b/zone/client_packet.cpp @@ -12183,7 +12183,7 @@ void Client::Handle_OP_RaidCommand(const EQApplicationPacket* app) uint32 i = raid->GetPlayerIndex(raid_command_packet->leader_name); raid->SetNewRaidLeader(i); raid->HandleBotGroupDisband(c_to_disband->CharacterID()); - raid->HandleOfflineBots(c_to_disband->CharacterID()); + raid->HandleOfflineBots(c_to_disband->CharacterID()); raid->RemoveMember(raid_command_packet->leader_name); raid->SendGroupDisband(c_to_disband); raid->GroupUpdate(group); diff --git a/zone/questmgr.cpp b/zone/questmgr.cpp index 027df7e0b..57e074891 100644 --- a/zone/questmgr.cpp +++ b/zone/questmgr.cpp @@ -448,9 +448,13 @@ void QuestManager::ZoneRaid(const char *zone_name) { initiator->MoveZone(zone_name); } else { auto client_raid = initiator->GetRaid(); - for (int member_index = 0; member_index < MAX_RAID_MEMBERS; member_index++) { - if (client_raid->members[member_index].member && client_raid->members[member_index].member->IsClient()) { - auto raid_member = client_raid->members[member_index].member->CastToClient(); + for (const auto& m : client_raid->members) { + if (m.is_bot) { + continue; + } + + if (m.member && m.member->IsClient()) { + auto raid_member = m.member->CastToClient(); raid_member->MoveZone(zone_name); } } diff --git a/zone/raids.cpp b/zone/raids.cpp index 54250e680..43f27530d 100644 --- a/zone/raids.cpp +++ b/zone/raids.cpp @@ -611,9 +611,8 @@ void Raid::RaidGroupSay(const char *msg, Client *c, uint8 language, uint8 lang_s uint32 Raid::GetPlayerIndex(const char *name) { - for(int x = 0; x < MAX_RAID_MEMBERS; x++) - { - if(strcmp(name, members[x].member_name) == 0) { + for (int x = 0; x < MAX_RAID_MEMBERS; x++) { + if (strcmp(name, members[x].member_name) == 0) { return x; } } @@ -832,6 +831,10 @@ void Raid::BalanceMana(int32 penalty, uint32 gid, float range, Mob* caster, int3 manataken /= numMem; for (const auto& m : members) { + if (m.is_bot) { + continue; + } + if (m.member && m.group_number == gid) { distance = DistanceSquared(caster->GetPosition(), m.member->GetPosition()); @@ -875,6 +878,10 @@ void Raid::SplitMoney(uint32 gid, uint32 copper, uint32 silver, uint32 gold, uin uint8 member_count = 0; for (const auto& m : members) { + if (m.is_bot) { + continue; + } + if (m.member && m.group_number == gid && m.member->IsClient()) { member_count++; } @@ -914,6 +921,10 @@ void Raid::SplitMoney(uint32 gid, uint32 copper, uint32 silver, uint32 gold, uin auto platinum_split = platinum / member_count; for (const auto& m : members) { + if (m.is_bot) { + continue; + } + if (m.member && m.group_number == gid && m.member->IsClient()) { // If Group Member is Client m.member->AddMoneyToPP( copper_split, @@ -952,6 +963,10 @@ void Raid::SplitMoney(uint32 gid, uint32 copper, uint32 silver, uint32 gold, uin void Raid::TeleportGroup(Mob* sender, uint32 zoneID, uint16 instance_id, float x, float y, float z, float heading, uint32 gid) { for (const auto& m : members) { + if (m.is_bot) { + continue; + } + if (m.member && m.group_number == gid && m.member->IsClient()) { m.member->MovePC(zoneID, instance_id, x, y, z, heading, 0, ZoneSolicited); } @@ -961,6 +976,10 @@ void Raid::TeleportGroup(Mob* sender, uint32 zoneID, uint16 instance_id, float x void Raid::TeleportRaid(Mob* sender, uint32 zoneID, uint16 instance_id, float x, float y, float z, float heading) { for (const auto& m : members) { + if (m.is_bot) { + continue; + } + if (m.member && m.member->IsClient()) { m.member->MovePC(zoneID, instance_id, x, y, z, heading, 0, ZoneSolicited); } @@ -981,6 +1000,10 @@ void Raid::AddRaidLooter(const char* looter) auto results = database.QueryDatabase(query); for (auto& m : members) { + if (m.is_bot) { + continue; + } + if (strcmp(looter, m.member_name) == 0) { m.is_looter = true; break; @@ -1002,6 +1025,10 @@ void Raid::RemoveRaidLooter(const char* looter) auto results = database.QueryDatabase(query); for (auto& m: members) { + if (m.is_bot) { + continue; + } + if (strcmp(looter, m.member_name) == 0) { m.is_looter = false; break; @@ -1258,6 +1285,10 @@ void Raid::SendBulkRaid(Client *to) void Raid::QueuePacket(const EQApplicationPacket *app, bool ack_req) { for (const auto& m : members) { + if (m.is_bot) { + continue; + } + if (m.member && m.member->IsClient()) { m.member->QueuePacket(app, ack_req); } @@ -1332,7 +1363,7 @@ void Raid::SendGroupUpdate(Client *to) gu->action = groupActUpdate; int i = 0; uint32 grp = GetGroup(to->GetName()); - if (grp >= MAX_RAID_MEMBERS) { + if (grp >= MAX_RAID_GROUPS) { safe_delete(outapp); return; } @@ -1502,6 +1533,10 @@ void Raid::SendRaidMOTD() } for (const auto& m: members) { + if (m.is_bot) { + continue; + } + if (m.member) { SendRaidMOTD(m.member); } @@ -1911,6 +1946,10 @@ const char *Raid::GetClientNameByIndex(uint8 index) void Raid::RaidMessageString(Mob* sender, uint32 type, uint32 string_id, const char* message,const char* message2,const char* message3,const char* message4,const char* message5,const char* message6,const char* message7,const char* message8,const char* message9, uint32 distance) { for (const auto& m : members) { + if (m.is_bot) { + continue; + } + if (m.member && m.member->IsClient() && m.member != sender) { m.member->MessageString(type, string_id, message, message2, message3, message4, message5, message6, message7, message8, message9, distance); diff --git a/zone/worldserver.cpp b/zone/worldserver.cpp index 70013c3e6..699db95fb 100644 --- a/zone/worldserver.cpp +++ b/zone/worldserver.cpp @@ -294,12 +294,19 @@ void WorldServer::HandleMessage(uint16 opcode, const EQ::Net::Packet &p) case VoiceMacroRaid: { Raid *r = entity_list.GetRaidByID(svm->RaidID); - if (!r) + if (!r) { break; + } - for (int i = 0; i < MAX_RAID_MEMBERS; i++) - if (r->members[i].member) - r->members[i].member->QueuePacket(outapp); + for (const auto& m: r->members) { + if (m.is_bot) { + continue; + } + + if (m.member) { + m.member->QueuePacket(outapp); + } + } break; } @@ -1055,7 +1062,7 @@ void WorldServer::HandleMessage(uint16 opcode, const EQ::Net::Packet &p) { auto outapp = new EQApplicationPacket(OP_GroupUpdate, sizeof(GroupJoin_Struct)); - GroupJoin_Struct* outgj = (GroupJoin_Struct*)outapp->pBuffer; + auto outgj = (GroupJoin_Struct*)outapp->pBuffer; strcpy(outgj->membername, Inviter->GetName()); strcpy(outgj->yourname, Inviter->GetName()); outgj->action = groupActInviteInitial; // 'You have formed the group'. @@ -1095,7 +1102,7 @@ void WorldServer::HandleMessage(uint16 opcode, const EQ::Net::Packet &p) Inviter->CastToClient()->UpdateLFP(); auto pack2 = new ServerPacket(ServerOP_GroupJoin, sizeof(ServerGroupJoin_Struct)); - ServerGroupJoin_Struct* gj = (ServerGroupJoin_Struct*)pack2->pBuffer; + auto gj = (ServerGroupJoin_Struct*)pack2->pBuffer; gj->gid = group->GetID(); gj->zoneid = zone->GetZoneID(); gj->instance_id = zone->GetInstanceID(); @@ -1213,7 +1220,7 @@ void WorldServer::HandleMessage(uint16 opcode, const EQ::Net::Packet &p) break; } case ServerOP_GroupJoin: { - ServerGroupJoin_Struct* gj = (ServerGroupJoin_Struct*)pack->pBuffer; + auto gj = (ServerGroupJoin_Struct*)pack->pBuffer; if (zone) { if (gj->zoneid == zone->GetZoneID() && gj->instance_id == zone->GetInstanceID()) break; @@ -1259,7 +1266,7 @@ void WorldServer::HandleMessage(uint16 opcode, const EQ::Net::Packet &p) break; } case ServerOP_RaidAdd: { - ServerRaidGeneralAction_Struct* rga = (ServerRaidGeneralAction_Struct*)pack->pBuffer; + auto rga = (ServerRaidGeneralAction_Struct*)pack->pBuffer; if (zone) { if (rga->zoneid == zone->GetZoneID() && rga->instance_id == zone->GetInstanceID()) break; @@ -1274,7 +1281,7 @@ void WorldServer::HandleMessage(uint16 opcode, const EQ::Net::Packet &p) break; } case ServerOP_RaidRemove: { - ServerRaidGeneralAction_Struct* rga = (ServerRaidGeneralAction_Struct*)pack->pBuffer; + auto rga = (ServerRaidGeneralAction_Struct*)pack->pBuffer; if (zone) { if (rga->zoneid == zone->GetZoneID() && rga->instance_id == zone->GetInstanceID()) break; @@ -1294,7 +1301,7 @@ void WorldServer::HandleMessage(uint16 opcode, const EQ::Net::Packet &p) break; } case ServerOP_RaidDisband: { - ServerRaidGeneralAction_Struct* rga = (ServerRaidGeneralAction_Struct*)pack->pBuffer; + auto rga = (ServerRaidGeneralAction_Struct*)pack->pBuffer; if (zone) { if (rga->zoneid == zone->GetZoneID() && rga->instance_id == zone->GetInstanceID()) break; @@ -1309,7 +1316,7 @@ void WorldServer::HandleMessage(uint16 opcode, const EQ::Net::Packet &p) break; } case ServerOP_RaidLockFlag: { - ServerRaidGeneralAction_Struct* rga = (ServerRaidGeneralAction_Struct*)pack->pBuffer; + auto rga = (ServerRaidGeneralAction_Struct*)pack->pBuffer; if (zone) { if (rga->zoneid == zone->GetZoneID() && rga->instance_id == zone->GetInstanceID()) break; @@ -1326,7 +1333,7 @@ void WorldServer::HandleMessage(uint16 opcode, const EQ::Net::Packet &p) break; } case ServerOP_RaidChangeGroup: { - ServerRaidGeneralAction_Struct* rga = (ServerRaidGeneralAction_Struct*)pack->pBuffer; + auto rga = (ServerRaidGeneralAction_Struct*)pack->pBuffer; if (zone) { if (rga->zoneid == zone->GetZoneID() && rga->instance_id == zone->GetInstanceID()) break; @@ -1354,7 +1361,7 @@ void WorldServer::HandleMessage(uint16 opcode, const EQ::Net::Packet &p) break; } case ServerOP_UpdateGroup: { - ServerRaidGeneralAction_Struct* rga = (ServerRaidGeneralAction_Struct*)pack->pBuffer; + auto rga = (ServerRaidGeneralAction_Struct*)pack->pBuffer; if (zone) { if (rga->zoneid == zone->GetZoneID() && rga->instance_id == zone->GetInstanceID()) break; @@ -1367,7 +1374,7 @@ void WorldServer::HandleMessage(uint16 opcode, const EQ::Net::Packet &p) break; } case ServerOP_RaidGroupLeader: { - ServerRaidGeneralAction_Struct* rga = (ServerRaidGeneralAction_Struct*)pack->pBuffer; + auto rga = (ServerRaidGeneralAction_Struct*)pack->pBuffer; if (zone) { if (rga->zoneid == zone->GetZoneID() && rga->instance_id == zone->GetInstanceID()) break; @@ -1375,7 +1382,7 @@ void WorldServer::HandleMessage(uint16 opcode, const EQ::Net::Packet &p) break; } case ServerOP_RaidLeader: { - ServerRaidGeneralAction_Struct* rga = (ServerRaidGeneralAction_Struct*)pack->pBuffer; + auto rga = (ServerRaidGeneralAction_Struct*)pack->pBuffer; if (zone) { if (rga->zoneid == zone->GetZoneID() && rga->instance_id == zone->GetInstanceID()) break; @@ -1395,7 +1402,7 @@ void WorldServer::HandleMessage(uint16 opcode, const EQ::Net::Packet &p) break; } case ServerOP_DetailsChange: { - ServerRaidGeneralAction_Struct* rga = (ServerRaidGeneralAction_Struct*)pack->pBuffer; + auto rga = (ServerRaidGeneralAction_Struct*)pack->pBuffer; if (zone) { if (rga->zoneid == zone->GetZoneID() && rga->instance_id == zone->GetInstanceID()) break; @@ -1410,7 +1417,7 @@ void WorldServer::HandleMessage(uint16 opcode, const EQ::Net::Packet &p) break; } case ServerOP_RaidGroupDisband: { - ServerRaidGeneralAction_Struct* rga = (ServerRaidGeneralAction_Struct*)pack->pBuffer; + auto rga = (ServerRaidGeneralAction_Struct*)pack->pBuffer; if (zone) { if (rga->zoneid == zone->GetZoneID() && rga->instance_id == zone->GetInstanceID()) break; @@ -1420,7 +1427,7 @@ void WorldServer::HandleMessage(uint16 opcode, const EQ::Net::Packet &p) { auto outapp = new EQApplicationPacket(OP_GroupUpdate, sizeof(GroupUpdate_Struct)); - GroupUpdate_Struct* gu = (GroupUpdate_Struct*)outapp->pBuffer; + auto gu = (GroupUpdate_Struct*)outapp->pBuffer; gu->action = groupActDisband; strn0cpy(gu->leadersname, c->GetName(), 64); strn0cpy(gu->yourname, c->GetName(), 64); @@ -1430,27 +1437,26 @@ void WorldServer::HandleMessage(uint16 opcode, const EQ::Net::Packet &p) break; } case ServerOP_RaidGroupAdd: { - ServerRaidGroupAction_Struct* rga = (ServerRaidGroupAction_Struct*)pack->pBuffer; + auto rga = (ServerRaidGroupAction_Struct*)pack->pBuffer; if (zone) { Raid *r = entity_list.GetRaidByID(rga->rid); if (r) { r->LearnMembers(); r->VerifyRaid(); auto outapp = new EQApplicationPacket(OP_GroupUpdate, sizeof(GroupJoin_Struct)); - GroupJoin_Struct* gj = (GroupJoin_Struct*)outapp->pBuffer; + auto gj = (GroupJoin_Struct*)outapp->pBuffer; strn0cpy(gj->membername, rga->membername, 64); gj->action = groupActJoin; - for (int x = 0; x < MAX_RAID_MEMBERS; x++) - { - if (r->members[x].member) - { - if (strcmp(r->members[x].member->GetName(), rga->membername) != 0) { - if ((rga->gid < 12) && rga->gid == r->members[x].group_number) - { - strn0cpy(gj->yourname, r->members[x].member->GetName(), 64); - r->members[x].member->QueuePacket(outapp); - } + for (const auto& m : r->members) { + if (m.is_bot) { + continue; + } + + if (m.member && strcmp(m.member->GetName(), rga->membername) != 0) { + if ((rga->gid < MAX_RAID_GROUPS) && rga->gid == m.group_number) { + strn0cpy(gj->yourname, m.member->GetName(), 64); + m.member->QueuePacket(outapp); } } } @@ -1460,27 +1466,26 @@ void WorldServer::HandleMessage(uint16 opcode, const EQ::Net::Packet &p) break; } case ServerOP_RaidGroupRemove: { - ServerRaidGroupAction_Struct* rga = (ServerRaidGroupAction_Struct*)pack->pBuffer; + auto rga = (ServerRaidGroupAction_Struct*)pack->pBuffer; if (zone) { Raid *r = entity_list.GetRaidByID(rga->rid); if (r) { r->LearnMembers(); r->VerifyRaid(); auto outapp = new EQApplicationPacket(OP_GroupUpdate, sizeof(GroupJoin_Struct)); - GroupJoin_Struct* gj = (GroupJoin_Struct*)outapp->pBuffer; + auto gj = (GroupJoin_Struct*)outapp->pBuffer; strn0cpy(gj->membername, rga->membername, 64); gj->action = groupActLeave; - for (int x = 0; x < MAX_RAID_MEMBERS; x++) - { - if (r->members[x].member) - { - if (strcmp(r->members[x].member->GetName(), rga->membername) != 0) { - if ((rga->gid < 12) && rga->gid == r->members[x].group_number) - { - strn0cpy(gj->yourname, r->members[x].member->GetName(), 64); - r->members[x].member->QueuePacket(outapp); - } + for (const auto& m : r->members) { + if (m.is_bot) { + continue; + } + + if (m.member && strcmp(m.member->GetName(), rga->membername) != 0) { + if ((rga->gid < MAX_RAID_GROUPS) && rga->gid == m.group_number) { + strn0cpy(gj->yourname, m.member->GetName(), 64); + m.member->QueuePacket(outapp); } } } @@ -1490,21 +1495,19 @@ void WorldServer::HandleMessage(uint16 opcode, const EQ::Net::Packet &p) break; } case ServerOP_RaidGroupSay: { - ServerRaidMessage_Struct* rmsg = (ServerRaidMessage_Struct*)pack->pBuffer; + auto rmsg = (ServerRaidMessage_Struct*)pack->pBuffer; if (zone) { Raid *r = entity_list.GetRaidByID(rmsg->rid); - if (r) - { - for (int x = 0; x < MAX_RAID_MEMBERS; x++) - { - if (r->members[x].member) { - if (strcmp(rmsg->from, r->members[x].member->GetName()) != 0) - { - if (r->members[x].group_number == rmsg->gid) { - if (!r->members[x].is_bot && r->members[x].member->GetFilter(FilterGroupChat) != 0) - { - r->members[x].member->ChannelMessageSend(rmsg->from, r->members[x].member->GetName(), ChatChannel_Group, rmsg->language, rmsg->lang_skill, rmsg->message); - } + if (r) { + for (const auto& m :r->members) { + if (m.is_bot) { + continue; + } + + if (m.member && strcmp(m.member->GetName(), rmsg->from) != 0) { + if (m.group_number == rmsg->gid) { + if (m.member->GetFilter(FilterGroupChat) != 0) { + m.member->ChannelMessageSend(rmsg->from, m.member->GetName(), ChatChannel_Group, rmsg->language, rmsg->lang_skill, rmsg->message); } } } @@ -1514,20 +1517,20 @@ void WorldServer::HandleMessage(uint16 opcode, const EQ::Net::Packet &p) break; } case ServerOP_RaidSay: { - ServerRaidMessage_Struct* rmsg = (ServerRaidMessage_Struct*)pack->pBuffer; - if (zone) - { + auto rmsg = (ServerRaidMessage_Struct*)pack->pBuffer; + if (zone) { Raid *r = entity_list.GetRaidByID(rmsg->rid); - if (r) - { - for (int x = 0; x < MAX_RAID_MEMBERS; x++) - { - if (r->members[x].member) { - if (strcmp(rmsg->from, r->members[x].member->GetName()) != 0) - { - if (!r->members[x].is_bot && r->members[x].member->GetFilter(FilterGroupChat) != 0) - { - r->members[x].member->ChannelMessageSend(rmsg->from, r->members[x].member->GetName(), ChatChannel_Raid, rmsg->language, rmsg->lang_skill, rmsg->message); + + if (r) { + for (const auto& m :r->members) { + if (m.is_bot) { + continue; + } + + if (m.member) { + if (strcmp(rmsg->from, m.member->GetName()) != 0) { + if (!m.is_bot && m.member->GetFilter(FilterGroupChat) != 0) { + m.member->ChannelMessageSend(rmsg->from, m.member->GetName(), ChatChannel_Raid, rmsg->language, rmsg->lang_skill, rmsg->message); } } } @@ -2144,10 +2147,13 @@ void WorldServer::HandleMessage(uint16 opcode, const EQ::Net::Packet &p) } else if (update_type == CZUpdateType_Raid) { auto client_raid = entity_list.GetRaidByID(update_identifier); if (client_raid) { - for (int member_index = 0; member_index < MAX_RAID_MEMBERS; member_index++) { - if (client_raid->members[member_index].member && client_raid->members[member_index].member->IsClient()) { - auto raid_member = client_raid->members[member_index].member->CastToClient(); - DialogueWindow::Render(raid_member, message); + for (const auto& m : client_raid->members) { + if (m.is_bot) { + continue; + } + + if (m.member && m.member->IsClient()) { + DialogueWindow::Render( m.member->CastToClient(), message); } } } @@ -2235,24 +2241,27 @@ void WorldServer::HandleMessage(uint16 opcode, const EQ::Net::Packet &p) } else if (update_type == CZUpdateType_Raid) { auto client_raid = entity_list.GetRaidByID(update_identifier); if (client_raid) { - for (int member_index = 0; member_index < MAX_RAID_MEMBERS; member_index++) { - auto client_raid_member = client_raid->members[member_index].member; - if (client_raid_member && client_raid_member->IsClient()) { + for (const auto& m : client_raid->members) { + if (m.is_bot) { + continue; + } + + if (m.member && m.member->IsClient()) { switch (update_subtype) { case CZLDoNUpdateSubtype_AddLoss: - client_raid_member->UpdateLDoNWinLoss(theme_id, false); + m.member->UpdateLDoNWinLoss(theme_id, false); break; case CZLDoNUpdateSubtype_AddPoints: - client_raid_member->UpdateLDoNPoints(theme_id, points); + m.member->UpdateLDoNPoints(theme_id, points); break; case CZLDoNUpdateSubtype_AddWin: - client_raid_member->UpdateLDoNWinLoss(theme_id, true); + m.member->UpdateLDoNWinLoss(theme_id, true); break; case CZLDoNUpdateSubtype_RemoveLoss: - client_raid_member->UpdateLDoNWinLoss(theme_id, false, true); + m.member->UpdateLDoNWinLoss(theme_id, false, true); break; case CZLDoNUpdateSubtype_RemoveWin: - client_raid_member->UpdateLDoNWinLoss(theme_id, true, true); + m.member->UpdateLDoNWinLoss(theme_id, true, true); break; default: break; @@ -2365,9 +2374,13 @@ void WorldServer::HandleMessage(uint16 opcode, const EQ::Net::Packet &p) } else if (update_type == CZUpdateType_Raid) { auto client_raid = entity_list.GetRaidByID(update_identifier); if (client_raid) { - for (int member_index = 0; member_index < MAX_RAID_MEMBERS; member_index++) { - if (client_raid->members[member_index].member && client_raid->members[member_index].member->IsClient()) { - auto raid_member = client_raid->members[member_index].member->CastToClient(); + for (const auto& m : client_raid->members) { + if (m.is_bot) { + continue; + } + + if (m.member && m.member->IsClient()) { + auto raid_member = m.member->CastToClient(); raid_member->SendMarqueeMessage(type, priority, fade_in, fade_out, duration, message); } } @@ -2418,9 +2431,13 @@ void WorldServer::HandleMessage(uint16 opcode, const EQ::Net::Packet &p) } else if (update_type == CZUpdateType_Raid) { auto client_raid = entity_list.GetRaidByID(update_identifier); if (client_raid) { - for (int member_index = 0; member_index < MAX_RAID_MEMBERS; member_index++) { - if (client_raid->members[member_index].member && client_raid->members[member_index].member->IsClient()) { - auto raid_member = client_raid->members[member_index].member->CastToClient(); + for (const auto& m : client_raid->members) { + if (m.is_bot) { + continue; + } + + if (m.member && m.member->IsClient()) { + auto raid_member = m.member->CastToClient(); raid_member->Message(type, message); } } @@ -2486,9 +2503,13 @@ void WorldServer::HandleMessage(uint16 opcode, const EQ::Net::Packet &p) } else if (update_type == CZUpdateType_Raid) { auto client_raid = entity_list.GetRaidByID(update_identifier); if (client_raid) { - for (int member_index = 0; member_index < MAX_RAID_MEMBERS; member_index++) { - if (client_raid->members[member_index].member && client_raid->members[member_index].member->IsClient()) { - auto raid_member = client_raid->members[member_index].member->CastToClient(); + for (const auto& m : client_raid->members) { + if (m.is_bot) { + continue; + } + + if (m.member && m.member->IsClient()) { + auto raid_member = m.member->CastToClient(); switch (update_subtype) { case CZMoveUpdateSubtype_MoveZone: raid_member->MoveZone(zone_short_name); @@ -2567,9 +2588,13 @@ void WorldServer::HandleMessage(uint16 opcode, const EQ::Net::Packet &p) } else if (update_type == CZUpdateType_Raid) { auto client_raid = entity_list.GetRaidByID(update_identifier); if (client_raid) { - for (int member_index = 0; member_index < MAX_RAID_MEMBERS; member_index++) { - if (client_raid->members[member_index].member && client_raid->members[member_index].member->IsClient()) { - auto raid_member = client_raid->members[member_index].member->CastToClient(); + for (const auto& m : client_raid->members) { + if (m.is_bot) { + continue; + } + + if (m.member && m.member->IsClient()) { + auto raid_member = m.member->CastToClient(); raid_member->SetEntityVariable(variable_name, variable_value); } } @@ -2601,7 +2626,7 @@ void WorldServer::HandleMessage(uint16 opcode, const EQ::Net::Packet &p) } case ServerOP_CZSignal: { - CZSignal_Struct* CZS = (CZSignal_Struct*) pack->pBuffer; + auto CZS = (CZSignal_Struct*) pack->pBuffer; uint8 update_type = CZS->update_type; int update_identifier = CZS->update_identifier; int signal_id = CZS->signal_id; @@ -2624,10 +2649,13 @@ void WorldServer::HandleMessage(uint16 opcode, const EQ::Net::Packet &p) } else if (update_type == CZUpdateType_Raid) { auto client_raid = entity_list.GetRaidByID(update_identifier); if (client_raid) { - for (int member_index = 0; member_index < MAX_RAID_MEMBERS; member_index++) { - if (client_raid->members[member_index].member && client_raid->members[member_index].member->IsClient()) { - auto raid_member = client_raid->members[member_index].member->CastToClient(); - raid_member->Signal(signal_id); + for (const auto& m : client_raid->members) { + if (m.is_bot) { + continue; + } + + if (m.member && m.member->IsClient()) { + m.member->CastToClient()->Signal(signal_id); } } } @@ -2696,9 +2724,13 @@ void WorldServer::HandleMessage(uint16 opcode, const EQ::Net::Packet &p) } else if (update_type == CZUpdateType_Raid) { auto client_raid = entity_list.GetRaidByID(update_identifier); if (client_raid) { - for (int member_index = 0; member_index < MAX_RAID_MEMBERS; member_index++) { - if (client_raid->members[member_index].member && client_raid->members[member_index].member->IsClient()) { - auto raid_member = client_raid->members[member_index].member->CastToClient(); + for (const auto& m : client_raid->members) { + if (m.is_bot) { + continue; + } + + if (m.member && m.member->IsClient()) { + auto raid_member = m.member->CastToClient(); switch (update_subtype) { case CZSpellUpdateSubtype_Cast: raid_member->ApplySpellBuff(spell_id); @@ -2825,9 +2857,12 @@ void WorldServer::HandleMessage(uint16 opcode, const EQ::Net::Packet &p) } else if (update_type == CZUpdateType_Raid) { auto client_raid = entity_list.GetRaidByID(update_identifier); if (client_raid) { - for (int member_index = 0; member_index < MAX_RAID_MEMBERS; member_index++) { - if (client_raid->members[member_index].member && client_raid->members[member_index].member->IsClient()) { - auto raid_member = client_raid->members[member_index].member->CastToClient(); + for (const auto& m : client_raid->members) { + if (m.is_bot) { + continue; + } + if (m.member && m.member->IsClient()) { + auto raid_member = m.member->CastToClient(); switch (update_subtype) { case CZTaskUpdateSubtype_ActivityReset: raid_member->ResetTaskActivity(task_identifier, task_subidentifier); From 1394b6a4d2f0eb29ab9043b34fd50caa3c2da824 Mon Sep 17 00:00:00 2001 From: Aeadoin <109764533+Aeadoin@users.noreply.github.com> Date: Sat, 25 Mar 2023 20:00:31 -0400 Subject: [PATCH 18/22] [Hotfix] Fix for Items looted from corpses. (#3147) --- common/eq_packet_structs.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/common/eq_packet_structs.h b/common/eq_packet_structs.h index 8d1b3f13e..f152e4dc4 100644 --- a/common/eq_packet_structs.h +++ b/common/eq_packet_structs.h @@ -5524,9 +5524,9 @@ struct ServerLootItem_Struct { uint32 aug_6; // uint32 aug_5; bool attuned; std::string custom_data; - uint32 ornamenticon; - uint32 ornamentidfile; - uint32 ornament_hero_model; + uint32 ornamenticon {}; + uint32 ornamentidfile {}; + uint32 ornament_hero_model {}; uint16 trivial_min_level; uint16 trivial_max_level; uint16 npc_min_level; From ec3ef411a1ed5efb34db0a73f0877b7b31233629 Mon Sep 17 00:00:00 2001 From: Aeadoin <109764533+Aeadoin@users.noreply.github.com> Date: Sat, 25 Mar 2023 20:08:40 -0400 Subject: [PATCH 19/22] [Fix] Fix for SQL Query in npc_scale_global_base (#3144) --- common/version.h | 2 +- utils/sql/db_update_manifest.txt | 1 + ...scale_global_base_heroic_strikethrough.sql | 2 +- ...023_03_24_npc_scale_global_base_verify.sql | 57 +++++++++++++++++++ 4 files changed, 60 insertions(+), 2 deletions(-) create mode 100644 utils/sql/git/required/2023_03_24_npc_scale_global_base_verify.sql diff --git a/common/version.h b/common/version.h index bb067bfb4..fc36df4c5 100644 --- a/common/version.h +++ b/common/version.h @@ -42,7 +42,7 @@ * Manifest: https://github.com/EQEmu/Server/blob/master/utils/sql/db_update_manifest.txt */ -#define CURRENT_BINARY_DATABASE_VERSION 9226 +#define CURRENT_BINARY_DATABASE_VERSION 9227 #define CURRENT_BINARY_BOTS_DATABASE_VERSION 9038 diff --git a/utils/sql/db_update_manifest.txt b/utils/sql/db_update_manifest.txt index c7aaab906..40cd1527a 100644 --- a/utils/sql/db_update_manifest.txt +++ b/utils/sql/db_update_manifest.txt @@ -480,6 +480,7 @@ 9224|2023_03_08_npc_scale_global_base_avoidance.sql|SHOW COLUMNS FROM `npc_scale_global_base` LIKE 'hp_regen_per_second'|empty| 9225|2023_01_21_bots_raid_members.sql|SHOW COLUMNS FROM `raid_members` LIKE 'bot_id'|empty| 9226|2023_03_17_corpse_fields.sql|SHOW COLUMNS FROM `character_corpse_items` LIKE 'custom_data'|empty| +9227|2023_03_24_npc_scale_global_base_verify.sql|SHOW COLUMNS FROM `npc_scale_global_base` LIKE 'heroic_strikethrough'|not_empty| # Upgrade conditions: # This won't be needed after this system is implemented, but it is used database that are not diff --git a/utils/sql/git/required/2023_03_04_npc_scale_global_base_heroic_strikethrough.sql b/utils/sql/git/required/2023_03_04_npc_scale_global_base_heroic_strikethrough.sql index 6559cb0a0..b2fd1cade 100644 --- a/utils/sql/git/required/2023_03_04_npc_scale_global_base_heroic_strikethrough.sql +++ b/utils/sql/git/required/2023_03_04_npc_scale_global_base_heroic_strikethrough.sql @@ -51,5 +51,5 @@ ALTER TABLE `npc_scale_global_base` MODIFY COLUMN `attack_delay` int(11) NOT NULL DEFAULT 0 AFTER `hp_regen_rate`, MODIFY COLUMN `spell_scale` int(11) NOT NULL DEFAULT 100 AFTER `attack_delay`, MODIFY COLUMN `heal_scale` int(11) NOT NULL DEFAULT 100 AFTER `spell_scale`, - MODIFY COLUMN `special_abilities` text CHARACTER SET latin1 COLLATE latin1_swedish_ci NOT NULL DEFAULT '' AFTER `heal_scale`, + MODIFY COLUMN special_abilities text CHARACTER SET latin1 COLLATE latin1_swedish_ci NOT NULL AFTER heal_scale, ADD COLUMN `heroic_strikethrough` int(11) NOT NULL DEFAULT 0 AFTER `heal_scale`; diff --git a/utils/sql/git/required/2023_03_24_npc_scale_global_base_verify.sql b/utils/sql/git/required/2023_03_24_npc_scale_global_base_verify.sql new file mode 100644 index 000000000..2036f918d --- /dev/null +++ b/utils/sql/git/required/2023_03_24_npc_scale_global_base_verify.sql @@ -0,0 +1,57 @@ +UPDATE `npc_scale_global_base` SET ac = 0 WHERE ac IS NULL; +UPDATE `npc_scale_global_base` SET hp = 0 WHERE hp IS NULL; +UPDATE `npc_scale_global_base` SET accuracy = 0 WHERE accuracy IS NULL; +UPDATE `npc_scale_global_base` SET slow_mitigation = 0 WHERE slow_mitigation IS NULL; +UPDATE `npc_scale_global_base` SET attack = 0 WHERE attack IS NULL; +UPDATE `npc_scale_global_base` SET strength = 0 WHERE strength IS NULL; +UPDATE `npc_scale_global_base` SET stamina = 0 WHERE stamina IS NULL; +UPDATE `npc_scale_global_base` SET dexterity = 0 WHERE dexterity IS NULL; +UPDATE `npc_scale_global_base` SET agility = 0 WHERE agility IS NULL; +UPDATE `npc_scale_global_base` SET intelligence = 0 WHERE intelligence IS NULL; +UPDATE `npc_scale_global_base` SET wisdom = 0 WHERE wisdom IS NULL; +UPDATE `npc_scale_global_base` SET charisma = 0 WHERE charisma IS NULL; +UPDATE `npc_scale_global_base` SET magic_resist = 0 WHERE magic_resist IS NULL; +UPDATE `npc_scale_global_base` SET cold_resist = 0 WHERE cold_resist IS NULL; +UPDATE `npc_scale_global_base` SET fire_resist = 0 WHERE fire_resist IS NULL; +UPDATE `npc_scale_global_base` SET poison_resist = 0 WHERE poison_resist IS NULL; +UPDATE `npc_scale_global_base` SET disease_resist = 0 WHERE disease_resist IS NULL; +UPDATE `npc_scale_global_base` SET corruption_resist = 0 WHERE corruption_resist IS NULL; +UPDATE `npc_scale_global_base` SET physical_resist = 0 WHERE physical_resist IS NULL; +UPDATE `npc_scale_global_base` SET min_dmg = 0 WHERE min_dmg IS NULL; +UPDATE `npc_scale_global_base` SET max_dmg = 0 WHERE max_dmg IS NULL; +UPDATE `npc_scale_global_base` SET hp_regen_rate = 0 WHERE hp_regen_rate IS NULL; +UPDATE `npc_scale_global_base` SET attack_delay = 0 WHERE attack_delay IS NULL; +UPDATE `npc_scale_global_base` SET physical_resist = 0 WHERE physical_resist IS NULL; +UPDATE `npc_scale_global_base` SET spell_scale = 100 WHERE spell_scale IS NULL; +UPDATE `npc_scale_global_base` SET heal_scale = 100 WHERE heal_scale IS NULL; +UPDATE `npc_scale_global_base` SET special_abilities = '' WHERE special_abilities IS NULL; +ALTER TABLE `npc_scale_global_base` + MODIFY COLUMN `ac` int(11) NOT NULL DEFAULT 0 AFTER `instance_version_list`, + MODIFY COLUMN `hp` bigint(20) NOT NULL DEFAULT 0 AFTER `ac`, + MODIFY COLUMN `accuracy` int(11) NOT NULL DEFAULT 0 AFTER `hp`, + MODIFY COLUMN `slow_mitigation` int(11) NOT NULL DEFAULT 0 AFTER `accuracy`, + MODIFY COLUMN `attack` int(11) NOT NULL DEFAULT 0 AFTER `slow_mitigation`, + MODIFY COLUMN `strength` int(11) NOT NULL DEFAULT 0 AFTER `attack`, + MODIFY COLUMN `stamina` int(11) NOT NULL DEFAULT 0 AFTER `strength`, + MODIFY COLUMN `dexterity` int(11) NOT NULL DEFAULT 0 AFTER `stamina`, + MODIFY COLUMN `agility` int(11) NOT NULL DEFAULT 0 AFTER `dexterity`, + MODIFY COLUMN `intelligence` int(11) NOT NULL DEFAULT 0 AFTER `agility`, + MODIFY COLUMN `wisdom` int(11) NOT NULL DEFAULT 0 AFTER `intelligence`, + MODIFY COLUMN `charisma` int(11) NOT NULL DEFAULT 0 AFTER `wisdom`, + MODIFY COLUMN `magic_resist` int(11) NOT NULL DEFAULT 0 AFTER `charisma`, + MODIFY COLUMN `cold_resist` int(11) NOT NULL DEFAULT 0 AFTER `magic_resist`, + MODIFY COLUMN `fire_resist` int(11) NOT NULL DEFAULT 0 AFTER `cold_resist`, + MODIFY COLUMN `poison_resist` int(11) NOT NULL DEFAULT 0 AFTER `fire_resist`, + MODIFY COLUMN `disease_resist` int(11) NOT NULL DEFAULT 0 AFTER `poison_resist`, + MODIFY COLUMN `corruption_resist` int(11) NOT NULL DEFAULT 0 AFTER `disease_resist`, + MODIFY COLUMN `physical_resist` int(11) NOT NULL DEFAULT 0 AFTER `corruption_resist`, + MODIFY COLUMN `min_dmg` int(11) NOT NULL DEFAULT 0 AFTER `physical_resist`, + MODIFY COLUMN `max_dmg` int(11) NOT NULL DEFAULT 0 AFTER `min_dmg`, + MODIFY COLUMN `hp_regen_rate` bigint(20) NOT NULL DEFAULT 0 AFTER `max_dmg`, + MODIFY COLUMN `attack_delay` int(11) NOT NULL DEFAULT 0 AFTER `hp_regen_rate`, + MODIFY COLUMN `hp_regen_per_second` bigint(20) NOT NULL DEFAULT 0 AFTER `hp_regen_rate`, + MODIFY COLUMN `spell_scale` int(11) NOT NULL DEFAULT 100 AFTER `attack_delay`, + MODIFY COLUMN `heal_scale` int(11) NOT NULL DEFAULT 100 AFTER `spell_scale`, + MODIFY COLUMN `heroic_strikethrough` int(11) NOT NULL DEFAULT 0 AFTER `avoidance`, + MODIFY COLUMN `avoidance` int(11) unsigned NOT NULL DEFAULT 0 AFTER `heal_scale`, + MODIFY COLUMN special_abilities text CHARACTER SET latin1 COLLATE latin1_swedish_ci NOT NULL AFTER heroic_strikethrough; \ No newline at end of file From 9d1ace627c856d85bd6b567d500184eb27e262a4 Mon Sep 17 00:00:00 2001 From: Alex King <89047260+Kinglykrab@users.noreply.github.com> Date: Sat, 25 Mar 2023 20:26:01 -0400 Subject: [PATCH 20/22] [Feature] Add support for -1 extradmgskill to allow all skills to be scaled. (#3136) * [Feature] Add support for -1 extradmgskill to allow all skills to be scaled. - `$mob->GetSkillDmgAmt(skill_id)` now uses `int` instead of `uint16`. - `statbonuses:GetSkillDamageAmount(skill_id)` now uses `-1` properly. - `mob:GetSkillDmgAmt(skill_id)` now uses `int` instead of `uint16`. - A `-1` value in `extradmgskill` denotes the ability to scale all skills at once. - Consolidated `AddItemBonuses()`, `AdditiveWornBonuses()`, `CalcItemBonuses()`, and `CalcRecommendedLevelBonus()` to mob-based methods to avoid code duplication. - Bots, NPCs, and Mercs can now use additive worn effects if the rule is enabled, as well as all other proper stat bonuses that only clients had before. - No SQL update required to change `extradmgskill` and `extradmgamt` to `int` as they already are this type in the database, just had to adjust `item_data.h` and `shareddb.cpp`. * Update mob.cpp * Cleanup. * Cleanup. * Move #include to header. * Add method for GetExtraDamageSkills * fix additembonuses * Update bonuses.cpp * Update mob.cpp * Out of bounds. * Update bonuses.cpp --------- Co-authored-by: Aeadoin <109764533+Aeadoin@users.noreply.github.com> --- common/item_data.h | 6 +- common/shareddb.cpp | 4 +- common/skills.cpp | 22 +- common/skills.h | 6 +- zone/bonuses.cpp | 888 +++++++++++++++++++++----------------- zone/bot.cpp | 348 --------------- zone/bot.h | 4 +- zone/client.h | 3 - zone/lua_mob.cpp | 4 +- zone/lua_mob.h | 2 +- zone/lua_stat_bonuses.cpp | 8 +- zone/merc.cpp | 385 ----------------- zone/merc.h | 4 - zone/mob.cpp | 40 +- zone/mob.h | 9 +- zone/npc.h | 1 - zone/perl_mob.cpp | 2 +- 17 files changed, 569 insertions(+), 1167 deletions(-) diff --git a/common/item_data.h b/common/item_data.h index 9c66f87a8..13b0f6d54 100644 --- a/common/item_data.h +++ b/common/item_data.h @@ -131,7 +131,7 @@ namespace EQ Mounts? Ornamentations? GuildBanners? - Collectible? + Collectible? Placeable? (others?) */ @@ -449,8 +449,8 @@ namespace EQ int8 Shielding; // PoP: Shielding % int8 StunResist; // PoP: Stun Resist % int8 StrikeThrough; // PoP: Strike Through % - uint32 ExtraDmgSkill; - uint32 ExtraDmgAmt; + int32 ExtraDmgSkill; + int32 ExtraDmgAmt; int8 SpellShield; // PoP: Spell Shield % int8 Avoidance; // PoP: Avoidance + int8 Accuracy; // PoP: Accuracy + diff --git a/common/shareddb.cpp b/common/shareddb.cpp index b37cb8127..75448e1fc 100644 --- a/common/shareddb.cpp +++ b/common/shareddb.cpp @@ -1107,8 +1107,8 @@ void SharedDatabase::LoadItems(void *data, uint32 size, int32 items, uint32 max_ item.SkillModType = Strings::ToUnsignedInt(row[ItemField::skillmodtype]); // Extra Damage Skill - item.ExtraDmgSkill = Strings::ToUnsignedInt(row[ItemField::extradmgskill]); - item.ExtraDmgAmt = Strings::ToUnsignedInt(row[ItemField::extradmgamt]); + item.ExtraDmgSkill = Strings::ToInt(row[ItemField::extradmgskill]); + item.ExtraDmgAmt = Strings::ToInt(row[ItemField::extradmgamt]); // Bard item.BardType = Strings::ToUnsignedInt(row[ItemField::bardtype]); diff --git a/common/skills.cpp b/common/skills.cpp index 2276a0e39..41f9b2841 100644 --- a/common/skills.cpp +++ b/common/skills.cpp @@ -1,5 +1,5 @@ /* EQEMu: Everquest Server Emulator - + Copyright (C) 2001-2016 EQEMu Development Team (http://eqemulator.net) This program is free software; you can redistribute it and/or modify @@ -260,13 +260,31 @@ const std::map& EQ::skills::GetSkillTypeMap( return skill_type_map; } +const std::vector& EQ::skills::GetExtraDamageSkills() +{ + static const std::vector v = { + EQ::skills::SkillBackstab, + EQ::skills::SkillBash, + EQ::skills::SkillDragonPunch, // Same ID as Tail Rake + EQ::skills::SkillEagleStrike, + EQ::skills::SkillFlyingKick, + EQ::skills::SkillKick, + EQ::skills::SkillRoundKick, + EQ::skills::SkillRoundKick, + EQ::skills::SkillTigerClaw, + EQ::skills::SkillFrenzy + }; + + return v; +} + std::string EQ::skills::GetSkillName(SkillType skill) { if (skill >= Skill1HBlunt && skill <= Skill2HPiercing) { auto skills = GetSkillTypeMap(); return skills[skill]; } - return std::string(); + return {}; } EQ::SkillProfile::SkillProfile() diff --git a/common/skills.h b/common/skills.h index 38f549015..6e40609b9 100644 --- a/common/skills.h +++ b/common/skills.h @@ -1,5 +1,5 @@ /* EQEMu: Everquest Server Emulator - + Copyright (C) 2001-2016 EQEMu Development Team (http://eqemulator.net) This program is free software; you can redistribute it and/or modify @@ -24,6 +24,7 @@ #include #include +#include namespace EQ @@ -170,6 +171,7 @@ namespace EQ bool IsMeleeDmg(SkillType skill); extern const std::map& GetSkillTypeMap(); + extern const std::vector& GetExtraDamageSkills(); std::string GetSkillName(SkillType skill); } /*skills*/ @@ -305,7 +307,7 @@ namespace EQ uint32 operator[](int skill_id) const { return const_cast(this)->GetSkill(skill_id); } }; - + } /*EQEmu*/ #endif /*COMMON_SKILLS_H*/ diff --git a/zone/bonuses.cpp b/zone/bonuses.cpp index fdedc1383..b6921d108 100644 --- a/zone/bonuses.cpp +++ b/zone/bonuses.cpp @@ -16,6 +16,7 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "../common/classes.h" +#include "../common/data_verification.h" #include "../common/global_define.h" #include "../common/item_instance.h" #include "../common/rulesys.h" @@ -129,54 +130,67 @@ void Client::CalcBonuses() consume_food_timer.SetTimer(timer); } -int Mob::CalcRecommendedLevelBonus(uint8 level, uint8 reclevel, int basestat) +int Mob::CalcRecommendedLevelBonus(uint8 current_level, uint8 recommended_level, int base_stat) { - if( (reclevel > 0) && (level < reclevel) ) - { - int32 statmod = (level * 10000 / reclevel) * basestat; + if (recommended_level && current_level < recommended_level) { + int32 stat_modifier = (current_level * 10000 / recommended_level) * base_stat; - if( statmod < 0 ) - { - statmod -= 5000; - return (statmod/10000); - } - else - { - statmod += 5000; - return (statmod/10000); - } + stat_modifier += stat_modifier < 0 ? -5000 : 5000; + + return (stat_modifier / 10000); } return 0; } -void Client::CalcItemBonuses(StatBonuses* newbon) { - //memset assumed to be done by caller. - - // Clear item faction mods +void Mob::CalcItemBonuses(StatBonuses* b) { ClearItemFactionBonuses(); SetShieldEquiped(false); SetTwoHandBluntEquiped(false); SetTwoHanderEquipped(false); SetDuelWeaponsEquiped(false); - unsigned int i; - // Update: MainAmmo should only calc skill mods (TODO: Check for other cases) + int16 i; + for (i = EQ::invslot::BONUS_BEGIN; i <= EQ::invslot::BONUS_SKILL_END; i++) { - const EQ::ItemInstance* inst = m_inv[i]; - if(inst == 0) + const EQ::ItemInstance* inst = nullptr; + if (IsOfClientBotMerc()) { + inst = GetInv().GetItem(i); + } else { + const auto* item = CastToNPC()->GetItem(i); + if (!item) { + continue; + } + + inst = database.CreateItem(item->item_id); + } + + if (!inst) { continue; - AddItemBonuses(inst, newbon, false, false, 0, (i == EQ::invslot::slotAmmo)); + } + + AddItemBonuses(inst, b, false, false, 0, (i == EQ::invslot::slotAmmo)); //These are given special flags due to how often they are checked for various spell effects. - const EQ::ItemData *item = inst->GetItem(); - if (i == EQ::invslot::slotSecondary && (item && item->ItemType == EQ::item::ItemTypeShield)) + const auto* item = inst->GetItem(); + if ( + item && + item->ItemType == EQ::item::ItemTypeShield && + i == EQ::invslot::slotSecondary + ) { SetShieldEquiped(true); - else if (i == EQ::invslot::slotPrimary && (item && item->ItemType == EQ::item::ItemType2HBlunt)) { + } else if ( + item && + item->ItemType == EQ::item::ItemType2HBlunt && + i == EQ::invslot::slotPrimary + ) { SetTwoHandBluntEquiped(true); SetTwoHanderEquipped(true); - } - else if (i == EQ::invslot::slotPrimary && (item && (item->ItemType == EQ::item::ItemType2HSlash || item->ItemType == EQ::item::ItemType2HPiercing))) { + } else if ( + item && + (item->ItemType == EQ::item::ItemType2HSlash || item->ItemType == EQ::item::ItemType2HPiercing) && + i == EQ::invslot::slotPrimary + ) { SetTwoHanderEquipped(true); } } @@ -185,23 +199,34 @@ void Client::CalcItemBonuses(StatBonuses* newbon) { SetDuelWeaponsEquiped(true); } - //tribute items - for (i = EQ::invslot::TRIBUTE_BEGIN; i <= EQ::invslot::TRIBUTE_END; i++) { - const EQ::ItemInstance* inst = m_inv[i]; - if(inst == 0) - continue; - AddItemBonuses(inst, newbon, false, true); + if (IsOfClientBot()) { + for (i = EQ::invslot::TRIBUTE_BEGIN; i <= EQ::invslot::TRIBUTE_END; i++) { + const EQ::ItemInstance* inst = m_inv[i]; + if (!inst) { + continue; + } + + AddItemBonuses(inst, b, false, true); + } } - //Optional ability to have worn effects calculate as an addititive bonus instead of highest value - if (RuleI(Spells, AdditiveBonusWornType) && RuleI(Spells, AdditiveBonusWornType) != EQ::item::ItemEffectWorn){ + if ( + RuleI(Spells, AdditiveBonusWornType) && + RuleI(Spells, AdditiveBonusWornType) != EQ::item::ItemEffectWorn + ) { for (i = EQ::invslot::BONUS_BEGIN; i <= EQ::invslot::BONUS_STAT_END; i++) { const EQ::ItemInstance* inst = m_inv[i]; - if(inst == 0) + if (!inst) { continue; - AdditiveWornBonuses(inst, newbon); + } + + AdditiveWornBonuses(inst, b); } } + + if (IsMerc()) { + SetAttackTimer(); + } } // These item stat caps depend on spells/AAs so we process them after those are processed @@ -221,378 +246,521 @@ void Mob::ProcessItemCaps() itembonuses.ATK = std::min(itembonuses.ATK, CalcItemATKCap()); - if (itembonuses.SpellDmg > RuleI(Character, ItemSpellDmgCap)) { + if (IsOfClientBotMerc() && itembonuses.SpellDmg > RuleI(Character, ItemSpellDmgCap)) { itembonuses.SpellDmg = RuleI(Character, ItemSpellDmgCap); } - if (itembonuses.HealAmt > RuleI(Character, ItemHealAmtCap)) { + if (IsOfClientBotMerc() && itembonuses.HealAmt > RuleI(Character, ItemHealAmtCap)) { itembonuses.HealAmt = RuleI(Character, ItemHealAmtCap); } - } -void Client::AddItemBonuses(const EQ::ItemInstance *inst, StatBonuses *newbon, bool isAug, bool isTribute, int rec_override, bool ammo_slot_item) -{ +void Mob::AddItemBonuses(const EQ::ItemInstance* inst, StatBonuses* b, bool is_augment, bool is_tribute, int recommended_level_override, bool is_ammo_item) { if (!inst || !inst->IsClassCommon()) { return; } - if (inst->GetAugmentType() == 0 && isAug == true) { + if (inst->GetAugmentType() == 0 && is_augment) { return; } - const EQ::ItemData *item = inst->GetItem(); + const auto* item = inst->GetItem(); + if (!item) { + return; + } - if (!isTribute && !inst->IsEquipable(GetBaseRace(), GetClass())) { - if (item->ItemType != EQ::item::ItemTypeFood && item->ItemType != EQ::item::ItemTypeDrink) + if (!is_tribute && !inst->IsEquipable(GetBaseRace(), GetClass())) { + if (item->ItemType != EQ::item::ItemTypeFood && item->ItemType != EQ::item::ItemTypeDrink) { return; + } } - if (GetLevel() < inst->GetItemRequiredLevel(true)) { + const auto current_level = GetLevel(); + + if (current_level < inst->GetItemRequiredLevel(true)) { return; } - // So there isn't a very nice way to get the real rec level from the aug's inst, so we just pass it in, only - // used for augs - auto rec_level = isAug ? rec_override : inst->GetItemRecommendedLevel(true); + if (!is_ammo_item) { + const auto recommended_level = is_augment ? recommended_level_override : inst->GetItemRecommendedLevel(true); - if (!ammo_slot_item) { - if (GetLevel() >= rec_level) { - newbon->AC += item->AC; - newbon->HP += item->HP; - newbon->Mana += item->Mana; - newbon->Endurance += item->Endur; - newbon->ATK += item->Attack; - newbon->STR += (item->AStr + item->HeroicStr); - newbon->STA += (item->ASta + item->HeroicSta); - newbon->DEX += (item->ADex + item->HeroicDex); - newbon->AGI += (item->AAgi + item->HeroicAgi); - newbon->INT += (item->AInt + item->HeroicInt); - newbon->WIS += (item->AWis + item->HeroicWis); - newbon->CHA += (item->ACha + item->HeroicCha); + if (current_level >= recommended_level) { + b->HP += item->HP; + b->Mana += item->Mana; + b->Endurance += item->Endur; - newbon->MR += (item->MR + item->HeroicMR); - newbon->FR += (item->FR + item->HeroicFR); - newbon->CR += (item->CR + item->HeroicCR); - newbon->PR += (item->PR + item->HeroicPR); - newbon->DR += (item->DR + item->HeroicDR); - newbon->Corrup += (item->SVCorruption + item->HeroicSVCorrup); + b->AC += item->AC; + b->ATK += item->Attack; - newbon->STRCapMod += item->HeroicStr; - newbon->STACapMod += item->HeroicSta; - newbon->DEXCapMod += item->HeroicDex; - newbon->AGICapMod += item->HeroicAgi; - newbon->INTCapMod += item->HeroicInt; - newbon->WISCapMod += item->HeroicWis; - newbon->CHACapMod += item->HeroicCha; - newbon->MRCapMod += item->HeroicMR; - newbon->CRCapMod += item->HeroicFR; - newbon->FRCapMod += item->HeroicCR; - newbon->PRCapMod += item->HeroicPR; - newbon->DRCapMod += item->HeroicDR; - newbon->CorrupCapMod += item->HeroicSVCorrup; + b->STR += (item->AStr + item->HeroicStr); + b->STA += (item->ASta + item->HeroicSta); + b->DEX += (item->ADex + item->HeroicDex); + b->AGI += (item->AAgi + item->HeroicAgi); + b->INT += (item->AInt + item->HeroicInt); + b->WIS += (item->AWis + item->HeroicWis); + b->CHA += (item->ACha + item->HeroicCha); - newbon->HeroicSTR += item->HeroicStr; - newbon->HeroicSTA += item->HeroicSta; - newbon->HeroicDEX += item->HeroicDex; - newbon->HeroicAGI += item->HeroicAgi; - newbon->HeroicINT += item->HeroicInt; - newbon->HeroicWIS += item->HeroicWis; - newbon->HeroicCHA += item->HeroicCha; - newbon->HeroicMR += item->HeroicMR; - newbon->HeroicFR += item->HeroicFR; - newbon->HeroicCR += item->HeroicCR; - newbon->HeroicPR += item->HeroicPR; - newbon->HeroicDR += item->HeroicDR; - newbon->HeroicCorrup += item->HeroicSVCorrup; + b->MR += (item->MR + item->HeroicMR); + b->FR += (item->FR + item->HeroicFR); + b->CR += (item->CR + item->HeroicCR); + b->PR += (item->PR + item->HeroicPR); + b->DR += (item->DR + item->HeroicDR); + b->Corrup += (item->SVCorruption + item->HeroicSVCorrup); - } - else { - int lvl = GetLevel(); + b->STRCapMod += item->HeroicStr; + b->STACapMod += item->HeroicSta; + b->DEXCapMod += item->HeroicDex; + b->AGICapMod += item->HeroicAgi; + b->INTCapMod += item->HeroicInt; + b->WISCapMod += item->HeroicWis; + b->CHACapMod += item->HeroicCha; - newbon->AC += CalcRecommendedLevelBonus(lvl, rec_level, item->AC); - newbon->HP += CalcRecommendedLevelBonus(lvl, rec_level, item->HP); - newbon->Mana += CalcRecommendedLevelBonus(lvl, rec_level, item->Mana); - newbon->Endurance += CalcRecommendedLevelBonus(lvl, rec_level, item->Endur); - newbon->ATK += CalcRecommendedLevelBonus(lvl, rec_level, item->Attack); - newbon->STR += CalcRecommendedLevelBonus(lvl, rec_level, (item->AStr + item->HeroicStr)); - newbon->STA += CalcRecommendedLevelBonus(lvl, rec_level, (item->ASta + item->HeroicSta)); - newbon->DEX += CalcRecommendedLevelBonus(lvl, rec_level, (item->ADex + item->HeroicDex)); - newbon->AGI += CalcRecommendedLevelBonus(lvl, rec_level, (item->AAgi + item->HeroicAgi)); - newbon->INT += CalcRecommendedLevelBonus(lvl, rec_level, (item->AInt + item->HeroicInt)); - newbon->WIS += CalcRecommendedLevelBonus(lvl, rec_level, (item->AWis + item->HeroicWis)); - newbon->CHA += CalcRecommendedLevelBonus(lvl, rec_level, (item->ACha + item->HeroicCha)); + b->MRCapMod += item->HeroicMR; + b->CRCapMod += item->HeroicFR; + b->FRCapMod += item->HeroicCR; + b->PRCapMod += item->HeroicPR; + b->DRCapMod += item->HeroicDR; + b->CorrupCapMod += item->HeroicSVCorrup; - newbon->MR += CalcRecommendedLevelBonus(lvl, rec_level, (item->MR + item->HeroicMR)); - newbon->FR += CalcRecommendedLevelBonus(lvl, rec_level, (item->FR + item->HeroicFR)); - newbon->CR += CalcRecommendedLevelBonus(lvl, rec_level, (item->CR + item->HeroicCR)); - newbon->PR += CalcRecommendedLevelBonus(lvl, rec_level, (item->PR + item->HeroicPR)); - newbon->DR += CalcRecommendedLevelBonus(lvl, rec_level, (item->DR + item->HeroicDR)); - newbon->Corrup += - CalcRecommendedLevelBonus(lvl, rec_level, (item->SVCorruption + item->HeroicSVCorrup)); + b->HeroicSTR += item->HeroicStr; + b->HeroicSTA += item->HeroicSta; + b->HeroicDEX += item->HeroicDex; + b->HeroicAGI += item->HeroicAgi; + b->HeroicINT += item->HeroicInt; + b->HeroicWIS += item->HeroicWis; + b->HeroicCHA += item->HeroicCha; - newbon->STRCapMod += CalcRecommendedLevelBonus(lvl, rec_level, item->HeroicStr); - newbon->STACapMod += CalcRecommendedLevelBonus(lvl, rec_level, item->HeroicSta); - newbon->DEXCapMod += CalcRecommendedLevelBonus(lvl, rec_level, item->HeroicDex); - newbon->AGICapMod += CalcRecommendedLevelBonus(lvl, rec_level, item->HeroicAgi); - newbon->INTCapMod += CalcRecommendedLevelBonus(lvl, rec_level, item->HeroicInt); - newbon->WISCapMod += CalcRecommendedLevelBonus(lvl, rec_level, item->HeroicWis); - newbon->CHACapMod += CalcRecommendedLevelBonus(lvl, rec_level, item->HeroicCha); - newbon->MRCapMod += CalcRecommendedLevelBonus(lvl, rec_level, item->HeroicMR); - newbon->CRCapMod += CalcRecommendedLevelBonus(lvl, rec_level, item->HeroicFR); - newbon->FRCapMod += CalcRecommendedLevelBonus(lvl, rec_level, item->HeroicCR); - newbon->PRCapMod += CalcRecommendedLevelBonus(lvl, rec_level, item->HeroicPR); - newbon->DRCapMod += CalcRecommendedLevelBonus(lvl, rec_level, item->HeroicDR); - newbon->CorrupCapMod += CalcRecommendedLevelBonus(lvl, rec_level, item->HeroicSVCorrup); + b->HeroicMR += item->HeroicMR; + b->HeroicFR += item->HeroicFR; + b->HeroicCR += item->HeroicCR; + b->HeroicPR += item->HeroicPR; + b->HeroicDR += item->HeroicDR; + b->HeroicCorrup += item->HeroicSVCorrup; + } else { + b->HP += CalcRecommendedLevelBonus(current_level, recommended_level, item->HP); + b->Mana += CalcRecommendedLevelBonus(current_level, recommended_level, item->Mana); + b->Endurance += CalcRecommendedLevelBonus(current_level, recommended_level, item->Endur); - newbon->HeroicSTR += CalcRecommendedLevelBonus(lvl, rec_level, item->HeroicStr); - newbon->HeroicSTA += CalcRecommendedLevelBonus(lvl, rec_level, item->HeroicSta); - newbon->HeroicDEX += CalcRecommendedLevelBonus(lvl, rec_level, item->HeroicDex); - newbon->HeroicAGI += CalcRecommendedLevelBonus(lvl, rec_level, item->HeroicAgi); - newbon->HeroicINT += CalcRecommendedLevelBonus(lvl, rec_level, item->HeroicInt); - newbon->HeroicWIS += CalcRecommendedLevelBonus(lvl, rec_level, item->HeroicWis); - newbon->HeroicCHA += CalcRecommendedLevelBonus(lvl, rec_level, item->HeroicCha); - newbon->HeroicMR += CalcRecommendedLevelBonus(lvl, rec_level, item->HeroicMR); - newbon->HeroicFR += CalcRecommendedLevelBonus(lvl, rec_level, item->HeroicFR); - newbon->HeroicCR += CalcRecommendedLevelBonus(lvl, rec_level, item->HeroicCR); - newbon->HeroicPR += CalcRecommendedLevelBonus(lvl, rec_level, item->HeroicPR); - newbon->HeroicDR += CalcRecommendedLevelBonus(lvl, rec_level, item->HeroicDR); - newbon->HeroicCorrup += CalcRecommendedLevelBonus(lvl, rec_level, item->HeroicSVCorrup); + b->AC += CalcRecommendedLevelBonus(current_level, recommended_level, item->AC); + b->ATK += CalcRecommendedLevelBonus(current_level, recommended_level, item->Attack); + + b->STR += CalcRecommendedLevelBonus(current_level, recommended_level, (item->AStr + item->HeroicStr)); + b->STA += CalcRecommendedLevelBonus(current_level, recommended_level, (item->ASta + item->HeroicSta)); + b->DEX += CalcRecommendedLevelBonus(current_level, recommended_level, (item->ADex + item->HeroicDex)); + b->AGI += CalcRecommendedLevelBonus(current_level, recommended_level, (item->AAgi + item->HeroicAgi)); + b->INT += CalcRecommendedLevelBonus(current_level, recommended_level, (item->AInt + item->HeroicInt)); + b->WIS += CalcRecommendedLevelBonus(current_level, recommended_level, (item->AWis + item->HeroicWis)); + b->CHA += CalcRecommendedLevelBonus(current_level, recommended_level, (item->ACha + item->HeroicCha)); + + b->MR += CalcRecommendedLevelBonus(current_level, recommended_level, (item->MR + item->HeroicMR)); + b->FR += CalcRecommendedLevelBonus(current_level, recommended_level, (item->FR + item->HeroicFR)); + b->CR += CalcRecommendedLevelBonus(current_level, recommended_level, (item->CR + item->HeroicCR)); + b->PR += CalcRecommendedLevelBonus(current_level, recommended_level, (item->PR + item->HeroicPR)); + b->DR += CalcRecommendedLevelBonus(current_level, recommended_level, (item->DR + item->HeroicDR)); + b->Corrup += CalcRecommendedLevelBonus(current_level, recommended_level, (item->SVCorruption + item->HeroicSVCorrup)); + + b->STRCapMod += CalcRecommendedLevelBonus(current_level, recommended_level, item->HeroicStr); + b->STACapMod += CalcRecommendedLevelBonus(current_level, recommended_level, item->HeroicSta); + b->DEXCapMod += CalcRecommendedLevelBonus(current_level, recommended_level, item->HeroicDex); + b->AGICapMod += CalcRecommendedLevelBonus(current_level, recommended_level, item->HeroicAgi); + b->INTCapMod += CalcRecommendedLevelBonus(current_level, recommended_level, item->HeroicInt); + b->WISCapMod += CalcRecommendedLevelBonus(current_level, recommended_level, item->HeroicWis); + b->CHACapMod += CalcRecommendedLevelBonus(current_level, recommended_level, item->HeroicCha); + + b->MRCapMod += CalcRecommendedLevelBonus(current_level, recommended_level, item->HeroicMR); + b->CRCapMod += CalcRecommendedLevelBonus(current_level, recommended_level, item->HeroicFR); + b->FRCapMod += CalcRecommendedLevelBonus(current_level, recommended_level, item->HeroicCR); + b->PRCapMod += CalcRecommendedLevelBonus(current_level, recommended_level, item->HeroicPR); + b->DRCapMod += CalcRecommendedLevelBonus(current_level, recommended_level, item->HeroicDR); + b->CorrupCapMod += CalcRecommendedLevelBonus(current_level, recommended_level, item->HeroicSVCorrup); + + b->HeroicSTR += CalcRecommendedLevelBonus(current_level, recommended_level, item->HeroicStr); + b->HeroicSTA += CalcRecommendedLevelBonus(current_level, recommended_level, item->HeroicSta); + b->HeroicDEX += CalcRecommendedLevelBonus(current_level, recommended_level, item->HeroicDex); + b->HeroicAGI += CalcRecommendedLevelBonus(current_level, recommended_level, item->HeroicAgi); + b->HeroicINT += CalcRecommendedLevelBonus(current_level, recommended_level, item->HeroicInt); + b->HeroicWIS += CalcRecommendedLevelBonus(current_level, recommended_level, item->HeroicWis); + b->HeroicCHA += CalcRecommendedLevelBonus(current_level, recommended_level, item->HeroicCha); + + b->HeroicMR += CalcRecommendedLevelBonus(current_level, recommended_level, item->HeroicMR); + b->HeroicFR += CalcRecommendedLevelBonus(current_level, recommended_level, item->HeroicFR); + b->HeroicCR += CalcRecommendedLevelBonus(current_level, recommended_level, item->HeroicCR); + b->HeroicPR += CalcRecommendedLevelBonus(current_level, recommended_level, item->HeroicPR); + b->HeroicDR += CalcRecommendedLevelBonus(current_level, recommended_level, item->HeroicDR); + b->HeroicCorrup += CalcRecommendedLevelBonus(current_level, recommended_level, item->HeroicSVCorrup); } - // FatherNitwit: New style haste, shields, and regens - if (newbon->haste < item->Haste) { - newbon->haste = item->Haste; - } - if (item->Regen > 0) - newbon->HPRegen += item->Regen; - - if (item->ManaRegen > 0) - newbon->ManaRegen += item->ManaRegen; - - if (item->EnduranceRegen > 0) - newbon->EnduranceRegen += item->EnduranceRegen; - - if (item->DamageShield > 0) { - if ((newbon->DamageShield + item->DamageShield) > RuleI(Character, ItemDamageShieldCap)) - newbon->DamageShield = RuleI(Character, ItemDamageShieldCap); - else - newbon->DamageShield += item->DamageShield; - } - if (item->SpellShield > 0) { - if ((newbon->SpellShield + item->SpellShield) > RuleI(Character, ItemSpellShieldingCap)) - newbon->SpellShield = RuleI(Character, ItemSpellShieldingCap); - else - newbon->SpellShield += item->SpellShield; - } - if (item->Shielding > 0) { - if ((newbon->MeleeMitigation + item->Shielding) > RuleI(Character, ItemShieldingCap)) - newbon->MeleeMitigation = RuleI(Character, ItemShieldingCap); - else - newbon->MeleeMitigation += item->Shielding; - } - if (item->StunResist > 0) { - if ((newbon->StunResist + item->StunResist) > RuleI(Character, ItemStunResistCap)) - newbon->StunResist = RuleI(Character, ItemStunResistCap); - else - newbon->StunResist += item->StunResist; - } - if (item->StrikeThrough > 0) { - if ((newbon->StrikeThrough + item->StrikeThrough) > RuleI(Character, ItemStrikethroughCap)) - newbon->StrikeThrough = RuleI(Character, ItemStrikethroughCap); - else - newbon->StrikeThrough += item->StrikeThrough; - } - if (item->Avoidance > 0) { - if ((newbon->AvoidMeleeChance + item->Avoidance) > RuleI(Character, ItemAvoidanceCap)) - newbon->AvoidMeleeChance = RuleI(Character, ItemAvoidanceCap); - else - newbon->AvoidMeleeChance += item->Avoidance; - } - if (item->Accuracy > 0) { - if ((newbon->HitChance + item->Accuracy) > RuleI(Character, ItemAccuracyCap)) - newbon->HitChance = RuleI(Character, ItemAccuracyCap); - else - newbon->HitChance += item->Accuracy; - } - if (item->CombatEffects > 0) { - if ((newbon->ProcChance + item->CombatEffects) > RuleI(Character, ItemCombatEffectsCap)) - newbon->ProcChance = RuleI(Character, ItemCombatEffectsCap); - else - newbon->ProcChance += item->CombatEffects; - } - if (item->DotShielding > 0) { - if ((newbon->DoTShielding + item->DotShielding) > RuleI(Character, ItemDoTShieldingCap)) - newbon->DoTShielding = RuleI(Character, ItemDoTShieldingCap); - else - newbon->DoTShielding += item->DotShielding; + if (b->haste < item->Haste) { + b->haste = item->Haste; } - if (item->HealAmt > 0) { - if ((newbon->HealAmt + item->HealAmt) > RuleI(Character, ItemHealAmtCap)) - newbon->HealAmt = RuleI(Character, ItemHealAmtCap); - else - newbon->HealAmt += item->HealAmt; - } - if (item->SpellDmg > 0) { - if ((newbon->SpellDmg + item->SpellDmg) > RuleI(Character, ItemSpellDmgCap)) - newbon->SpellDmg = RuleI(Character, ItemSpellDmgCap); - else - newbon->SpellDmg += item->SpellDmg; - } - if (item->Clairvoyance > 0) { - if ((newbon->Clairvoyance + item->Clairvoyance) > RuleI(Character, ItemClairvoyanceCap)) - newbon->Clairvoyance = RuleI(Character, ItemClairvoyanceCap); - else - newbon->Clairvoyance += item->Clairvoyance; + if (item->Regen != 0) { + b->HPRegen += item->Regen; } - if (item->DSMitigation > 0) { - if ((newbon->DSMitigation + item->DSMitigation) > RuleI(Character, ItemDSMitigationCap)) - newbon->DSMitigation = RuleI(Character, ItemDSMitigationCap); - else - newbon->DSMitigation += item->DSMitigation; - } - if (item->Worn.Effect > 0 && item->Worn.Type == EQ::item::ItemEffectWorn) { // latent effects - ApplySpellsBonuses(item->Worn.Effect, item->Worn.Level, newbon, 0, item->Worn.Type); + if (item->ManaRegen != 0) { + b->ManaRegen += item->ManaRegen; } - if (item->Focus.Effect > 0 && (item->Focus.Type == EQ::item::ItemEffectFocus)) { // focus effects - ApplySpellsBonuses(item->Focus.Effect, item->Focus.Level, newbon, 0); + if (item->EnduranceRegen != 0) { + b->EnduranceRegen += item->EnduranceRegen; + } + + if (item->Attack != 0) { + unsigned int cap = RuleI(Character, ItemATKCap); + cap += itembonuses.ItemATKCap + spellbonuses.ItemATKCap + aabonuses.ItemATKCap; + + if ( + IsOfClientBotMerc() && + (b->ATK + item->Attack) > cap + ) { + b->ATK = RuleI(Character, ItemATKCap); + } else { + b->ATK += item->Attack; + } + } + + if (item->DamageShield != 0) { + if ( + IsOfClientBotMerc() && + (b->DamageShield + item->DamageShield) > RuleI(Character, ItemDamageShieldCap) + ) { + b->DamageShield = RuleI(Character, ItemDamageShieldCap); + } else { + b->DamageShield += item->DamageShield; + } + } + + if (item->SpellShield != 0) { + if ( + IsOfClientBotMerc() && + (b->SpellShield + item->SpellShield) > RuleI(Character, ItemSpellShieldingCap) + ) { + b->SpellShield = RuleI(Character, ItemSpellShieldingCap); + } else { + b->SpellShield += item->SpellShield; + } + } + + if (item->Shielding != 0) { + if ( + IsOfClientBotMerc() && + (b->MeleeMitigation + item->Shielding) > RuleI(Character, ItemShieldingCap) + ) { + b->MeleeMitigation = RuleI(Character, ItemShieldingCap); + } else { + b->MeleeMitigation += item->Shielding; + } + } + + if (item->StunResist != 0) { + if ( + IsOfClientBotMerc() && + (b->StunResist + item->StunResist) > RuleI(Character, ItemStunResistCap) + ) { + b->StunResist = RuleI(Character, ItemStunResistCap); + } else { + b->StunResist += item->StunResist; + } + } + + if (item->StrikeThrough != 0) { + if ( + IsOfClientBotMerc() && + (b->StrikeThrough + item->StrikeThrough) > RuleI(Character, ItemStrikethroughCap) + ) { + b->StrikeThrough = RuleI(Character, ItemStrikethroughCap); + } else { + b->StrikeThrough += item->StrikeThrough; + } + } + + if (item->Avoidance != 0) { + if ( + IsOfClientBotMerc() && + (b->AvoidMeleeChance + item->Avoidance) > RuleI(Character, ItemAvoidanceCap) + ) { + b->AvoidMeleeChance = RuleI(Character, ItemAvoidanceCap); + } else { + b->AvoidMeleeChance += item->Avoidance; + } + } + + if (item->Accuracy != 0) { + if ( + IsOfClientBotMerc() && + (b->HitChance + item->Accuracy) > RuleI(Character, ItemAccuracyCap) + ) { + b->HitChance = RuleI(Character, ItemAccuracyCap); + } else { + b->HitChance += item->Accuracy; + } + } + + if (item->CombatEffects != 0) { + if ( + IsOfClientBotMerc() && + (b->ProcChance + item->CombatEffects) > RuleI(Character, ItemCombatEffectsCap) + ) { + b->ProcChance = RuleI(Character, ItemCombatEffectsCap); + } else { + b->ProcChance += item->CombatEffects; + } + } + + if (item->DotShielding != 0) { + if ( + IsOfClientBotMerc() && + (b->DoTShielding + item->DotShielding) > RuleI(Character, ItemDoTShieldingCap) + ) { + b->DoTShielding = RuleI(Character, ItemDoTShieldingCap); + } else { + b->DoTShielding += item->DotShielding; + } + } + + if (item->HealAmt != 0) { + if ( + IsOfClientBotMerc() && + (b->HealAmt + item->HealAmt) > RuleI(Character, ItemHealAmtCap) + ) { + b->HealAmt = RuleI(Character, ItemHealAmtCap); + } else { + b->HealAmt += item->HealAmt; + } + } + + if (item->SpellDmg != 0) { + if ( + IsOfClientBotMerc() && + (b->SpellDmg + item->SpellDmg) > RuleI(Character, ItemSpellDmgCap) + ) { + b->SpellDmg = RuleI(Character, ItemSpellDmgCap); + } else { + b->SpellDmg += item->SpellDmg; + } + } + + if (item->Clairvoyance != 0) { + if ( + IsOfClientBotMerc() && + (b->Clairvoyance + item->Clairvoyance) > RuleI(Character, ItemClairvoyanceCap) + ) { + b->Clairvoyance = RuleI(Character, ItemClairvoyanceCap); + } else { + b->Clairvoyance += item->Clairvoyance; + } + } + + if (item->DSMitigation != 0) { + if ( + IsOfClientBotMerc() && + (b->DSMitigation + item->DSMitigation) > RuleI(Character, ItemDSMitigationCap) + ) { + b->DSMitigation = RuleI(Character, ItemDSMitigationCap); + } else { + b->DSMitigation += item->DSMitigation; + } + } + + if (item->Worn.Effect > 0 && item->Worn.Type == EQ::item::ItemEffectWorn) { + ApplySpellsBonuses(item->Worn.Effect, item->Worn.Level, b, 0, item->Worn.Type); + } + + if (item->Focus.Effect > 0 && item->Focus.Type == EQ::item::ItemEffectFocus) { + if ( + IsOfClientBotMerc() || + (IsNPC() && RuleB(Spells, NPC_UseFocusFromItems)) + ) { + ApplySpellsBonuses(item->Focus.Effect, item->Focus.Level, b, 0); + } } switch (item->BardType) { - case 51: /* All (e.g. Singing Short Sword) */ - if (item->BardValue > newbon->singingMod) - newbon->singingMod = item->BardValue; - if (item->BardValue > newbon->brassMod) - newbon->brassMod = item->BardValue; - if (item->BardValue > newbon->stringedMod) - newbon->stringedMod = item->BardValue; - if (item->BardValue > newbon->percussionMod) - newbon->percussionMod = item->BardValue; - if (item->BardValue > newbon->windMod) - newbon->windMod = item->BardValue; - break; - case 50: /* Singing */ - if (item->BardValue > newbon->singingMod) - newbon->singingMod = item->BardValue; - break; - case 23: /* Wind */ - if (item->BardValue > newbon->windMod) - newbon->windMod = item->BardValue; - break; - case 24: /* stringed */ - if (item->BardValue > newbon->stringedMod) - newbon->stringedMod = item->BardValue; - break; - case 25: /* brass */ - if (item->BardValue > newbon->brassMod) - newbon->brassMod = item->BardValue; - break; - case 26: /* Percussion */ - if (item->BardValue > newbon->percussionMod) - newbon->percussionMod = item->BardValue; - break; + case EQ::item::ItemTypeAllInstrumentTypes: { // (e.g. Singing Short Sword) + if (item->BardValue > b->singingMod) { + b->singingMod = item->BardValue; + } + + if (item->BardValue > b->brassMod) { + b->brassMod = item->BardValue; + } + + if (item->BardValue > b->stringedMod) { + b->stringedMod = item->BardValue; + } + + if (item->BardValue > b->percussionMod) { + b->percussionMod = item->BardValue; + } + + if (item->BardValue > b->windMod) { + b->windMod = item->BardValue; + } + + break; + } + case EQ::item::ItemTypeSinging: { + if (item->BardValue > b->singingMod) { + b->singingMod = item->BardValue; + } + + break; + } + case EQ::item::ItemTypeWindInstrument: { + if (item->BardValue > b->windMod) { + b->windMod = item->BardValue; + } + + break; + } + case EQ::item::ItemTypeStringedInstrument: { + if (item->BardValue > b->stringedMod) { + b->stringedMod = item->BardValue; + } + + break; + } + case EQ::item::ItemTypeBrassInstrument: { + if (item->BardValue > b->brassMod) { + b->brassMod = item->BardValue; + } + + break; + } + case EQ::item::ItemTypePercussionInstrument: { + if (item->BardValue > b->percussionMod) { + b->percussionMod = item->BardValue; + } + + break; + } + } + + if (item->SkillModValue != 0 && item->SkillModType <= EQ::skills::HIGHEST_SKILL) { + if ( + (item->SkillModValue > 0 && b->skillmod[item->SkillModType] < item->SkillModValue) || + (item->SkillModValue < 0 && b->skillmod[item->SkillModType] > item->SkillModValue) + ) { + b->skillmod[item->SkillModType] = item->SkillModValue; + } } - // Add Item Faction Mods if (item->FactionMod1) { if (item->FactionAmt1 > 0 && item->FactionAmt1 > GetItemFactionBonus(item->FactionMod1)) { AddItemFactionBonus(item->FactionMod1, item->FactionAmt1); - } - else if (item->FactionAmt1 < 0 && item->FactionAmt1 < GetItemFactionBonus(item->FactionMod1)) { + } else if (item->FactionAmt1 < 0 && item->FactionAmt1 < GetItemFactionBonus(item->FactionMod1)) { AddItemFactionBonus(item->FactionMod1, item->FactionAmt1); } } + if (item->FactionMod2) { if (item->FactionAmt2 > 0 && item->FactionAmt2 > GetItemFactionBonus(item->FactionMod2)) { AddItemFactionBonus(item->FactionMod2, item->FactionAmt2); - } - else if (item->FactionAmt2 < 0 && item->FactionAmt2 < GetItemFactionBonus(item->FactionMod2)) { + } else if (item->FactionAmt2 < 0 && item->FactionAmt2 < GetItemFactionBonus(item->FactionMod2)) { AddItemFactionBonus(item->FactionMod2, item->FactionAmt2); } } + if (item->FactionMod3) { if (item->FactionAmt3 > 0 && item->FactionAmt3 > GetItemFactionBonus(item->FactionMod3)) { AddItemFactionBonus(item->FactionMod3, item->FactionAmt3); - } - else if (item->FactionAmt3 < 0 && item->FactionAmt3 < GetItemFactionBonus(item->FactionMod3)) { + } else if (item->FactionAmt3 < 0 && item->FactionAmt3 < GetItemFactionBonus(item->FactionMod3)) { AddItemFactionBonus(item->FactionMod3, item->FactionAmt3); } } + if (item->FactionMod4) { if (item->FactionAmt4 > 0 && item->FactionAmt4 > GetItemFactionBonus(item->FactionMod4)) { AddItemFactionBonus(item->FactionMod4, item->FactionAmt4); - } - else if (item->FactionAmt4 < 0 && item->FactionAmt4 < GetItemFactionBonus(item->FactionMod4)) { + } else if (item->FactionAmt4 < 0 && item->FactionAmt4 < GetItemFactionBonus(item->FactionMod4)) { AddItemFactionBonus(item->FactionMod4, item->FactionAmt4); } } if (item->ExtraDmgAmt != 0 && item->ExtraDmgSkill <= EQ::skills::HIGHEST_SKILL) { - if ( - RuleI(Character, ItemExtraDmgCap) >= 0 && - (newbon->SkillDamageAmount[item->ExtraDmgSkill] + item->ExtraDmgAmt) > RuleI(Character, ItemExtraDmgCap) - ) { - newbon->SkillDamageAmount[item->ExtraDmgSkill] = RuleI(Character, ItemExtraDmgCap); + if (item->ExtraDmgSkill == ALL_SKILLS) { + for (const auto& skill_id : EQ::skills::GetExtraDamageSkills()) { + if ( + !IsNPC() && + RuleI(Character, ItemExtraDmgCap) >= 0 && + (b->SkillDamageAmount[skill_id] + item->ExtraDmgAmt) > RuleI(Character, ItemExtraDmgCap) + ) { + b->SkillDamageAmount[skill_id] = RuleI(Character, ItemExtraDmgCap); + } else { + b->SkillDamageAmount[skill_id] += item->ExtraDmgAmt; + } + } } else { - newbon->SkillDamageAmount[item->ExtraDmgSkill] += item->ExtraDmgAmt; + if ( + !IsNPC() && + RuleI(Character, ItemExtraDmgCap) >= 0 && + (b->SkillDamageAmount[item->ExtraDmgSkill] + item->ExtraDmgAmt) > RuleI(Character, ItemExtraDmgCap) + ) { + b->SkillDamageAmount[item->ExtraDmgSkill] = RuleI(Character, ItemExtraDmgCap); + } else { + b->SkillDamageAmount[item->ExtraDmgSkill] += item->ExtraDmgAmt; + } + } + } + + if (!is_augment) { + for (int i = EQ::invaug::SOCKET_BEGIN; i <= EQ::invaug::SOCKET_END; i++) { + const auto* augment = inst->GetAugment(i); + if (!augment) { + continue; + } + + AddItemBonuses(augment, b, true, false, recommended_level); } } } - - // Process when ammo_slot_item = true or false - if (item->SkillModValue != 0 && item->SkillModType <= EQ::skills::HIGHEST_SKILL) { - if ((item->SkillModValue > 0 && newbon->skillmod[item->SkillModType] < item->SkillModValue) || - (item->SkillModValue < 0 && newbon->skillmod[item->SkillModType] > item->SkillModValue)) { - - newbon->skillmod[item->SkillModType] = item->SkillModValue; - newbon->skillmodmax[item->SkillModType] = item->SkillModMax; - } - } - - if (!isAug) { - for (int i = EQ::invaug::SOCKET_BEGIN; i <= EQ::invaug::SOCKET_END; i++) - AddItemBonuses(inst->GetAugment(i), newbon, true, false, rec_level, ammo_slot_item); - } } -void Client::AdditiveWornBonuses(const EQ::ItemInstance *inst, StatBonuses* newbon, bool isAug) { +void Mob::AdditiveWornBonuses(const EQ::ItemInstance* inst, StatBonuses* b, bool is_augment) { /* - Powerful Non-live like option allows developers to add worn effects on items that - can stack with other worn effects of the same spell effect type, instead of only taking the highest value. - Ie Cleave I = 40 pct cleave - So if you equip 3 cleave I items you will have a 120 pct cleave bonus. - To enable use RuleI(Spells, AdditiveBonusWornType) - Setting value = 2 Will force all live items to automatically be calculated additivily - Setting value to anything else will indicate the item 'worntype' that if set to the same, will cause the bonuses to use this calculation - which will also stack with regular (worntype 2) effects. [Ie set rule = 3 and item worntype = 3] + Powerful Non-live like option allows developers to add worn effects on items that + can stack with other worn effects of the same spell effect type, instead of only taking the highest value. + Ie Cleave I = 40 pct cleave - So if you equip 3 cleave I items you will have a 120% cleave bonus. + To enable use RuleI(Spells, AdditiveBonusWornType) + Setting value = 2 Will force all live items to automatically be calculated additively + Setting value to anything else will indicate the item 'worntype' that if set to the same, will cause the bonuses to use this calculation + which will also stack with regular (worntype 2) effects. [Ie set rule = 3 and item worntype = 3] */ - if (!inst || !inst->IsClassCommon()) + if (!inst || !inst->IsClassCommon()) { return; + } - if(inst->GetAugmentType()==0 && isAug == true) + if (inst->GetAugmentType() == 0 && is_augment) { return; + } - const EQ::ItemData *item = inst->GetItem(); + const auto* item = inst->GetItem(); - if(!inst->IsEquipable(GetBaseRace(),GetClass())) + if (!inst->IsEquipable(GetBaseRace(), GetClass())) { return; + } - if(GetLevel() < item->ReqLevel) + if (GetLevel() < item->ReqLevel) { return; + } - if (item->Worn.Effect > 0 && item->Worn.Type == RuleI(Spells, AdditiveBonusWornType)) - ApplySpellsBonuses(item->Worn.Effect, item->Worn.Level, newbon, 0, item->Worn.Type);// Non-live like - Addititive latent effects + if (item->Worn.Effect > 0 && item->Worn.Type == RuleI(Spells, AdditiveBonusWornType)) { + ApplySpellsBonuses( + item->Worn.Effect, + item->Worn.Level, + b, + 0, + item->Worn.Type + ); + } - - if (!isAug) - { + if (!is_augment) { int i; for (i = EQ::invaug::SOCKET_BEGIN; i <= EQ::invaug::SOCKET_END; i++) { - AdditiveWornBonuses(inst->GetAugment(i),newbon,true); + AdditiveWornBonuses(inst->GetAugment(i), b, true); } } } @@ -1232,7 +1400,7 @@ void Mob::ApplyAABonuses(const AA::Rank &rank, StatBonuses *newbon) newbon->SkillAttackProc[i + SBIndex::SKILLATK_PROC_CHANCE] = base_value; // Chance base 1000 = 100% proc rate newbon->SkillAttackProc[i + SBIndex::SKILLATK_PROC_SKILL] = limit_value; // Skill to Proc Offr - if (limit_value < EQ::skills::HIGHEST_SKILL) { + if (limit_value <= EQ::skills::HIGHEST_SKILL) { newbon->HasSkillAttackProc[limit_value] = true; //check first before looking for any effects. } break; @@ -3623,7 +3791,7 @@ void Mob::ApplySpellsBonuses(uint16 spell_id, uint8 casterlevel, StatBonuses *ne new_bonus->SkillAttackProc[i + SBIndex::SKILLATK_PROC_CHANCE] = effect_value; // Chance base 1000 = 100% proc rate new_bonus->SkillAttackProc[i + SBIndex::SKILLATK_PROC_SKILL] = limit_value; // Skill to Proc Offr - if (limit_value < EQ::skills::HIGHEST_SKILL) { + if (limit_value <= EQ::skills::HIGHEST_SKILL) { new_bonus->HasSkillAttackProc[limit_value] = true; //check first before looking for any effects. } break; @@ -3896,84 +4064,6 @@ void Mob::ApplySpellsBonuses(uint16 spell_id, uint8 casterlevel, StatBonuses *ne } } -void NPC::CalcItemBonuses(StatBonuses *newbon) -{ - if(newbon){ - - for (int i = EQ::invslot::BONUS_BEGIN; i <= EQ::invslot::BONUS_STAT_END; i++){ - const EQ::ItemData *cur = database.GetItem(equipment[i]); - if(cur){ - //basic stats - newbon->AC += cur->AC; - newbon->HP += cur->HP; - newbon->Mana += cur->Mana; - newbon->Endurance += cur->Endur; - newbon->STR += (cur->AStr + cur->HeroicStr); - newbon->STA += (cur->ASta + cur->HeroicSta); - newbon->DEX += (cur->ADex + cur->HeroicDex); - newbon->AGI += (cur->AAgi + cur->HeroicAgi); - newbon->INT += (cur->AInt + cur->HeroicInt); - newbon->WIS += (cur->AWis + cur->HeroicWis); - newbon->CHA += (cur->ACha + cur->HeroicCha); - newbon->MR += (cur->MR + cur->HeroicMR); - newbon->FR += (cur->FR + cur->HeroicFR); - newbon->CR += (cur->CR + cur->HeroicCR); - newbon->PR += (cur->PR + cur->HeroicPR); - newbon->DR += (cur->DR + cur->HeroicDR); - newbon->Corrup += (cur->SVCorruption + cur->HeroicSVCorrup); - - //more complex stats - if(cur->Regen > 0) { - newbon->HPRegen += cur->Regen; - } - if(cur->ManaRegen > 0) { - newbon->ManaRegen += cur->ManaRegen; - } - if(cur->Attack > 0) { - newbon->ATK += cur->Attack; - } - if(cur->DamageShield > 0) { - newbon->DamageShield += cur->DamageShield; - } - if(cur->SpellShield > 0) { - newbon->SpellShield += cur->SpellShield; - } - if(cur->Shielding > 0) { - newbon->MeleeMitigation += cur->Shielding; - } - if(cur->StunResist > 0) { - newbon->StunResist += cur->StunResist; - } - if(cur->StrikeThrough > 0) { - newbon->StrikeThrough += cur->StrikeThrough; - } - if(cur->Avoidance > 0) { - newbon->AvoidMeleeChance += cur->Avoidance; - } - if(cur->Accuracy > 0) { - newbon->HitChance += cur->Accuracy; - } - if(cur->CombatEffects > 0) { - newbon->ProcChance += cur->CombatEffects; - } - if (cur->Worn.Effect>0 && (cur->Worn.Type == EQ::item::ItemEffectWorn)) { // latent effects - ApplySpellsBonuses(cur->Worn.Effect, cur->Worn.Level, newbon, 0, cur->Worn.Type); - } - - if (RuleB(Spells, NPC_UseFocusFromItems)){ - if (cur->Focus.Effect>0 && (cur->Focus.Type == EQ::item::ItemEffectFocus)){ // focus effects - ApplySpellsBonuses(cur->Focus.Effect, cur->Focus.Level, newbon); - } - } - - if (cur->Haste > newbon->haste) - newbon->haste = cur->Haste; - } - } - - } -} - void Client::CalcItemScale() { bool changed = false; diff --git a/zone/bot.cpp b/zone/bot.cpp index e68789e07..c420a1283 100644 --- a/zone/bot.cpp +++ b/zone/bot.cpp @@ -7009,354 +7009,6 @@ void Bot::ProcessBotInspectionRequest(Bot* inspectedBot, Client* client) { } } -void Bot::CalcItemBonuses(StatBonuses* newbon) -{ - const EQ::ItemData* itemtmp = nullptr; - - for (int i = EQ::invslot::BONUS_BEGIN; i <= EQ::invslot::BONUS_STAT_END; ++i) { - const EQ::ItemInstance* item = GetBotItem(i); - if (item) { - AddItemBonuses(item, newbon); - } - } - - // Caps - if (newbon->HPRegen > CalcHPRegenCap()) - newbon->HPRegen = CalcHPRegenCap(); - - if (newbon->ManaRegen > CalcManaRegenCap()) - newbon->ManaRegen = CalcManaRegenCap(); - - if (newbon->EnduranceRegen > CalcEnduranceRegenCap()) - newbon->EnduranceRegen = CalcEnduranceRegenCap(); -} - -void Bot::AddItemBonuses(const EQ::ItemInstance *inst, StatBonuses* newbon, bool isAug, bool isTribute, int rec_override) { - if (!inst || !inst->IsClassCommon()) - { - return; - } - - if (inst->GetAugmentType()==0 && isAug) - { - return; - } - - const EQ::ItemData *item = inst->GetItem(); - - if (!isTribute && !inst->IsEquipable(GetBaseRace(),GetClass())) - { - if (item->ItemType != EQ::item::ItemTypeFood && item->ItemType != EQ::item::ItemTypeDrink) - return; - } - - if (GetLevel() < inst->GetItemRequiredLevel(true)) - { - return; - } - - auto rec_level = isAug ? rec_override : inst->GetItemRecommendedLevel(true); - if (GetLevel() >= rec_level) - { - newbon->AC += item->AC; - newbon->HP += item->HP; - newbon->Mana += item->Mana; - newbon->Endurance += item->Endur; - newbon->ATK += item->Attack; - newbon->STR += (item->AStr + item->HeroicStr); - newbon->STA += (item->ASta + item->HeroicSta); - newbon->DEX += (item->ADex + item->HeroicDex); - newbon->AGI += (item->AAgi + item->HeroicAgi); - newbon->INT += (item->AInt + item->HeroicInt); - newbon->WIS += (item->AWis + item->HeroicWis); - newbon->CHA += (item->ACha + item->HeroicCha); - - newbon->MR += (item->MR + item->HeroicMR); - newbon->FR += (item->FR + item->HeroicFR); - newbon->CR += (item->CR + item->HeroicCR); - newbon->PR += (item->PR + item->HeroicPR); - newbon->DR += (item->DR + item->HeroicDR); - newbon->Corrup += (item->SVCorruption + item->HeroicSVCorrup); - - newbon->STRCapMod += item->HeroicStr; - newbon->STACapMod += item->HeroicSta; - newbon->DEXCapMod += item->HeroicDex; - newbon->AGICapMod += item->HeroicAgi; - newbon->INTCapMod += item->HeroicInt; - newbon->WISCapMod += item->HeroicWis; - newbon->CHACapMod += item->HeroicCha; - newbon->MRCapMod += item->HeroicMR; - newbon->CRCapMod += item->HeroicFR; - newbon->FRCapMod += item->HeroicCR; - newbon->PRCapMod += item->HeroicPR; - newbon->DRCapMod += item->HeroicDR; - newbon->CorrupCapMod += item->HeroicSVCorrup; - - newbon->HeroicSTR += item->HeroicStr; - newbon->HeroicSTA += item->HeroicSta; - newbon->HeroicDEX += item->HeroicDex; - newbon->HeroicAGI += item->HeroicAgi; - newbon->HeroicINT += item->HeroicInt; - newbon->HeroicWIS += item->HeroicWis; - newbon->HeroicCHA += item->HeroicCha; - newbon->HeroicMR += item->HeroicMR; - newbon->HeroicFR += item->HeroicFR; - newbon->HeroicCR += item->HeroicCR; - newbon->HeroicPR += item->HeroicPR; - newbon->HeroicDR += item->HeroicDR; - newbon->HeroicCorrup += item->HeroicSVCorrup; - - } - else - { - int lvl = GetLevel(); - - newbon->AC += CalcRecommendedLevelBonus( lvl, rec_level, item->AC ); - newbon->HP += CalcRecommendedLevelBonus( lvl, rec_level, item->HP ); - newbon->Mana += CalcRecommendedLevelBonus( lvl, rec_level, item->Mana ); - newbon->Endurance += CalcRecommendedLevelBonus( lvl, rec_level, item->Endur ); - newbon->ATK += CalcRecommendedLevelBonus( lvl, rec_level, item->Attack ); - newbon->STR += CalcRecommendedLevelBonus( lvl, rec_level, (item->AStr + item->HeroicStr) ); - newbon->STA += CalcRecommendedLevelBonus( lvl, rec_level, (item->ASta + item->HeroicSta) ); - newbon->DEX += CalcRecommendedLevelBonus( lvl, rec_level, (item->ADex + item->HeroicDex) ); - newbon->AGI += CalcRecommendedLevelBonus( lvl, rec_level, (item->AAgi + item->HeroicAgi) ); - newbon->INT += CalcRecommendedLevelBonus( lvl, rec_level, (item->AInt + item->HeroicInt) ); - newbon->WIS += CalcRecommendedLevelBonus( lvl, rec_level, (item->AWis + item->HeroicWis) ); - newbon->CHA += CalcRecommendedLevelBonus( lvl, rec_level, (item->ACha + item->HeroicCha) ); - - newbon->MR += CalcRecommendedLevelBonus( lvl, rec_level, (item->MR + item->HeroicMR) ); - newbon->FR += CalcRecommendedLevelBonus( lvl, rec_level, (item->FR + item->HeroicFR) ); - newbon->CR += CalcRecommendedLevelBonus( lvl, rec_level, (item->CR + item->HeroicCR) ); - newbon->PR += CalcRecommendedLevelBonus( lvl, rec_level, (item->PR + item->HeroicPR) ); - newbon->DR += CalcRecommendedLevelBonus( lvl, rec_level, (item->DR + item->HeroicDR) ); - newbon->Corrup += CalcRecommendedLevelBonus( lvl, rec_level, (item->SVCorruption + item->HeroicSVCorrup) ); - - newbon->STRCapMod += CalcRecommendedLevelBonus( lvl, rec_level, item->HeroicStr ); - newbon->STACapMod += CalcRecommendedLevelBonus( lvl, rec_level, item->HeroicSta ); - newbon->DEXCapMod += CalcRecommendedLevelBonus( lvl, rec_level, item->HeroicDex ); - newbon->AGICapMod += CalcRecommendedLevelBonus( lvl, rec_level, item->HeroicAgi ); - newbon->INTCapMod += CalcRecommendedLevelBonus( lvl, rec_level, item->HeroicInt ); - newbon->WISCapMod += CalcRecommendedLevelBonus( lvl, rec_level, item->HeroicWis ); - newbon->CHACapMod += CalcRecommendedLevelBonus( lvl, rec_level, item->HeroicCha ); - newbon->MRCapMod += CalcRecommendedLevelBonus( lvl, rec_level, item->HeroicMR ); - newbon->CRCapMod += CalcRecommendedLevelBonus( lvl, rec_level, item->HeroicFR ); - newbon->FRCapMod += CalcRecommendedLevelBonus( lvl, rec_level, item->HeroicCR ); - newbon->PRCapMod += CalcRecommendedLevelBonus( lvl, rec_level, item->HeroicPR ); - newbon->DRCapMod += CalcRecommendedLevelBonus( lvl, rec_level, item->HeroicDR ); - newbon->CorrupCapMod += CalcRecommendedLevelBonus( lvl, rec_level, item->HeroicSVCorrup ); - - newbon->HeroicSTR += CalcRecommendedLevelBonus( lvl, rec_level, item->HeroicStr ); - newbon->HeroicSTA += CalcRecommendedLevelBonus( lvl, rec_level, item->HeroicSta ); - newbon->HeroicDEX += CalcRecommendedLevelBonus( lvl, rec_level, item->HeroicDex ); - newbon->HeroicAGI += CalcRecommendedLevelBonus( lvl, rec_level, item->HeroicAgi ); - newbon->HeroicINT += CalcRecommendedLevelBonus( lvl, rec_level, item->HeroicInt ); - newbon->HeroicWIS += CalcRecommendedLevelBonus( lvl, rec_level, item->HeroicWis ); - newbon->HeroicCHA += CalcRecommendedLevelBonus( lvl, rec_level, item->HeroicCha ); - newbon->HeroicMR += CalcRecommendedLevelBonus( lvl, rec_level, item->HeroicMR ); - newbon->HeroicFR += CalcRecommendedLevelBonus( lvl, rec_level, item->HeroicFR ); - newbon->HeroicCR += CalcRecommendedLevelBonus( lvl, rec_level, item->HeroicCR ); - newbon->HeroicPR += CalcRecommendedLevelBonus( lvl, rec_level, item->HeroicPR ); - newbon->HeroicDR += CalcRecommendedLevelBonus( lvl, rec_level, item->HeroicDR ); - newbon->HeroicCorrup += CalcRecommendedLevelBonus( lvl, rec_level, item->HeroicSVCorrup ); - } - - //FatherNitwit: New style haste, shields, and regens - if (newbon->haste < (int32)item->Haste) { - newbon->haste = item->Haste; - } - if (item->Regen > 0) - newbon->HPRegen += item->Regen; - - if (item->ManaRegen > 0) - newbon->ManaRegen += item->ManaRegen; - - if (item->EnduranceRegen > 0) - newbon->EnduranceRegen += item->EnduranceRegen; - - if (item->DamageShield > 0) { - if ((newbon->DamageShield + item->DamageShield) > RuleI(Character, ItemDamageShieldCap)) - newbon->DamageShield = RuleI(Character, ItemDamageShieldCap); - else - newbon->DamageShield += item->DamageShield; - } - if (item->SpellShield > 0) { - if ((newbon->SpellShield + item->SpellShield) > RuleI(Character, ItemSpellShieldingCap)) - newbon->SpellShield = RuleI(Character, ItemSpellShieldingCap); - else - newbon->SpellShield += item->SpellShield; - } - if (item->Shielding > 0) { - if ((newbon->MeleeMitigation + item->Shielding) > RuleI(Character, ItemShieldingCap)) - newbon->MeleeMitigation = RuleI(Character, ItemShieldingCap); - else - newbon->MeleeMitigation += item->Shielding; - } - if (item->StunResist > 0) { - if ((newbon->StunResist + item->StunResist) > RuleI(Character, ItemStunResistCap)) - newbon->StunResist = RuleI(Character, ItemStunResistCap); - else - newbon->StunResist += item->StunResist; - } - if (item->StrikeThrough > 0) { - if ((newbon->StrikeThrough + item->StrikeThrough) > RuleI(Character, ItemStrikethroughCap)) - newbon->StrikeThrough = RuleI(Character, ItemStrikethroughCap); - else - newbon->StrikeThrough += item->StrikeThrough; - } - if (item->Avoidance > 0) { - if ((newbon->AvoidMeleeChance + item->Avoidance) > RuleI(Character, ItemAvoidanceCap)) - newbon->AvoidMeleeChance = RuleI(Character, ItemAvoidanceCap); - else - newbon->AvoidMeleeChance += item->Avoidance; - } - if (item->Accuracy > 0) { - if ((newbon->HitChance + item->Accuracy) > RuleI(Character, ItemAccuracyCap)) - newbon->HitChance = RuleI(Character, ItemAccuracyCap); - else - newbon->HitChance += item->Accuracy; - } - if (item->CombatEffects > 0) { - if ((newbon->ProcChance + item->CombatEffects) > RuleI(Character, ItemCombatEffectsCap)) - newbon->ProcChance = RuleI(Character, ItemCombatEffectsCap); - else - newbon->ProcChance += item->CombatEffects; - } - if (item->DotShielding > 0) { - if ((newbon->DoTShielding + item->DotShielding) > RuleI(Character, ItemDoTShieldingCap)) - newbon->DoTShielding = RuleI(Character, ItemDoTShieldingCap); - else - newbon->DoTShielding += item->DotShielding; - } - - if (item->HealAmt > 0) { - if ((newbon->HealAmt + item->HealAmt) > RuleI(Character, ItemHealAmtCap)) - newbon->HealAmt = RuleI(Character, ItemHealAmtCap); - else - newbon->HealAmt += item->HealAmt; - } - if (item->SpellDmg > 0) { - if ((newbon->SpellDmg + item->SpellDmg) > RuleI(Character, ItemSpellDmgCap)) - newbon->SpellDmg = RuleI(Character, ItemSpellDmgCap); - else - newbon->SpellDmg += item->SpellDmg; - } - if (item->Clairvoyance > 0) { - if ((newbon->Clairvoyance + item->Clairvoyance) > RuleI(Character, ItemClairvoyanceCap)) - newbon->Clairvoyance = RuleI(Character, ItemClairvoyanceCap); - else - newbon->Clairvoyance += item->Clairvoyance; - } - - if (item->DSMitigation > 0) { - if ((newbon->DSMitigation + item->DSMitigation) > RuleI(Character, ItemDSMitigationCap)) - newbon->DSMitigation = RuleI(Character, ItemDSMitigationCap); - else - newbon->DSMitigation += item->DSMitigation; - } - if (item->Worn.Effect > 0 && item->Worn.Type == EQ::item::ItemEffectWorn) {// latent effects - ApplySpellsBonuses(item->Worn.Effect, item->Worn.Level, newbon, 0, item->Worn.Type); - } - - if (item->Focus.Effect>0 && (item->Focus.Type == EQ::item::ItemEffectFocus)) { // focus effects - ApplySpellsBonuses(item->Focus.Effect, item->Focus.Level, newbon, 0); - } - - switch(item->BardType) - { - case EQ::item::ItemTypeAllInstrumentTypes: // (e.g. Singing Short Sword) - { - if (item->BardValue > newbon->singingMod) - newbon->singingMod = item->BardValue; - if (item->BardValue > newbon->brassMod) - newbon->brassMod = item->BardValue; - if (item->BardValue > newbon->stringedMod) - newbon->stringedMod = item->BardValue; - if (item->BardValue > newbon->percussionMod) - newbon->percussionMod = item->BardValue; - if (item->BardValue > newbon->windMod) - newbon->windMod = item->BardValue; - break; - } - case EQ::item::ItemTypeSinging: - { - if (item->BardValue > newbon->singingMod) - newbon->singingMod = item->BardValue; - break; - } - case EQ::item::ItemTypeWindInstrument: - { - if (item->BardValue > newbon->windMod) - newbon->windMod = item->BardValue; - break; - } - case EQ::item::ItemTypeStringedInstrument: - { - if (item->BardValue > newbon->stringedMod) - newbon->stringedMod = item->BardValue; - break; - } - case EQ::item::ItemTypeBrassInstrument: - { - if (item->BardValue > newbon->brassMod) - newbon->brassMod = item->BardValue; - break; - } - case EQ::item::ItemTypePercussionInstrument: - { - if (item->BardValue > newbon->percussionMod) - newbon->percussionMod = item->BardValue; - break; - } - } - - if (item->SkillModValue != 0 && item->SkillModType <= EQ::skills::HIGHEST_SKILL) { - if ((item->SkillModValue > 0 && newbon->skillmod[item->SkillModType] < item->SkillModValue) || - (item->SkillModValue < 0 && newbon->skillmod[item->SkillModType] > item->SkillModValue)) - { - newbon->skillmod[item->SkillModType] = item->SkillModValue; - } - } - - if (item->ExtraDmgAmt != 0 && item->ExtraDmgSkill <= EQ::skills::HIGHEST_SKILL) { - if ( - RuleI(Character, ItemExtraDmgCap) >= 0 && - (newbon->SkillDamageAmount[item->ExtraDmgSkill] + item->ExtraDmgAmt) > RuleI(Character, ItemExtraDmgCap) - ) { - newbon->SkillDamageAmount[item->ExtraDmgSkill] = RuleI(Character, ItemExtraDmgCap); - } else { - newbon->SkillDamageAmount[item->ExtraDmgSkill] += item->ExtraDmgAmt; - } - } - - if (!isAug) - { - for (int i = EQ::invaug::SOCKET_BEGIN; i <= EQ::invaug::SOCKET_END; i++) - AddItemBonuses(inst->GetAugment(i),newbon,true, false, rec_level); - } - -} - -int Bot::CalcRecommendedLevelBonus(uint8 level, uint8 reclevel, int basestat) -{ - if ( (reclevel > 0) && (level < reclevel) ) - { - int32 statmod = (level * 10000 / reclevel) * basestat; - - if ( statmod < 0 ) - { - statmod -= 5000; - return (statmod/10000); - } - else - { - statmod += 5000; - return (statmod/10000); - } - } - - return 0; -} - // This method is intended to call all necessary methods to do all bot stat calculations, including spell buffs, equipment, AA bonsues, etc. void Bot::CalcBotStats(bool showtext) { if (!GetBotOwner()) diff --git a/zone/bot.h b/zone/bot.h index 3f31f451d..e36b19461 100644 --- a/zone/bot.h +++ b/zone/bot.h @@ -184,9 +184,7 @@ public: void RogueAssassinate(Mob* other) override; void DoClassAttacks(Mob *target, bool IsRiposte=false); void CalcBonuses() override; - void CalcItemBonuses(StatBonuses* newbon); - void AddItemBonuses(const EQ::ItemInstance *inst, StatBonuses* newbon, bool isAug = false, bool isTribute = false, int rec_override = 0); - int CalcRecommendedLevelBonus(uint8 level, uint8 reclevel, int basestat); + void MakePet(uint16 spell_id, const char* pettype, const char *petname = nullptr) override; FACTION_VALUE GetReverseFactionCon(Mob* iOther) override; inline bool IsPet() override { return false; } diff --git a/zone/client.h b/zone/client.h index 9362bca60..db63a5b24 100644 --- a/zone/client.h +++ b/zone/client.h @@ -1645,9 +1645,6 @@ public: protected: friend class Mob; - void CalcItemBonuses(StatBonuses* newbon); - void AddItemBonuses(const EQ::ItemInstance *inst, StatBonuses* newbon, bool isAug = false, bool isTribute = false, int rec_override = 0, bool ammo_slot_item = false); - void AdditiveWornBonuses(const EQ::ItemInstance *inst, StatBonuses* newbon, bool isAug = false); void CalcEdibleBonuses(StatBonuses* newbon); void MakeBuffFadePacket(uint16 spell_id, int slot_id, bool send_message = true); bool client_data_loaded; diff --git a/zone/lua_mob.cpp b/zone/lua_mob.cpp index 8fee8297c..869c2e2dd 100644 --- a/zone/lua_mob.cpp +++ b/zone/lua_mob.cpp @@ -1964,10 +1964,10 @@ int Lua_Mob::GetFcDamageAmtIncoming(Lua_Mob caster, int32 spell_id) return self->GetFcDamageAmtIncoming(caster, spell_id); } -int Lua_Mob::GetSkillDmgAmt(uint16 skill) +int Lua_Mob::GetSkillDmgAmt(int skill_id) { Lua_Safe_Call_Int(); - return self->GetSkillDmgAmt(skill); + return self->GetSkillDmgAmt(skill_id); } void Lua_Mob::SetAllowBeneficial(bool value) { diff --git a/zone/lua_mob.h b/zone/lua_mob.h index 3657b3323..832bc2ca2 100644 --- a/zone/lua_mob.h +++ b/zone/lua_mob.h @@ -392,7 +392,7 @@ public: int GetModSkillDmgTaken(int skill); int GetSkillDmgTaken(int skill); int GetFcDamageAmtIncoming(Lua_Mob caster, int32 spell_id); - int GetSkillDmgAmt(uint16 skill); + int GetSkillDmgAmt(int skill_id); void SetAllowBeneficial(bool value); bool GetAllowBeneficial(); bool IsBeneficialAllowed(Lua_Mob target); diff --git a/zone/lua_stat_bonuses.cpp b/zone/lua_stat_bonuses.cpp index 92099a47e..8f50f7992 100644 --- a/zone/lua_stat_bonuses.cpp +++ b/zone/lua_stat_bonuses.cpp @@ -1,5 +1,7 @@ #ifdef LUA_EQEMU +#include "../common/data_verification.h" + #include "lua.hpp" #include @@ -1097,7 +1099,11 @@ int32 Lua_StatBonuses::GetSkillReuseTime(int idx) const { int32 Lua_StatBonuses::GetSkillDamageAmount(int idx) const { Lua_Safe_Call_Int(); - return self->SkillDamageAmount[idx]; + if (!EQ::ValueWithin(idx, ALL_SKILLS, EQ::skills::HIGHEST_SKILL)) { + return 0; + } + + return idx == ALL_SKILLS ? self->SkillDamageAmount[EQ::skills::HIGHEST_SKILL + 1] : self->SkillDamageAmount[idx]; } int Lua_StatBonuses::GetHPPercCap(int idx) const { diff --git a/zone/merc.cpp b/zone/merc.cpp index 558c2fc7b..e6634d8e6 100644 --- a/zone/merc.cpp +++ b/zone/merc.cpp @@ -190,391 +190,6 @@ float Merc::GetDefaultSize() { return MercSize; } -int Merc::CalcRecommendedLevelBonus(uint8 level, uint8 reclevel, int basestat) -{ - if( (reclevel > 0) && (level < reclevel) ) - { - int32 statmod = (level * 10000 / reclevel) * basestat; - - if( statmod < 0 ) - { - statmod -= 5000; - return (statmod/10000); - } - else - { - statmod += 5000; - return (statmod/10000); - } - } - - return 0; -} - -void Merc::CalcItemBonuses(StatBonuses* newbon) { - //memset assumed to be done by caller. - - - unsigned int i; - //should not include 21 (SLOT_AMMO) - for (i = EQ::invslot::BONUS_BEGIN; i <= EQ::invslot::BONUS_STAT_END; i++) { - if (i == EQ::invslot::slotAmmo) - continue; - if (equipment[i] == 0) - continue; - const EQ::ItemData * itm = database.GetItem(equipment[i]); - if (itm) - AddItemBonuses(itm, newbon); - } - - // Caps - if(newbon->HPRegen > CalcHPRegenCap()) - newbon->HPRegen = CalcHPRegenCap(); - - if(newbon->ManaRegen > CalcManaRegenCap()) - newbon->ManaRegen = CalcManaRegenCap(); - - if(newbon->EnduranceRegen > CalcEnduranceRegenCap()) - newbon->EnduranceRegen = CalcEnduranceRegenCap(); - - SetAttackTimer(); -} - -void Merc::AddItemBonuses(const EQ::ItemData *item, StatBonuses* newbon) { - - if(GetLevel() < item->ReqLevel) - { - return; - } - - if(GetLevel() >= item->RecLevel) - { - newbon->AC += item->AC; - newbon->HP += item->HP; - newbon->Mana += item->Mana; - newbon->Endurance += item->Endur; - newbon->STR += (item->AStr + item->HeroicStr); - newbon->STA += (item->ASta + item->HeroicSta); - newbon->DEX += (item->ADex + item->HeroicDex); - newbon->AGI += (item->AAgi + item->HeroicAgi); - newbon->INT += (item->AInt + item->HeroicInt); - newbon->WIS += (item->AWis + item->HeroicWis); - newbon->CHA += (item->ACha + item->HeroicCha); - - newbon->MR += (item->MR + item->HeroicMR); - newbon->FR += (item->FR + item->HeroicFR); - newbon->CR += (item->CR + item->HeroicCR); - newbon->PR += (item->PR + item->HeroicPR); - newbon->DR += (item->DR + item->HeroicDR); - newbon->Corrup += (item->SVCorruption + item->HeroicSVCorrup); - - newbon->STRCapMod += item->HeroicStr; - newbon->STACapMod += item->HeroicSta; - newbon->DEXCapMod += item->HeroicDex; - newbon->AGICapMod += item->HeroicAgi; - newbon->INTCapMod += item->HeroicInt; - newbon->WISCapMod += item->HeroicWis; - newbon->CHACapMod += item->HeroicCha; - newbon->MRCapMod += item->HeroicMR; - newbon->CRCapMod += item->HeroicFR; - newbon->FRCapMod += item->HeroicCR; - newbon->PRCapMod += item->HeroicPR; - newbon->DRCapMod += item->HeroicDR; - newbon->CorrupCapMod += item->HeroicSVCorrup; - - newbon->HeroicSTR += item->HeroicStr; - newbon->HeroicSTA += item->HeroicSta; - newbon->HeroicDEX += item->HeroicDex; - newbon->HeroicAGI += item->HeroicAgi; - newbon->HeroicINT += item->HeroicInt; - newbon->HeroicWIS += item->HeroicWis; - newbon->HeroicCHA += item->HeroicCha; - newbon->HeroicMR += item->HeroicMR; - newbon->HeroicFR += item->HeroicFR; - newbon->HeroicCR += item->HeroicCR; - newbon->HeroicPR += item->HeroicPR; - newbon->HeroicDR += item->HeroicDR; - newbon->HeroicCorrup += item->HeroicSVCorrup; - - } - else - { - int lvl = GetLevel(); - int reclvl = item->RecLevel; - - newbon->AC += CalcRecommendedLevelBonus( lvl, reclvl, item->AC ); - newbon->HP += CalcRecommendedLevelBonus( lvl, reclvl, item->HP ); - newbon->Mana += CalcRecommendedLevelBonus( lvl, reclvl, item->Mana ); - newbon->Endurance += CalcRecommendedLevelBonus( lvl, reclvl, item->Endur ); - newbon->STR += CalcRecommendedLevelBonus( lvl, reclvl, (item->AStr + item->HeroicStr) ); - newbon->STA += CalcRecommendedLevelBonus( lvl, reclvl, (item->ASta + item->HeroicSta) ); - newbon->DEX += CalcRecommendedLevelBonus( lvl, reclvl, (item->ADex + item->HeroicDex) ); - newbon->AGI += CalcRecommendedLevelBonus( lvl, reclvl, (item->AAgi + item->HeroicAgi) ); - newbon->INT += CalcRecommendedLevelBonus( lvl, reclvl, (item->AInt + item->HeroicInt) ); - newbon->WIS += CalcRecommendedLevelBonus( lvl, reclvl, (item->AWis + item->HeroicWis) ); - newbon->CHA += CalcRecommendedLevelBonus( lvl, reclvl, (item->ACha + item->HeroicCha) ); - - newbon->MR += CalcRecommendedLevelBonus( lvl, reclvl, (item->MR + item->HeroicMR) ); - newbon->FR += CalcRecommendedLevelBonus( lvl, reclvl, (item->FR + item->HeroicFR) ); - newbon->CR += CalcRecommendedLevelBonus( lvl, reclvl, (item->CR + item->HeroicCR) ); - newbon->PR += CalcRecommendedLevelBonus( lvl, reclvl, (item->PR + item->HeroicPR) ); - newbon->DR += CalcRecommendedLevelBonus( lvl, reclvl, (item->DR + item->HeroicDR) ); - newbon->Corrup += CalcRecommendedLevelBonus( lvl, reclvl, (item->SVCorruption + item->HeroicSVCorrup) ); - - newbon->STRCapMod += CalcRecommendedLevelBonus( lvl, reclvl, item->HeroicStr ); - newbon->STACapMod += CalcRecommendedLevelBonus( lvl, reclvl, item->HeroicSta ); - newbon->DEXCapMod += CalcRecommendedLevelBonus( lvl, reclvl, item->HeroicDex ); - newbon->AGICapMod += CalcRecommendedLevelBonus( lvl, reclvl, item->HeroicAgi ); - newbon->INTCapMod += CalcRecommendedLevelBonus( lvl, reclvl, item->HeroicInt ); - newbon->WISCapMod += CalcRecommendedLevelBonus( lvl, reclvl, item->HeroicWis ); - newbon->CHACapMod += CalcRecommendedLevelBonus( lvl, reclvl, item->HeroicCha ); - newbon->MRCapMod += CalcRecommendedLevelBonus( lvl, reclvl, item->HeroicMR ); - newbon->CRCapMod += CalcRecommendedLevelBonus( lvl, reclvl, item->HeroicFR ); - newbon->FRCapMod += CalcRecommendedLevelBonus( lvl, reclvl, item->HeroicCR ); - newbon->PRCapMod += CalcRecommendedLevelBonus( lvl, reclvl, item->HeroicPR ); - newbon->DRCapMod += CalcRecommendedLevelBonus( lvl, reclvl, item->HeroicDR ); - newbon->CorrupCapMod += CalcRecommendedLevelBonus( lvl, reclvl, item->HeroicSVCorrup ); - - newbon->HeroicSTR += CalcRecommendedLevelBonus( lvl, reclvl, item->HeroicStr ); - newbon->HeroicSTA += CalcRecommendedLevelBonus( lvl, reclvl, item->HeroicSta ); - newbon->HeroicDEX += CalcRecommendedLevelBonus( lvl, reclvl, item->HeroicDex ); - newbon->HeroicAGI += CalcRecommendedLevelBonus( lvl, reclvl, item->HeroicAgi ); - newbon->HeroicINT += CalcRecommendedLevelBonus( lvl, reclvl, item->HeroicInt ); - newbon->HeroicWIS += CalcRecommendedLevelBonus( lvl, reclvl, item->HeroicWis ); - newbon->HeroicCHA += CalcRecommendedLevelBonus( lvl, reclvl, item->HeroicCha ); - newbon->HeroicMR += CalcRecommendedLevelBonus( lvl, reclvl, item->HeroicMR ); - newbon->HeroicFR += CalcRecommendedLevelBonus( lvl, reclvl, item->HeroicFR ); - newbon->HeroicCR += CalcRecommendedLevelBonus( lvl, reclvl, item->HeroicCR ); - newbon->HeroicPR += CalcRecommendedLevelBonus( lvl, reclvl, item->HeroicPR ); - newbon->HeroicDR += CalcRecommendedLevelBonus( lvl, reclvl, item->HeroicDR ); - newbon->HeroicCorrup += CalcRecommendedLevelBonus( lvl, reclvl, item->HeroicSVCorrup ); - } - - //FatherNitwit: New style haste, shields, and regens - if(newbon->haste < item->Haste) { - newbon->haste = item->Haste; - } - if(item->Regen > 0) - newbon->HPRegen += item->Regen; - - if(item->ManaRegen > 0) - newbon->ManaRegen += item->ManaRegen; - - if(item->EnduranceRegen > 0) - newbon->EnduranceRegen += item->EnduranceRegen; - - if(item->Attack > 0) { - - unsigned int cap = RuleI(Character, ItemATKCap); - cap += itembonuses.ItemATKCap + spellbonuses.ItemATKCap + aabonuses.ItemATKCap; - - if((newbon->ATK + item->Attack) > cap) - newbon->ATK = RuleI(Character, ItemATKCap); - else - newbon->ATK += item->Attack; - } - if(item->DamageShield > 0) { - if((newbon->DamageShield + item->DamageShield) > RuleI(Character, ItemDamageShieldCap)) - newbon->DamageShield = RuleI(Character, ItemDamageShieldCap); - else - newbon->DamageShield += item->DamageShield; - } - if(item->SpellShield > 0) { - if((newbon->SpellShield + item->SpellShield) > RuleI(Character, ItemSpellShieldingCap)) - newbon->SpellShield = RuleI(Character, ItemSpellShieldingCap); - else - newbon->SpellShield += item->SpellShield; - } - if(item->Shielding > 0) { - if((newbon->MeleeMitigation + item->Shielding) > RuleI(Character, ItemShieldingCap)) - newbon->MeleeMitigation = RuleI(Character, ItemShieldingCap); - else - newbon->MeleeMitigation += item->Shielding; - } - if(item->StunResist > 0) { - if((newbon->StunResist + item->StunResist) > RuleI(Character, ItemStunResistCap)) - newbon->StunResist = RuleI(Character, ItemStunResistCap); - else - newbon->StunResist += item->StunResist; - } - if(item->StrikeThrough > 0) { - if((newbon->StrikeThrough + item->StrikeThrough) > RuleI(Character, ItemStrikethroughCap)) - newbon->StrikeThrough = RuleI(Character, ItemStrikethroughCap); - else - newbon->StrikeThrough += item->StrikeThrough; - } - if(item->Avoidance > 0) { - if((newbon->AvoidMeleeChance + item->Avoidance) > RuleI(Character, ItemAvoidanceCap)) - newbon->AvoidMeleeChance = RuleI(Character, ItemAvoidanceCap); - else - newbon->AvoidMeleeChance += item->Avoidance; - } - if(item->Accuracy > 0) { - if((newbon->HitChance + item->Accuracy) > RuleI(Character, ItemAccuracyCap)) - newbon->HitChance = RuleI(Character, ItemAccuracyCap); - else - newbon->HitChance += item->Accuracy; - } - if(item->CombatEffects > 0) { - if((newbon->ProcChance + item->CombatEffects) > RuleI(Character, ItemCombatEffectsCap)) - newbon->ProcChance = RuleI(Character, ItemCombatEffectsCap); - else - newbon->ProcChance += item->CombatEffects; - } - if(item->DotShielding > 0) { - if((newbon->DoTShielding + item->DotShielding) > RuleI(Character, ItemDoTShieldingCap)) - newbon->DoTShielding = RuleI(Character, ItemDoTShieldingCap); - else - newbon->DoTShielding += item->DotShielding; - } - - if(item->HealAmt > 0) { - if((newbon->HealAmt + item->HealAmt) > RuleI(Character, ItemHealAmtCap)) - newbon->HealAmt = RuleI(Character, ItemHealAmtCap); - else - newbon->HealAmt += item->HealAmt; - } - if(item->SpellDmg > 0) { - if((newbon->SpellDmg + item->SpellDmg) > RuleI(Character, ItemSpellDmgCap)) - newbon->SpellDmg = RuleI(Character, ItemSpellDmgCap); - else - newbon->SpellDmg += item->SpellDmg; - } - if(item->Clairvoyance > 0) { - if((newbon->Clairvoyance + item->Clairvoyance) > RuleI(Character, ItemClairvoyanceCap)) - newbon->Clairvoyance = RuleI(Character, ItemClairvoyanceCap); - else - newbon->Clairvoyance += item->Clairvoyance; - } - - if(item->DSMitigation > 0) { - if((newbon->DSMitigation + item->DSMitigation) > RuleI(Character, ItemDSMitigationCap)) - newbon->DSMitigation = RuleI(Character, ItemDSMitigationCap); - else - newbon->DSMitigation += item->DSMitigation; - } - if (item->Worn.Effect>0 && (item->Worn.Type == EQ::item::ItemEffectWorn)) { // latent effects - ApplySpellsBonuses(item->Worn.Effect, item->Worn.Level, newbon, 0, item->Worn.Type); - } - - if (item->Focus.Effect>0 && (item->Focus.Type == EQ::item::ItemEffectFocus)) { // focus effects - ApplySpellsBonuses(item->Focus.Effect, item->Focus.Level, newbon, 0); - } - - switch(item->BardType) - { - case 51: /* All (e.g. Singing Short Sword) */ - { - if(item->BardValue > newbon->singingMod) - newbon->singingMod = item->BardValue; - if(item->BardValue > newbon->brassMod) - newbon->brassMod = item->BardValue; - if(item->BardValue > newbon->stringedMod) - newbon->stringedMod = item->BardValue; - if(item->BardValue > newbon->percussionMod) - newbon->percussionMod = item->BardValue; - if(item->BardValue > newbon->windMod) - newbon->windMod = item->BardValue; - break; - } - case 50: /* Singing */ - { - if(item->BardValue > newbon->singingMod) - newbon->singingMod = item->BardValue; - break; - } - case 23: /* Wind */ - { - if(item->BardValue > newbon->windMod) - newbon->windMod = item->BardValue; - break; - } - case 24: /* stringed */ - { - if(item->BardValue > newbon->stringedMod) - newbon->stringedMod = item->BardValue; - break; - } - case 25: /* brass */ - { - if(item->BardValue > newbon->brassMod) - newbon->brassMod = item->BardValue; - break; - } - case 26: /* Percussion */ - { - if(item->BardValue > newbon->percussionMod) - newbon->percussionMod = item->BardValue; - break; - } - } - - if (item->SkillModValue != 0 && item->SkillModType <= EQ::skills::HIGHEST_SKILL){ - if ((item->SkillModValue > 0 && newbon->skillmod[item->SkillModType] < item->SkillModValue) || - (item->SkillModValue < 0 && newbon->skillmod[item->SkillModType] > item->SkillModValue)) - { - newbon->skillmod[item->SkillModType] = item->SkillModValue; - } - } - - // Add Item Faction Mods - if (item->FactionMod1) - { - if (item->FactionAmt1 > 0 && item->FactionAmt1 > GetItemFactionBonus(item->FactionMod1)) - { - AddItemFactionBonus(item->FactionMod1, item->FactionAmt1); - } - else if (item->FactionAmt1 < 0 && item->FactionAmt1 < GetItemFactionBonus(item->FactionMod1)) - { - AddItemFactionBonus(item->FactionMod1, item->FactionAmt1); - } - } - if (item->FactionMod2) - { - if (item->FactionAmt2 > 0 && item->FactionAmt2 > GetItemFactionBonus(item->FactionMod2)) - { - AddItemFactionBonus(item->FactionMod2, item->FactionAmt2); - } - else if (item->FactionAmt2 < 0 && item->FactionAmt2 < GetItemFactionBonus(item->FactionMod2)) - { - AddItemFactionBonus(item->FactionMod2, item->FactionAmt2); - } - } - if (item->FactionMod3) - { - if (item->FactionAmt3 > 0 && item->FactionAmt3 > GetItemFactionBonus(item->FactionMod3)) - { - AddItemFactionBonus(item->FactionMod3, item->FactionAmt3); - } - else if (item->FactionAmt3 < 0 && item->FactionAmt3 < GetItemFactionBonus(item->FactionMod3)) - { - AddItemFactionBonus(item->FactionMod3, item->FactionAmt3); - } - } - if (item->FactionMod4) - { - if (item->FactionAmt4 > 0 && item->FactionAmt4 > GetItemFactionBonus(item->FactionMod4)) - { - AddItemFactionBonus(item->FactionMod4, item->FactionAmt4); - } - else if (item->FactionAmt4 < 0 && item->FactionAmt4 < GetItemFactionBonus(item->FactionMod4)) - { - AddItemFactionBonus(item->FactionMod4, item->FactionAmt4); - } - } - - if (item->ExtraDmgAmt != 0 && item->ExtraDmgSkill <= EQ::skills::HIGHEST_SKILL) { - if ( - RuleI(Character, ItemExtraDmgCap) >= 0 && - (newbon->SkillDamageAmount[item->ExtraDmgSkill] + item->ExtraDmgAmt) > RuleI(Character, ItemExtraDmgCap) - ) { - newbon->SkillDamageAmount[item->ExtraDmgSkill] = RuleI(Character, ItemExtraDmgCap); - } else { - newbon->SkillDamageAmount[item->ExtraDmgSkill] += item->ExtraDmgAmt; - } - } -} - int Merc::GroupLeadershipAAHealthEnhancement() { Group *g = GetGroup(); diff --git a/zone/merc.h b/zone/merc.h index 57ffe3438..307eb340c 100644 --- a/zone/merc.h +++ b/zone/merc.h @@ -268,10 +268,6 @@ public: bool FindTarget(); protected: - void CalcItemBonuses(StatBonuses* newbon); - void AddItemBonuses(const EQ::ItemData *item, StatBonuses* newbon); - int CalcRecommendedLevelBonus(uint8 level, uint8 reclevel, int basestat); - int64 GetFocusEffect(focusType type, uint16 spell_id, bool from_buff_tic = false); std::vector merc_spells; diff --git a/zone/mob.cpp b/zone/mob.cpp index 17f680a8a..e80fcda27 100644 --- a/zone/mob.cpp +++ b/zone/mob.cpp @@ -16,6 +16,7 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ +#include "../common/data_verification.h" #include "../common/spdat.h" #include "../common/strings.h" #include "../common/misc_functions.h" @@ -3999,7 +4000,7 @@ void Mob::QuestJournalledSay(Client *QuestInitiator, const char *str, Journal::O const char *Mob::GetCleanName() { - if (!strlen(clean_name)) { + if (!strlen(clean_name)) { CleanMobName(GetName(), clean_name); } @@ -5549,16 +5550,41 @@ int16 Mob::GetSkillReuseTime(uint16 skill) return skill_reduction; } -int Mob::GetSkillDmgAmt(uint16 skill) +int Mob::GetSkillDmgAmt(int skill_id) { int skill_dmg = 0; - // All skill dmg(only spells do this) + Skill specific - skill_dmg += spellbonuses.SkillDamageAmount[EQ::skills::HIGHEST_SKILL + 1] + itembonuses.SkillDamageAmount[EQ::skills::HIGHEST_SKILL + 1] + aabonuses.SkillDamageAmount[EQ::skills::HIGHEST_SKILL + 1] - + itembonuses.SkillDamageAmount[skill] + spellbonuses.SkillDamageAmount[skill] + aabonuses.SkillDamageAmount[skill]; + if (!EQ::ValueWithin(skill_id, ALL_SKILLS, EQ::skills::HIGHEST_SKILL)) { + return skill_dmg; + } - skill_dmg += spellbonuses.SkillDamageAmount2[EQ::skills::HIGHEST_SKILL + 1] + itembonuses.SkillDamageAmount2[EQ::skills::HIGHEST_SKILL + 1] - + itembonuses.SkillDamageAmount2[skill] + spellbonuses.SkillDamageAmount2[skill]; + skill_dmg += ( + spellbonuses.SkillDamageAmount[EQ::skills::HIGHEST_SKILL + 1] + + itembonuses.SkillDamageAmount[EQ::skills::HIGHEST_SKILL + 1] + + aabonuses.SkillDamageAmount[EQ::skills::HIGHEST_SKILL + 1] + ); + + if (skill_id != ALL_SKILLS) { + skill_dmg += ( + itembonuses.SkillDamageAmount[skill_id] + + spellbonuses.SkillDamageAmount[skill_id] + + aabonuses.SkillDamageAmount[skill_id] + ); + } + + skill_dmg += ( + spellbonuses.SkillDamageAmount2[EQ::skills::HIGHEST_SKILL + 1] + + itembonuses.SkillDamageAmount2[EQ::skills::HIGHEST_SKILL + 1] + + aabonuses.SkillDamageAmount2[EQ::skills::HIGHEST_SKILL + 1] + ); + + if (skill_id != ALL_SKILLS) { + skill_dmg += ( + itembonuses.SkillDamageAmount2[skill_id] + + spellbonuses.SkillDamageAmount2[skill_id] + + aabonuses.SkillDamageAmount2[skill_id] + ); + } return skill_dmg; } diff --git a/zone/mob.h b/zone/mob.h index bbd4ce944..9fc1cde6f 100644 --- a/zone/mob.h +++ b/zone/mob.h @@ -664,8 +664,6 @@ public: virtual int32 CalcItemATKCap() { return 0; } virtual bool IsSitting() const { return false; } - int CalcRecommendedLevelBonus(uint8 level, uint8 reclevel, int basestat); - void CopyHateList(Mob* to); //Group @@ -953,7 +951,7 @@ public: int16 GetMeleeDmgPositionMod(Mob* defender); int16 GetSkillReuseTime(uint16 skill); int GetCriticalChanceBonus(uint16 skill); - int GetSkillDmgAmt(uint16 skill); + int GetSkillDmgAmt(int skill_id); int16 GetPositionalDmgAmt(Mob* defender); inline bool CanBlockSpell() const { return(spellbonuses.FocusEffects[focusBlockNextSpell]); } bool DoHPToManaCovert(int32 mana_cost = 0); @@ -1378,6 +1376,11 @@ public: void ApplyAABonuses(const AA::Rank &rank, StatBonuses* newbon); bool CheckAATimer(int timer); + void CalcItemBonuses(StatBonuses* b); + void AddItemBonuses(const EQ::ItemInstance* inst, StatBonuses* b, bool is_augment = false, bool is_tribute = false, int recommended_level_override = 0, bool is_ammo_item = false); + void AdditiveWornBonuses(const EQ::ItemInstance* inst, StatBonuses* b, bool is_augment = false); + int CalcRecommendedLevelBonus(uint8 current_level, uint8 recommended_level, int base_stat); + int NPCAssistCap() { return npc_assist_cap; } void AddAssistCap() { ++npc_assist_cap; } void DelAssistCap() { --npc_assist_cap; } diff --git a/zone/npc.h b/zone/npc.h index a33f649ad..6c59b54fb 100644 --- a/zone/npc.h +++ b/zone/npc.h @@ -162,7 +162,6 @@ public: virtual void SetTarget(Mob* mob); virtual uint16 GetSkill(EQ::skills::SkillType skill_num) const { if (skill_num <= EQ::skills::HIGHEST_SKILL) { return skills[skill_num]; } return 0; } - void CalcItemBonuses(StatBonuses *newbon); virtual void CalcBonuses(); virtual int GetCurrentBuffSlots() const { return RuleI(Spells, MaxBuffSlotsNPC); } virtual int GetCurrentSongSlots() const { return RuleI(Spells, MaxSongSlotsNPC); } diff --git a/zone/perl_mob.cpp b/zone/perl_mob.cpp index fb83bb496..ae25aec8a 100644 --- a/zone/perl_mob.cpp +++ b/zone/perl_mob.cpp @@ -2517,7 +2517,7 @@ void Perl_Mob_ApplySpellBuff(Mob* self, int spell_id, int duration) // @categori self->ApplySpellBuff(spell_id, duration); } -int Perl_Mob_GetSkillDmgAmt(Mob* self, uint16 skill_id) +int Perl_Mob_GetSkillDmgAmt(Mob* self, int skill_id) { return self->GetSkillDmgAmt(skill_id); } From eb51550109767dfee3d5612fc7095d84b4a19f74 Mon Sep 17 00:00:00 2001 From: Aeadoin <109764533+Aeadoin@users.noreply.github.com> Date: Sat, 25 Mar 2023 20:32:30 -0400 Subject: [PATCH 21/22] [Cleanup] Cleanup Strings::ToInt uses. (#3142) * [Cleanup] Cleanup Strings::ToInt uses. * fix for conversion * remove != 0 * cleanup --- common/database.cpp | 2 +- common/database_conversions.cpp | 6 +++--- common/events/player_events.h | 2 +- common/shareddb.cpp | 8 ++++---- loginserver/database.cpp | 10 +++++----- zone/aa.cpp | 20 ++++++++++---------- zone/aa_ability.h | 2 +- zone/aa_rank.h | 2 +- zone/aa_rank_effects.h | 2 +- zone/bot.cpp | 4 ++-- zone/zoning.cpp | 2 +- 11 files changed, 30 insertions(+), 30 deletions(-) diff --git a/common/database.cpp b/common/database.cpp index a25667995..43854172c 100644 --- a/common/database.cpp +++ b/common/database.cpp @@ -812,7 +812,7 @@ uint32 Database::GetAccountIDByChar(const char* charname, uint32* oCharID) { auto row = results.begin(); - uint32 accountId = Strings::ToInt(row[0]); + uint32 accountId = Strings::ToUnsignedInt(row[0]); if (oCharID) *oCharID = Strings::ToUnsignedInt(row[1]); diff --git a/common/database_conversions.cpp b/common/database_conversions.cpp index d78e43fff..69c432f99 100644 --- a/common/database_conversions.cpp +++ b/common/database_conversions.cpp @@ -499,7 +499,7 @@ bool Database::CheckDatabaseConvertPPDeblob(){ ExtendedProfile_Struct* e_pp; uint32 pplen = 0; uint32 i; - int character_id = 0; + uint32 character_id = 0; int account_id = 0; int number_of_characters = 0; int printppdebug = 0; /* Prints Player Profile */ @@ -929,12 +929,12 @@ bool Database::CheckDatabaseConvertPPDeblob(){ for (auto row = results.begin(); row != results.end(); ++row) { char_iter_count++; - squery = StringFormat("SELECT `id`, `profile`, `name`, `level`, `account_id`, `firstlogon`, `lfg`, `lfp`, `mailkey`, `xtargets`, `inspectmessage`, `extprofile` FROM `character_` WHERE `id` = %i", Strings::ToInt(row[0])); + squery = StringFormat("SELECT `id`, `profile`, `name`, `level`, `account_id`, `firstlogon`, `lfg`, `lfp`, `mailkey`, `xtargets`, `inspectmessage`, `extprofile` FROM `character_` WHERE `id` = %i", Strings::ToUnsignedInt(row[0])); auto results2 = QueryDatabase(squery); auto row2 = results2.begin(); pp = (Convert::PlayerProfile_Struct*)row2[1]; e_pp = (ExtendedProfile_Struct*)row2[11]; - character_id = Strings::ToInt(row[0]); + character_id = Strings::ToUnsignedInt(row[0]); account_id = Strings::ToInt(row2[4]); /* Convert some data from the character_ table that is still relevant */ firstlogon = Strings::ToUnsignedInt(row2[5]); diff --git a/common/events/player_events.h b/common/events/player_events.h index c87872e88..bec940473 100644 --- a/common/events/player_events.h +++ b/common/events/player_events.h @@ -384,7 +384,7 @@ namespace PlayerEvent { }; struct AAPurchasedEvent { - int32 aa_id; + uint32 aa_id; int32 aa_cost; int32 aa_previous_id; int32 aa_next_id; diff --git a/common/shareddb.cpp b/common/shareddb.cpp index 75448e1fc..a22501009 100644 --- a/common/shareddb.cpp +++ b/common/shareddb.cpp @@ -964,10 +964,10 @@ void SharedDatabase::LoadItems(void *data, uint32 size, int32 items, uint32 max_ // Flags item.ArtifactFlag = Strings::ToBool(row[ItemField::artifactflag]); - item.Attuneable = !disable_attuneable && Strings::ToInt(row[ItemField::attuneable]) != 0; - item.BenefitFlag = Strings::ToBool(row[ItemField::benefitflag]) != 0; - item.FVNoDrop = Strings::ToInt(row[ItemField::fvnodrop]) != 0; - item.Magic = Strings::ToBool(row[ItemField::magic]) != 0; + item.Attuneable = !disable_attuneable && Strings::ToBool(row[ItemField::attuneable]); + item.BenefitFlag = Strings::ToBool(row[ItemField::benefitflag]); + item.FVNoDrop = Strings::ToBool(row[ItemField::fvnodrop]); + item.Magic = Strings::ToBool(row[ItemField::magic]); item.NoDrop = disable_no_drop ? static_cast(255) : static_cast(Strings::ToUnsignedInt(row[ItemField::nodrop])); item.NoPet = !disable_no_pet && Strings::ToBool(row[ItemField::nopet]); item.NoRent = disable_no_rent ? static_cast(255) : static_cast(Strings::ToUnsignedInt(row[ItemField::norent])); diff --git a/loginserver/database.cpp b/loginserver/database.cpp index 08c5855a3..d388211af 100644 --- a/loginserver/database.cpp +++ b/loginserver/database.cpp @@ -32,7 +32,7 @@ Database::Database( user.c_str(), pass.c_str(), name.c_str(), - Strings::ToInt(port), + Strings::ToUnsignedInt(port), &errnum, errbuf ) @@ -93,7 +93,7 @@ bool Database::GetLoginDataFromAccountInfo( auto row = results.begin(); - id = Strings::ToInt(row[0]); + id = Strings::ToUnsignedInt(row[0]); password = row[1]; LogDebug( @@ -145,7 +145,7 @@ bool Database::GetLoginTokenDataFromToken( } if (strcmp(row[2], "login_server_id") == 0) { - db_account_id = Strings::ToInt(row[3]); + db_account_id = Strings::ToUnsignedInt(row[3]); found_login_id = true; continue; } @@ -373,7 +373,7 @@ Database::DbWorldRegistration Database::GetWorldRegistration( r.server_list_type = Strings::ToInt(row[3]); r.is_server_trusted = Strings::ToInt(row[2]) > 0; r.server_list_description = row[4]; - r.server_admin_id = Strings::ToInt(row[5]); + r.server_admin_id = Strings::ToUnsignedInt(row[5]); if (r.server_admin_id <= 0) { return r; @@ -513,7 +513,7 @@ bool Database::CreateWorldRegistration( auto row = results.begin(); - id = Strings::ToInt(row[0]); + id = Strings::ToUnsignedInt(row[0]); auto insert_query = fmt::format( "INSERT INTO login_world_servers SET id = {0}, long_name = '{1}', short_name = '{2}', last_ip_address = '{3}', \n" "login_server_list_type_id = 3, login_server_admin_id = {4}, is_server_trusted = 0, tag_description = ''", diff --git a/zone/aa.cpp b/zone/aa.cpp index 66b5f7b0f..f147c78ed 100644 --- a/zone/aa.cpp +++ b/zone/aa.cpp @@ -1448,9 +1448,9 @@ bool ZoneDatabase::LoadAlternateAdvancement(Client *c) { int i = 0; for(auto row = results.begin(); row != results.end(); ++row) { - uint32 aa = Strings::ToInt(row[0]); - uint32 value = Strings::ToInt(row[1]); - uint32 charges = Strings::ToInt(row[2]); + uint32 aa = Strings::ToUnsignedInt(row[0]); + uint32 value = Strings::ToUnsignedInt(row[1]); + uint32 charges = Strings::ToUnsignedInt(row[2]); auto rank = zone->GetAlternateAdvancementRank(aa); if(!rank) { @@ -1775,7 +1775,7 @@ bool ZoneDatabase::LoadAlternateAdvancementAbilities(std::unordered_mapid = Strings::ToInt(row[0]); + ability->id = Strings::ToUnsignedInt(row[0]); ability->name = row[1]; ability->category = Strings::ToInt(row[2]); //EQ client has classes left shifted by one bit for some odd reason @@ -1786,8 +1786,8 @@ bool ZoneDatabase::LoadAlternateAdvancementAbilities(std::unordered_mapstatus = Strings::ToInt(row[7]); ability->type = Strings::ToInt(row[8]); ability->charges = Strings::ToInt(row[9]); - ability->grant_only = Strings::ToInt(row[10]) != 0 ? true : false; - ability->reset_on_death = Strings::ToInt(row[11]) != 0 ? true : false; + ability->grant_only = Strings::ToBool(row[10]); + ability->reset_on_death = Strings::ToBool(row[11]); ability->first_rank_id = Strings::ToInt(row[12]); ability->first = nullptr; @@ -1814,7 +1814,7 @@ bool ZoneDatabase::LoadAlternateAdvancementAbilities(std::unordered_mapid = Strings::ToInt(row[0]); + rank->id = Strings::ToUnsignedInt(row[0]); rank->upper_hotkey_sid = Strings::ToInt(row[1]); rank->lower_hotkey_sid = Strings::ToInt(row[2]); rank->title_sid = Strings::ToInt(row[3]); @@ -1846,8 +1846,8 @@ bool ZoneDatabase::LoadAlternateAdvancementAbilities(std::unordered_mapIDFile) > 2) - ns->spawn.equipment.Primary.Material = Strings::ToInt(&item->IDFile[2]); + ns->spawn.equipment.Primary.Material = Strings::ToUnsignedInt(&item->IDFile[2]); ns->spawn.equipment_tint.Primary.Color = GetEquipmentColor(EQ::textures::weaponPrimary); @@ -3475,7 +3475,7 @@ void Bot::FillSpawnStruct(NewSpawn_Struct* ns, Mob* ForWho) { if(item) { if(strlen(item->IDFile) > 2) - ns->spawn.equipment.Secondary.Material = Strings::ToInt(&item->IDFile[2]); + ns->spawn.equipment.Secondary.Material = Strings::ToUnsignedInt(&item->IDFile[2]); ns->spawn.equipment_tint.Secondary.Color = GetEquipmentColor(EQ::textures::weaponSecondary); } diff --git a/zone/zoning.cpp b/zone/zoning.cpp index 560e35758..3a41ecb1d 100644 --- a/zone/zoning.cpp +++ b/zone/zoning.cpp @@ -1262,7 +1262,7 @@ bool Client::CanEnterZone(const std::string& zone_short_name, int16 instance_ver return false; } - if (!z->flag_needed.empty() && Strings::IsNumber(z->flag_needed) && Strings::ToInt(z->flag_needed) == 1) { + if (!z->flag_needed.empty() && Strings::IsNumber(z->flag_needed) && Strings::ToBool(z->flag_needed)) { if (Admin() < minStatusToIgnoreZoneFlags && !HasZoneFlag(z->zoneidnumber)) { LogInfo( "Character [{}] does not have the flag to be in this zone [{}]!", From b6917ec78282ec2bf5415c71a2114370e6092156 Mon Sep 17 00:00:00 2001 From: Aeadoin <109764533+Aeadoin@users.noreply.github.com> Date: Sat, 25 Mar 2023 20:48:43 -0400 Subject: [PATCH 22/22] [Release] 22.8.0 (#3148) --- CHANGELOG.md | 20 ++++++++++++++++++++ common/version.h | 2 +- package.json | 2 +- 3 files changed, 22 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 6627e5d23..f5cae613d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,23 @@ +## [22.8.0] - 03/25/2023 + +### Code + +* Cleanup Strings::ToInt uses. ([#3142](https://github.com/EQEmu/Server/pull/3142)) @Aeadoin 2023-03-26 +* Remove extern bool Critical ([#3146](https://github.com/EQEmu/Server/pull/3146)) @Kinglykrab 2023-03-25 + +### Crash + +* Fix for crash in Raid::QueuePacket ([#3145](https://github.com/EQEmu/Server/pull/3145)) @Aeadoin 2023-03-25 + +### Feature + +* Add support for -1 extradmgskill to allow all skills to be scaled. ([#3136](https://github.com/EQEmu/Server/pull/3136)) @Kinglykrab 2023-03-26 + +### Fixes + +* Fix for Items looted from corpses. ([#3147](https://github.com/EQEmu/Server/pull/3147)) @Aeadoin 2023-03-26 +* Fix for SQL Query in npc_scale_global_base ([#3144](https://github.com/EQEmu/Server/pull/3144)) @Aeadoin 2023-03-26 + ## [22.7.0] - 03/24/2023 ### Bots diff --git a/common/version.h b/common/version.h index fc36df4c5..4a679a794 100644 --- a/common/version.h +++ b/common/version.h @@ -25,7 +25,7 @@ // Build variables // these get injected during the build pipeline -#define CURRENT_VERSION "22.7.0-dev" // always append -dev to the current version for custom-builds +#define CURRENT_VERSION "22.8.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__ diff --git a/package.json b/package.json index 47da5ac06..238e6489f 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "eqemu-server", - "version": "22.7.0", + "version": "22.8.0", "repository": { "type": "git", "url": "https://github.com/EQEmu/Server.git"