diff --git a/CHANGELOG.md b/CHANGELOG.md index 70eedf0bd..355658a66 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,131 @@ +## [22.19.0] - 07/08/2023 + +### Bots + +* Add Pickpocket Command ([#3484](https://github.com/EQEmu/Server/pull/3484)) @tuday2 2023-07-08 + +### Code + +* Move #find item summon links to front ([#3483](https://github.com/EQEmu/Server/pull/3483)) @Kinglykrab 2023-07-05 +* Remove LoadItemDBFieldNames() from common/misc.cpp and common/misc.h ([#3473](https://github.com/EQEmu/Server/pull/3473)) @Kinglykrab 2023-07-04 + +### Commands + +* Add #itemsearch alias to #find aliases ([#3485](https://github.com/EQEmu/Server/pull/3485)) @Kinglykrab 2023-07-08 +* Consolidate #show commands into a singular #show command ([#3478](https://github.com/EQEmu/Server/pull/3478)) @Kinglykrab 2023-07-08 + +### Fixes + +* Fix _PutItem having a slot_id of -1 on mobs with no items ([#3474](https://github.com/EQEmu/Server/pull/3474)) @Kinglykrab 2023-07-04 + +### Rules + +* Add Skills:TrivialTradeskillCombinesNoFail Rule ([#3481](https://github.com/EQEmu/Server/pull/3481)) @JasXSL 2023-07-05 + +## [22.18.0] - 07/04/2023 + +### Commands + +* Add #emotesearch to #find command ([#3480](https://github.com/EQEmu/Server/pull/3480)) @Kinglykrab 2023-07-04 +* Cleanup #copycharacter Command ([#3479](https://github.com/EQEmu/Server/pull/3479)) @Kinglykrab 2023-07-04 + +### Fixes + +* Add chatchannel_reserved_names to a new manifest ([#3482](https://github.com/EQEmu/Server/pull/3482)) @Kinglykrab 2023-07-04 +* Fix issue in zone store of returning reference to local variable ([#3477](https://github.com/EQEmu/Server/pull/3477)) @Kinglykrab 2023-07-04 + +## [22.17.0] - 07/03/2023 + +### Cleanup/Feature + +* Add support for bots to #showstats/#mystats ([#3427](https://github.com/EQEmu/Server/pull/3427)) @Kinglykrab 2023-07-01 + +### Code + +* Remove LoadItemDBFieldNames() from common/misc.cpp and common/misc.h ([#3473](https://github.com/EQEmu/Server/pull/3473)) @Kinglykrab 2023-07-04 +* Remove handle_npc_single_npc from zone/lua_parser_events.cpp and zone/lua_parser_events.h ([#3467](https://github.com/EQEmu/Server/pull/3467)) @Kinglykrab 2023-07-03 + +### Database + +* Set multi statements off when returning early ([#3462](https://github.com/EQEmu/Server/pull/3462)) @Akkadius 2023-07-01 + +### Feature + +* Add Strings::BeginsWith() and Strings::EndsWith() ([#3471](https://github.com/EQEmu/Server/pull/3471)) @Kinglykrab 2023-07-03 + +### Fixes + +* Add check for underscores in botcreate command ([#3458](https://github.com/EQEmu/Server/pull/3458)) @tuday2 2023-06-29 +* EVENT_LANGUAGE_SKILL_UP in Lua was using EVENT_SKILL_UP logic ([#3466](https://github.com/EQEmu/Server/pull/3466)) @Kinglykrab 2023-07-03 +* Fix _PutItem having a slot_id of -1 on mobs with no items ([#3474](https://github.com/EQEmu/Server/pull/3474)) @Kinglykrab 2023-07-04 +* Fix data type of GetAggroCount() ([#3470](https://github.com/EQEmu/Server/pull/3470)) @Kinglykrab 2023-07-03 + +### Logging + +* Fix logging crash when % are sent through query logs ([#3461](https://github.com/EQEmu/Server/pull/3461)) @Akkadius 2023-07-01 + +### Quest API + +* Add ClearAccountFlag() and GetAccountFlags() to Perl/Lua ([#3469](https://github.com/EQEmu/Server/pull/3469)) @Kinglykrab 2023-07-03 +* Add GetClassAbbreviation() and GetRaceAbbreviation() to Perl/Lua ([#3463](https://github.com/EQEmu/Server/pull/3463)) @Kinglykrab 2023-07-02 +* Add GetClassPlural() and GetRacePlural() to Perl/Lua ([#3468](https://github.com/EQEmu/Server/pull/3468)) @Kinglykrab 2023-07-03 +* Add GetCloseMobList() and CalculateDistance() overload to Perl/Lua ([#3455](https://github.com/EQEmu/Server/pull/3455)) @Kinglykrab 2023-07-02 +* Add Hate Entry Methods to Perl ([#3459](https://github.com/EQEmu/Server/pull/3459)) @Kinglykrab 2023-07-02 +* Add ItemData Class to Perl ([#3465](https://github.com/EQEmu/Server/pull/3465)) @Kinglykrab 2023-07-02 +* Add Spawn2 Class to Perl ([#3456](https://github.com/EQEmu/Server/pull/3456)) @Kinglykrab 2023-07-02 +* Add StatBonuses Class to Perl ([#3460](https://github.com/EQEmu/Server/pull/3460)) @Kinglykrab 2023-07-02 +* Add missing Item Methods to Perl/Lua. ([#3464](https://github.com/EQEmu/Server/pull/3464)) @Kinglykrab 2023-07-02 + +## [22.16.0] - 06/27/2023 + +### Code + +* Default skill type to Hand to Hand in #npcedit meleetype ([#3422](https://github.com/EQEmu/Server/pull/3422)) @Kinglykrab 2023-06-19 +* Delete common/worldconn.cpp ([#3436](https://github.com/EQEmu/Server/pull/3436)) @Kinglykrab 2023-06-24 +* Remove DatabaseCastAccepted() from zone/npc.cpp and zone/npc.h ([#3449](https://github.com/EQEmu/Server/pull/3449)) @Kinglykrab 2023-06-24 +* Remove GetACAvoid() from zone/merc.h ([#3447](https://github.com/EQEmu/Server/pull/3447)) @Kinglykrab 2023-06-25 +* Remove GetACMit() from zone/merc.h ([#3446](https://github.com/EQEmu/Server/pull/3446)) @Kinglykrab 2023-06-24 +* Remove _ClearWaypints() from zone/npc.h ([#3445](https://github.com/EQEmu/Server/pull/3445)) @Kinglykrab 2023-06-24 +* Remove acmod() from zone/merc.h ([#3448](https://github.com/EQEmu/Server/pull/3448)) @Kinglykrab 2023-06-24 +* Remove command_packetprofile from zone/command.h ([#3432](https://github.com/EQEmu/Server/pull/3432)) @Kinglykrab 2023-06-24 +* Remove command_showpetspell in zone/command.h ([#3430](https://github.com/EQEmu/Server/pull/3430)) @Kinglykrab 2023-06-24 +* Remove command_unlock from zone/command.h ([#3431](https://github.com/EQEmu/Server/pull/3431)) @Kinglykrab 2023-06-24 + +### Commands + +* Add #finddeity Command ([#3435](https://github.com/EQEmu/Server/pull/3435)) @Kinglykrab 2023-06-26 +* Add #findlanguage Command ([#3434](https://github.com/EQEmu/Server/pull/3434)) @Kinglykrab 2023-06-25 +* Add #showspells Command ([#3429](https://github.com/EQEmu/Server/pull/3429)) @Kinglykrab 2023-06-24 +* Add missing subcommands to #npcedit ([#3423](https://github.com/EQEmu/Server/pull/3423)) @Kinglykrab 2023-06-19 +* Cleanup #showbuffs Command ([#3439](https://github.com/EQEmu/Server/pull/3439)) @Kinglykrab 2023-06-26 +* Cleanup #shownpcgloballoot and #showzonegloballoot Commands ([#3440](https://github.com/EQEmu/Server/pull/3440)) @Kinglykrab 2023-06-24 +* Cleanup #viewcurrencies Command ([#3441](https://github.com/EQEmu/Server/pull/3441)) @Kinglykrab 2023-06-25 +* Consolidate #findX commands to a singular #find Command ([#3452](https://github.com/EQEmu/Server/pull/3452)) @Kinglykrab 2023-06-28 +* Consolidate #merchant_close_shop and #merchant_open_shop to #merchantshop ([#3433](https://github.com/EQEmu/Server/pull/3433)) @Kinglykrab 2023-06-24 +* Delete #showbonusstats Command ([#3437](https://github.com/EQEmu/Server/pull/3437)) @Kinglykrab 2023-06-24 +* Delete #spellinfo Command ([#3438](https://github.com/EQEmu/Server/pull/3438)) @Kinglykrab 2023-06-24 + +### Database + +* Fix database version checking edge case issue ([#3428](https://github.com/EQEmu/Server/pull/3428)) @Akkadius 2023-06-22 +* Fix multi-statement error reporting ([#3425](https://github.com/EQEmu/Server/pull/3425)) @Akkadius 2023-06-19 +* Implement native database migrations in server ([#2857](https://github.com/EQEmu/Server/pull/2857)) @Akkadius 2023-06-19 + +### Fixes + +* Fix NPC Item Stat Bonuses ([#3444](https://github.com/EQEmu/Server/pull/3444)) @Kinglykrab 2023-06-26 +* Fix error in 023_01_21_bots_raid_members.sql ([#3453](https://github.com/EQEmu/Server/pull/3453)) @mibastian 2023-06-28 +* Fix possible crash with #npcedit weapon ([#3421](https://github.com/EQEmu/Server/pull/3421)) @Kinglykrab 2023-06-19 +* Merchant Open Flag set only for regular Merchants ([#3454](https://github.com/EQEmu/Server/pull/3454)) @Kinglykrab 2023-06-27 + +### Readme + +* Update new location of database updates ([#3424](https://github.com/EQEmu/Server/pull/3424)) @joligario 2023-06-19 + +### Rules + +* Add ClientPetsUserOwnerNameInLastName rule ([#3442](https://github.com/EQEmu/Server/pull/3442)) @Kinglykrab 2023-06-25 + ## [22.15.3] - 06/19/2023 ### Fixes diff --git a/common/classes.cpp b/common/classes.cpp index 693b826b1..994eb7b31 100644 --- a/common/classes.cpp +++ b/common/classes.cpp @@ -17,6 +17,7 @@ */ #include "../common/global_define.h" #include "../common/classes.h" +#include "data_verification.h" const char *GetClassIDName(uint8 class_id, uint8 level) { @@ -750,3 +751,51 @@ uint8 ClassArmorType(uint8 class_id) return ARMOR_TYPE_UNKNOWN; } } + +const std::string GetPlayerClassAbbreviation(uint8 class_id) +{ + if (!EQ::ValueWithin(class_id, WARRIOR, BERSERKER)) { + return std::string("UNK"); + } + + switch (class_id) { + case WARRIOR: + return "WAR"; + case CLERIC: + return "CLR"; + case PALADIN: + return "PAL"; + case RANGER: + return "RNG"; + case SHADOWKNIGHT: + return "SHD"; + case DRUID: + return "DRU"; + case MONK: + return "MNK"; + case BARD: + return "BRD"; + case ROGUE: + return "ROG"; + case SHAMAN: + return "SHM"; + case NECROMANCER: + return "NEC"; + case WIZARD: + return "WIZ"; + case MAGICIAN: + return "MAG"; + case ENCHANTER: + return "ENC"; + case BEASTLORD: + return "BST"; + case BERSERKER: + return "BER"; + } + + return std::string("UNK"); +} + +bool IsPlayerClass(uint8 class_id) { + return EQ::ValueWithin(class_id, WARRIOR, BERSERKER); +} diff --git a/common/classes.h b/common/classes.h index df5dedcd7..a9cc7d9fc 100644 --- a/common/classes.h +++ b/common/classes.h @@ -19,6 +19,7 @@ #define CLASSES_CH #include "../common/types.h" +#include #define NO_CLASS 0 #define WARRIOR 1 @@ -127,6 +128,9 @@ const char* GetClassIDName(uint8 class_id, uint8 level = 0); const char* GetPlayerClassName(uint32 player_class_value, uint8 level = 0); +bool IsPlayerClass(uint8 class_id); +const std::string GetPlayerClassAbbreviation(uint8 class_id); + uint32 GetPlayerClassValue(uint8 class_id); uint32 GetPlayerClassBit(uint8 class_id); diff --git a/common/database/database_update_manifest.cpp b/common/database/database_update_manifest.cpp index ea7f5c438..cbfa25af9 100644 --- a/common/database/database_update_manifest.cpp +++ b/common/database/database_update_manifest.cpp @@ -4642,11 +4642,10 @@ ADD COLUMN `avoidance` int(11) unsigned NOT NULL DEFAULT 0 AFTER `heal_scale`; .condition = "empty", .match = "", .sql = R"( -ALTER TABLE `npc_scale_global_base` -MODIFY COLUMN `hp` bigint(20) NOT NULL DEFAULT 0 AFTER `ac`, -MODIFY COLUMN `hp_regen_rate` bigint(20) NOT NULL DEFAULT 0 AFTER `max_dmg`, -ADD COLUMN `hp_regen_per_second` bigint(20) NOT NULL DEFAULT 0 AFTER `hp_regen_rate`, -ADD COLUMN `avoidance` int(11) unsigned NOT NULL DEFAULT 0 AFTER `heal_scale`; +DROP INDEX `PRIMARY` ON `raid_members`; +CREATE UNIQUE INDEX `UNIQUE` ON `raid_members`(`name`); +ALTER TABLE `raid_members` ADD COLUMN `bot_id` int(4) NOT NULL DEFAULT 0 AFTER `charid`; +ALTER TABLE `raid_members` ADD COLUMN `id` BIGINT UNSIGNED NOT NULL PRIMARY KEY AUTO_INCREMENT FIRST; )" }, @@ -4745,6 +4744,22 @@ ADD COLUMN `id` int(11) NOT NULL AUTO_INCREMENT FIRST, ADD PRIMARY KEY (`id`); )", }, + ManifestEntry{ + .version = 9229, + .description = "2023_07_04_chatchannel_reserved_names_fix.sql", + .check = "SHOW TABLES LIKE 'chatchannel_reserved_names'", + .condition = "empty", + .match = "", + .sql = R"( +CREATE TABLE `chatchannel_reserved_names` +( +`id` int(11) NOT NULL AUTO_INCREMENT, +`name` varchar(64) NOT NULL, +PRIMARY KEY (`id`) USING BTREE, +UNIQUE KEY `name` (`name`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4; +)" + }, // -- template; copy/paste this when you need to create a new entry // ManifestEntry{ diff --git a/common/dbcore.cpp b/common/dbcore.cpp index 1db87afac..410362dfa 100644 --- a/common/dbcore.cpp +++ b/common/dbcore.cpp @@ -365,6 +365,8 @@ MySQLRequestResult DBcore::QueryDatabaseMulti(const std::string &query) mysql_free_result(res); } + SetMultiStatementsOff(); + return r; } } @@ -418,6 +420,8 @@ MySQLRequestResult DBcore::QueryDatabaseMulti(const std::string &query) r.SetErrorMessage(error_message); r.SetErrorNumber(mysql_errno(mysql)); + SetMultiStatementsOff(); + // we handle errors elsewhere return r; } diff --git a/common/deity.cpp b/common/deity.cpp index 0923c43d0..bbaf0b4e0 100644 --- a/common/deity.cpp +++ b/common/deity.cpp @@ -11,7 +11,7 @@ are required to give you total support for your newly bought product; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. - + You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA @@ -19,131 +19,81 @@ #include "deity.h" - -EQ::deity::DeityTypeBit EQ::deity::ConvertDeityTypeToDeityTypeBit(DeityType deity_type) +EQ::deity::DeityTypeBit EQ::deity::GetDeityBitmask(DeityType deity_type) { switch (deity_type) { - case DeityBertoxxulous: - return bit_DeityBertoxxulous; - case DeityBrellSirilis: - return bit_DeityBrellSirilis; - case DeityCazicThule: - return bit_DeityCazicThule; - case DeityErollisiMarr: - return bit_DeityErollisiMarr; - case DeityBristlebane: - return bit_DeityBristlebane; - case DeityInnoruuk: - return bit_DeityInnoruuk; - case DeityKarana: - return bit_DeityKarana; - case DeityMithanielMarr: - return bit_DeityMithanielMarr; - case DeityPrexus: - return bit_DeityPrexus; - case DeityQuellious: - return bit_DeityQuellious; - case DeityRallosZek: - return bit_DeityRallosZek; - case DeityRodcetNife: - return bit_DeityRodcetNife; - case DeitySolusekRo: - return bit_DeitySolusekRo; - case DeityTheTribunal: - return bit_DeityTheTribunal; - case DeityTunare: - return bit_DeityTunare; - case DeityVeeshan: - return bit_DeityVeeshan; - case DeityAgnostic_LB: - case DeityAgnostic: - return bit_DeityAgnostic; - default: - return bit_DeityAll; - }; + case DeityBertoxxulous: + return bit_DeityBertoxxulous; + case DeityBrellSirilis: + return bit_DeityBrellSirilis; + case DeityCazicThule: + return bit_DeityCazicThule; + case DeityErollisiMarr: + return bit_DeityErollisiMarr; + case DeityBristlebane: + return bit_DeityBristlebane; + case DeityInnoruuk: + return bit_DeityInnoruuk; + case DeityKarana: + return bit_DeityKarana; + case DeityMithanielMarr: + return bit_DeityMithanielMarr; + case DeityPrexus: + return bit_DeityPrexus; + case DeityQuellious: + return bit_DeityQuellious; + case DeityRallosZek: + return bit_DeityRallosZek; + case DeityRodcetNife: + return bit_DeityRodcetNife; + case DeitySolusekRo: + return bit_DeitySolusekRo; + case DeityTheTribunal: + return bit_DeityTheTribunal; + case DeityTunare: + return bit_DeityTunare; + case DeityVeeshan: + return bit_DeityVeeshan; + case DeityAgnostic_LB: + case DeityAgnostic: + return bit_DeityAgnostic; + default: + return bit_DeityAll; + } } -EQ::deity::DeityType EQ::deity::ConvertDeityTypeBitToDeityType(DeityTypeBit deity_type_bit) +const std::map& EQ::deity::GetDeityMap() { - switch (deity_type_bit) { - case bit_DeityAgnostic: - return DeityAgnostic; - case bit_DeityBertoxxulous: - return DeityBertoxxulous; - case bit_DeityBrellSirilis: - return DeityBrellSirilis; - case bit_DeityCazicThule: - return DeityCazicThule; - case bit_DeityErollisiMarr: - return DeityErollisiMarr; - case bit_DeityBristlebane: - return DeityBristlebane; - case bit_DeityInnoruuk: - return DeityInnoruuk; - case bit_DeityKarana: - return DeityKarana; - case bit_DeityMithanielMarr: - return DeityMithanielMarr; - case bit_DeityPrexus: - return DeityPrexus; - case bit_DeityQuellious: - return DeityQuellious; - case bit_DeityRallosZek: - return DeityRallosZek; - case bit_DeityRodcetNife: - return DeityRodcetNife; - case bit_DeitySolusekRo: - return DeitySolusekRo; - case bit_DeityTheTribunal: - return DeityTheTribunal; - case bit_DeityTunare: - return DeityTunare; - case bit_DeityVeeshan: - return DeityVeeshan; - default: - return DeityUnknown; + static const std::map deity_map = { + { DeityAgnostic, "Agnostic" }, + { DeityAgnostic_LB, "Agnostic" }, + { DeityBertoxxulous, "Bertoxxulous" }, + { DeityBrellSirilis, "Brell Serilis" }, + { DeityBristlebane, "Bristlebane" }, + { DeityCazicThule, "Cazic-Thule" }, + { DeityErollisiMarr, "Erollisi Marr" }, + { DeityInnoruuk, "Innoruuk" }, + { DeityKarana, "Karana" }, + { DeityMithanielMarr, "Mithaniel Marr" }, + { DeityPrexus, "Prexus" }, + { DeityQuellious, "Quellious" }, + { DeityRallosZek, "Rallos Zek" }, + { DeityRodcetNife, "Rodcet Nife" }, + { DeitySolusekRo, "Solusek Ro" }, + { DeityTheTribunal, "The Tribunal" }, + { DeityTunare, "Tunare" }, + { DeityVeeshan, "Veeshan" } }; + + return deity_map; } -const char* EQ::deity::DeityName(DeityType deity_type) +std::string EQ::deity::GetDeityName(DeityType deity_type) { - switch (deity_type) { - case DeityBertoxxulous: - return "Bertoxxulous"; - case DeityBrellSirilis: - return "Brell Serilis"; - case DeityCazicThule: - return "Cazic-Thule"; - case DeityErollisiMarr: - return "Erollisi Marr"; - case DeityBristlebane: - return "Bristlebane"; - case DeityInnoruuk: - return "Innoruuk"; - case DeityKarana: - return "Karana"; - case DeityMithanielMarr: - return "Mithaniel Marr"; - case DeityPrexus: - return "Prexus"; - case DeityQuellious: - return "Quellious"; - case DeityRallosZek: - return "Rallos Zek"; - case DeityRodcetNife: - return "Rodcet Nife"; - case DeitySolusekRo: - return "Solusek Ro"; - case DeityTheTribunal: - return "The Tribunal"; - case DeityTunare: - return "Tunare"; - case DeityVeeshan: - return "Veeshan"; - case DeityAgnostic_LB: - case DeityAgnostic: - return "Agnostic"; - default: - return "Unknown"; - }; + + if (EQ::deity::GetDeityMap().find(deity_type) != EQ::deity::GetDeityMap().end()) { + return EQ::deity::GetDeityMap().find(deity_type)->second; + } + + return std::string(); } diff --git a/common/deity.h b/common/deity.h index 8d0fe4c7a..43542bb7d 100644 --- a/common/deity.h +++ b/common/deity.h @@ -21,6 +21,8 @@ #define COMMON_DEITY_H #include "types.h" +#include +#include namespace EQ @@ -49,30 +51,29 @@ namespace EQ }; enum DeityTypeBit : uint32 { - bit_DeityNone = 0x00000000, - bit_DeityAgnostic = 0x00000001, - bit_DeityBertoxxulous = 0x00000002, - bit_DeityBrellSirilis = 0x00000004, - bit_DeityCazicThule = 0x00000008, - bit_DeityErollisiMarr = 0x00000010, - bit_DeityBristlebane = 0x00000020, - bit_DeityInnoruuk = 0x00000040, - bit_DeityKarana = 0x00000080, + bit_DeityAgnostic = 0x00000001, + bit_DeityBertoxxulous = 0x00000002, + bit_DeityBrellSirilis = 0x00000004, + bit_DeityCazicThule = 0x00000008, + bit_DeityErollisiMarr = 0x00000010, + bit_DeityBristlebane = 0x00000020, + bit_DeityInnoruuk = 0x00000040, + bit_DeityKarana = 0x00000080, bit_DeityMithanielMarr = 0x00000100, - bit_DeityPrexus = 0x00000200, - bit_DeityQuellious = 0x00000400, - bit_DeityRallosZek = 0x00000800, - bit_DeityRodcetNife = 0x00001000, - bit_DeitySolusekRo = 0x00002000, - bit_DeityTheTribunal = 0x00004000, - bit_DeityTunare = 0x00008000, - bit_DeityVeeshan = 0x00010000, - bit_DeityAll = 0xFFFFFFFF + bit_DeityPrexus = 0x00000200, + bit_DeityQuellious = 0x00000400, + bit_DeityRallosZek = 0x00000800, + bit_DeityRodcetNife = 0x00001000, + bit_DeitySolusekRo = 0x00002000, + bit_DeityTheTribunal = 0x00004000, + bit_DeityTunare = 0x00008000, + bit_DeityVeeshan = 0x00010000, + bit_DeityAll = UINT32_MAX }; - extern DeityTypeBit ConvertDeityTypeToDeityTypeBit(DeityType deity_type); - extern DeityType ConvertDeityTypeBitToDeityType(DeityTypeBit deity_type_bit); - extern const char* DeityName(DeityType deity_type); + extern DeityTypeBit GetDeityBitmask(DeityType deity_type); + extern std::string GetDeityName(DeityType deity_type); + extern const std::map& GetDeityMap(); } /*deity*/ diff --git a/common/eqemu_logsys.cpp b/common/eqemu_logsys.cpp index e131932ca..df6508daf 100644 --- a/common/eqemu_logsys.cpp +++ b/common/eqemu_logsys.cpp @@ -446,6 +446,8 @@ void EQEmuLogSys::Out( // remove this when we remove all legacy logs bool ignore_log_legacy_format = ( log_category == Logs::Netcode || + log_category == Logs::MySQLQuery || + log_category == Logs::MySQLError || log_category == Logs::PacketServerClient || log_category == Logs::PacketClientServer || log_category == Logs::PacketServerToServer diff --git a/common/inventory_profile.cpp b/common/inventory_profile.cpp index f9c173a66..915976c9a 100644 --- a/common/inventory_profile.cpp +++ b/common/inventory_profile.cpp @@ -353,7 +353,7 @@ bool EQ::InventoryProfile::SwapItem( fail_state = swapRaceClass; return false; } - if (deity_id && source_item->Deity && !(deity::ConvertDeityTypeToDeityTypeBit((deity::DeityType)deity_id) & source_item->Deity)) { + if (deity_id && source_item->Deity && !(deity::GetDeityBitmask((deity::DeityType)deity_id) & source_item->Deity)) { fail_state = swapDeity; return false; } @@ -379,7 +379,7 @@ bool EQ::InventoryProfile::SwapItem( fail_state = swapRaceClass; return false; } - if (deity_id && destination_item->Deity && !(deity::ConvertDeityTypeToDeityTypeBit((deity::DeityType)deity_id) & destination_item->Deity)) { + if (deity_id && destination_item->Deity && !(deity::GetDeityBitmask((deity::DeityType)deity_id) & destination_item->Deity)) { fail_state = swapDeity; return false; } @@ -1444,7 +1444,7 @@ int16 EQ::InventoryProfile::_PutItem(int16 slot_id, ItemInstance* inst) } if (result == INVALID_INDEX) { - LogError("InventoryProfile::_PutItem: Invalid slot_id specified ({}) with parent slot id ({})", slot_id, parentSlot); + LogError("Invalid slot_id specified ({}) with parent slot id ({})", slot_id, parentSlot); InventoryProfile::MarkDirty(inst); // Slot not found, clean up } diff --git a/common/languages.h b/common/languages.h index a14e78460..4cc17b80a 100644 --- a/common/languages.h +++ b/common/languages.h @@ -48,5 +48,7 @@ #define LANG_HADAL 26 #define LANG_UNKNOWN 27 +#define MAX_LANGUAGE_SKILL 100 + #endif diff --git a/common/misc.cpp b/common/misc.cpp index f9c096acb..4c5103fa3 100644 --- a/common/misc.cpp +++ b/common/misc.cpp @@ -214,123 +214,6 @@ std::string x; return i; } -void LoadItemDBFieldNames() { - DBFieldNames[0]="N/A"; // Charges - DBFieldNames[1]="unknown002"; // ? - DBFieldNames[2]="N/A"; // Current Equip Slot - DBFieldNames[3]="unknown004"; - DBFieldNames[4]="unknown005"; // ? - DBFieldNames[5]="itemclass"; // "Item Type (0=common, 1=container, 2=book)" - DBFieldNames[6]="name"; // Name - DBFieldNames[7]="lore"; // "Lore Name (*=lore, &=summoned, #=artifact)" - DBFieldNames[8]="idfile"; // IDFile - DBFieldNames[9]="id"; // ItemNumber - DBFieldNames[10]="weight"; // Weight - DBFieldNames[11]="norent"; // "NoRent (0=norent, 255=not norent)" - DBFieldNames[12]="nodrop"; // "NoDrop (0=nodrop, 255=not nodrop)" - DBFieldNames[13]="size"; // "Size (0=tiny, 1=small, 2=medium, 3=large, 4=giant)" - DBFieldNames[14]="slots"; // EquipSlots - DBFieldNames[15]="cost"; // Cost - DBFieldNames[16]="icon"; // IconNumber - DBFieldNames[17]="unknown018"; - DBFieldNames[18]="unknown019"; - DBFieldNames[19]="unknown020"; // ? - DBFieldNames[20]="tradeskills"; // "Tradeskill Item (1=is a tradeskill item, 0=not)" - DBFieldNames[21]="cr"; // SvCold - DBFieldNames[22]="dr"; // SvDisease - DBFieldNames[23]="pr"; // SvPoison - DBFieldNames[24]="mr"; // SvMagic - DBFieldNames[25]="fr"; // SvFire - DBFieldNames[26]="astr"; // STR - DBFieldNames[27]="asta"; // STA - DBFieldNames[28]="aagi"; // AGI - DBFieldNames[29]="adex"; // DEX - DBFieldNames[30]="acha"; // CHA - DBFieldNames[31]="aint"; // INT - DBFieldNames[32]="awis"; // WIS - DBFieldNames[33]="hp"; // HP - DBFieldNames[34]="mana"; // Mana - DBFieldNames[35]="ac"; // AC - DBFieldNames[36]="deity"; // Deity - DBFieldNames[37]="skillmodvalue"; // Skill Mod Value - DBFieldNames[38]="skillmodtype"; // Skill Mod Type - DBFieldNames[39]="banedmgrace"; // Bane Dmg Race - DBFieldNames[40]="banedmgamt"; // Band Dmg - DBFieldNames[41]="banedmgbody"; // Band Dmg Body - DBFieldNames[42]="magic"; // "Magic (0=not magic, 1=magic)" - DBFieldNames[43]="casttime2"; // Casttime appears twice - DBFieldNames[44]="hasteproclvl"; // "Level (Haste value, rather)" - DBFieldNames[45]="reqlevel"; // Required Level - DBFieldNames[46]="bardtype"; // Bard Type - DBFieldNames[47]="bardvalue"; // Bard Type Amount - DBFieldNames[48]="light"; // Light - DBFieldNames[49]="delay"; // Attack Delay - DBFieldNames[50]="reclevel"; // Recommended Level - DBFieldNames[51]="recskill"; // Recommended Skill - DBFieldNames[52]="elemdmgamt"; // "Elemental Dmg Type (1=magic, 2=fire, 3=cold, 4=poison, 5=disease)" - DBFieldNames[53]="elemdmgtype"; // Elemental Dmg - DBFieldNames[54]="effecttype"; // "Effect Type (0=combat, 1=clicky, 2=Worn, 3=Expendable charges, 4=Must Equip Clicky, 5=clicky)" - DBFieldNames[55]="range"; // Range - DBFieldNames[56]="damage"; // Damage - DBFieldNames[57]="color"; // Color - DBFieldNames[58]="classes"; // Classes - DBFieldNames[59]="races"; // Races - DBFieldNames[60]="unknown061"; - DBFieldNames[61]="spellid"; // SpellId - DBFieldNames[62]="maxcharges"; // MaxCharges - DBFieldNames[63]="itemtype"; // "Skill (ItemType: 1hs, etc)" - DBFieldNames[64]="material"; // Material - DBFieldNames[65]="sellrate"; // ** Sell Rate - DBFieldNames[66]="unknown067"; - DBFieldNames[67]="casttime"; // CastTime (milliseconds) - DBFieldNames[68]="unknown069"; - DBFieldNames[69]="unknown070"; // ? - DBFieldNames[70]="focusid"; // Focus Effect Spell Id - DBFieldNames[71]="combateffects"; // CombatEffects - DBFieldNames[72]="shielding"; // Shielding - DBFieldNames[73]="stunresist"; // StunResist - DBFieldNames[74]="strikethrough"; // StrikeThrough - DBFieldNames[75]="unknown076"; - DBFieldNames[76]="unknown077"; // ? - DBFieldNames[77]="spellshield"; // Spell Shield - DBFieldNames[78]="avoidance"; // Avoidance - DBFieldNames[79]="accuracy"; // Accuracy - DBFieldNames[80]="factionmod1"; // Faction Mod Index 1 - DBFieldNames[81]="factionmod2"; // Faction Mod Index 2 - DBFieldNames[82]="factionmod3"; // Faction Mod Index 3 - DBFieldNames[83]="factionmod4"; // Faction Mod Index 4 - DBFieldNames[84]="factionamt1"; // Faction Mod Value 1 - DBFieldNames[85]="factionamt2"; // Faction Mod Value 2 - DBFieldNames[86]="factionamt3"; // Faction Mod Value 3 - DBFieldNames[87]="factionamt4"; // Faction Mod Value 4 - DBFieldNames[88]="unknown089"; - DBFieldNames[89]="charmfile"; // ** Charm File - DBFieldNames[90]="unknown091"; - DBFieldNames[91]="augslot1type"; // Slot1Type - DBFieldNames[92]="augslot2type"; // Slot2Type - DBFieldNames[93]="augslot3type"; // Slot3Type - DBFieldNames[94]="augslot4type"; // Slot4Type - DBFieldNames[95]="augslot5type"; // Slot5Type - DBFieldNames[96]="ldonpointtheme"; - DBFieldNames[97]="ldonpointcost"; // ? - DBFieldNames[98]="unknown099"; - DBFieldNames[99]="bagtype"; // bag type - DBFieldNames[100]="bagslots"; // bag slots - DBFieldNames[101]="bagsize"; // bag size capacity - DBFieldNames[102]="bagwr"; // bag weight reduction - DBFieldNames[103]="booktype"; // "book type (0=rolled up note, 1=book)" - DBFieldNames[104]="unknown105"; - DBFieldNames[105]="filename"; // Book Filename - DBFieldNames[106]="unknown107"; - DBFieldNames[107]="unknown108"; - DBFieldNames[108]="loreflag"; - DBFieldNames[109]="unknown111"; - DBFieldNames[110]="unknown112"; - DBFieldNames[111]="unknown113"; - DBFieldNames[112]="unknown114"; - DBFieldNames[113]="unknown115"; // ? (end quote) -} - void dump_message_column(unsigned char *buffer, unsigned long length, std::string leader, FILE *to) { unsigned long i,j; diff --git a/common/misc.h b/common/misc.h index a099ab823..bb1c3550d 100644 --- a/common/misc.h +++ b/common/misc.h @@ -15,8 +15,6 @@ bool ItemParse(const char *data, int length, std::map & tokens, char delim='|'); -void LoadItemDBFieldNames(); - #ifndef WIN32 int print_stacktrace(); #endif diff --git a/common/races.cpp b/common/races.cpp index bb7cce9c0..780206812 100644 --- a/common/races.cpp +++ b/common/races.cpp @@ -17,6 +17,7 @@ */ #include "../common/races.h" +#include "data_verification.h" const char* GetRaceIDName(uint16 race_id) { @@ -67,7 +68,7 @@ const char* GetRaceIDName(uint16 race_id) // return "Froglok"; //case DRAKKIN: // return "Drakkin"; - + // RoF2 Race Labels case RT_ABHORRENT: return "Abhorrent"; @@ -1696,7 +1697,7 @@ bool PlayerAppearance::IsValidBeardColor(uint16 race_id, uint8 gender_id, uint8 { if (beard_color_value == 0xFF) return true; - + switch (BINDRG(race_id, gender_id)) { case GNOME_MALE: if (beard_color_value <= 24) @@ -1783,7 +1784,7 @@ bool PlayerAppearance::IsValidEyeColor(uint16 race_id, uint8 gender_id, uint8 ey case VAHSHIR_FEMALE: if (eye_color_value <= 9) return true; - break; + break; case TROLL_MALE: case TROLL_FEMALE: if (eye_color_value <= 10) @@ -2109,7 +2110,7 @@ bool PlayerAppearance::IsValidTexture(uint16 race_id, uint8 gender_id, uint8 tex { if (texture_value == 0xFF) return true; - + if (use_luclin) { switch (BINDRG(race_id, gender_id)) { case HUMAN_MALE: @@ -2243,4 +2244,58 @@ const char* GetGenderName(uint32 gender_id) { gender_name = "Neuter"; } return gender_name; -} \ No newline at end of file +} + +const std::string GetPlayerRaceAbbreviation(uint16 race_id) +{ + if (!IsPlayerRace(race_id)) { + return std::string("UNK"); + } + + switch (race_id) { + case RACE_HUMAN_1: + return "HUM"; + case RACE_BARBARIAN_2: + return "BAR"; + case RACE_ERUDITE_3: + return "ERU"; + case RACE_WOOD_ELF_4: + return "ELF"; + case RACE_HIGH_ELF_5: + return "HIE"; + case RACE_DARK_ELF_6: + return "DEF"; + case RACE_HALF_ELF_7: + return "HEF"; + case RACE_DWARF_8: + return "DWF"; + case RACE_TROLL_9: + return "TRL"; + case RACE_OGRE_10: + return "OGR"; + case RACE_HALFLING_11: + return "HFL"; + case RACE_GNOME_12: + return "GNM"; + case RACE_IKSAR_128: + return "IKS"; + case RACE_VAH_SHIR_130: + return "VAH"; + case RACE_FROGLOK_330: + return "FRG"; + case RACE_DRAKKIN_522: + return "DRK"; + } + + return std::string("UNK"); +} + +bool IsPlayerRace(uint16 race_id) { + return ( + EQ::ValueWithin(race_id, RACE_HUMAN_1, RACE_GNOME_12) || + race_id == RACE_IKSAR_128 || + race_id == RACE_VAH_SHIR_130 || + race_id == RACE_FROGLOK_330 || + race_id == RACE_DRAKKIN_522 + ); +} diff --git a/common/races.h b/common/races.h index 3373c8353..3ec25e4f9 100644 --- a/common/races.h +++ b/common/races.h @@ -19,6 +19,7 @@ #ifndef RACES_H #define RACES_H #include "../common/types.h" +#include #define MALE 0 #define FEMALE 1 @@ -853,6 +854,9 @@ const char* GetRaceIDName(uint16 race_id); const char* GetPlayerRaceName(uint32 player_race_value); const char* GetGenderName(uint32 gender_id); +bool IsPlayerRace(uint16 race_id); +const std::string GetPlayerRaceAbbreviation(uint16 race_id); + uint32 GetPlayerRaceValue(uint16 race_id); uint32 GetPlayerRaceBit(uint16 race_id); diff --git a/common/repositories/account_flags_repository.h b/common/repositories/account_flags_repository.h index e1ebb32f4..b9ebea21d 100644 --- a/common/repositories/account_flags_repository.h +++ b/common/repositories/account_flags_repository.h @@ -44,7 +44,35 @@ public: */ // Custom extended repository methods here + static void ClearFlag( + Database& db, + AccountFlagsRepository::AccountFlags e + ) { + AccountFlagsRepository::DeleteWhere( + database, + fmt::format( + "p_accid = {} AND p_flag = '{}'", + e.p_accid, + Strings::Escape(e.p_flag) + ) + ); + } + static void ReplaceFlag( + Database& db, + AccountFlagsRepository::AccountFlags e + ) { + db.QueryDatabase( + fmt::format( + "REPLACE INTO {} ({}) VALUES ({}, '{}', '{}')", + TableName(), + ColumnsRaw(), + e.p_accid, + Strings::Escape(e.p_flag), + Strings::Escape(e.p_value) + ) + ); + } }; #endif //EQEMU_ACCOUNT_FLAGS_REPOSITORY_H diff --git a/common/repositories/base/base_items_repository.h b/common/repositories/base/base_items_repository.h index ef908262e..06d91ade0 100644 --- a/common/repositories/base/base_items_repository.h +++ b/common/repositories/base/base_items_repository.h @@ -16,6 +16,7 @@ #include "../../strings.h" #include + class BaseItemsRepository { public: struct Items { @@ -122,7 +123,7 @@ public: int32_t pr; int32_t procrate; int32_t races; - int32_t range; + int32_t range_; int32_t reclevel; int32_t recskill; int32_t reqlevel; @@ -417,7 +418,7 @@ public: "pr", "procrate", "races", - "range", + "`range`", "reclevel", "recskill", "reqlevel", @@ -708,7 +709,7 @@ public: "pr", "procrate", "races", - "range", + "`range`", "reclevel", "recskill", "reqlevel", @@ -1033,7 +1034,7 @@ public: e.pr = 0; e.procrate = 0; e.races = 0; - e.range = 0; + e.range_ = 0; e.reclevel = 0; e.recskill = 0; e.reqlevel = 0; @@ -1240,8 +1241,9 @@ public: { auto results = db.QueryDatabase( fmt::format( - "{} WHERE id = {} LIMIT 1", + "{} WHERE {} = {} LIMIT 1", BaseSelect(), + PrimaryKey(), items_id ) ); @@ -1353,7 +1355,7 @@ public: e.pr = static_cast(atoi(row[100])); e.procrate = static_cast(atoi(row[101])); e.races = static_cast(atoi(row[102])); - e.range = static_cast(atoi(row[103])); + e.range_ = static_cast(atoi(row[103])); e.reclevel = static_cast(atoi(row[104])); e.recskill = static_cast(atoi(row[105])); e.reqlevel = static_cast(atoi(row[106])); @@ -1671,7 +1673,7 @@ public: v.push_back(columns[100] + " = " + std::to_string(e.pr)); v.push_back(columns[101] + " = " + std::to_string(e.procrate)); v.push_back(columns[102] + " = " + std::to_string(e.races)); - v.push_back(columns[103] + " = " + std::to_string(e.range)); + v.push_back(columns[103] + " = " + std::to_string(e.range_)); v.push_back(columns[104] + " = " + std::to_string(e.reclevel)); v.push_back(columns[105] + " = " + std::to_string(e.recskill)); v.push_back(columns[106] + " = " + std::to_string(e.reqlevel)); @@ -1977,7 +1979,7 @@ public: v.push_back(std::to_string(e.pr)); v.push_back(std::to_string(e.procrate)); v.push_back(std::to_string(e.races)); - v.push_back(std::to_string(e.range)); + v.push_back(std::to_string(e.range_)); v.push_back(std::to_string(e.reclevel)); v.push_back(std::to_string(e.recskill)); v.push_back(std::to_string(e.reqlevel)); @@ -2291,7 +2293,7 @@ public: v.push_back(std::to_string(e.pr)); v.push_back(std::to_string(e.procrate)); v.push_back(std::to_string(e.races)); - v.push_back(std::to_string(e.range)); + v.push_back(std::to_string(e.range_)); v.push_back(std::to_string(e.reclevel)); v.push_back(std::to_string(e.recskill)); v.push_back(std::to_string(e.reqlevel)); @@ -2609,7 +2611,7 @@ public: e.pr = static_cast(atoi(row[100])); e.procrate = static_cast(atoi(row[101])); e.races = static_cast(atoi(row[102])); - e.range = static_cast(atoi(row[103])); + e.range_ = static_cast(atoi(row[103])); e.reclevel = static_cast(atoi(row[104])); e.recskill = static_cast(atoi(row[105])); e.reqlevel = static_cast(atoi(row[106])); @@ -2918,7 +2920,7 @@ public: e.pr = static_cast(atoi(row[100])); e.procrate = static_cast(atoi(row[101])); e.races = static_cast(atoi(row[102])); - e.range = static_cast(atoi(row[103])); + e.range_ = static_cast(atoi(row[103])); e.reclevel = static_cast(atoi(row[104])); e.recskill = static_cast(atoi(row[105])); e.reqlevel = static_cast(atoi(row[106])); diff --git a/common/repositories/items_repository.h b/common/repositories/items_repository.h index aac7d3697..d2c2cbc3a 100644 --- a/common/repositories/items_repository.h +++ b/common/repositories/items_repository.h @@ -44,7 +44,35 @@ public: */ // Custom extended repository methods here + static std::vector GetItemIDsBySearchCriteria( + Database& db, + std::string search_string, + int query_limit = 0 + ) + { + auto query = fmt::format( + "SELECT `id` FROM {} WHERE LOWER(`name`) LIKE '%%{}%%' ORDER BY id ASC", + TableName(), + search_string + ); + if (query_limit >= 1) { + query += fmt::format(" LIMIT {}", query_limit); + } + + std::vector item_id_list; + + auto results = db.QueryDatabase(query); + if (!results.Success() || !results.RowCount()) { + return item_id_list; + } + + for (auto row : results) { + item_id_list.emplace_back(Strings::ToInt(row[0])); + } + + return item_id_list; + } }; #endif //EQEMU_ITEMS_REPOSITORY_H diff --git a/common/ruletypes.h b/common/ruletypes.h index 53f65b4c4..3135b892a 100644 --- a/common/ruletypes.h +++ b/common/ruletypes.h @@ -241,6 +241,7 @@ RULE_CATEGORY_END() RULE_CATEGORY(Skills) RULE_INT(Skills, MaxTrainTradeskills, 21, "Highest level for trading skills that can be learnt by the trainer") RULE_BOOL(Skills, UseLimitTradeskillSearchSkillDiff, true, "Enables the limit for the maximum difference between trivial and skill for recipe searches and favorites") +RULE_BOOL(Skills, TrivialTradeskillCombinesNoFail, false, "Enable to make all trivial tradeskill combines unable to fail") RULE_INT(Skills, MaxTradeskillSearchSkillDiff, 50, "The maximum difference in skill between the trivial of an item and the skill of the player if the trivial is higher than the skill. Recipes that have not been learnt or made at least once via the Experiment mode will be removed from searches based on this criteria.") RULE_INT(Skills, MaxTrainSpecializations, 50, "Maximum level a GM trainer will train casting specializations") RULE_INT(Skills, SwimmingStartValue, 100, "Start value of swimming skill") @@ -256,6 +257,7 @@ RULE_BOOL(Pets, UnTargetableSwarmPet, false, "Setting whether swarm pets should RULE_REAL(Pets, PetPowerLevelCap, 10, "Maximum number of levels a player pet can go up with pet power") RULE_BOOL(Pets, CanTakeNoDrop, false, "Setting whether anyone can give no-drop items to pets") RULE_BOOL(Pets, LivelikeBreakCharmOnInvis, true, "Default: true will break charm on any type of invis (hide/ivu/iva/etc) false will only break if the pet can not see you (ex. you have an undead pet and cast IVU") +RULE_BOOL(Pets, ClientPetsUseOwnerNameInLastName, true, "Disable this to keep client pet's last names from being owner_name's pet") RULE_CATEGORY_END() RULE_CATEGORY(GM) diff --git a/common/servertalk.h b/common/servertalk.h index 7f14a1f6c..f9740752f 100644 --- a/common/servertalk.h +++ b/common/servertalk.h @@ -1824,6 +1824,11 @@ struct ServerOOCMute_Struct { bool is_muted; }; +struct ServerZoneStatus_Struct { + char name[64]; + int16 admin; +}; + #pragma pack() #endif diff --git a/common/strings.cpp b/common/strings.cpp index 4ecb178ec..b4cf5d011 100644 --- a/common/strings.cpp +++ b/common/strings.cpp @@ -695,8 +695,31 @@ std::string Strings::ConvertToDigit(int n, const std::string& suffix) return NUM_TO_ENGLISH_X[n] + suffix; } } + +bool Strings::BeginsWith(const std::string& subject, const std::string& search) +{ + if (subject.length() < search.length()) { + return false; + } + + return subject.starts_with(search); +} + +bool Strings::EndsWith(const std::string& subject, const std::string& search) +{ + if (subject.length() < search.length()) { + return false; + } + + return subject.ends_with(search); +} + bool Strings::Contains(const std::string& subject, const std::string& search) { + if (subject.length() < search.length()) { + return false; + } + return subject.find(search) != std::string::npos; } diff --git a/common/strings.h b/common/strings.h index 3cf30cb31..0ef35f93f 100644 --- a/common/strings.h +++ b/common/strings.h @@ -128,6 +128,8 @@ public: 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); + static bool BeginsWith(const std::string& subject, const std::string& search); + static bool EndsWith(const std::string& subject, const std::string& search); template static std::string diff --git a/common/version.h b/common/version.h index 50d9af96c..2e19f9c55 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.15.3-dev" // always append -dev to the current version for custom-builds +#define CURRENT_VERSION "22.19.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__ @@ -42,7 +42,7 @@ * Manifest: https://github.com/EQEmu/Server/blob/master/utils/sql/db_update_manifest.txt */ -#define CURRENT_BINARY_DATABASE_VERSION 9228 +#define CURRENT_BINARY_DATABASE_VERSION 9229 #define CURRENT_BINARY_BOTS_DATABASE_VERSION 9039 diff --git a/common/zone_store.cpp b/common/zone_store.cpp index 3e0e3ba18..7bcb2cb6f 100644 --- a/common/zone_store.cpp +++ b/common/zone_store.cpp @@ -370,7 +370,7 @@ uint32 ZoneStore::GetZoneRuleSet(uint32 zone_id, int version) return 0; } -const std::string& ZoneStore::GetZoneNote(uint32 zone_id, int version) +const std::string ZoneStore::GetZoneNote(uint32 zone_id, int version) { for (auto &z: m_zones) { if (z.zoneidnumber == zone_id && z.version == version) { @@ -384,8 +384,7 @@ const std::string& ZoneStore::GetZoneNote(uint32 zone_id, int version) } } - const auto& note = std::string(); - return note; + return ""; } float ZoneStore::GetZoneUnderworld(uint32 zone_id, int version) @@ -736,7 +735,7 @@ float ZoneStore::GetZoneFogDensity(uint32 zone_id, int version) return 0.0f; } -const std::string& ZoneStore::GetZoneFlagNeeded(uint32 zone_id, int version) +const std::string ZoneStore::GetZoneFlagNeeded(uint32 zone_id, int version) { for (auto &z: m_zones) { if (z.zoneidnumber == zone_id && z.version == version) { @@ -750,8 +749,7 @@ const std::string& ZoneStore::GetZoneFlagNeeded(uint32 zone_id, int version) } } - const auto& flag_needed = std::string(); - return flag_needed; + return ""; } int8 ZoneStore::GetZoneCanBind(uint32 zone_id, int version) @@ -1259,7 +1257,7 @@ int8 ZoneStore::GetZoneMaximumExpansion(uint32 zone_id, int version) return DEFAULT_ZONE_MIN_MAX_EXPANSION; } -const std::string& ZoneStore::GetZoneContentFlags(uint32 zone_id, int version) +const std::string ZoneStore::GetZoneContentFlags(uint32 zone_id, int version) { for (auto &z: m_zones) { if (z.zoneidnumber == zone_id && z.version == version) { @@ -1271,13 +1269,12 @@ const std::string& ZoneStore::GetZoneContentFlags(uint32 zone_id, int version) if (z.zoneidnumber == zone_id && z.version == 0) { return z.content_flags; } - } + }; - const auto& content_flags = std::string(); - return content_flags; + return ""; } -const std::string& ZoneStore::GetZoneContentFlagsDisabled(uint32 zone_id, int version) +const std::string ZoneStore::GetZoneContentFlagsDisabled(uint32 zone_id, int version) { for (auto &z: m_zones) { if (z.zoneidnumber == zone_id && z.version == version) { @@ -1291,8 +1288,7 @@ const std::string& ZoneStore::GetZoneContentFlagsDisabled(uint32 zone_id, int ve } } - const auto& content_flags_disabled = std::string(); - return content_flags_disabled; + return ""; } int ZoneStore::GetZoneUnderworldTeleportIndex(uint32 zone_id, int version) diff --git a/common/zone_store.h b/common/zone_store.h index d1b72a802..bc245643a 100644 --- a/common/zone_store.h +++ b/common/zone_store.h @@ -54,7 +54,7 @@ public: int GetZoneTimeZone(uint32 zone_id, int version = 0); int GetZoneMaximumPlayers(uint32 zone_id, int version = 0); uint32 GetZoneRuleSet(uint32 zone_id, int version = 0); - const std::string& GetZoneNote(uint32 zone_id, int version = 0); + const std::string GetZoneNote(uint32 zone_id, int version = 0); float GetZoneUnderworld(uint32 zone_id, int version = 0); float GetZoneMinimumClip(uint32 zone_id, int version = 0); float GetZoneMaximumClip(uint32 zone_id, int version = 0); @@ -69,7 +69,7 @@ public: float GetZoneWalkSpeed(uint32 zone_id, int version = 0); uint8 GetZoneTimeType(uint32 zone_id, int version = 0); float GetZoneFogDensity(uint32 zone_id, int version = 0); - const std::string& GetZoneFlagNeeded(uint32 zone_id, int version = 0); + const std::string GetZoneFlagNeeded(uint32 zone_id, int version = 0); int8 GetZoneCanBind(uint32 zone_id, int version = 0); int8 GetZoneCanCombat(uint32 zone_id, int version = 0); int8 GetZoneCanLevitate(uint32 zone_id, int version = 0); @@ -95,8 +95,8 @@ public: uint32 GetZoneMaximumMovementUpdateRange(uint32 zone_id, int version = 0); int8 GetZoneMinimumExpansion(uint32 zone_id, int version = 0); int8 GetZoneMaximumExpansion(uint32 zone_id, int version = 0); - const std::string& GetZoneContentFlags(uint32 zone_id, int version = 0); - const std::string& GetZoneContentFlagsDisabled(uint32 zone_id, int version = 0); + const std::string GetZoneContentFlags(uint32 zone_id, int version = 0); + const std::string GetZoneContentFlagsDisabled(uint32 zone_id, int version = 0); int GetZoneUnderworldTeleportIndex(uint32 zone_id, int version = 0); int GetZoneLavaDamage(uint32 zone_id, int version = 0); int GetZoneMinimumLavaDamage(uint32 zone_id, int version = 0); diff --git a/package.json b/package.json index 9dd484fae..2fe8006bd 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "eqemu-server", - "version": "22.15.3", + "version": "22.19.0", "repository": { "type": "git", "url": "https://github.com/EQEmu/Server.git" diff --git a/utils/scripts/generators/repository-generator.pl b/utils/scripts/generators/repository-generator.pl index a943613ba..507a3e05a 100644 --- a/utils/scripts/generators/repository-generator.pl +++ b/utils/scripts/generators/repository-generator.pl @@ -586,7 +586,8 @@ sub get_reserved_cpp_variable_names { return ( "class", "int", - "key" + "key", + "range" ); } diff --git a/world/zoneserver.cpp b/world/zoneserver.cpp index bfd8ecd6f..c79debaaf 100644 --- a/world/zoneserver.cpp +++ b/world/zoneserver.cpp @@ -748,7 +748,8 @@ void ZoneServer::HandleMessage(uint16 opcode, const EQ::Net::Packet &p) { } case ServerOP_ZoneStatus: { if (pack->size >= 1) { - zoneserver_list.SendZoneStatus((char *)&pack->pBuffer[1], (uint8)pack->pBuffer[0], this); + auto z = (ServerZoneStatus_Struct*) pack->pBuffer; + zoneserver_list.SendZoneStatus(z->name, z->admin, this); } break; diff --git a/zone/CMakeLists.txt b/zone/CMakeLists.txt index 3c5cc266e..9451c3a72 100644 --- a/zone/CMakeLists.txt +++ b/zone/CMakeLists.txt @@ -118,8 +118,11 @@ SET(zone_sources perl_perlpacket.cpp perl_player_corpse.cpp perl_questitem.cpp + perl_questitem_data.cpp perl_raids.cpp + perl_spawn.cpp perl_spell.cpp + perl_stat_bonuses.cpp perlpacket.cpp petitions.cpp pets.cpp diff --git a/zone/bonuses.cpp b/zone/bonuses.cpp index 438d0022f..9337920af 100644 --- a/zone/bonuses.cpp +++ b/zone/bonuses.cpp @@ -146,7 +146,8 @@ void Mob::CalcItemBonuses(StatBonuses* b) { int16 i; for (i = EQ::invslot::BONUS_BEGIN; i <= EQ::invslot::BONUS_SKILL_END; i++) { - const EQ::ItemInstance* inst = GetInv().GetItem(i); + const auto* inst = GetInv().GetItem(i); + if (!inst) { continue; } diff --git a/zone/bot_command.cpp b/zone/bot_command.cpp index 3ccd3a702..56e691bb2 100644 --- a/zone/bot_command.cpp +++ b/zone/bot_command.cpp @@ -1423,6 +1423,7 @@ int bot_command_init(void) bot_command_add("petremove", "Orders a bot to remove its charmed pet", AccountStatus::Player, bot_subcommand_pet_remove) || bot_command_add("petsettype", "Orders a Magician bot to use a specified pet type", AccountStatus::Player, bot_subcommand_pet_set_type) || bot_command_add("picklock", "Orders a capable bot to pick the lock of the closest door", AccountStatus::Player, bot_command_pick_lock) || + bot_command_add("pickpocket", "Orders a capable bot to pickpocket a NPC", AccountStatus::Player, bot_command_pickpocket) || bot_command_add("precombat", "Sets flag used to determine pre-combat behavior", AccountStatus::Player, bot_command_precombat) || bot_command_add("portal", "Orders a Wizard bot to open a magical doorway to a specified destination", AccountStatus::Player, bot_subcommand_portal) || bot_command_add("pull", "Orders a designated bot to 'pull' an enemy", AccountStatus::Player, bot_command_pull) || @@ -2814,19 +2815,6 @@ void bot_command_bot(Client *c, const Seperator *sep) helper_send_available_subcommands(c, "bot", subcommand_list); } -void bot_command_botgroup(Client *c, const Seperator *sep) -{ - const std::list subcommand_list = { - "botgroupaddmember", "botgroupcreate", "botgroupdelete", "botgrouplist", "botgroupload", "botgroupremovemember" - }; - - if (helper_command_alias_fail(c, "bot_command_botgroup", sep->arg[0], "botgroup")) { - return; - } - - helper_send_available_subcommands(c, "bot-group", subcommand_list); -} - void bot_command_charm(Client *c, const Seperator *sep) { auto local_list = &bot_command_spells[BCEnum::SpT_Charm]; @@ -5316,7 +5304,7 @@ void bot_command_view_combos(Client *c, const Seperator *sep) const uint16 bot_race = static_cast(Strings::ToUnsignedInt(sep->arg[1])); const std::string race_name = GetRaceIDName(bot_race); - if (!Mob::IsPlayerRace(bot_race)) { + if (!IsPlayerRace(bot_race)) { c->Message( Chat::White, fmt::format( @@ -5512,6 +5500,12 @@ void bot_subcommand_bot_create(Client *c, const Seperator *sep) std::string bot_name = sep->arg[1]; bot_name = Strings::UcFirst(bot_name); + + if (Strings::Contains(bot_name, "_")) { + c->Message(Chat::White, "Bot name cannot contain underscores!"); + return; + } + if (arguments < 2 || !sep->IsNumber(2)) { c->Message(Chat::White, "Invalid class!"); return; @@ -8894,7 +8888,7 @@ uint32 helper_bot_create(Client *bot_owner, std::string bot_name, uint8 bot_clas return bot_id; } - if (!Bot::IsValidRaceClassCombo(bot_race, bot_class) && bot_owner->IsPlayerRace(bot_race)) { + if (!Bot::IsValidRaceClassCombo(bot_race, bot_class) && IsPlayerRace(bot_race)) { const std::string bot_race_name = GetRaceIDName(bot_race); const std::string bot_class_name = GetClassIDName(bot_class); const auto view_saylink = Saylink::Silent( @@ -10007,3 +10001,194 @@ void bot_command_caster_range(Client* c, const Seperator* sep) c->Message(Chat::White, "Incorrect argument, use help for a list of options."); } } + +void bot_command_pickpocket(Client *c, const Seperator *sep) +{ + if (helper_command_alias_fail(c, "bot_command_pickpocket", sep->arg[0], "pickpocket")) { + return; + } + + if (helper_is_help_or_usage(sep->arg[1])) { + c->Message(Chat::White, "usage: ", sep->arg[0]); + return; + } + + std::list sbl; + MyBots::PopulateSBL_BySpawnedBots(c, sbl); + + // Check for capable rogue + ActionableBots::Filter_ByClasses(c, sbl, PLAYER_CLASS_ROGUE_BIT); + Bot *my_bot = ActionableBots::AsSpawned_ByMinLevelAndClass(c, sbl, 7, ROGUE); + if (!my_bot) { + c->Message(Chat::White, "No bots are capable of performing this action"); + return; + } + + // Make sure a mob is targetted and a valid NPC + Mob *target_mob = ActionableTarget::AsSingle_ByAttackable(c); + if (!target_mob || !target_mob->IsNPC()) { + c->Message(Chat::White, "You must an enemy to use this command"); + return; + } + + NPC *target_npc = ActionableTarget::AsSingle_ByAttackable(c)->CastToNPC(); + + // Check if mob is close enough + glm::vec4 mob_distance = (c->GetPosition() - target_mob->GetPosition()); + float mob_xy_distance = ((mob_distance.x * mob_distance.x) + (mob_distance.y * mob_distance.y)); + float mob_z_distance = (mob_distance.z * mob_distance.z); + if (mob_z_distance >= 25 || mob_xy_distance > 250) { + c->Message(Chat::White, "You must be closer to an enemy to use this command"); + return; + } + + // Adapted from pickpock skill in npc.cpp + // Make sure we are allowed to target them + uint8 over_level = target_mob->GetLevel(); + if (over_level > (my_bot->GetLevel() + THIEF_PICKPOCKET_OVER)) { + c->Message(Chat::Red, "You are too inexperienced to pick pocket this target"); + return; + } + + // Random fail roll + if (zone->random.Roll(5)) { + if (zone->CanDoCombat()) { + target_mob->AddToHateList(c, 50); + } + target_mob->Say("Stop thief!"); + c->Message(Chat::Red, "You are noticed trying to steal!"); + return; + } + + // Setup variables for calcs + bool steal_skill = my_bot->GetSkill(EQ::skills::SkillPickPockets); + bool steal_chance = steal_skill * 100 / (5 * over_level + 5); + + // Determine whether to steal money or an item. + uint32 money[6] = { + 0, + ((steal_skill >= 125) ? (target_npc->GetPlatinum()) : (0)), + ((steal_skill >= 60) ? (target_npc->GetGold()) : (0)), + target_npc->GetSilver(), + target_npc->GetCopper(), + 0 + }; + + bool has_coin = ((money[PickPocketPlatinum] | money[PickPocketGold] | money[PickPocketSilver] | money[PickPocketCopper]) != 0); + bool steal_item = (steal_skill >= steal_chance && (zone->random.Roll(50) || !has_coin)); + + // Steal item + while (steal_item) { + std::vector> loot_selection; // + for (auto item_iter: target_npc->itemlist) { + if (!item_iter || !item_iter->item_id) { + continue; + } + auto item_test = database.GetItem(item_iter->item_id); + if (item_test->Magic || !item_test->NoDrop || item_test->IsClassBag() || c->CheckLoreConflict(item_test) || + item_iter->equip_slot != EQ::invslot::SLOT_INVALID) { + continue; + } + loot_selection.emplace_back( + std::make_pair( + item_test, + ((item_test->Stackable) ? (1) : (item_iter->charges)) + ) + ); + } + if (loot_selection.empty()) { + steal_item = false; + break; + } + + int random = zone->random.Int(0, (loot_selection.size() - 1)); + + int16 slot_id = c->GetInv().FindFreeSlot( + false, + true, + (loot_selection[random].first->Size), + (loot_selection[random].first->ItemType == EQ::item::ItemTypeArrow) + ); + if (slot_id == INVALID_INDEX) { + steal_item = false; + break; + } + + auto item_inst = database.CreateItem(loot_selection[random].first, loot_selection[random].second); + if (item_inst == nullptr) { + steal_item = false; + break; + } + + // Successful item pickpocket + if (item_inst->IsStackable() && RuleB(Character, UseStackablePickPocketing)) { + if (!c->TryStacking(item_inst, ItemPacketTrade, false, false)) { + c->PutItemInInventory(slot_id, *item_inst); + c->SendItemPacket(slot_id, item_inst, ItemPacketTrade); + } + } + else { + c->PutItemInInventory(slot_id, *item_inst); + c->SendItemPacket(slot_id, item_inst, ItemPacketTrade); + } + target_npc->RemoveItem(item_inst->GetID()); + c->Message(Chat::White, "You stole an item."); + safe_delete(item_inst); + return; + } + + // no items, try money + while (!steal_item && has_coin) { + uint32 coin_amount = zone->random.Int(1, (steal_skill / 25) + 1); + + int coin_type = PickPocketPlatinum; + while (coin_type <= PickPocketCopper) { + if (money[coin_type]) { + if (coin_amount > money[coin_type]) { + coin_amount = money[coin_type]; + } + break; + } + ++coin_type; + } + if (coin_type > PickPocketCopper) { + break; + } + + memset(money, 0, (sizeof(int) * 6)); + money[coin_type] = coin_amount; + + if (zone->random.Roll(steal_chance)) { // Successful coin pickpocket + switch (coin_type) { + case PickPocketPlatinum: + target_npc->SetPlatinum(target_npc->GetPlatinum() - coin_amount); + break; + case PickPocketGold: + target_npc->SetGold(target_npc->GetGold() - coin_amount); + break; + case PickPocketSilver: + target_npc->SetSilver(target_npc->GetSilver() - coin_amount); + break; + case PickPocketCopper: + target_npc->SetCopper(target_npc->GetCopper() - coin_amount); + break; + default: // has_coin..but, doesn't have coin? + c->Message(Chat::Red, "You failed to pickpocket."); + return; + } + c->Message(Chat::White, "You stole money."); + c->AddMoneyToPP( + money[PickPocketCopper], + money[PickPocketSilver], + money[PickPocketGold], + money[PickPocketPlatinum], + true + ); + return; + } + + c->Message(Chat::Red, "You failed to pickpocket."); + return; + } + c->Message(Chat::White, "This target's pockets are empty"); +} diff --git a/zone/bot_command.h b/zone/bot_command.h index 312038096..83c543108 100644 --- a/zone/bot_command.h +++ b/zone/bot_command.h @@ -552,7 +552,6 @@ void bot_command_apply_potion(Client* c, const Seperator* sep); void bot_command_attack(Client *c, const Seperator *sep); void bot_command_bind_affinity(Client *c, const Seperator *sep); void bot_command_bot(Client *c, const Seperator *sep); -void bot_command_botgroup(Client *c, const Seperator *sep); void bot_command_caster_range(Client* c, const Seperator* sep); void bot_command_charm(Client *c, const Seperator *sep); void bot_command_cure(Client *c, const Seperator *sep); @@ -576,6 +575,7 @@ void bot_command_movement_speed(Client *c, const Seperator *sep); void bot_command_owner_option(Client *c, const Seperator *sep); void bot_command_pet(Client *c, const Seperator *sep); void bot_command_pick_lock(Client *c, const Seperator *sep); +void bot_command_pickpocket(Client* c, const Seperator* sep); void bot_command_precombat(Client* c, const Seperator* sep); void bot_command_pull(Client *c, const Seperator *sep); void bot_command_release(Client *c, const Seperator *sep); diff --git a/zone/client.cpp b/zone/client.cpp index 4f9a362bf..a74a922df 100644 --- a/zone/client.cpp +++ b/zone/client.cpp @@ -58,6 +58,7 @@ extern volatile bool RunLoops; #include "mob_movement_manager.h" #include "cheat_manager.h" +#include "../common/repositories/account_flags_repository.h" #include "../common/repositories/bug_reports_repository.h" #include "../common/repositories/char_recipe_list_repository.h" #include "../common/repositories/character_spells_repository.h" @@ -3958,32 +3959,32 @@ void Client::SendFullPopup( } void Client::SendWindow( - uint32 PopupID, - uint32 NegativeID, - uint32 Buttons, - const char *ButtonName0, - const char *ButtonName1, - uint32 Duration, + uint32 button_one_id, + uint32 button_two_id, + uint32 button_type, + const char* button_one_text, + const char* button_two_text, + uint32 duration, int title_type, - Client *target, - const char *Title, - const char *Text, + Mob* target, + const char* title, + const char* text, ... ) { va_list argptr; char buffer[4096]; - va_start(argptr, Text); - vsnprintf(buffer, sizeof(buffer), Text, argptr); + va_start(argptr, text); + vsnprintf(buffer, sizeof(buffer), text, argptr); va_end(argptr); size_t len = strlen(buffer); - auto app = new EQApplicationPacket(OP_OnLevelMessage, sizeof(OnLevelMessage_Struct)); - OnLevelMessage_Struct *olms = (OnLevelMessage_Struct *) app->pBuffer; + auto app = new EQApplicationPacket(OP_OnLevelMessage, sizeof(OnLevelMessage_Struct)); + auto* olms = (OnLevelMessage_Struct *) app->pBuffer; - if (strlen(Text) > (sizeof(olms->Text) - 1)) { + if (strlen(text) > (sizeof(olms->Text) - 1)) { safe_delete(app); return; } @@ -3996,47 +3997,47 @@ void Client::SendWindow( case 1: { char name[64] = ""; strcpy(name, target->GetName()); + if (strlen(target->GetLastName()) > 0) { char last_name[64] = ""; strcpy(last_name, target->GetLastName()); strcat(name, " "); strcat(name, last_name); } + strcpy(olms->Title, name); break; } case 2: { - if (target->GuildID()) { - char *guild_name = (char *) guild_mgr.GetGuildName(target->GuildID()); - strcpy(olms->Title, guild_name); - } - else { + if (target->IsClient() && target->CastToClient()->GuildID()) { + auto guild_name = guild_mgr.GetGuildName(target->CastToClient()->GuildID()); + strn0cpy(olms->Title, guild_name, sizeof(olms->Title)); + } else { strcpy(olms->Title, "No Guild"); } break; } default: { - strcpy(olms->Title, Title); + strcpy(olms->Title, title); break; } } memcpy(olms->Text, buffer, len + 1); - olms->Buttons = Buttons; + olms->Buttons = button_type; - sprintf(olms->ButtonName0, "%s", ButtonName0); - sprintf(olms->ButtonName1, "%s", ButtonName1); + strn0cpy(olms->ButtonName0, button_one_text, sizeof(olms->ButtonName0)); + strn0cpy(olms->ButtonName1, button_two_text, sizeof(olms->ButtonName1)); - if (Duration > 0) { - olms->Duration = Duration * 1000; - } - else { - olms->Duration = 0xffffffff; + if (duration > 0) { + olms->Duration = duration * 1000; + } else { + olms->Duration = UINT32_MAX; } - olms->PopupID = PopupID; - olms->NegativeID = NegativeID; + olms->PopupID = button_one_id; + olms->NegativeID = button_two_id; FastQueuePacket(&app); } @@ -4530,7 +4531,7 @@ bool Client::IsLeadershipEXPOn() { } -int Client::GetAggroCount() { +uint32 Client::GetAggroCount() { return AggroCount; } @@ -5938,90 +5939,64 @@ void Client::AdventureFinish(bool win, int theme, int points) FastQueuePacket(&outapp); } -void Client::CheckLDoNHail(Mob *target) +void Client::CheckLDoNHail(NPC* n) { - if(!zone->adv_data) - { + if (!zone->adv_data || !n || n->GetOwnerID()) { return; } - if(!target || !target->IsNPC()) - { + auto* ds = (ServerZoneAdventureDataReply_Struct*) zone->adv_data; + if (ds->type != Adventure_Rescue || ds->data_id != n->GetNPCTypeID()) { return; } - if(target->GetOwnerID() != 0) - { + if (entity_list.CheckNPCsClose(n)) { + n->Say( + "You're here to save me? I couldn't possibly risk leaving yet. There are " + "far too many of those horrid things out there waiting to recapture me! Please get " + "rid of some more of those vermin and then we can try to leave." + ); return; } - ServerZoneAdventureDataReply_Struct* ds = (ServerZoneAdventureDataReply_Struct*)zone->adv_data; - if(ds->type != Adventure_Rescue) - { - return; - } - - if(ds->data_id != target->GetNPCTypeID()) - { - return; - } - - if(entity_list.CheckNPCsClose(target) != 0) - { - target->Say("You're here to save me? I couldn't possibly risk leaving yet. There are " - "far too many of those horrid things out there waiting to recapture me! Please get" - " rid of some more of those vermin and then we can try to leave."); - return; - } - - Mob *pet = GetPet(); - if(pet) - { - if(pet->GetPetType() == petCharmed) - { + auto pet = GetPet(); + if (pet) { + if (pet->GetPetType() == petCharmed) { pet->BuffFadeByEffect(SE_Charm); - } - else if(pet->GetPetType() == petNPCFollow) - { + } else if (pet->GetPetType() == petNPCFollow) { pet->SetOwnerID(0); - } - else - { + } else { pet->Depop(); } } - SetPet(target); - target->SetOwnerID(GetID()); - target->Say("Wonderful! Someone to set me free! I feared for my life for so long," - " never knowing when they might choose to end my life. Now that you're here though" - " I can rest easy. Please help me find my way out of here as soon as you can" - " I'll stay close behind you!"); + SetPet(n); + n->SetOwnerID(GetID()); + n->Say( + "Wonderful! Someone to set me free! I feared for my life for so long, " + "never knowing when they might choose to end my life. Now that you're here though " + "I can rest easy. Please help me find my way out of here as soon as you can " + "I'll stay close behind you!" + ); } -void Client::CheckEmoteHail(Mob *target, const char* message) +void Client::CheckEmoteHail(NPC* n, const char* message) { - if( - (message[0] != 'H' && - message[0] != 'h') || - message[1] != 'a' || - message[2] != 'i' || - message[3] != 'l'){ + if ( + !Strings::BeginsWith(message, "hail") && + !Strings::BeginsWith(message, "Hail") + ) { return; } - if(!target || !target->IsNPC()) - { + if (!n || n->GetOwnerID()) { return; } - if(target->GetOwnerID() != 0) - { - return; + const auto emote_id = n->GetEmoteID(); + if (emote_id) { + n->DoNPCEmote(EQ::constants::EmoteEventTypes::Hailed, emote_id); } - uint32 emoteid = target->GetEmoteID(); - if(emoteid != 0) - target->CastToNPC()->DoNPCEmote(EQ::constants::EmoteEventTypes::Hailed, emoteid); } void Client::MarkSingleCompassLoc(float in_x, float in_y, float in_z, uint8 count) @@ -6365,544 +6340,6 @@ void Client::RemoveFromInstance(uint16 instance_id) database.RemoveClientFromInstance(instance_id, CharacterID()); } -void Client::SendStatsWindow(Client* client, bool use_window) -{ - // Define the types of page breaks we need - std::string indP = " "; - std::string indS = "          "; - std::string indM = "                          "; - std::string indL = "                                 "; - std::string div = " | "; - - std::string color_red = ""; - std::string color_blue = ""; - std::string color_green = ""; - std::string bright_green = ""; - std::string bright_red = ""; - std::string heroic_color = " +"; - - // Set Class - std::string class_Name = itoa(GetClass()); - std::string class_List[] = { "WAR", "CLR", "PAL", "RNG", "SHD", "DRU", "MNK", "BRD", "ROG", "SHM", "NEC", "WIZ", "MAG", "ENC", "BST", "BER" }; - - if (GetClass() < 17 && GetClass() > 0) { - class_Name = class_List[GetClass() - 1]; - } - - // Race - std::string race_name = GetRaceIDName(GetRace()); - - /*########################################################## - ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - H/M/E String - ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - ##########################################################*/ - std::string HME_row = ""; - //Loop Variables - /*===========================*/ - std::string cur_field = ""; - std::string total_field = ""; - std::string cur_name = ""; - std::string cur_spacing = ""; - std::string cur_color = ""; - - int hme_rows = 3; // Rows in display - int max_HME_value_len = 9; // 9 digits in the displayed value - - for(int hme_row_counter = 0; hme_row_counter < hme_rows; hme_row_counter++) - { - switch(hme_row_counter) { - case 0: { - cur_name = " H: "; - cur_field = itoa(GetHP()); - total_field = itoa(GetMaxHP()); - break; - } - case 1: { - if(CalcMaxMana() > 0) { - cur_name = " M: "; - cur_field = itoa(GetMana()); - total_field = itoa(GetMaxMana()); - } - else { continue; } - - break; - } - case 2: { - cur_name = " E: "; - cur_field = itoa(GetEndurance()); - total_field = itoa(GetMaxEndurance()); - break; - } - default: { break; } - } - if(cur_field.compare(total_field) == 0) { cur_color = bright_green; } - else { cur_color = bright_red; } - - cur_spacing.clear(); - for(int a = cur_field.size(); a < max_HME_value_len; a++) { cur_spacing += " ."; } - - HME_row += indM + cur_name + cur_spacing + cur_color + cur_field + " / " + total_field + "
"; - } - /*########################################################## - ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - Regen String - ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - ##########################################################*/ - std::string regen_string; - //Loop Variables - /*===========================*/ - std::string regen_row_header = ""; - std::string regen_row_color = ""; - std::string base_regen_field = ""; - std::string base_regen_spacing = ""; - std::string item_regen_field = ""; - std::string item_regen_spacing = ""; - std::string cap_regen_field = ""; - std::string cap_regen_spacing = ""; - std::string spell_regen_field = ""; - std::string spell_regen_spacing = ""; - std::string aa_regen_field = ""; - std::string aa_regen_spacing = ""; - std::string total_regen_field = ""; - int regen_rows = 3; // Number of rows - int max_regen_value_len = 5; // 5 digits in the displayed value(larger values will not get cut off, this is just a baseline) - - for(int regen_row_counter = 0; regen_row_counter < regen_rows; regen_row_counter++) - { - switch(regen_row_counter) - { - case 0: { - regen_row_header = "H: "; - regen_row_color = color_red; - - base_regen_field = itoa(LevelRegen()); - 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); - total_regen_field = itoa(CalcHPRegen(true)); - break; - } - case 1: { - if(GetMaxMana() > 0) { - regen_row_header = "M: "; - regen_row_color = color_blue; - - base_regen_field = itoa(CalcBaseManaRegen()); - 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); - aa_regen_field = itoa(aabonuses.ManaRegen); - total_regen_field = itoa(CalcManaRegen(true)); - } - else { continue; } - break; - } - case 2: { - regen_row_header = "E: "; - regen_row_color = color_green; - - base_regen_field = itoa(((GetLevel() * 4 / 10) + 2)); - 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); - total_regen_field = itoa(CalcEnduranceRegen(true)); - break; - } - default: { break; } - } - - base_regen_spacing.clear(); - item_regen_spacing.clear(); - cap_regen_spacing.clear(); - spell_regen_spacing.clear(); - aa_regen_spacing.clear(); - - for(int b = base_regen_field.size(); b < max_regen_value_len; b++) { base_regen_spacing += " ."; } - for(int b = item_regen_field.size(); b < max_regen_value_len; b++) { item_regen_spacing += " ."; } - for(int b = cap_regen_field.size(); b < max_regen_value_len; b++) { cap_regen_spacing += " ."; } - for(int b = spell_regen_field.size(); b < max_regen_value_len; b++) { spell_regen_spacing += " ."; } - for(int b = aa_regen_field.size(); b < max_regen_value_len; b++) { aa_regen_spacing += " ."; } - - regen_string += indS + regen_row_color + regen_row_header + base_regen_spacing + base_regen_field; - regen_string += div + item_regen_spacing + item_regen_field + " (" + cap_regen_field; - regen_string += ") " + cap_regen_spacing + div + spell_regen_spacing + spell_regen_field; - regen_string += div + aa_regen_spacing + aa_regen_field + div + total_regen_field + "

"; - } - /*########################################################## - ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - Stat String - ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - ##########################################################*/ - std::string stat_field = ""; - //Loop Variables - /*===========================*/ - //first field(stat) - std::string a_stat = "";; - std::string a_stat_name = ""; - std::string a_stat_spacing = ""; - //second field(heroic stat) - std::string h_stat = ""; - std::string h_stat_spacing = ""; - //third field(resist) - std::string a_resist = ""; - std::string a_resist_name = ""; - std::string a_resist_spacing = ""; - //fourth field(heroic resist) - std::string h_resist_field = ""; - - int stat_rows = 7; // Number of rows - int max_stat_value_len = 3; // 3 digits in the displayed value - - for(int stat_row_counter = 0; stat_row_counter < stat_rows; stat_row_counter++) - { - switch(stat_row_counter) { - case 0: { - a_stat_name = " STR: "; - a_resist_name = "MR: "; - a_stat = itoa(GetSTR()); - h_stat = itoa(GetHeroicSTR()); - a_resist = itoa(GetMR()); - h_resist_field = itoa(GetHeroicMR()); - break; - } - case 1: { - a_stat_name = " STA: "; - a_resist_name = "CR: "; - a_stat = itoa(GetSTA()); - h_stat = itoa(GetHeroicSTA()); - a_resist = itoa(GetCR()); - h_resist_field = itoa(GetHeroicCR()); - break; - } - case 2: { - a_stat_name = " AGI : "; - a_resist_name = "FR: "; - a_stat = itoa(GetAGI()); - h_stat = itoa(GetHeroicAGI()); - a_resist = itoa(GetFR()); - h_resist_field = itoa(GetHeroicFR()); - break; - } - case 3: { - a_stat_name = " DEX: "; - a_resist_name = "PR: "; - a_stat = itoa(GetDEX()); - h_stat = itoa(GetHeroicDEX()); - a_resist = itoa(GetPR()); - h_resist_field = itoa(GetHeroicPR()); - break; - } - case 4: { - a_stat_name = " INT : "; - a_resist_name = "DR: "; - a_stat = itoa(GetINT()); - h_stat = itoa(GetHeroicINT()); - a_resist = itoa(GetDR()); - h_resist_field = itoa(GetHeroicDR()); - break; - } - case 5: { - a_stat_name = " WIS: "; - a_resist_name = "Cp: "; - a_stat = itoa(GetWIS()); - h_stat = itoa(GetHeroicWIS()); - a_resist = itoa(GetCorrup()); - h_resist_field = itoa(GetHeroicCorrup()); - break; - } - case 6: { - a_stat_name = " CHA: "; - a_resist_name = "PhR: "; // Not implemented for clients yet - a_stat = itoa(GetCHA()); - h_stat = itoa(GetHeroicCHA()); - a_resist = itoa(GetPhR()); - h_resist_field = itoa(GetHeroicPhR()); - break; - } - default: { break; } - } - - a_stat_spacing.clear(); - h_stat_spacing.clear(); - a_resist_spacing.clear(); - - for(int a = a_stat.size(); a < max_stat_value_len; a++) { a_stat_spacing += " . "; } - for(int h = h_stat.size(); h < 20; h++) { h_stat_spacing += " . "; } - for(int h = a_resist.size(); h < max_stat_value_len; h++) { a_resist_spacing += " . "; } - - stat_field += indP + a_stat_name + a_stat_spacing + a_stat + heroic_color + h_stat + "
"; - stat_field += h_stat_spacing + a_resist_name + a_resist_spacing + a_resist + heroic_color + h_resist_field + "
"; - if(stat_row_counter < 6) { - stat_field += "
"; - } - } - /*########################################################## - ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - Mod2 String - ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - ##########################################################*/ - std::string mod2_field = ""; - //Loop Variables - /*===========================*/ - std::string mod2a = ""; - std::string mod2a_name = ""; - std::string mod2a_spacing = ""; - std::string mod2a_cap = ""; - std::string mod_row_spacing = ""; - std::string mod2b = ""; - std::string mod2b_name = ""; - std::string mod2b_spacing = ""; - std::string mod2b_cap = ""; - int mod2a_space_count; - int mod2b_space_count; - - int mod2_rows = 4; - int max_mod2_value_len = 3; // 3 digits in the displayed value - - for(int mod2_row_counter = 0; mod2_row_counter < mod2_rows; mod2_row_counter++) - { - switch (mod2_row_counter) - { - case 0: { - mod2a_name = "Avoidance: "; - mod2b_name = "Combat Effects: "; - mod2a = itoa(GetAvoidance()); - mod2a_cap = itoa(RuleI(Character, ItemAvoidanceCap)); - mod2b = itoa(GetCombatEffects()); - mod2b_cap = itoa(RuleI(Character, ItemCombatEffectsCap)); - mod2a_space_count = 2; - mod2b_space_count = 0; - break; - } - case 1: { - mod2a_name = "Accuracy: "; - mod2b_name = "Strike Through: "; - mod2a = itoa(GetAccuracy()); - mod2a_cap = itoa(RuleI(Character, ItemAccuracyCap)); - mod2b = itoa(GetStrikeThrough()); - mod2b_cap = itoa(RuleI(Character, ItemStrikethroughCap)); - mod2a_space_count = 3; - mod2b_space_count = 1; - break; - } - case 2: { - mod2a_name = "Shielding: "; - mod2b_name = "Spell Shielding: "; - mod2a = itoa(GetShielding()); - mod2a_cap = itoa(RuleI(Character, ItemShieldingCap)); - mod2b = itoa(GetSpellShield()); - mod2b_cap = itoa(RuleI(Character, ItemSpellShieldingCap)); - mod2a_space_count = 2; - mod2b_space_count = 1; - break; - } - case 3: { - mod2a_name = "Stun Resist: "; - mod2b_name = "DoT Shielding: "; - mod2a = itoa(GetStunResist()); - mod2a_cap = itoa(RuleI(Character, ItemStunResistCap)); - mod2b = itoa(GetDoTShield()); - mod2b_cap = itoa(RuleI(Character, ItemDoTShieldingCap)); - mod2a_space_count = 0; - mod2b_space_count = 2; - break; - } - } - - mod2a_spacing.clear(); - mod_row_spacing.clear(); - mod2b_spacing.clear(); - - for(int a = mod2a.size(); a < (max_mod2_value_len + mod2a_space_count); a++) { mod2a_spacing += " . "; } - for(int a = mod2a_cap.size(); a < 6 ; a++) { mod_row_spacing += " . "; } - for(int a = mod2b.size(); a < (max_mod2_value_len + mod2b_space_count); a++) { mod2b_spacing += " . "; } - - mod2_field += indP + mod2a_name + mod2a_spacing + mod2a + " / " + mod2a_cap + mod_row_spacing; - mod2_field += mod2b_name + mod2b_spacing + mod2b + " / " + mod2b_cap + "
"; - } - - uint32 rune_number = 0; - uint32 magic_rune_number = 0; - uint32 buff_count = GetMaxTotalSlots(); - for (int i=0; i < buff_count; i++) { - if (IsValidSpell(buffs[i].spellid)) { - if (buffs[i].melee_rune > 0) { rune_number += buffs[i].melee_rune; } - - if (buffs[i].magic_rune > 0) { magic_rune_number += buffs[i].magic_rune; } - } - } - - int shield_ac = 0; - GetRawACNoShield(shield_ac); - - std::string skill_list[] = { - "1H Blunt","1H Slashing","2H Blunt","2H Slashing","Abjuration", - "Alteration","Apply Poison","Archery","Backstab","Bind Wound", - "Bash","Block","Brass Instruments","Channeling","Conjuration", - "Defense","Disarm","Disarm Traps","Divination","Dodge", - "Double Attack","Dragon Punch","Dual Wield","Eagle Strike","Evocation", - "Feign Death","Flying Kick","Forage","Hand To Hand","Hide", - "Kick","Meditate","Mend","Offense","Parry", - "Pick Lock","1H Piercing","Riposte","Round Kick","Safe Fall", - "Sense Heading","Singing","Sneak","Specialize Abjuration","Specialize Alteration", - "Specialize Conjuration","Specialize Divination","Specialize Evocation","Pick Pockets","Stringed Instruments", - "Swimming","Throwing","Tiger Claw","Tracking","Wind Instruments", - "Fishing","Make Poison","Tinkering","Research","Alchemy", - "Baking","Tailoring","Sense Traps","Blacksmithing","Fletching", - "Brewing","Alcohol_Tolerance","Begging","Jewelry Making","Pottery", - "Percussion Instruments","Intimidation","Berserking","Taunt","Frenzy", - "Remove Traps","Triple Attack","2H Piercing" - }; - - std::string skill_mods = ""; - for (int j = 0; j <= EQ::skills::HIGHEST_SKILL; j++) { - if(itembonuses.skillmod[j] > 0) - skill_mods += indP + skill_list[j] + " : +" + itoa(itembonuses.skillmod[j]) + "%
"; - else if(itembonuses.skillmod[j] < 0) - skill_mods += indP + skill_list[j] + " : -" + itoa(itembonuses.skillmod[j]) + "%
"; - } - - std::string skill_dmgs = ""; - for (int j = 0; j <= EQ::skills::HIGHEST_SKILL; j++) { - if((itembonuses.SkillDamageAmount[j] + spellbonuses.SkillDamageAmount[j]) > 0) - skill_dmgs += indP + skill_list[j] + " : +" + itoa(itembonuses.SkillDamageAmount[j] + spellbonuses.SkillDamageAmount[j]) + "
"; - else if((itembonuses.SkillDamageAmount[j] + spellbonuses.SkillDamageAmount[j]) < 0) - skill_dmgs += indP + skill_list[j] + " : -" + itoa(itembonuses.SkillDamageAmount[j] + spellbonuses.SkillDamageAmount[j]) + "
"; - } - - std::string faction_item_string = ""; - char faction_buf[256]; - - for (auto iter = item_faction_bonuses.begin(); iter != item_faction_bonuses.end(); ++iter) { - memset(&faction_buf, 0, sizeof(faction_buf)); - - if(!content_db.GetFactionName((int)((*iter).first), faction_buf, sizeof(faction_buf))) - strcpy(faction_buf, "Not in DB"); - - if((*iter).second > 0) { - faction_item_string += indP + faction_buf + " : +" + itoa((*iter).second) + "
"; - } - else if((*iter).second < 0) { - faction_item_string += indP + faction_buf + " : -" + itoa((*iter).second) + "
"; - } - } - - std::string bard_info = ""; - if(GetClass() == BARD) { - bard_info = indP + "Singing: " + itoa(GetSingMod()) + "
" + - indP + "Brass: " + itoa(GetBrassMod()) + "
" + - indP + "String: " + itoa(GetStringMod()) + "
" + - indP + "Percussion: " + itoa(GetPercMod()) + "
" + - indP + "Wind: " + itoa(GetWindMod()) + "
"; - } - - EQ::skills::SkillType skill = EQ::skills::SkillHandtoHand; - auto *inst = GetInv().GetItem(EQ::invslot::slotPrimary); - if (inst && inst->IsClassCommon()) { - switch (inst->GetItem()->ItemType) { - case EQ::item::ItemType1HSlash: - skill = EQ::skills::Skill1HSlashing; - break; - case EQ::item::ItemType2HSlash: - skill = EQ::skills::Skill2HSlashing; - break; - case EQ::item::ItemType1HPiercing: - skill = EQ::skills::Skill1HPiercing; - break; - case EQ::item::ItemType1HBlunt: - skill = EQ::skills::Skill1HBlunt; - break; - case EQ::item::ItemType2HBlunt: - skill = EQ::skills::Skill2HBlunt; - break; - case EQ::item::ItemType2HPiercing: - if (ClientVersion() < EQ::versions::ClientVersion::RoF2) - skill = EQ::skills::Skill1HPiercing; - else - skill = EQ::skills::Skill2HPiercing; - break; - default: - break; - } - } - - std::ostringstream final_string; - final_string << - /* C/L/R */ indP << "Class: " << class_Name << indS << "Level: " << static_cast(GetLevel()) << indS << "Race: " << race_name << "
" << - /* Runes */ indP << "Rune: " << rune_number << indL << indS << "Spell Rune: " << magic_rune_number << "
" << - /* HP/M/E */ HME_row << - /* DS */ indP << "DS: " << (itembonuses.DamageShield + spellbonuses.DamageShield*-1) << " (Spell: " << (spellbonuses.DamageShield*-1) << " + Item: " << itembonuses.DamageShield << " / " << RuleI(Character, ItemDamageShieldCap) << ")
" << - /* Atk */ indP << "tohit: " << compute_tohit(skill) << " / " << GetTotalToHit(skill, 0) << "
" << - /* Atk2 */ indP << "- Offense: " << offense(skill) << " | Item: " << itembonuses.ATK << " (" << RuleI(Character, ItemATKCap) << ")~Used: " << (itembonuses.ATK * 1.342) << " | Spell: " << spellbonuses.ATK << "
" << - /* AC */ indP << "mitigation AC: " << GetMitigationAC() << "
" << - /* AC2 */ indP << "- defense: " << compute_defense() << " / " << GetTotalDefense() << " | Spell: " << spellbonuses.AC << " | Shield: " << shield_ac << "
" << - /* Haste */ indP << "Haste: " << GetHaste() << "
" << - /* Haste2 */ indP << " - Item: " << itembonuses.haste << " + Spell: " << (spellbonuses.haste + spellbonuses.hastetype2) << " (Cap: " << RuleI(Character, HasteCap) << ") | Over: " << (spellbonuses.hastetype3 + ExtraHaste) << "
" << - /* RunSpeed*/ indP << "Runspeed: " << GetRunspeed() << "
" << - /* RegenLbl */ indL << indS << "Regen
" << indS << indP << indP << " Base | Items (Cap) " << indP << " | Spell | A.A.s | Total
" << - /* Regen */ regen_string << "
" << - /* Stats */ stat_field << "

" << - /* Mod2s */ mod2_field << "
" << - /* HealAmt */ indP << "Heal Amount: " << GetHealAmt() << " / " << RuleI(Character, ItemHealAmtCap) << "
" << - /* SpellDmg*/ indP << "Spell Dmg: " << GetSpellDmg() << " / " << RuleI(Character, ItemSpellDmgCap) << "
" << - /* Clair */ indP << "Clairvoyance: " << GetClair() << " / " << RuleI(Character, ItemClairvoyanceCap) << "
" << - /* DSMit */ indP << "Dmg Shld Mit: " << GetDSMit() << " / " << RuleI(Character, ItemDSMitigationCap) << "

"; - if(GetClass() == BARD) - final_string << bard_info << "
"; - if(skill_mods.size() > 0) - final_string << skill_mods << "
"; - if(skill_dmgs.size() > 0) - final_string << skill_dmgs << "
"; - if(faction_item_string.size() > 0) - final_string << faction_item_string; - - std::string final_stats = final_string.str(); - - if(use_window) { - if(final_stats.size() < 4096) - { - uint32 Buttons = (client->ClientVersion() < EQ::versions::ClientVersion::SoD) ? 0 : 1; - client->SendWindow(0, POPUPID_UPDATE_SHOWSTATSWINDOW, Buttons, "Cancel", "Update", 0, 1, this, "", "%s", final_stats.c_str()); - goto Extra_Info; - } - else { - client->Message(Chat::Yellow, "The window has exceeded its character limit, displaying stats to chat window:"); - } - } - - client->Message(Chat::Yellow, "~~~~~ %s %s ~~~~~", GetCleanName(), GetLastName()); - client->Message(Chat::White, " Level: %i Class: %i Race: %i DS: %i/%i Size: %1.1f Weight: %.1f/%d ", GetLevel(), GetClass(), GetRace(), GetDS(), RuleI(Character, ItemDamageShieldCap), GetSize(), (float)CalcCurrentWeight() / 10.0f, GetSTR()); - client->Message(Chat::White, " HP: %i/%i HP Regen: %i/%i",GetHP(), GetMaxHP(), CalcHPRegen(), CalcHPRegenCap()); - client->Message(Chat::White, " compute_tohit: %i TotalToHit: %i", compute_tohit(skill), GetTotalToHit(skill, 0)); - client->Message(Chat::White, " compute_defense: %i TotalDefense: %i", compute_defense(), GetTotalDefense()); - client->Message(Chat::White, " offense: %i mitigation ac: %i", offense(skill), GetMitigationAC()); - client->Message(Chat::White, " AFK: %i LFG: %i Anon: %i PVP: %i GM: %i Flymode: %i GMSpeed: %i Hideme: %i GMInvul: %d LD: %i ClientVersion: %i TellsOff: %i", AFK, LFG, GetAnon(), GetPVP(), GetGM(), flymode, GetGMSpeed(), GetHideMe(), GetGMInvul(), IsLD(), ClientVersionBit(), tellsoff); - if(CalcMaxMana() > 0) - client->Message(Chat::White, " Mana: %i/%i Mana Regen: %i/%i", GetMana(), GetMaxMana(), CalcManaRegen(), CalcManaRegenCap()); - client->Message(Chat::White, " End.: %i/%i End. Regen: %i/%i",GetEndurance(), GetMaxEndurance(), CalcEnduranceRegen(), CalcEnduranceRegenCap()); - client->Message(Chat::White, " ATK: %i Worn/Spell ATK %i/%i Server Side ATK: %i", GetTotalATK(), RuleI(Character, ItemATKCap), GetATKBonus(), GetATK()); - client->Message(Chat::White, " Haste: %i / %i (Item: %i + Spell: %i + Over: %i) Run speed: %i", GetHaste(), RuleI(Character, HasteCap), itembonuses.haste, spellbonuses.haste + spellbonuses.hastetype2, spellbonuses.hastetype3 + ExtraHaste, GetRunspeed()); - client->Message(Chat::White, " STR: %i STA: %i DEX: %i AGI: %i INT: %i WIS: %i CHA: %i", GetSTR(), GetSTA(), GetDEX(), GetAGI(), GetINT(), GetWIS(), GetCHA()); - client->Message(Chat::White, " hSTR: %i hSTA: %i hDEX: %i hAGI: %i hINT: %i hWIS: %i hCHA: %i", GetHeroicSTR(), GetHeroicSTA(), GetHeroicDEX(), GetHeroicAGI(), GetHeroicINT(), GetHeroicWIS(), GetHeroicCHA()); - client->Message(Chat::White, " MR: %i PR: %i FR: %i CR: %i DR: %i Corruption: %i PhR: %i", GetMR(), GetPR(), GetFR(), GetCR(), GetDR(), GetCorrup(), GetPhR()); - client->Message(Chat::White, " hMR: %i hPR: %i hFR: %i hCR: %i hDR: %i hCorruption: %i", GetHeroicMR(), GetHeroicPR(), GetHeroicFR(), GetHeroicCR(), GetHeroicDR(), GetHeroicCorrup()); - client->Message(Chat::White, " Shielding: %i Spell Shield: %i DoT Shielding: %i Stun Resist: %i Strikethrough: %i Avoidance: %i Accuracy: %i Combat Effects: %i", GetShielding(), GetSpellShield(), GetDoTShield(), GetStunResist(), GetStrikeThrough(), GetAvoidance(), GetAccuracy(), GetCombatEffects()); - client->Message(Chat::White, " Heal Amt.: %i Spell Dmg.: %i Clairvoyance: %i DS Mitigation: %i", GetHealAmt(), GetSpellDmg(), GetClair(), GetDSMit()); - if(GetClass() == BARD) - client->Message(Chat::White, " Singing: %i Brass: %i String: %i Percussion: %i Wind: %i", GetSingMod(), GetBrassMod(), GetStringMod(), GetPercMod(), GetWindMod()); - - Extra_Info: - - client->Message(Chat::White, " BaseRace: %i Gender: %i BaseGender: %i Texture: %i HelmTexture: %i", GetBaseRace(), GetGender(), GetBaseGender(), GetTexture(), GetHelmTexture()); - if (client->Admin() >= AccountStatus::GMAdmin) { - client->Message(Chat::White, " CharID: %i EntityID: %i PetID: %i OwnerID: %i AIControlled: %i Targetted: %i", CharacterID(), GetID(), GetPetID(), GetOwnerID(), IsAIControlled(), targeted); - } -} - void Client::SendAltCurrencies() { if (ClientVersion() >= EQ::versions::ClientVersion::SoF) { uint32 count = zone->AlternateCurrencies.size(); @@ -7442,87 +6879,6 @@ void Client::SetMaxXTargets(uint8 NewMax) FastQueuePacket(&outapp); } -const char* Client::GetRacePlural(Client* client) { - - switch (client->CastToMob()->GetRace()) { - case HUMAN: - return "Humans"; break; - case BARBARIAN: - return "Barbarians"; break; - case ERUDITE: - return "Erudites"; break; - case WOOD_ELF: - return "Wood Elves"; break; - case HIGH_ELF: - return "High Elves"; break; - case DARK_ELF: - return "Dark Elves"; break; - case HALF_ELF: - return "Half Elves"; break; - case DWARF: - return "Dwarves"; break; - case TROLL: - return "Trolls"; break; - case OGRE: - return "Ogres"; break; - case HALFLING: - return "Halflings"; break; - case GNOME: - return "Gnomes"; break; - case IKSAR: - return "Iksar"; break; - case VAHSHIR: - return "Vah Shir"; break; - case FROGLOK: - return "Frogloks"; break; - case DRAKKIN: - return "Drakkin"; break; - default: - return "Races"; break; - } -} - -const char* Client::GetClassPlural(Client* client) { - - switch (client->CastToMob()->GetClass()) { - case WARRIOR: - return "Warriors"; break; - case CLERIC: - return "Clerics"; break; - case PALADIN: - return "Paladins"; break; - case RANGER: - return "Rangers"; break; - case SHADOWKNIGHT: - return "Shadowknights"; break; - case DRUID: - return "Druids"; break; - case MONK: - return "Monks"; break; - case BARD: - return "Bards"; break; - case ROGUE: - return "Rogues"; break; - case SHAMAN: - return "Shamen"; break; - case NECROMANCER: - return "Necromancers"; break; - case WIZARD: - return "Wizards"; break; - case MAGICIAN: - return "Magicians"; break; - case ENCHANTER: - return "Enchanters"; break; - case BEASTLORD: - return "Beastlords"; break; - case BERSERKER: - return "Berserkers"; break; - default: - return "Classes"; break; - } -} - - void Client::SendWebLink(const char *website) { if (website) { @@ -8099,36 +7455,57 @@ void Client::SendFactionMessage(int32 tmpvalue, int32 faction_id, int32 faction_ void Client::LoadAccountFlags() { - accountflags.clear(); - std::string query = StringFormat("SELECT p_flag, p_value " - "FROM account_flags WHERE p_accid = '%d'", - account_id); - auto results = database.QueryDatabase(query); - if (!results.Success()) { + + const auto& l = AccountFlagsRepository::GetWhere(database, fmt::format("p_accid = {}", account_id)); + if (l.empty()) { return; } - for (auto row = results.begin(); row != results.end(); ++row) - accountflags[row[0]] = row[1]; -} - -void Client::SetAccountFlag(std::string flag, std::string val) { - - std::string query = StringFormat("REPLACE INTO account_flags (p_accid, p_flag, p_value) " - "VALUES( '%d', '%s', '%s')", - account_id, flag.c_str(), val.c_str()); - auto results = database.QueryDatabase(query); - if(!results.Success()) { - return; + for (const auto& e : l) { + accountflags[e.p_flag] = e.p_value; } - - accountflags[flag] = val; } -std::string Client::GetAccountFlag(std::string flag) +void Client::ClearAccountFlag(const std::string& flag) { - return(accountflags[flag]); + auto e = AccountFlagsRepository::NewEntity(); + + e.p_accid = account_id; + e.p_flag = flag; + + AccountFlagsRepository::ClearFlag(database, e); +} + +void Client::SetAccountFlag(const std::string& flag, const std::string& value) +{ + auto e = AccountFlagsRepository::NewEntity(); + + e.p_accid = account_id; + e.p_flag = flag; + e.p_value = value; + + AccountFlagsRepository::ReplaceFlag(database, e); + + accountflags[flag] = value; +} + +std::string Client::GetAccountFlag(const std::string& flag) +{ + return accountflags[flag]; +} + +std::vector Client::GetAccountFlags() +{ + std::vector l; + + l.reserve(accountflags.size()); + + for (const auto& e : accountflags) { + l.emplace_back(e.first); + } + + return l; } void Client::TickItemCheck() @@ -8531,17 +7908,6 @@ void Client::ExpeditionSay(const char *str, int ExpID) { } -void Client::ShowNumHits() -{ - uint32 buffcount = GetMaxTotalSlots(); - for (uint32 buffslot = 0; buffslot < buffcount; buffslot++) { - const Buffs_Struct &curbuff = buffs[buffslot]; - if (IsValidSpell(curbuff.spellid) && curbuff.hit_number) - Message(0, "You have %d hits left on %s", curbuff.hit_number, GetSpellName(curbuff.spellid)); - } - return; -} - int Client::GetQuiverHaste(int delay) { const EQ::ItemInstance *pi = nullptr; diff --git a/zone/client.h b/zone/client.h index eb144e2c9..c4ef78ca3 100644 --- a/zone/client.h +++ b/zone/client.h @@ -772,7 +772,6 @@ public: void SetLanguageSkill(int langid, int value); void SetHoTT(uint32 mobid); void ShowSkillsWindow(); - void SendStatsWindow(Client* client, bool use_window); uint16 MaxSkill(EQ::skills::SkillType skillid, uint16 class_, uint16 level) const; inline uint16 MaxSkill(EQ::skills::SkillType skillid) const { return MaxSkill(skillid, GetClass(), GetLevel()); } @@ -1095,7 +1094,7 @@ public: uint16 GetMaxSkillAfterSpecializationRules(EQ::skills::SkillType skillid, uint16 maxSkill); void SendPopupToClient(const char *Title, const char *Text, uint32 PopupID = 0, uint32 Buttons = 0, uint32 Duration = 0); void SendFullPopup(const char *Title, const char *Text, uint32 PopupID = 0, uint32 NegativeID = 0, uint32 Buttons = 0, uint32 Duration = 0, const char *ButtonName0 = 0, const char *ButtonName1 = 0, uint32 SoundControls = 0); - void SendWindow(uint32 PopupID, uint32 NegativeID, uint32 Buttons, const char *ButtonName0, const char *ButtonName1, uint32 Duration, int title_type, Client* target, const char *Title, const char *Text, ...); + void SendWindow(uint32 button_one_id, uint32 button_two_id, uint32 button_type, const char* button_one_text, const char* button_two_text, uint32 duration, int title_type, Mob* target, const char* title, const char* text, ...); bool PendingTranslocate; time_t TranslocateTime; bool PendingSacrifice; @@ -1348,7 +1347,7 @@ public: bool CanEnterZone(const std::string& zone_short_name = "", int16 instance_version = -1); - int GetAggroCount(); + uint32 GetAggroCount(); void IncrementAggroCount(bool raid_target = false); void DecrementAggroCount(); void SendPVPStats(); @@ -1361,8 +1360,8 @@ public: uint32 GetLDoNLossesTheme(uint32 t); uint32 GetLDoNPointsTheme(uint32 t); void UpdateLDoNWinLoss(uint32 theme_id, bool win = false, bool remove = false); - void CheckLDoNHail(Mob *target); - void CheckEmoteHail(Mob *target, const char* message); + void CheckLDoNHail(NPC* n); + void CheckEmoteHail(NPC* n, const char* message); void HandleLDoNOpen(NPC *target); void HandleLDoNSenseTraps(NPC *target, uint16 skill, uint8 type); @@ -1560,8 +1559,6 @@ public: Timer* GetMercTimer() { return &merc_timer; }; Timer* GetPickLockTimer() { return &pick_lock_timer; }; - const char* GetRacePlural(Client* client); - const char* GetClassPlural(Client* client); void SendWebLink(const char* website); void SendMarqueeMessage(uint32 type, std::string message, uint32 duration = 3000); void SendMarqueeMessage(uint32 type, uint32 priority, uint32 fade_in, uint32 fade_out, uint32 duration, std::string message); @@ -1584,8 +1581,10 @@ public: int32 GetActWIS() { return( std::min(GetMaxWIS(), GetWIS()) ); } int32 GetActCHA() { return( std::min(GetMaxCHA(), GetCHA()) ); } void LoadAccountFlags(); - void SetAccountFlag(std::string flag, std::string val); - std::string GetAccountFlag(std::string flag); + void ClearAccountFlag(const std::string& flag); + void SetAccountFlag(const std::string& flag, const std::string& value); + std::string GetAccountFlag(const std::string& flag); + std::vector GetAccountFlags(); void SetGMStatus(int16 new_status); void Consume(const EQ::ItemData *item, uint8 type, int16 slot, bool auto_consume); void PlayMP3(const char* fname); @@ -1597,8 +1596,6 @@ public: void SetInvulnerableEnvironmentDamage(bool val) { invulnerable_environment_damage = val; } void SetIntoxication(int32 in_intoxication); - void ShowNumHits(); // work around function for numhits not showing on buffs - void ApplyWeaponsStance(); void TogglePassiveAlternativeAdvancement(const AA::Rank &rank, uint32 ability_id); bool UseTogglePassiveHotkey(const AA::Rank &rank); @@ -1908,7 +1905,7 @@ private: int8 last_reported_mana_percent; int8 last_reported_endurance_percent; - unsigned int AggroCount; // How many mobs are aggro on us. + uint32 AggroCount; // How many mobs are aggro on us. bool ooc_regen; float AreaHPRegen; diff --git a/zone/client_mods.cpp b/zone/client_mods.cpp index 267d2dfc5..c83d253f5 100644 --- a/zone/client_mods.cpp +++ b/zone/client_mods.cpp @@ -649,7 +649,7 @@ int64 Client::CalcBaseMana() int64 Client::CalcBaseManaRegen() { uint8 clevel = GetLevel(); - int32 regen = 0; + int64 regen = 0; if (IsSitting() || (GetHorseId() != 0)) { if (HasSkill(EQ::skills::SkillMeditate)) { regen = (((GetSkill(EQ::skills::SkillMeditate) / 10) + (clevel - (clevel / 4))) / 4) + 4; @@ -666,7 +666,7 @@ int64 Client::CalcBaseManaRegen() int64 Client::CalcManaRegen(bool bCombat) { - int regen = 0; + int64 regen = 0; auto level = GetLevel(); // so the new formulas break down with older skill caps where you don't have the skill until 4 or 8 // so for servers that want to use the old skill progression they can set this rule so they @@ -688,9 +688,9 @@ int64 Client::CalcManaRegen(bool bCombat) } } if (old) - regen = std::max(regen, 2); + regen = std::max(regen, static_cast(2)); } else if (old) { - regen = std::max(regen, 1); + regen = std::max(regen, static_cast(1)); } } diff --git a/zone/client_packet.cpp b/zone/client_packet.cpp index 97fb2c21e..d52b26cb4 100644 --- a/zone/client_packet.cpp +++ b/zone/client_packet.cpp @@ -6779,16 +6779,14 @@ void Client::Handle_OP_GMSearchCorpse(const EQApplicationPacket *app) void Client::Handle_OP_GMServers(const EQApplicationPacket *app) { - if (!worldserver.Connected()) - Message(Chat::Red, "Error: World server disconnected"); - else { - auto pack = new ServerPacket(ServerOP_ZoneStatus, strlen(GetName()) + 2); - memset(pack->pBuffer, (uint8)admin, 1); - strcpy((char *)&pack->pBuffer[1], GetName()); - worldserver.SendPacket(pack); - safe_delete(pack); - } - return; + auto pack = new ServerPacket(ServerOP_ZoneStatus, sizeof(ServerZoneStatus_Struct)); + + auto z = (ServerZoneStatus_Struct *) pack->pBuffer; + z->admin = Admin(); + strn0cpy(z->name, GetName(), sizeof(z->name)); + + worldserver.SendPacket(pack); + delete pack; } void Client::Handle_OP_GMSummon(const EQApplicationPacket *app) @@ -9147,8 +9145,14 @@ void Client::Handle_OP_ItemVerifyRequest(const EQApplicationPacket *app) } else if (inst->IsClassCommon()) { - if (!RuleB(Skills, RequireTomeHandin) && item->ItemType == EQ::item::ItemTypeSpell && (strstr((const char*)item->Name, "Tome of ") || strstr((const char*)item->Name, "Skill: "))) - { + if ( + !RuleB(Skills, RequireTomeHandin) && + item->ItemType == EQ::item::ItemTypeSpell && + ( + Strings::BeginsWith(item->Name, "Tome of ") || + Strings::BeginsWith(item->Name, "Skill: ") + ) + ) { DeleteItemInInventory(slot_id, 1, true); TrainDiscipline(item->ID); } @@ -10712,7 +10716,7 @@ void Client::Handle_OP_PetCommands(const EQApplicationPacket *app) case PET_HEALTHREPORT: { if ((mypet->GetPetType() == petAnimation && aabonuses.PetCommands[PetCommand]) || mypet->GetPetType() != petAnimation) { MessageString(Chat::PetResponse, PET_REPORT_HP, ConvertArrayF(mypet->GetHPRatio(), val1)); - mypet->ShowBuffList(this); + mypet->ShowBuffs(this); } break; } @@ -11462,10 +11466,9 @@ void Client::Handle_OP_PopupResponse(const EQApplicationPacket *app) break; case POPUPID_UPDATE_SHOWSTATSWINDOW: - if (GetTarget() && GetTarget()->IsClient()) { - GetTarget()->CastToClient()->SendStatsWindow(this, true); - } - else { + if (GetTarget() && GetTarget()->IsOfClientBot()) { + GetTarget()->SendStatsWindow(this, true); + } else { SendStatsWindow(this, true); } return; diff --git a/zone/command.cpp b/zone/command.cpp index 2fea8458e..266e57fe9 100644 --- a/zone/command.cpp +++ b/zone/command.cpp @@ -86,7 +86,6 @@ int command_init(void) if ( command_add("acceptrules", "[acceptrules] - Accept the EQEmu Agreement", AccountStatus::Player, command_acceptrules) || command_add("advnpcspawn", "[maketype|makegroup|addgroupentry|addgroupspawn][removegroupspawn|movespawn|editgroupbox|cleargroupbox]", AccountStatus::GMLeadAdmin, command_advnpcspawn) || - command_add("aggro", "[Distance] [-v] - Display aggro information for all mobs 'Distance' distance from your target. (-v is verbose Faction Information)", AccountStatus::QuestTroupe, command_aggro) || command_add("aggrozone", "[aggro] - Aggro every mob in the zone with X aggro. Default is 0. Not recommend if you're not invulnerable.", AccountStatus::GMAdmin, command_aggrozone) || command_add("ai", "[factionid/spellslist/con/guard/roambox/stop/start] - Modify AI on NPC target", AccountStatus::GMAdmin, command_ai) || command_add("appearance", "[type] [value] - Send an appearance packet for you or your target", AccountStatus::GMLeadAdmin, command_appearance) || @@ -101,12 +100,10 @@ int command_init(void) command_add("camerashake", "[Duration (Milliseconds)] [Intensity (1-10)] - Shakes the camera on everyone's screen globally.", AccountStatus::QuestTroupe, command_camerashake) || command_add("castspell", "[Spell ID] [Instant (0 = False, 1 = True, Default is 1 if Unused)] - Cast a spell", AccountStatus::Guide, command_castspell) || command_add("chat", "[Channel ID] [Message] - Send a channel message to all zones", AccountStatus::GMMgmt, command_chat) || - command_add("checklos", "Check for line of sight to your target", AccountStatus::Guide, command_checklos) || command_add("copycharacter", "[source_char_name] [dest_char_name] [dest_account_name] - Copies character to destination account", AccountStatus::GMImpossible, command_copycharacter) || command_add("corpse", "Manipulate corpses, use with no arguments for help", AccountStatus::Guide, command_corpse) || command_add("corpsefix", "Attempts to bring corpses from underneath the ground within close proximity of the player", AccountStatus::Player, command_corpsefix) || command_add("countitem", "[Item ID] - Counts the specified Item ID in your or your target's inventory", AccountStatus::GMLeadAdmin, command_countitem) || - command_add("cvs", "Summary of client versions currently online.", AccountStatus::GMMgmt, command_cvs) || command_add("damage", "[Amount] - Damage yourself or your target", AccountStatus::GMAdmin, command_damage) || command_add("databuckets", "View|Delete [key] [limit]- View data buckets, limit 50 default or Delete databucket by key", AccountStatus::QuestTroupe, command_databuckets) || command_add("date", "[Year] [Month] [Day] [Hour] [Minute] - Set EQ time (Hour and Minute are optional)", AccountStatus::EQSupport, command_date) || @@ -118,7 +115,6 @@ int command_init(void) command_add("devtools", "[Enable|Disable] - Manages Developer Tools (send no parameter for menu)", AccountStatus::GMMgmt, command_devtools) || command_add("disablerecipe", "[Recipe ID] - Disables a Recipe", AccountStatus::QuestTroupe, command_disablerecipe) || command_add("disarmtrap", "Analog for ldon disarm trap for the newer clients since we still don't have it working.", AccountStatus::QuestTroupe, command_disarmtrap) || - command_add("distance", "Reports the distance between you and your target.", AccountStatus::QuestTroupe, command_distance) || command_add("door", "Door editing command", AccountStatus::QuestTroupe, command_door) || command_add("doanim", "[Animation ID|Animation Name] [Speed] - Send an animation by ID or name at the specified speed to you or your target (Speed is optional)", AccountStatus::Guide, command_doanim) || command_add("dye", "[slot|'help'] [red] [green] [blue] [use_tint] - Dyes the specified armor slot to Red, Green, and Blue provided, allows you to bypass darkness limits.", AccountStatus::ApprenticeGuide, command_dye) || @@ -126,8 +122,6 @@ int command_init(void) command_add("dzkickplayers", "Removes all players from current expedition. (/kickplayers alternative for pre-RoF clients)", AccountStatus::Player, command_dzkickplayers) || command_add("editmassrespawn", "[name-search] [second-value] - Mass (Zone wide) NPC respawn timer editing command", AccountStatus::GMAdmin, command_editmassrespawn) || command_add("emote", "[Name|World|Zone] [type] [message] - Send an emote message by name, to the world, or to your zone (^ separator allows multiple messages to be sent at once)", AccountStatus::QuestTroupe, command_emote) || - command_add("emotesearch", "[Search Criteria] - Search for NPC Emotes", AccountStatus::QuestTroupe, command_emotesearch) || - command_add("emoteview", "Lists all NPC Emotes", AccountStatus::QuestTroupe, command_emoteview) || command_add("emptyinventory", "Clears your or your target's entire inventory (Equipment, General, Bank, and Shared Bank)", AccountStatus::GMImpossible, command_emptyinventory) || command_add("enablerecipe", "[Recipe ID] - Enables a Recipe", AccountStatus::QuestTroupe, command_enablerecipe) || command_add("endurance", "Restores your or your target's endurance.", AccountStatus::Guide, command_endurance) || @@ -137,35 +131,17 @@ int command_init(void) command_add("factionassociation", "[factionid] [amount] - triggers a faction hits via association", AccountStatus::GMLeadAdmin, command_faction_association) || command_add("feature", "Change your or your target's feature's temporarily", AccountStatus::QuestTroupe, command_feature) || command_add("size", "Change your targets size (alias of #feature size)", AccountStatus::QuestTroupe, command_feature) || - command_add("findaa", "[Search Criteria] - Search for an AA", AccountStatus::Guide, command_findaa) || - command_add("findaliases", "[Search Criteria]- Searches for available command aliases, by alias or command", AccountStatus::Player, command_findaliases) || - command_add("findcharacter", "[Search Criteria] - Search for a character", AccountStatus::Guide, command_findcharacter) || - command_add("findclass", "[Search Criteria] - Search for a class", AccountStatus::Guide, command_findclass) || - command_add("findcurrency", "[Search Criteria] - Search for an alternate currency", AccountStatus::Guide, command_findcurrency) || - command_add("findfaction", "[Search Criteria] - Search for a faction", AccountStatus::Guide, command_findfaction) || - command_add("findnpctype", "[Search Criteria] - Search database NPC types", AccountStatus::GMAdmin, command_findnpctype) || - command_add("findrace", "[Search Criteria] - Search for a race", AccountStatus::Guide, command_findrace) || - command_add("findrecipe", "[Search Criteria] - Search for a recipe", AccountStatus::Guide, command_findrecipe) || - command_add("findskill", "[Search Criteria] - Search for a skill", AccountStatus::Guide, command_findskill) || - command_add("findspell", "[Search Criteria] - Search for a spell", AccountStatus::Guide, command_findspell) || - command_add("findtask", "[Search Criteria] - Search for a task", AccountStatus::Guide, command_findtask) || - command_add("findzone", "[Search Criteria] - Search database zones", AccountStatus::GMAdmin, command_findzone) || + command_add("find", "Search command used to find various things", AccountStatus::Guide, command_find) || command_add("fixmob", "[race|gender|texture|helm|face|hair|haircolor|beard|beardcolor|heritage|tattoo|detail] [next|prev] - Manipulate appearance of your target", AccountStatus::QuestTroupe, command_fixmob) || command_add("flag", "[Status] [Account Name] - Refresh your admin status, or set an account's Admin status if arguments provided", AccountStatus::Player, command_flag) || command_add("flagedit", "Edit zone flags on your target. Use #flagedit help for more info.", AccountStatus::GMAdmin, command_flagedit) || - command_add("flags", "displays the Zone Flags of you or your target", AccountStatus::Player, command_flags) || command_add("flymode", "[0/1/2/3/4/5] - Set your or your player target's flymode to ground/flying/levitate/water/floating/levitate_running", AccountStatus::Guide, command_flymode) || - command_add("fov", "Check wether you're behind or in your target's field of view", AccountStatus::QuestTroupe, command_fov) || command_add("freeze", "Freeze your target", AccountStatus::QuestTroupe, command_freeze) || command_add("gassign", "[Grid ID] - Assign targetted NPC to predefined wandering grid id", AccountStatus::GMAdmin, command_gassign) || command_add("gearup", "Developer tool to quickly equip yourself or your target", AccountStatus::GMMgmt, command_gearup) || command_add("gender", "[0/1/2] - Change your or your target's gender to male/female/neuter", AccountStatus::Guide, command_gender) || - command_add("getplayerburiedcorpsecount", "Get your or your target's total number of buried player corpses.", AccountStatus::GMAdmin, command_getplayerburiedcorpsecount) || - command_add("getvariable", "[Variable Name] - Get the value of a variable from the database", AccountStatus::GMMgmt, command_getvariable) || - command_add("ginfo", "get group info on target.", AccountStatus::ApprenticeGuide, command_ginfo) || command_add("giveitem", "[itemid] [charges] - Summon an item onto your target's cursor. Charges are optional.", AccountStatus::GMMgmt, command_giveitem) || command_add("givemoney", "[Platinum] [Gold] [Silver] [Copper] - Gives specified amount of money to you or your player target", AccountStatus::GMMgmt, command_givemoney) || - command_add("globalview", "Lists all qglobals in cache if you were to do a quest with this target.", AccountStatus::QuestTroupe, command_globalview) || command_add("gm", "[On|Off] - Modify your or your target's GM Flag", AccountStatus::QuestTroupe, command_gm) || command_add("gmspeed", "[On|Off] - Turn GM Speed On or Off for you or your player target", AccountStatus::GMAdmin, command_gmspeed) || command_add("gmzone", "[Zone ID|Zone Short Name] [Version] [Instance Identifier] - Zones to a private GM instance (Version defaults to 0 and Instance Identifier defaults to 'gmzone' if not used)", AccountStatus::GMAdmin, command_gmzone) || @@ -174,7 +150,6 @@ int command_init(void) command_add("grid", "[add/delete] [grid_num] [wandertype] [pausetype] - Create/delete a wandering grid", AccountStatus::GMAreas, command_grid) || command_add("guild", "Guild manipulation commands. Use argument help for more info.", AccountStatus::Steward, command_guild) || command_add("haste", "[Percentage] - Set your or your target's GM Bonus Haste (100 is 100% more Attack Speed)", AccountStatus::GMAdmin, command_haste) || - command_add("hatelist", "Display hate list for NPC.", AccountStatus::QuestTroupe, command_hatelist) || command_add("heal", "Completely heal your target", AccountStatus::Steward, command_heal) || command_add("help", "[Search Criteria] - List available commands and their description, specify partial command as argument to search", AccountStatus::Player, command_help) || command_add("heromodel", "[Hero Model] [Slot] - Set your or your target's appearance to a full set of Hero's Forge Armor, if slot is set, sends exact model just to slot.", AccountStatus::GMMgmt, command_heromodel) || @@ -188,15 +163,12 @@ int command_init(void) command_add("invsnapshot", "Manipulates inventory snapshots for your current target", AccountStatus::QuestTroupe, command_invsnapshot) || command_add("invul", "[On|Off]] - Turn player target's or your invulnerable flag on or off", AccountStatus::QuestTroupe, command_invul) || command_add("ipban", "[IP] - Ban IP", AccountStatus::GMMgmt, command_ipban) || - command_add("iplookup", "[charname] - Look up IP address of charname", AccountStatus::GMMgmt, command_iplookup) || - command_add("itemsearch", "[Search Criteria] - Search for an item", AccountStatus::Steward, command_itemsearch) || command_add("kick", "[Character Name] - Disconnect a player by name", AccountStatus::GMLeadAdmin, command_kick) || command_add("kill", "Kill your target", AccountStatus::GMAdmin, command_kill) || command_add("killallnpcs", "[npc_name] - Kills all npcs by search name, leave blank for all attackable NPC's", AccountStatus::GMMgmt, command_killallnpcs) || command_add("lastname", "[Last Name] - Set your or your player target's last name (use \"-1\" to remove last name)", AccountStatus::Guide, command_lastname) || command_add("level", "[Level] - Set your or your target's level", AccountStatus::Steward, command_level) || command_add("list", "[npcs|players|corpses|doors|objects] [search] - Search entities", AccountStatus::ApprenticeGuide, command_list) || - command_add("listpetition", "List petitions", AccountStatus::Guide, command_listpetition) || command_add("lootsim", "[npc_type_id] [loottable_id] [iterations] - Runs benchmark simulations using real loot logic to report numbers and data", AccountStatus::GMImpossible, command_lootsim) || command_add("load_shared_memory", "[shared_memory_name] - Reloads shared memory and uses the input as output", AccountStatus::GMImpossible, command_load_shared_memory) || command_add("loc", "Print out your or your target's current location and heading", AccountStatus::Player, command_loc) || @@ -214,8 +186,6 @@ int command_init(void) command_add("mysql", "[Help|Query] [SQL Query] - Mysql CLI, see 'Help' for options.", AccountStatus::GMImpossible, command_mysql) || command_add("mystats", "Show details about you or your pet", AccountStatus::Guide, command_mystats) || command_add("name", "[New Name] - Rename your player target", AccountStatus::GMLeadAdmin, command_name) || - command_add("netstats", "Gets the network stats for a stream.", AccountStatus::GMMgmt, command_netstats) || - command_add("network", "Admin commands for the udp network interface.", AccountStatus::GMImpossible, command_network) || command_add("npccast", "[targetname/entityid] [spellid] - Causes NPC target to cast spellid on targetname/entityid", AccountStatus::QuestTroupe, command_npccast) || command_add("npcedit", "[column] [value] - Mega NPC editing command", AccountStatus::GMAdmin, command_npcedit) || command_add("npceditmass", "[name-search] [column] [value] - Mass (Zone wide) NPC data editing command", AccountStatus::GMAdmin, command_npceditmass) || @@ -224,7 +194,6 @@ int command_init(void) command_add("npcsay", "[Message] - Make your NPC target say a message.", AccountStatus::GMLeadAdmin, command_npcsay) || command_add("npcshout", "[Message] - Make your NPC target shout a message.", AccountStatus::GMLeadAdmin, command_npcshout) || command_add("npcspawn", "[create/add/update/remove/delete] - Manipulate spawn DB", AccountStatus::GMAreas, command_npcspawn) || - command_add("npcstats", "Show stats about target NPC", AccountStatus::QuestTroupe, command_npcstats) || command_add("npctypespawn", "[NPC ID] [Faction ID] - Spawn an NPC by ID from the database with an option of setting its Faction ID", AccountStatus::Steward, command_npctypespawn) || command_add("nudge", "Nudge your target's current position by specific values", AccountStatus::QuestTroupe, command_nudge) || command_add("nukebuffs", "[Beneficial|Detrimental|Help] - Strip all buffs by type on you or your target (no argument to remove all buffs)", AccountStatus::Guide, command_nukebuffs) || @@ -233,21 +202,16 @@ int command_init(void) command_add("oocmute", "[0|1] - Enable or Disable Server OOC", AccountStatus::GMMgmt, command_oocmute) || command_add("opcode", "Reloads all opcodes from server patch files", AccountStatus::GMMgmt, command_reload) || command_add("path", "view and edit pathing", AccountStatus::GMMgmt, command_path) || - command_add("peekinv", "[equip/gen/cursor/poss/limbo/curlim/trib/bank/shbank/allbank/trade/world/all] - Print out contents of your player target's inventory", AccountStatus::GMAdmin, command_peekinv) || command_add("peqzone", "[Zone ID|Zone Short Name] - Teleports you to the specified zone if you meet the requirements.", AccountStatus::Player, command_peqzone) || - command_add("peqzone_flags", "displays the PEQZone Flags of you or your target", AccountStatus::Player, command_peqzone_flags) || command_add("permaclass", "[Class ID] - Change your or your player target's class, changed client is disconnected", AccountStatus::QuestTroupe, command_permaclass) || command_add("permagender", "[Gender ID] - Change your or your player target's gender", AccountStatus::QuestTroupe, command_permagender) || command_add("permarace", "[Race ID] - Change your or your player target's race", AccountStatus::QuestTroupe, command_permarace) || command_add("petitems", "View your pet's items if you have one", AccountStatus::ApprenticeGuide, command_petitems) || - command_add("petitioninfo", "[petition number] - Get info about a petition", AccountStatus::ApprenticeGuide, command_petitioninfo) || command_add("picklock", "Analog for ldon pick lock for the newer clients since we still don't have it working.", AccountStatus::Player, command_picklock) || command_add("profanity", "Manage censored language.", AccountStatus::GMLeadAdmin, command_profanity) || command_add("push", "[Back Push] [Up Push] - Lets you do spell push on an NPC", AccountStatus::GMLeadAdmin, command_push) || - command_add("proximity", "Shows NPC proximity", AccountStatus::GMLeadAdmin, command_proximity) || command_add("pvp", "[On|Off] - Set you or your player target's PVP status", AccountStatus::GMAdmin, command_pvp) || command_add("qglobal", "[On|Off|View] - Toggles quest global functionality for your NPC target", AccountStatus::GMAdmin, command_qglobal) || - command_add("questerrors", "Shows quest errors.", AccountStatus::GMAdmin, command_questerrors) || command_add("race", "[racenum] - Change your or your target's race. Use racenum 0 to return to normal", AccountStatus::Guide, command_race) || command_add("raidloot", "[All|GroupLeader|RaidLeader|Selected] - Sets your Raid Loot Type if you have permission to do so.", AccountStatus::Player, command_raidloot) || command_add("randomfeatures", "Temporarily randomizes the Facial Features of your target", AccountStatus::QuestTroupe, command_randomfeatures) || @@ -269,7 +233,6 @@ int command_init(void) command_add("scribespells", "[Max level] [Min level] - Scribe all spells for you or your player target that are usable by them, up to level specified. (may freeze client for a few seconds)", AccountStatus::GMLeadAdmin, command_scribespells) || command_add("sendzonespawns", "Refresh spawn list for all clients in zone", AccountStatus::GMLeadAdmin, command_sendzonespawns) || command_add("sensetrap", "Analog for ldon sense trap for the newer clients since we still don't have it working.", AccountStatus::Player, command_sensetrap) || - command_add("serverinfo", "Get CPU, Operating System, and Process Information about the server", AccountStatus::GMMgmt, command_serverinfo) || command_add("serverlock", "[0|1] - Lock or Unlock the World Server (0 = Unlocked, 1 = Locked)", AccountStatus::GMLeadAdmin, command_serverlock) || command_add("serverrules", "Read this server's rules", AccountStatus::Player, command_serverrules) || command_add("setaapts", "[AA|Group|Raid] [AA Amount] - Set your or your player target's Available AA Points by Type", AccountStatus::GMAdmin, command_setaapts) || @@ -292,20 +255,11 @@ int command_init(void) command_add("setstartzone", "[Zone ID|Zone Short Name] - Sets your or your target's starting zone (Use '0' or 'Reset' to allow the player use of /setstartcity)", AccountStatus::QuestTroupe, command_setstartzone) || command_add("setstat", "Sets the stats to a specific value.", AccountStatus::Max, command_setstat) || command_add("setxp", "[value] - Set your or your player target's experience", AccountStatus::GMAdmin, command_setxp) || - command_add("showbuffs", "List buffs active on your target or you if no target", AccountStatus::Guide, command_showbuffs) || - command_add("shownumhits", "Shows buffs numhits for yourself.", AccountStatus::Player, command_shownumhits) || - command_add("shownpcgloballoot", "Show global loot entries for your target NPC", AccountStatus::Guide, command_shownpcgloballoot) || - command_add("showskills", "[Start Skill ID] [All] - Show the values of your or your player target's skills in a popup 50 at a time, use 'all' as second argument to show non-usable skill's values", AccountStatus::Guide, command_showskills) || - command_add("showspells", "[disciplines|spells] - Show your or your target's memorized spells or learned disciplines", AccountStatus::GMAdmin, command_showspells) || - command_add("showspellslist", "Shows spell list of targeted NPC", AccountStatus::GMAdmin, command_showspellslist) || - command_add("showstats", "Show details about you or your target", AccountStatus::Guide, command_showstats) || - command_add("showzonegloballoot", "Show global loot entries for your current zone", AccountStatus::Guide, command_showzonegloballoot) || - command_add("showzonepoints", "Show zone points for current zone", AccountStatus::Guide, command_showzonepoints) || + command_add("show", "List command used to show various things", AccountStatus::Guide, command_show) || command_add("shutdown", "Shut this zone process down", AccountStatus::GMLeadAdmin, command_shutdown) || command_add("spawn", "[name] [race] [level] [material] [hp] [gender] [class] [priweapon] [secweapon] [merchantid] - Spawn an NPC", AccountStatus::Steward, command_spawn) || command_add("spawneditmass", "[Search Criteria] [Edit Option] [Edit Value] [Apply] Mass editing spawn command (Apply is optional, 0 = False, 1 = True, default is False)", AccountStatus::GMLeadAdmin, command_spawneditmass) || command_add("spawnfix", "Find targeted NPC in database based on its X/Y/heading and update the database to make it spawn at your current location/heading.", AccountStatus::GMAreas, command_spawnfix) || - command_add("spawnstatus", "[All|Disabled|Enabled|Spawn ID] - Show respawn timer status", AccountStatus::GMAdmin, command_spawnstatus) || command_add("stun", "[duration] - Stuns you or your target for duration", AccountStatus::GMAdmin, command_stun) || command_add("summon", "[Character Name] - Summons your corpse, NPC, or player target, or by character name if specified", AccountStatus::QuestTroupe, command_summon) || command_add("summonburiedplayercorpse", "Summons the target's oldest buried corpse, if any exist.", AccountStatus::GMAdmin, command_summonburiedplayercorpse) || @@ -317,12 +271,10 @@ int command_init(void) command_add("petname", "[newname] - Temporarily renames your pet. Leave name blank to restore the original name.", AccountStatus::GMAdmin, command_petname) || command_add("texture", "[Texture] [Helmet Texture] - Change your or your target's texture (Helmet Texture defaults to 0 if not used)", AccountStatus::Steward, command_texture) || command_add("time", "[Hour] [Minute] - Set world time to specified time", AccountStatus::EQSupport, command_time) || - command_add("timers", "Display persistent timers for target", AccountStatus::GMMgmt, command_timers) || command_add("timezone", "[Hour] [Minutes] - Set timezone (Minutes are optional)", AccountStatus::EQSupport, command_timezone) || command_add("title", "[Title] - Set your or your player target's title (use \"-1\" to remove title)", AccountStatus::Guide, command_title) || command_add("titlesuffix", "[Title Suffix] - Set your or your player target's title suffix (use \"-1\" to remove title suffix)", AccountStatus::Guide, command_titlesuffix) || command_add("traindisc", "[level] - Trains all the disciplines usable by the target, up to level specified. (may freeze client for a few seconds)", AccountStatus::GMLeadAdmin, command_traindisc) || - command_add("trapinfo", "Gets infomation about the traps currently spawned in the zone.", AccountStatus::QuestTroupe, command_trapinfo) || command_add("tune", "Calculate statistical values related to combat.", AccountStatus::GMAdmin, command_tune) || command_add("undye", "Remove dye from all of your or your target's armor slots", AccountStatus::GMAdmin, command_undye) || command_add("unfreeze", "Unfreeze your target", AccountStatus::QuestTroupe, command_unfreeze) || @@ -333,22 +285,12 @@ int command_init(void) command_add("untraindisc", "[Spell ID] - Untrain your or your target's discipline by Spell ID", AccountStatus::GMCoder, command_untraindisc) || command_add("untraindiscs", "Untrains all disciplines from your target.", AccountStatus::GMCoder, command_untraindiscs) || command_add("updatechecksum", "update client checksum", AccountStatus::GMImpossible, command_updatechecksum) || - command_add("uptime", "[zone server id] - Get uptime of worldserver, or zone server if argument provided", AccountStatus::Steward, command_uptime) || - command_add("version", "Display current version of EQEmu server", AccountStatus::Player, command_version) || - command_add("viewcurrencies", "View your or your target's currencies", AccountStatus::GMAdmin, command_viewcurrencies) || - command_add("viewnpctype", "[NPC ID] - Show stats for an NPC by NPC ID", AccountStatus::GMAdmin, command_viewnpctype) || - command_add("viewpetition", "[petition number] - View a petition", AccountStatus::ApprenticeGuide, command_viewpetition) || - command_add("viewrecipe", "[Recipe ID] - Show a recipe's entries", AccountStatus::GMAdmin, command_viewrecipe) || - command_add("viewzoneloot", "[item id] - Allows you to search a zone's loot for a specific item ID. (0 shows all loot in the zone)", AccountStatus::QuestTroupe, command_viewzoneloot) || command_add("wc", "[Slot ID] [Material] [Hero Forge Model] [Elite Material] - Sets the specified slot for you or your target to a material, Hero Forge Model and Elite Material are optional", AccountStatus::GMMgmt, command_wc) || command_add("weather", "[0/1/2/3] (Off/Rain/Snow/Manual) - Change the weather", AccountStatus::QuestTroupe, command_weather) || - command_add("who", "[search]", AccountStatus::ApprenticeGuide, command_who) || command_add("worldshutdown", "Shut down world and all zones", AccountStatus::GMMgmt, command_worldshutdown) || command_add("wp", "[add|delete] [grid_id] [pause] [waypoint_id] [-h] - Add or delete a waypoint by grid ID. (-h to use current heading)", AccountStatus::GMAreas, command_wp) || command_add("wpadd", "[pause] [-h] - Add your current location as a waypoint to your NPC target's AI path. (-h to use current heading)", AccountStatus::GMAreas, command_wpadd) || - command_add("wpinfo", "Show waypoint info about your NPC target", AccountStatus::GMAreas, command_wpinfo) || command_add("worldwide", "Performs world-wide GM functions such as cast (can be extended for other commands). Use caution", AccountStatus::GMImpossible, command_worldwide) || - command_add("xtargets", "[New Max XTargets] - Show your or your target's XTargets and optionally set max XTargets.", AccountStatus::GMImpossible, command_xtargets) || command_add("zclip", "[Minimum Clip] [Maximum Clip] [Fog Minimum Clip] [Fog Maximum Clip] [Permanent (0 = False, 1 = True)] - Change zone clipping", AccountStatus::QuestTroupe, command_zclip) || command_add("zcolor", "[Red] [Green] [Blue] [Permanent (0 = False, 1 = True)] - Change sky color", AccountStatus::QuestTroupe, command_zcolor) || command_add("zheader", "[Zone ID|Zone Short Name] [Version] - Load a zone header from the database", AccountStatus::QuestTroupe, command_zheader) || @@ -357,12 +299,10 @@ int command_init(void) command_add("zoneinstance", "[Instance ID] [X] [Y] [Z] - Teleport to specified Instance by ID (coordinates are optional)", AccountStatus::Guide, command_zone_instance) || command_add("zonelock", "[List|Lock|Unlock] [Zone ID|Zone Short Name] - Set or get lock status of a Zone by ID or Short Name", AccountStatus::GMAdmin, command_zonelock) || command_add("zoneshutdown", "[shortname] - Shut down a zone server", AccountStatus::GMLeadAdmin, command_zoneshutdown) || - command_add("zonestatus", "Show connected zoneservers, synonymous with /servers", AccountStatus::GMLeadAdmin, command_zonestatus) || command_add("zopp", "Troubleshooting command - Sends a fake item packet to you. No server reference is created.", AccountStatus::GMImpossible, command_zopp) || command_add("zsafecoords", "[X] [Y] [Z] [Heading] [Permanent (0 = False, 1 = True)] - Set the current zone's safe coordinates", AccountStatus::QuestTroupe, command_zsafecoords) || command_add("zsave", " Saves zheader to the database", AccountStatus::QuestTroupe, command_zsave) || command_add("zsky", "[Sky Type] [Permanent (0 = False, 1 = True)] - Change zone sky type", AccountStatus::QuestTroupe, command_zsky) || - command_add("zstats", "Show info about zone header", AccountStatus::QuestTroupe, command_zstats) || command_add("zunderworld", "[Z] [Permanent (0 = False, 1 = True)] - Change zone underworld Z", AccountStatus::QuestTroupe, command_zunderworld) ) { command_deinit(); @@ -375,6 +315,104 @@ int command_init(void) std::vector> injected_command_settings; std::vector orphaned_command_settings; + // static aliases + struct StaticAlias { + std::string command; + std::vector aliases; + }; + + std::vector static_aliases = { + { + .command = "find", + .aliases = { + "fi", + "fn", + "fs", + "fz", + "findaa", + "findcharacter", + "findclass", + "findcurrency", + "finddeity", + "findemote", + "findfaction", + "finditem", + "findlanguage", + "findnpc", + "findnpctype", + "findrace", + "findrecipe", + "findskill", + "findspell", + "findtask", + "findzone", + "itemsearch" + } + }, + { + .command = "show", + .aliases = { + "aggro", + "checklos", + "cvs", + "distance", + "emoteview", + "flags", + "fov", + "getplayerburiedcorpsecount", + "getvariable", + "ginfo", + "globalview", + "hatelist", + "iplookup", + "listpetition", + "network", + "netstats", + "npcstats", + "peekinv", + "petitioninfo", + "peqzone_flags", + "proximity", + "questerrors", + "serverinfo", + "showbuffs", + "shownpcgloballoot", + "showskills", + "showspells", + "showspellslist", + "showstats", + "showzonegloballoot", + "showzonepoints", + "spawnstatus", + "timers", + "trapinfo", + "uptime", + "version", + "viewcurrencies", + "viewnpctype", + "viewpetition", + "viewrecipe", + "viewzoneloot", + "who", + "wpinfo", + "xtargets", + "zonestatus", + "zstats" + } + }, + }; + + // inject static aliases + for (auto& cs : command_settings) { + for (const auto& sa : static_aliases) { + if (cs.first == sa.command) { + for (const auto& alias : sa.aliases) { + cs.second.second.emplace_back(alias); + } + } + } + } + for (const auto& cs : command_settings) { auto cl = commandlist.find(cs.first); if (cl == commandlist.end()) { @@ -386,7 +424,7 @@ int command_init(void) } } - if (orphaned_command_settings.size()) { + if (!orphaned_command_settings.empty()) { if (!database.UpdateOrphanedCommandSettings(orphaned_command_settings)) { LogInfo("Failed to process 'Orphaned Commands' update operation."); } @@ -396,16 +434,16 @@ int command_init(void) for (const auto& w : working_cl) { auto cs = command_settings.find(w.first); if (cs == command_settings.end()) { - injected_command_settings.emplace_back(std::pair(w.first, w.second->admin)); + injected_command_settings.emplace_back(w.first, w.second->admin); LogInfo( - "New Command [{}] found... Adding to `command_settings` table with admin [{}]...", + "New Command [{}] found. Adding to `command_settings` table with admin [{}]...", w.first, w.second->admin ); if (w.second->admin == AccountStatus::Player) { LogCommands( - "command_init(): Warning: Command [{}] defaulting to admin level 0!", + "Warning: Command [{}] defaulting to admin level 0!", w.first ); } @@ -415,7 +453,7 @@ int command_init(void) w.second->admin = cs->second.first; LogCommands( - "command_init(): - Command [{}] set to admin level [{}]", + "Command [{}] set to admin level [{}]", w.first, cs->second.first ); @@ -449,7 +487,7 @@ int command_init(void) } } - if (injected_command_settings.size()) { + if (!injected_command_settings.empty()) { if (!database.UpdateInjectedCommandSettings(injected_command_settings)) { LogInfo("Failed to process 'Injected Commands' update operation."); } @@ -932,7 +970,6 @@ void command_bot(Client *c, const Seperator *sep) #include "gm_commands/acceptrules.cpp" #include "gm_commands/advnpcspawn.cpp" -#include "gm_commands/aggro.cpp" #include "gm_commands/aggrozone.cpp" #include "gm_commands/ai.cpp" #include "gm_commands/appearance.cpp" @@ -945,12 +982,10 @@ void command_bot(Client *c, const Seperator *sep) #include "gm_commands/camerashake.cpp" #include "gm_commands/castspell.cpp" #include "gm_commands/chat.cpp" -#include "gm_commands/checklos.cpp" #include "gm_commands/copycharacter.cpp" #include "gm_commands/corpse.cpp" #include "gm_commands/corpsefix.cpp" #include "gm_commands/countitem.cpp" -#include "gm_commands/cvs.cpp" #include "gm_commands/damage.cpp" #include "gm_commands/databuckets.cpp" #include "gm_commands/date.cpp" @@ -962,7 +997,6 @@ void command_bot(Client *c, const Seperator *sep) #include "gm_commands/devtools.cpp" #include "gm_commands/disablerecipe.cpp" #include "gm_commands/disarmtrap.cpp" -#include "gm_commands/distance.cpp" #include "gm_commands/doanim.cpp" #include "gm_commands/door.cpp" #include "gm_commands/door_manipulation.cpp" @@ -971,8 +1005,6 @@ void command_bot(Client *c, const Seperator *sep) #include "gm_commands/dzkickplayers.cpp" #include "gm_commands/editmassrespawn.cpp" #include "gm_commands/emote.cpp" -#include "gm_commands/emotesearch.cpp" -#include "gm_commands/emoteview.cpp" #include "gm_commands/emptyinventory.cpp" #include "gm_commands/enablerecipe.cpp" #include "gm_commands/endurance.cpp" @@ -980,34 +1012,17 @@ void command_bot(Client *c, const Seperator *sep) #include "gm_commands/exptoggle.cpp" #include "gm_commands/faction.cpp" #include "gm_commands/feature.cpp" -#include "gm_commands/findaa.cpp" -#include "gm_commands/findcharacter.cpp" -#include "gm_commands/findclass.cpp" -#include "gm_commands/findcurrency.cpp" -#include "gm_commands/findfaction.cpp" -#include "gm_commands/findnpctype.cpp" -#include "gm_commands/findrace.cpp" -#include "gm_commands/findrecipe.cpp" -#include "gm_commands/findskill.cpp" -#include "gm_commands/findspell.cpp" -#include "gm_commands/findtask.cpp" -#include "gm_commands/findzone.cpp" +#include "gm_commands/find.cpp" #include "gm_commands/fixmob.cpp" #include "gm_commands/flag.cpp" #include "gm_commands/flagedit.cpp" -#include "gm_commands/flags.cpp" #include "gm_commands/flymode.cpp" -#include "gm_commands/fov.cpp" #include "gm_commands/freeze.cpp" #include "gm_commands/gassign.cpp" #include "gm_commands/gearup.cpp" #include "gm_commands/gender.cpp" -#include "gm_commands/getplayerburiedcorpsecount.cpp" -#include "gm_commands/getvariable.cpp" -#include "gm_commands/ginfo.cpp" #include "gm_commands/giveitem.cpp" #include "gm_commands/givemoney.cpp" -#include "gm_commands/globalview.cpp" #include "gm_commands/gm.cpp" #include "gm_commands/gmspeed.cpp" #include "gm_commands/gmzone.cpp" @@ -1016,7 +1031,6 @@ void command_bot(Client *c, const Seperator *sep) #include "gm_commands/grid.cpp" #include "gm_commands/guild.cpp" #include "gm_commands/haste.cpp" -#include "gm_commands/hatelist.cpp" #include "gm_commands/heal.cpp" #include "gm_commands/heromodel.cpp" #include "gm_commands/hideme.cpp" @@ -1028,15 +1042,12 @@ void command_bot(Client *c, const Seperator *sep) #include "gm_commands/invsnapshot.cpp" #include "gm_commands/invul.cpp" #include "gm_commands/ipban.cpp" -#include "gm_commands/iplookup.cpp" -#include "gm_commands/itemsearch.cpp" #include "gm_commands/kick.cpp" #include "gm_commands/kill.cpp" #include "gm_commands/killallnpcs.cpp" #include "gm_commands/lastname.cpp" #include "gm_commands/level.cpp" #include "gm_commands/list.cpp" -#include "gm_commands/listpetition.cpp" #include "gm_commands/lootsim.cpp" #include "gm_commands/loc.cpp" #include "gm_commands/logs.cpp" @@ -1053,8 +1064,6 @@ void command_bot(Client *c, const Seperator *sep) #include "gm_commands/mysql.cpp" #include "gm_commands/mystats.cpp" #include "gm_commands/name.cpp" -#include "gm_commands/netstats.cpp" -#include "gm_commands/network.cpp" #include "gm_commands/npccast.cpp" #include "gm_commands/npcedit.cpp" #include "gm_commands/npceditmass.cpp" @@ -1063,7 +1072,6 @@ void command_bot(Client *c, const Seperator *sep) #include "gm_commands/npcsay.cpp" #include "gm_commands/npcshout.cpp" #include "gm_commands/npcspawn.cpp" -#include "gm_commands/npcstats.cpp" #include "gm_commands/npctypespawn.cpp" #include "gm_commands/nudge.cpp" #include "gm_commands/nukebuffs.cpp" @@ -1071,22 +1079,17 @@ void command_bot(Client *c, const Seperator *sep) #include "gm_commands/object.cpp" #include "gm_commands/oocmute.cpp" #include "gm_commands/path.cpp" -#include "gm_commands/peekinv.cpp" #include "gm_commands/peqzone.cpp" -#include "gm_commands/peqzone_flags.cpp" #include "gm_commands/permaclass.cpp" #include "gm_commands/permagender.cpp" #include "gm_commands/permarace.cpp" #include "gm_commands/petitems.cpp" -#include "gm_commands/petitioninfo.cpp" #include "gm_commands/petname.cpp" #include "gm_commands/picklock.cpp" #include "gm_commands/profanity.cpp" -#include "gm_commands/proximity.cpp" #include "gm_commands/push.cpp" #include "gm_commands/pvp.cpp" #include "gm_commands/qglobal.cpp" -#include "gm_commands/questerrors.cpp" #include "gm_commands/race.cpp" #include "gm_commands/raidloot.cpp" #include "gm_commands/randomfeatures.cpp" @@ -1106,7 +1109,6 @@ void command_bot(Client *c, const Seperator *sep) #include "gm_commands/scribespells.cpp" #include "gm_commands/sendzonespawns.cpp" #include "gm_commands/sensetrap.cpp" -#include "gm_commands/serverinfo.cpp" #include "gm_commands/serverlock.cpp" #include "gm_commands/serverrules.cpp" #include "gm_commands/set_adventure_points.cpp" @@ -1129,20 +1131,11 @@ void command_bot(Client *c, const Seperator *sep) #include "gm_commands/setstartzone.cpp" #include "gm_commands/setstat.cpp" #include "gm_commands/setxp.cpp" -#include "gm_commands/showbuffs.cpp" -#include "gm_commands/shownpcgloballoot.cpp" -#include "gm_commands/shownumhits.cpp" -#include "gm_commands/showskills.cpp" -#include "gm_commands/showspells.cpp" -#include "gm_commands/showspellslist.cpp" -#include "gm_commands/showstats.cpp" -#include "gm_commands/showzonegloballoot.cpp" -#include "gm_commands/showzonepoints.cpp" +#include "gm_commands/show.cpp" #include "gm_commands/shutdown.cpp" #include "gm_commands/spawn.cpp" #include "gm_commands/spawneditmass.cpp" #include "gm_commands/spawnfix.cpp" -#include "gm_commands/spawnstatus.cpp" #include "gm_commands/faction_association.cpp" #include "gm_commands/stun.cpp" #include "gm_commands/summon.cpp" @@ -1154,12 +1147,10 @@ void command_bot(Client *c, const Seperator *sep) #include "gm_commands/tempname.cpp" #include "gm_commands/texture.cpp" #include "gm_commands/time.cpp" -#include "gm_commands/timers.cpp" #include "gm_commands/timezone.cpp" #include "gm_commands/title.cpp" #include "gm_commands/titlesuffix.cpp" #include "gm_commands/traindisc.cpp" -#include "gm_commands/trapinfo.cpp" #include "gm_commands/tune.cpp" #include "gm_commands/undye.cpp" #include "gm_commands/unfreeze.cpp" @@ -1170,22 +1161,12 @@ void command_bot(Client *c, const Seperator *sep) #include "gm_commands/updatechecksum.cpp" #include "gm_commands/untraindisc.cpp" #include "gm_commands/untraindiscs.cpp" -#include "gm_commands/uptime.cpp" -#include "gm_commands/version.cpp" -#include "gm_commands/viewcurrencies.cpp" -#include "gm_commands/viewnpctype.cpp" -#include "gm_commands/viewpetition.cpp" -#include "gm_commands/viewrecipe.cpp" -#include "gm_commands/viewzoneloot.cpp" #include "gm_commands/wc.cpp" #include "gm_commands/weather.cpp" -#include "gm_commands/who.cpp" #include "gm_commands/worldshutdown.cpp" #include "gm_commands/worldwide.cpp" #include "gm_commands/wp.cpp" #include "gm_commands/wpadd.cpp" -#include "gm_commands/wpinfo.cpp" -#include "gm_commands/xtargets.cpp" #include "gm_commands/zclip.cpp" #include "gm_commands/zcolor.cpp" #include "gm_commands/zheader.cpp" @@ -1193,11 +1174,9 @@ void command_bot(Client *c, const Seperator *sep) #include "gm_commands/zonebootup.cpp" #include "gm_commands/zonelock.cpp" #include "gm_commands/zoneshutdown.cpp" -#include "gm_commands/zonestatus.cpp" #include "gm_commands/zone_instance.cpp" #include "gm_commands/zopp.cpp" #include "gm_commands/zsafecoords.cpp" #include "gm_commands/zsave.cpp" #include "gm_commands/zsky.cpp" -#include "gm_commands/zstats.cpp" #include "gm_commands/zunderworld.cpp" diff --git a/zone/command.h b/zone/command.h index 9e6e1229d..34cad6fad 100644 --- a/zone/command.h +++ b/zone/command.h @@ -33,12 +33,11 @@ std::string GetModifyNPCStatDescription(std::string stat); void SendNPCEditSubCommands(Client *c); void SendRuleSubCommands(Client *c); void SendGuildSubCommands(Client *c); -void SendPeekInvSubCommands(Client *c); +void SendShowInventorySubCommands(Client *c); // Commands void command_acceptrules(Client *c, const Seperator *sep); void command_advnpcspawn(Client *c, const Seperator *sep); -void command_aggro(Client *c, const Seperator *sep); void command_aggrozone(Client *c, const Seperator *sep); void command_ai(Client *c, const Seperator *sep); void command_appearance(Client *c, const Seperator *sep); @@ -52,12 +51,10 @@ void command_bugs(Client *c, const Seperator *sep); void command_camerashake(Client *c, const Seperator *sep); void command_castspell(Client *c, const Seperator *sep); void command_chat(Client *c, const Seperator *sep); -void command_checklos(Client *c, const Seperator *sep); void command_copycharacter(Client *c, const Seperator *sep); void command_corpse(Client *c, const Seperator *sep); void command_corpsefix(Client *c, const Seperator *sep); void command_countitem(Client *c, const Seperator *sep); -void command_cvs(Client *c, const Seperator *sep); void command_damage(Client *c, const Seperator *sep); void command_databuckets(Client *c, const Seperator *sep); void command_date(Client *c, const Seperator *sep); @@ -70,15 +67,12 @@ void command_devtools(Client *c, const Seperator *sep); void command_disablerecipe(Client *c, const Seperator *sep); void command_disarmtrap(Client *c, const Seperator *sep); void command_door(Client *c, const Seperator *sep); -void command_distance(Client *c, const Seperator *sep); void command_doanim(Client *c, const Seperator *sep); void command_dye(Client *c, const Seperator *sep); void command_dz(Client *c, const Seperator *sep); void command_dzkickplayers(Client *c, const Seperator *sep); void command_editmassrespawn(Client *c, const Seperator *sep); void command_emote(Client *c, const Seperator *sep); -void command_emotesearch(Client *c, const Seperator *sep); -void command_emoteview(Client *c, const Seperator *sep); void command_emptyinventory(Client *c, const Seperator *sep); void command_enablerecipe(Client *c, const Seperator *sep); void command_endurance(Client *c, const Seperator *sep); @@ -87,35 +81,17 @@ void command_exptoggle(Client *c, const Seperator *sep); void command_faction(Client *c, const Seperator *sep); void command_faction_association(Client *c, const Seperator *sep); void command_feature(Client *c, const Seperator *sep); -void command_findaa(Client *c, const Seperator *sep); -void command_findaliases(Client *c, const Seperator *sep); -void command_findcharacter(Client *c, const Seperator *sep); -void command_findclass(Client *c, const Seperator *sep); -void command_findcurrency(Client *c, const Seperator *sep); -void command_findfaction(Client *c, const Seperator *sep); -void command_findnpctype(Client *c, const Seperator *sep); -void command_findrace(Client *c, const Seperator *sep); -void command_findrecipe(Client *c, const Seperator *sep); -void command_findskill(Client *c, const Seperator *sep); -void command_findspell(Client *c, const Seperator *sep); -void command_findtask(Client *c, const Seperator *sep); -void command_findzone(Client *c, const Seperator *sep); +void command_find(Client *c, const Seperator *sep); void command_fixmob(Client *c, const Seperator *sep); void command_flag(Client *c, const Seperator *sep); void command_flagedit(Client *c, const Seperator *sep); -void command_flags(Client *c, const Seperator *sep); void command_flymode(Client *c, const Seperator *sep); -void command_fov(Client *c, const Seperator *sep); void command_freeze(Client *c, const Seperator *sep); void command_gassign(Client *c, const Seperator *sep); void command_gearup(Client *c, const Seperator *sep); void command_gender(Client *c, const Seperator *sep); -void command_getplayerburiedcorpsecount(Client *c, const Seperator *sep); -void command_getvariable(Client *c, const Seperator *sep); -void command_ginfo(Client *c, const Seperator *sep); void command_giveitem(Client *c, const Seperator *sep); void command_givemoney(Client *c, const Seperator *sep); -void command_globalview(Client *c, const Seperator *sep); void command_gm(Client *c, const Seperator *sep); void command_gmspeed(Client *c, const Seperator *sep); void command_gmzone(Client *c, const Seperator *sep); @@ -124,7 +100,6 @@ void command_goto(Client *c, const Seperator *sep); void command_grid(Client *c, const Seperator *sep); void command_guild(Client *c, const Seperator *sep); void command_haste(Client *c, const Seperator *sep); -void command_hatelist(Client *c, const Seperator *sep); void command_heal(Client *c, const Seperator *sep); void command_help(Client *c, const Seperator *sep); void command_heromodel(Client *c, const Seperator *sep); @@ -138,15 +113,12 @@ void command_interrupt(Client *c, const Seperator *sep); void command_invsnapshot(Client *c, const Seperator *sep); void command_invul(Client *c, const Seperator *sep); void command_ipban(Client *c, const Seperator *sep); -void command_iplookup(Client *c, const Seperator *sep); -void command_itemsearch(Client *c, const Seperator *sep); void command_kick(Client *c, const Seperator *sep); void command_killallnpcs(Client *c, const Seperator *sep); void command_kill(Client *c, const Seperator *sep); void command_lastname(Client *c, const Seperator *sep); void command_level(Client *c, const Seperator *sep); void command_list(Client *c, const Seperator *sep); -void command_listpetition(Client *c, const Seperator *sep); void command_lootsim(Client *c, const Seperator *sep); void command_load_shared_memory(Client *c, const Seperator *sep); void command_loc(Client *c, const Seperator *sep); @@ -164,8 +136,6 @@ void command_myskills(Client *c, const Seperator *sep); void command_mysql(Client *c, const Seperator *sep); void command_mystats(Client *c, const Seperator *sep); void command_name(Client *c, const Seperator *sep); -void command_netstats(Client *c, const Seperator *sep); -void command_network(Client *c, const Seperator *sep); void command_npccast(Client *c, const Seperator *sep); void command_npcedit(Client *c, const Seperator *sep); void command_npceditmass(Client *c, const Seperator *sep); @@ -174,7 +144,6 @@ void command_npcloot(Client *c, const Seperator *sep); void command_npcsay(Client *c, const Seperator *sep); void command_npcshout(Client *c, const Seperator *sep); void command_npcspawn(Client *c, const Seperator *sep); -void command_npcstats(Client *c, const Seperator *sep); void command_npctypespawn(Client *c, const Seperator *sep); void command_nudge(Client *c, const Seperator *sep); void command_nukebuffs(Client *c, const Seperator *sep); @@ -182,21 +151,16 @@ void command_nukeitem(Client *c, const Seperator *sep); void command_object(Client *c, const Seperator *sep); void command_oocmute(Client *c, const Seperator *sep); void command_path(Client *c, const Seperator *sep); -void command_peekinv(Client *c, const Seperator *sep); void command_peqzone(Client *c, const Seperator *sep); -void command_peqzone_flags(Client *c, const Seperator *sep); void command_permaclass(Client *c, const Seperator *sep); void command_permagender(Client *c, const Seperator *sep); void command_permarace(Client *c, const Seperator *sep); void command_petitems(Client *c, const Seperator *sep); -void command_petitioninfo(Client *c, const Seperator *sep); void command_picklock(Client *c, const Seperator *sep); void command_profanity(Client *c, const Seperator *sep); -void command_proximity(Client *c, const Seperator *sep); void command_push(Client *c, const Seperator *sep); void command_pvp(Client *c, const Seperator *sep); void command_qglobal(Client *c, const Seperator *sep); -void command_questerrors(Client *c, const Seperator *sep); void command_race(Client *c, const Seperator *sep); void command_raidloot(Client* c, const Seperator* sep); void command_randomfeatures(Client *c, const Seperator *sep); @@ -217,7 +181,6 @@ void command_scribespell(Client *c, const Seperator *sep); void command_scribespells(Client *c, const Seperator *sep); void command_sendzonespawns(Client *c, const Seperator *sep); void command_sensetrap(Client *c, const Seperator *sep); -void command_serverinfo(Client *c, const Seperator *sep); void command_serverrules(Client *c, const Seperator *sep); void command_set_adventure_points(Client *c, const Seperator *sep); void command_setaapts(Client *c, const Seperator *sep); @@ -239,20 +202,11 @@ void command_setskillall(Client *c, const Seperator *sep); void command_setstartzone(Client *c, const Seperator *sep); void command_setstat(Client *c, const Seperator *sep); void command_setxp(Client *c, const Seperator *sep); -void command_showbuffs(Client *c, const Seperator *sep); -void command_shownumhits(Client *c, const Seperator *sep); -void command_shownpcgloballoot(Client *c, const Seperator *sep); -void command_showskills(Client *c, const Seperator *sep); -void command_showspells(Client *c, const Seperator *sep); -void command_showspellslist(Client *c, const Seperator *sep); -void command_showstats(Client *c, const Seperator *sep); -void command_showzonegloballoot(Client *c, const Seperator *sep); -void command_showzonepoints(Client *c, const Seperator *sep); +void command_show(Client *c, const Seperator *sep); void command_shutdown(Client *c, const Seperator *sep); void command_spawn(Client *c, const Seperator *sep); void command_spawneditmass(Client *c, const Seperator *sep); void command_spawnfix(Client *c, const Seperator *sep); -void command_spawnstatus(Client *c, const Seperator *sep); void command_stun(Client *c, const Seperator *sep); void command_summon(Client *c, const Seperator *sep); void command_summonburiedplayercorpse(Client *c, const Seperator *sep); @@ -264,12 +218,10 @@ void command_tempname(Client *c, const Seperator *sep); void command_petname(Client *c, const Seperator *sep); void command_texture(Client *c, const Seperator *sep); void command_time(Client *c, const Seperator *sep); -void command_timers(Client *c, const Seperator *sep); void command_timezone(Client *c, const Seperator *sep); void command_title(Client *c, const Seperator *sep); void command_titlesuffix(Client *c, const Seperator *sep); void command_traindisc(Client *c, const Seperator *sep); -void command_trapinfo(Client *c, const Seperator *sep); void command_tune(Client *c, const Seperator *sep); void command_undye(Client *c, const Seperator *sep); void command_unfreeze(Client *c, const Seperator *sep); @@ -280,22 +232,12 @@ void command_unscribespells(Client *c, const Seperator *sep); void command_untraindisc(Client *c, const Seperator *sep); void command_untraindiscs(Client *c, const Seperator *sep); void command_updatechecksum(Client* c, const Seperator* sep); -void command_uptime(Client *c, const Seperator *sep); -void command_version(Client *c, const Seperator *sep); -void command_viewcurrencies(Client *c, const Seperator *sep); -void command_viewnpctype(Client *c, const Seperator *sep); -void command_viewpetition(Client *c, const Seperator *sep); -void command_viewrecipe(Client *c, const Seperator *sep); -void command_viewzoneloot(Client *c, const Seperator *sep); void command_wc(Client *c, const Seperator *sep); void command_weather(Client *c, const Seperator *sep); -void command_who(Client *c, const Seperator *sep); void command_worldshutdown(Client *c, const Seperator *sep); void command_wp(Client *c, const Seperator *sep); void command_wpadd(Client *c, const Seperator *sep); -void command_wpinfo(Client *c, const Seperator *sep); void command_worldwide(Client *c, const Seperator *sep); -void command_xtargets(Client *c, const Seperator *sep); void command_zclip(Client *c, const Seperator *sep); void command_zcolor(Client *c, const Seperator *sep); void command_zheader(Client *c, const Seperator *sep); @@ -304,12 +246,10 @@ void command_zone_instance(Client *c, const Seperator *sep); void command_zonebootup(Client *c, const Seperator *sep); void command_zonelock(Client *c, const Seperator *sep); void command_zoneshutdown(Client *c, const Seperator *sep); -void command_zonestatus(Client *c, const Seperator *sep); void command_zopp(Client *c, const Seperator *sep); void command_zsafecoords(Client *c, const Seperator *sep); void command_zsave(Client *c, const Seperator *sep); void command_zsky(Client *c, const Seperator *sep); -void command_zstats(Client *c, const Seperator *sep); void command_zunderworld(Client *c, const Seperator *sep); #include "bot.h" diff --git a/zone/effects.cpp b/zone/effects.cpp index 06292b28e..0570251f2 100644 --- a/zone/effects.cpp +++ b/zone/effects.cpp @@ -622,8 +622,8 @@ bool Client::TrainDiscipline(uint32 itemid) { const std::string item_name = item->Name; if ( - item_name.substr(0, 5) != std::string("Tome ") && - item_name.substr(0, 7) != std::string("Skill: ") + !Strings::BeginsWith(item_name, "Tome of ") && + !Strings::BeginsWith(item_name, "Skill: ") ) { Message(Chat::Red, "This item is not a tome."); //summon them the item back... @@ -709,8 +709,8 @@ bool Client::MemorizeSpellFromItem(uint32 item_id) { const std::string item_name = item->Name; if ( - item_name.substr(0, 7) != std::string("Spell: ") && - item_name.substr(0, 6) != std::string("Song: ") + !Strings::BeginsWith(item_name, "Spell: ") && + !Strings::BeginsWith(item_name, "Song: ") ) { Message(Chat::Red, "This item is not a scroll."); SummonItem(item_id); diff --git a/zone/embparser.cpp b/zone/embparser.cpp index 6763b5fa7..a0867553a 100644 --- a/zone/embparser.cpp +++ b/zone/embparser.cpp @@ -46,7 +46,10 @@ void perl_register_group(); void perl_register_raid(); void perl_register_inventory(); void perl_register_questitem(); +void perl_register_questitem_data(); +void perl_register_spawn(); void perl_register_spell(); +void perl_register_stat_bonuses(); void perl_register_hateentry(); void perl_register_object(); void perl_register_doors(); @@ -1068,7 +1071,10 @@ void PerlembParser::MapFunctions() perl_register_raid(); perl_register_inventory(); perl_register_questitem(); + perl_register_questitem_data(); + perl_register_spawn(); perl_register_spell(); + perl_register_stat_bonuses(); perl_register_hateentry(); perl_register_object(); perl_register_doors(); diff --git a/zone/entity.h b/zone/entity.h index a1de10ae7..3bf128fc7 100644 --- a/zone/entity.h +++ b/zone/entity.h @@ -539,7 +539,7 @@ public: inline const std::unordered_map &GetObjectList() { return object_list; } inline const std::unordered_map &GetDoorsList() { return door_list; } - std::unordered_map &GetCloseMobList(Mob *mob, float distance = 0); + std::unordered_map &GetCloseMobList(Mob *mob, float distance = 0.0f); void DepopAll(int NPCTypeID, bool StartSpawnTimer = true); @@ -553,7 +553,7 @@ public: bool add_self_to_other_lists = false ); - void GetTrapInfo(Client* client); + void GetTrapInfo(Client* c); bool IsTrapGroupSpawned(uint32 trap_id, uint8 group); void UpdateAllTraps(bool respawn, bool repopnow = false); void ClearTrapPointers(); diff --git a/zone/gm_commands/aggro.cpp b/zone/gm_commands/aggro.cpp deleted file mode 100755 index 926904131..000000000 --- a/zone/gm_commands/aggro.cpp +++ /dev/null @@ -1,28 +0,0 @@ -#include "../client.h" - -void command_aggro(Client *c, const Seperator *sep) -{ - int arguments = sep->argnum; - if (!arguments || !sep->IsNumber(1)) { - c->Message(Chat::White, "Usage: #aggro [Distance] [-v] (-v is verbose Faction Information)"); - return; - } - - if ( - !c->GetTarget() || - ( - c->GetTarget() && - !c->GetTarget()->IsNPC() - ) - ) { - c->Message(Chat::White, "You must target an NPC to use this command."); - return; - } - - NPC* target = c->GetTarget()->CastToNPC(); - - float distance = Strings::ToFloat(sep->arg[1]); - bool verbose = !strcasecmp("-v", sep->arg[2]); - entity_list.DescribeAggro(c, target, distance, verbose); -} - diff --git a/zone/gm_commands/checklos.cpp b/zone/gm_commands/checklos.cpp deleted file mode 100755 index 150e74649..000000000 --- a/zone/gm_commands/checklos.cpp +++ /dev/null @@ -1,23 +0,0 @@ -#include "../client.h" - -void command_checklos(Client *c, const Seperator *sep) -{ - if (!c->GetTarget()) { - c->Message(Chat::White, "You must have a target to use this command."); - return; - } - - auto target = c->GetTarget(); - - bool has_los = c->CheckLosFN(target); - - c->Message( - Chat::White, - fmt::format( - "You {}have line of sight to {}.", - has_los ? "" : "do not ", - c->GetTargetDescription(target) - ).c_str() - ); -} - diff --git a/zone/gm_commands/copycharacter.cpp b/zone/gm_commands/copycharacter.cpp index 136093005..84af27677 100755 --- a/zone/gm_commands/copycharacter.cpp +++ b/zone/gm_commands/copycharacter.cpp @@ -2,26 +2,31 @@ void command_copycharacter(Client *c, const Seperator *sep) { - if (sep->argnum < 3) { + if ( + sep->argnum < 3 || + sep->IsNumber(1) || + sep->IsNumber(2) || + sep->IsNumber(3) + ) { c->Message( Chat::White, - "Usage: [source_character_name] [destination_character_name] [destination_account_name]" + "Usage: #copycharacter [source_character_name] [destination_character_name] [destination_account_name]" ); return; } - std::string source_character_name = sep->arg[1]; - std::string destination_character_name = sep->arg[2]; - std::string destination_account_name = sep->arg[3]; + const std::string& source_character_name = sep->arg[1]; + const std::string& destination_character_name = sep->arg[2]; + const std::string& destination_account_name = sep->arg[3]; - bool result = database.CopyCharacter( + const bool result = database.CopyCharacter( source_character_name, destination_character_name, destination_account_name ); c->Message( - Chat::Yellow, + Chat::White, fmt::format( "Character Copy [{}] to [{}] via account [{}] [{}]", source_character_name, diff --git a/zone/gm_commands/cvs.cpp b/zone/gm_commands/cvs.cpp deleted file mode 100755 index a9f99c369..000000000 --- a/zone/gm_commands/cvs.cpp +++ /dev/null @@ -1,14 +0,0 @@ -#include "../client.h" -#include "../worldserver.h" - -extern WorldServer worldserver; - -void command_cvs(Client *c, const Seperator *sep) -{ - auto pack = new ServerPacket(ServerOP_ClientVersionSummary, sizeof(ServerRequestClientVersionSummary_Struct)); - auto srcvss = (ServerRequestClientVersionSummary_Struct *) pack->pBuffer; - strn0cpy(srcvss->Name, c->GetName(), sizeof(srcvss->Name)); - worldserver.SendPacket(pack); - safe_delete(pack); -} - diff --git a/zone/gm_commands/distance.cpp b/zone/gm_commands/distance.cpp deleted file mode 100755 index f69446129..000000000 --- a/zone/gm_commands/distance.cpp +++ /dev/null @@ -1,22 +0,0 @@ -#include "../client.h" - -void command_distance(Client *c, const Seperator *sep) -{ - if (c->GetTarget()) { - Mob *target = c->GetTarget(); - if (c != target) { - c->Message( - Chat::White, - fmt::format( - "{} is {:.2f} units from you.", - c->GetTargetDescription(target), - Distance( - c->GetPosition(), - target->GetPosition() - ) - ).c_str() - ); - } - } -} - diff --git a/zone/gm_commands/emotesearch.cpp b/zone/gm_commands/emotesearch.cpp deleted file mode 100755 index 209f46c71..000000000 --- a/zone/gm_commands/emotesearch.cpp +++ /dev/null @@ -1,142 +0,0 @@ -#include "../client.h" - -void command_emotesearch(Client *c, const Seperator *sep) -{ - auto arguments = sep->argnum; - if (!arguments) { - c->Message(Chat::White, "Usage: #emotesearch [Emote ID]"); - c->Message(Chat::White, "Usage: #emotesearch [Search Crteria]"); - return; - } - - auto emote_count = 0; - auto emote_number = 1; - - std::string search_criteria = sep->argplus[1]; - bool found_by_id = false; - - if (!sep->IsNumber(1)) { - LinkedListIterator iterator(zone->NPCEmoteList); - iterator.Reset(); - while (iterator.MoreElements()) { - auto &e = iterator.GetData(); - auto current_text = Strings::ToLower(e->text); - - if (Strings::Contains(current_text, Strings::ToLower(search_criteria))) { - c->Message( - Chat::White, - fmt::format( - "Emote {} | Emote ID: {}", - emote_number, - e->emoteid - ).c_str() - ); - - c->Message( - Chat::White, - fmt::format( - "Emote {} | Event: {} ({}) Type: {} ({})", - emote_number, - EQ::constants::GetEmoteEventTypeName(e->event_), - e->event_, - EQ::constants::GetEmoteTypeName(e->type), - e->type - ).c_str() - ); - - c->Message( - Chat::White, - fmt::format( - "Emote {} | Text: {}", - emote_number, - e->text - ).c_str() - ); - - emote_count++; - emote_number++; - } - - if (emote_count == 50) { - break; - } - - iterator.Advance(); - } - } else { - auto emote_id = Strings::ToUnsignedInt(search_criteria); - - LinkedListIterator iterator(zone->NPCEmoteList); - iterator.Reset(); - while (iterator.MoreElements()) { - auto &e = iterator.GetData(); - if (emote_id == e->emoteid) { - found_by_id = true; - - c->Message( - Chat::White, - fmt::format( - "Emote {} | Event: {} ({}) Type: {} ({})", - emote_number, - EQ::constants::GetEmoteEventTypeName(e->event_), - e->event_, - EQ::constants::GetEmoteTypeName(e->type), - e->type - ).c_str() - ); - - c->Message( - Chat::White, - fmt::format( - "Emote {} | Text: {}", - emote_number, - e->text - ).c_str() - ); - - emote_count++; - emote_number++; - } - - if (emote_count == 50) { - break; - } - - iterator.Advance(); - } - } - - auto found_string = ( - found_by_id ? - fmt::format("ID {}", search_criteria) : - search_criteria - ); - - if (!emote_count) { - c->Message( - Chat::White, - fmt::format( - "No Emotes found matching {}.", - found_string - ).c_str() - ); - } else if (emote_count == 50) { - c->Message( - Chat::White, - fmt::format( - "50 Emotes shown matching {}, too many results.", - found_string - ).c_str() - ); - } else { - c->Message( - Chat::White, - fmt::format( - "{} Emote{} found matching {}.", - emote_count, - emote_count != 1 ? "s" : "", - found_string - ).c_str() - ); - } -} diff --git a/zone/gm_commands/find.cpp b/zone/gm_commands/find.cpp new file mode 100644 index 000000000..910c0a677 --- /dev/null +++ b/zone/gm_commands/find.cpp @@ -0,0 +1,99 @@ +#include "../client.h" +#include "find/aa.cpp" +#include "find/character.cpp" +#include "find/class.cpp" +#include "find/currency.cpp" +#include "find/deity.cpp" +#include "find/emote.cpp" +#include "find/faction.cpp" +#include "find/item.cpp" +#include "find/language.cpp" +#include "find/npctype.cpp" +#include "find/race.cpp" +#include "find/recipe.cpp" +#include "find/skill.cpp" +#include "find/spell.cpp" +#include "find/task.cpp" +#include "find/zone.cpp" + +void command_find(Client *c, const Seperator *sep) +{ + // Cmd represents a command + // variables are short to save space horizontally + // when adding a new sub-command, add it to the vector below + struct Cmd { + std::string cmd{}; // command + std::string u{}; // usage + void (*fn)(Client *c, const Seperator *sep) = nullptr; // function + std::vector a{}; // aliases + }; + + std::vector commands = { + Cmd{.cmd = "aa", .u = "aa [Search Criteria]", .fn = FindAA, .a = {"#findaa"}}, + Cmd{.cmd = "character", .u = "character [Search Criteria]", .fn = FindCharacter, .a = {"#findcharacter"}}, + Cmd{.cmd = "class", .u = "class [Search Criteria]", .fn = FindClass, .a = {"#findclass"}}, + Cmd{.cmd = "currency", .u = "currency [Search Criteria]", .fn = FindCurrency, .a = {"#findcurrency"}}, + Cmd{.cmd = "deity", .u = "deity [Search Criteria]", .fn = FindDeity, .a = {"#finddeity"}}, + Cmd{.cmd = "emote", .u = "emote [Search Criteria]", .fn = FindEmote, .a = {"#findemote"}}, + Cmd{.cmd = "faction", .u = "faction [Search Criteria]", .fn = FindFaction, .a = {"#findfaction"}}, + Cmd{.cmd = "item", .u = "item [Search Criteria]", .fn = FindItem, .a = {"#fi", "#finditem"}}, + Cmd{.cmd = "language", .u = "language [Search Criteria]", .fn = FindLanguage, .a = {"#findlanguage"}}, + Cmd{ + .cmd = "npctype", .u = "npctype [Search Criteria]", .fn = FindNPCType, .a = { + "#fn", + "#findnpc", + "#findnpctype" + } + }, + Cmd{.cmd = "race", .u = "race [Search Criteria]", .fn = FindRace, .a = {"#findrace"}}, + Cmd{.cmd = "recipe", .u = "recipe [Search Criteria]", .fn = FindRecipe, .a = {"#findrecipe"}}, + Cmd{.cmd = "skill", .u = "skill [Search Criteria]", .fn = FindSkill, .a = {"#findskill"}}, + Cmd{.cmd = "spell", .u = "spell [Search Criteria]", .fn = FindSpell, .a = {"#fs", "#findspell"}}, + Cmd{.cmd = "task", .u = "task [Search Criteria]", .fn = FindTask, .a = {"#findtask"}}, + Cmd{.cmd = "zone", .u = "zone [Search Criteria]", .fn = FindZone, .a = {"#fz", "#findzone"}}, + }; + + // Check for arguments + const auto arguments = sep->argnum; + if (!arguments) { + for (const auto &cmd: commands) { + c->Message(Chat::White, fmt::format("Usage: #find {}", cmd.u).c_str()); + } + return; + } + + // look for alias or command + for (const auto &cmd: commands) { + // Check for alias first + for (const auto &alias: cmd.a) { + if (!alias.empty() && alias == Strings::ToLower(sep->arg[0])) { + // build string from sep args + std::vector args = {}; + + // skip the first arg + for (auto i = 1; i <= arguments; i++) { + args.emplace_back(sep->arg[i]); + } + + // build the rewrite string + std::string rewrite = fmt::format("#find {} {}", cmd.cmd, Strings::Join(args, " ")); + + // rewrite to #find + c->SendGMCommand(rewrite); + return; + } + } + + // Check for command + if (cmd.cmd == Strings::ToLower(sep->arg[1])) { + cmd.fn(c, sep); + return; + } + } + + // Command not found + c->Message(Chat::White, "Command not found. Usage: #find [command]"); + for (const auto &cmd: commands) { + c->Message(Chat::White, fmt::format("Usage: #find {}", cmd.u).c_str()); + } +} diff --git a/zone/gm_commands/find/aa.cpp b/zone/gm_commands/find/aa.cpp new file mode 100644 index 000000000..fd1ce0bd4 --- /dev/null +++ b/zone/gm_commands/find/aa.cpp @@ -0,0 +1,88 @@ +#include "../../client.h" + +void FindAA(Client *c, const Seperator *sep) +{ + if (sep->IsNumber(2)) { + const auto aa_id = Strings::ToInt(sep->arg[2]); + const auto& aa_name = zone->GetAAName(aa_id); + if (!aa_name.empty()) { + c->Message( + Chat::White, + fmt::format( + "AA {} | {}", + Strings::Commify(aa_id), + aa_name + ).c_str() + ); + + return; + } + + c->Message( + Chat::White, + fmt::format( + "AA ID {} was not found.", + Strings::Commify(aa_id) + ).c_str() + ); + + return; + } + + const auto& search_criteria = Strings::ToLower(sep->argplus[2]); + + auto found_count = 0; + + std::map ordered_aas; + + for (const auto &a: zone->aa_abilities) { + ordered_aas[a.second.get()->first->id] = a.second.get()->name; + } + + for (const auto &a: ordered_aas) { + const auto& aa_name = zone->GetAAName(a.first); + if (!aa_name.empty()) { + const auto& aa_name_lower = Strings::ToLower(aa_name); + if (!Strings::Contains(aa_name_lower, search_criteria)) { + continue; + } + + c->Message( + Chat::White, + fmt::format( + "AA {} | {}", + Strings::Commify(a.first), + aa_name + ).c_str() + ); + + found_count++; + + if (found_count == 50) { + break; + } + } + } + + if (found_count == 50) { + c->Message( + Chat::White, + fmt::format( + "50 AAs were found matching '{}', max reached.", + sep->argplus[2] + ).c_str() + ); + + return; + } + + c->Message( + Chat::White, + fmt::format( + "{} AA{} found matching '{}'.", + found_count, + found_count != 1 ? "s" : "", + sep->argplus[2] + ).c_str() + ); +} diff --git a/zone/gm_commands/find/character.cpp b/zone/gm_commands/find/character.cpp new file mode 100644 index 000000000..9aeab28f1 --- /dev/null +++ b/zone/gm_commands/find/character.cpp @@ -0,0 +1,95 @@ +#include "../../client.h" +#include "../../common/repositories/character_data_repository.h" + +void FindCharacter(Client *c, const Seperator *sep) +{ + if (sep->IsNumber(2)) { + const auto character_id = Strings::ToUnsignedInt(sep->arg[2]); + + const auto& e = CharacterDataRepository::FindOne(content_db, character_id); + if (!e.id) { + c->Message( + Chat::White, + fmt::format( + "Character ID {} does not exist or is invalid.", + Strings::Commify(character_id) + ).c_str() + ); + + return; + } + + c->Message( + Chat::White, + fmt::format( + "Character ID {} | {}", + Strings::Commify(character_id), + e.name + ).c_str() + ); + + return; + } + + const auto search_criteria = Strings::ToLower(sep->argplus[2]); + + const auto& l = CharacterDataRepository::GetWhere( + content_db, + fmt::format( + "LOWER(`name`) LIKE '%%{}%%' ORDER BY `id` ASC LIMIT 50", + search_criteria + ) + ); + + if (l.empty()) { + c->Message( + Chat::White, + fmt::format( + "No characters found matching '{}'.", + sep->argplus[2] + ).c_str() + ); + } + + auto found_count = 0; + + for (const auto& e : l) { + c->Message( + Chat::White, + fmt::format( + "Character ID {} | {}", + Strings::Commify(e.id), + e.name + ).c_str() + ); + + found_count++; + + if (found_count == 50) { + break; + } + } + + if (found_count == 50) { + c->Message( + Chat::White, + fmt::format( + "50 Characters found matching '{}', max reached.", + sep->argplus[2] + ).c_str() + ); + + return; + } + + c->Message( + Chat::White, + fmt::format( + "{} Character{} found matching '{}'.", + found_count, + found_count != 1 ? "s" : "", + sep->argplus[2] + ).c_str() + ); +} + diff --git a/zone/gm_commands/find/class.cpp b/zone/gm_commands/find/class.cpp new file mode 100644 index 000000000..c838e0a93 --- /dev/null +++ b/zone/gm_commands/find/class.cpp @@ -0,0 +1,80 @@ +#include "../../client.h" + +void FindClass(Client *c, const Seperator *sep) +{ + if (sep->IsNumber(2)) { + const auto class_id = Strings::ToInt(sep->arg[2]); + if (EQ::ValueWithin(class_id, WARRIOR, BERSERKER)) { + const std::string& class_name = GetClassIDName(class_id); + c->Message( + Chat::White, + fmt::format( + "Class {} | {}{}", + class_id, + class_name, + ( + IsPlayerClass(class_id) ? + fmt::format( + " ({})", + Strings::Commify(GetPlayerClassBit(class_id)) + ) : + "" + ) + ).c_str() + ); + + return; + } + + c->Message( + Chat::White, + fmt::format( + "Class ID {} was not found.", + class_id + ).c_str() + ); + + return; + } + + const auto& search_criteria = Strings::ToLower(sep->argplus[2]); + + auto found_count = 0; + + for (uint16 class_id = WARRIOR; class_id <= MERCENARY_MASTER; class_id++) { + const std::string& class_name = GetClassIDName(class_id); + const auto& class_name_lower = Strings::ToLower(class_name); + if (!Strings::Contains(class_name_lower, search_criteria)) { + continue; + } + + c->Message( + Chat::White, + fmt::format( + "Class {} | {}{}", + class_id, + class_name, + ( + IsPlayerClass(class_id) ? + fmt::format( + " | ({})", + Strings::Commify(GetPlayerClassBit(class_id)) + ) : + "" + ) + ).c_str() + ); + + found_count++; + } + + c->Message( + Chat::White, + fmt::format( + "{} Class{} found matching '{}'.", + found_count, + found_count != 1 ? "es" : "", + sep->argplus[2] + ).c_str() + ); +} diff --git a/zone/gm_commands/find/currency.cpp b/zone/gm_commands/find/currency.cpp new file mode 100644 index 000000000..dde937824 --- /dev/null +++ b/zone/gm_commands/find/currency.cpp @@ -0,0 +1,131 @@ +#include "../../client.h" + +void FindCurrency(Client *c, const Seperator *sep) +{ + const auto can_summon_items = c->Admin() >= GetCommandStatus(c, "summonitem"); + + if (sep->IsNumber(2)) { + const auto item_id = Strings::ToUnsignedInt(sep->arg[2]); + const auto currency_id = zone->GetCurrencyID(item_id); + + if (!currency_id) { + c->Message( + Chat::White, + fmt::format( + "There is no currency with an item ID of {}.", + Strings::Commify(item_id) + ).c_str() + ); + + return; + } + + const auto item_data = database.GetItem(item_id); + if (!item_data) { + c->Message( + Chat::White, + fmt::format( + "Item ID {} does not exist.", + Strings::Commify(item_id) + ).c_str() + ); + + return; + } + + c->Message( + Chat::White, + fmt::format( + "Currency {} | {}{}", + currency_id, + database.CreateItemLink(item_id), + ( + can_summon_items ? + fmt::format( + " | {}", + Saylink::Silent( + fmt::format( + "#summonitem {} {}", + item_id, + item_data->StackSize + ), + "Summon" + ) + ) : + "" + ) + ).c_str() + ); + + return; + } + + const auto& search_criteria = Strings::ToLower(sep->argplus[2]); + + auto found_count = 0; + + for (const auto& e : zone->AlternateCurrencies) { + const auto item_data = database.GetItem(e.item_id); + if (!item_data) { + continue; + } + + const auto& item_name = Strings::ToLower(item_data->Name); + + if (!Strings::Contains(item_name, search_criteria)) { + continue; + } + + c->Message( + Chat::White, + fmt::format( + "Currency {} | {}{}", + e.id, + database.CreateItemLink(e.item_id), + ( + can_summon_items ? + fmt::format( + " | {}", + Saylink::Silent( + fmt::format( + "#summonitem {} {}", + e.item_id, + item_data->StackSize + ), + "Summon" + ) + ) : + "" + ) + ).c_str() + ); + + found_count++; + + if (found_count == 50) { + break; + } + } + + if (found_count == 50) { + c->Message( + Chat::White, + fmt::format( + "50 Currencies found matching '{}', max reached.", + sep->argplus[2] + ).c_str() + ); + + return; + } + + c->Message( + Chat::White, + fmt::format( + "{} Currenc{} found matching '{}'.", + found_count, + found_count != 1 ? "ies" : "y", + sep->argplus[2] + ).c_str() + ); +} diff --git a/zone/gm_commands/find/deity.cpp b/zone/gm_commands/find/deity.cpp new file mode 100644 index 000000000..25d9365d7 --- /dev/null +++ b/zone/gm_commands/find/deity.cpp @@ -0,0 +1,69 @@ +#include "../../client.h" + +void FindDeity(Client *c, const Seperator *sep) +{ + if (sep->IsNumber(2)) { + const auto deity_id = static_cast(Strings::ToInt(sep->arg[2])); + const auto& deity_name = EQ::deity::GetDeityName(deity_id); + if (!deity_name.empty()) { + const auto deity_bit = EQ::deity::GetDeityBitmask(deity_id); + + c->Message( + Chat::White, + fmt::format( + "Deity {} | {} ({})", + deity_id, + deity_name, + Strings::Commify(deity_bit) + ).c_str() + ); + + return; + } + + c->Message( + Chat::White, + fmt::format( + "Deity ID {} was not found.", + deity_id + ).c_str() + ); + + return; + } + + const auto& search_criteria = Strings::ToLower(sep->argplus[2]); + + auto found_count = 0; + + for (const auto& d : EQ::deity::GetDeityMap()) { + const auto& deity_name_lower = Strings::ToLower(d.second); + if (!Strings::Contains(deity_name_lower, search_criteria)) { + continue; + } + + const auto deity_bit = EQ::deity::GetDeityBitmask(d.first); + + c->Message( + Chat::White, + fmt::format( + "Deity {} | {} ({})", + d.first, + d.second, + Strings::Commify(deity_bit) + ).c_str() + ); + + found_count++; + } + + c->Message( + Chat::White, + fmt::format( + "{} Deit{} found matching '{}'.", + found_count, + found_count != 1 ? "ies" : "y", + sep->argplus[2] + ).c_str() + ); +} diff --git a/zone/gm_commands/find/emote.cpp b/zone/gm_commands/find/emote.cpp new file mode 100644 index 000000000..c6926caf8 --- /dev/null +++ b/zone/gm_commands/find/emote.cpp @@ -0,0 +1,133 @@ +#include "../../client.h" + +void FindEmote(Client *c, const Seperator *sep) +{ + uint32 found_count = 0; + + if (sep->IsNumber(2)) { + auto emote_id = Strings::ToUnsignedInt(sep->arg[2]); + + LinkedListIterator iterator(zone->NPCEmoteList); + iterator.Reset(); + while (iterator.MoreElements()) { + auto &e = iterator.GetData(); + if (emote_id == e->emoteid) { + c->Message( + Chat::White, + fmt::format( + "Emote {} | Event: {} ({}) Type: {} ({})", + e->emoteid, + EQ::constants::GetEmoteEventTypeName(e->event_), + e->event_, + EQ::constants::GetEmoteTypeName(e->type), + e->type + ).c_str() + ); + + c->Message( + Chat::White, + fmt::format( + "Emote {} | Text: {}", + e->emoteid, + e->text + ).c_str() + ); + + found_count++; + } + + if (found_count == 50) { + break; + } + + iterator.Advance(); + } + + if (found_count == 50) { + c->Message( + Chat::White, + fmt::format( + "50 Emotes shown matching ID '{}', max reached.", + emote_id + ).c_str() + ); + + return; + } + + c->Message( + Chat::White, + fmt::format( + "{} Emote{} found matching ID '{}'.", + found_count, + found_count != 1 ? "s" : "", + emote_id + ).c_str() + ); + + return; + } + + const std::string& search_criteria = sep->argplus[2]; + + LinkedListIterator iterator(zone->NPCEmoteList); + iterator.Reset(); + while (iterator.MoreElements()) { + auto &e = iterator.GetData(); + + const std::string& current_text = Strings::ToLower(e->text); + + if (Strings::Contains(current_text, Strings::ToLower(search_criteria))) { + c->Message( + Chat::White, + fmt::format( + "Emote {} | Event: {} ({}) Type: {} ({})", + e->emoteid, + EQ::constants::GetEmoteEventTypeName(e->event_), + e->event_, + EQ::constants::GetEmoteTypeName(e->type), + e->type + ).c_str() + ); + + c->Message( + Chat::White, + fmt::format( + "Emote {} | Text: {}", + e->emoteid, + e->text + ).c_str() + ); + + found_count++; + } + + if (found_count == 50) { + break; + } + + iterator.Advance(); + } + + if (found_count == 50) { + c->Message( + Chat::White, + fmt::format( + "50 Emotes shown matching '{}', max reached.", + search_criteria + ).c_str() + ); + + return; + } + + c->Message( + Chat::White, + fmt::format( + "{} Emote{} found matching '{}'.", + found_count, + found_count != 1 ? "s" : "", + search_criteria + ).c_str() + ); +} diff --git a/zone/gm_commands/find/faction.cpp b/zone/gm_commands/find/faction.cpp new file mode 100644 index 000000000..f8412d013 --- /dev/null +++ b/zone/gm_commands/find/faction.cpp @@ -0,0 +1,84 @@ +#include "../../client.h" + +void FindFaction(Client *c, const Seperator *sep) +{ + if (sep->IsNumber(2)) { + const auto faction_id = Strings::ToInt(sep->arg[2]); + const auto& faction_name = content_db.GetFactionName(faction_id); + if (!faction_name.empty()) { + c->Message( + Chat::White, + fmt::format( + "Faction {} | {}", + Strings::Commify(faction_id), + faction_name + ).c_str() + ); + + return; + } + + c->Message( + Chat::White, + fmt::format( + "Faction ID {} was not found.", + Strings::Commify(faction_id) + ).c_str() + ); + + return; + } + + const auto& search_criteria = Strings::ToLower(sep->argplus[2]); + auto found_count = 0; + const auto max_faction_id = content_db.GetMaxFaction(); + + for (uint32 faction_id = 0; faction_id < max_faction_id; faction_id++) { + const auto& faction_name = content_db.GetFactionName(faction_id); + const auto& faction_name_lower = Strings::ToLower(faction_name); + if (faction_name.empty()) { + continue; + } + + if (!Strings::Contains(faction_name_lower, search_criteria)) { + continue; + } + + c->Message( + Chat::White, + fmt::format( + "Faction {} | {}", + Strings::Commify(faction_id), + faction_name + ).c_str() + ); + + found_count++; + + if (found_count == 50) { + break; + } + } + + if (found_count == 50) { + c->Message( + Chat::White, + fmt::format( + "50 Factions found matching '{}', max reached.", + sep->argplus[2] + ).c_str() + ); + + return; + } + + c->Message( + Chat::White, + fmt::format( + "{} Faction{} found matching '{}'.", + found_count, + found_count != 1 ? "s" : "", + sep->argplus[2] + ).c_str() + ); +} diff --git a/zone/gm_commands/find/item.cpp b/zone/gm_commands/find/item.cpp new file mode 100644 index 000000000..a0400f521 --- /dev/null +++ b/zone/gm_commands/find/item.cpp @@ -0,0 +1,135 @@ +#include "../../client.h" +#include "../../common/repositories/items_repository.h" + +void FindItem(Client *c, const Seperator *sep) +{ + if (sep->IsNumber(2)) { + const auto item_id = Strings::ToUnsignedInt(sep->arg[2]); + const auto* item = database.GetItem(item_id); + if (item) { + std::string summon_links = Saylink::Silent( + fmt::format( + "#si {}", + item_id + ), + "X" + ); + + if (item->Stackable && item->StackSize > 1) { + summon_links += fmt::format( + " | {}", + Saylink::Silent( + fmt::format( + "#si {} {}", + item_id, + item->StackSize + ), + std::to_string(item->StackSize) + ) + ); + } + + c->Message( + Chat::White, + fmt::format( + "{} | {}", + summon_links, + database.CreateItemLink(item_id) + ).c_str() + ); + + return; + } + + c->Message( + Chat::White, + fmt::format( + "Item ID {} not found", + item_id + ).c_str() + ); + + return; + } + + const auto& search_criteria = Strings::ToLower(sep->argplus[2]); + + const auto& l = ItemsRepository::GetItemIDsBySearchCriteria(content_db, search_criteria, 50); + + if (l.empty()) { + c->Message( + Chat::White, + fmt::format( + "No items were found matching '{}'.", + sep->argplus[2] + ).c_str() + ); + + return; + } + + auto found_count = 0; + + for (const auto& e : l) { + const auto* item = database.GetItem(e); + std::string summon_links = Saylink::Silent( + fmt::format( + "#si {}", + e + ), + "X" + ); + + if (item->Stackable && item->StackSize > 1) { + summon_links += fmt::format( + " | {}", + Saylink::Silent( + fmt::format( + "#si {} {}", + e, + item->StackSize + ), + std::to_string(item->StackSize) + ) + ); + } + + c->Message( + Chat::White, + fmt::format( + "{} | {}", + summon_links, + database.CreateItemLink(e) + ).c_str() + ); + + found_count++; + + if (found_count == 50) { + break; + } + } + + if (found_count == 50) { + c->Message( + Chat::White, + fmt::format( + "50 Items found matching '{}', max reached.", + sep->argplus[2] + ).c_str() + ); + + return; + } + + c->Message( + Chat::White, + fmt::format( + "{} Item{} found matching '{}'.", + found_count, + found_count != 1 ? "s" :"", + sep->argplus[2] + ).c_str() + ); +} + diff --git a/zone/gm_commands/find/language.cpp b/zone/gm_commands/find/language.cpp new file mode 100644 index 000000000..217e54bfe --- /dev/null +++ b/zone/gm_commands/find/language.cpp @@ -0,0 +1,64 @@ +#include "../../client.h" +#include "../../common/languages.h" + +void FindLanguage(Client *c, const Seperator *sep) +{ + if (sep->IsNumber(2)) { + const auto language_id = Strings::ToInt(sep->arg[2]); + if (EQ::ValueWithin(language_id, LANG_COMMON_TONGUE, LANG_UNKNOWN)) { + c->Message( + Chat::White, + fmt::format( + "Language {} | {}", + language_id, + EQ::constants::GetLanguageName(language_id) + ).c_str() + ); + + return; + } + + c->Message( + Chat::White, + fmt::format( + "Language ID {} was not found.", + language_id + ).c_str() + ); + + return; + } + + const auto& search_criteria = Strings::ToLower(sep->argplus[2]); + + auto found_count = 0; + + for (const auto& l : EQ::constants::GetLanguageMap()) { + const auto& language_name_lower = Strings::ToLower(l.second); + if (!Strings::Contains(language_name_lower, search_criteria)) { + continue; + } + + c->Message( + Chat::White, + fmt::format( + "Language {} | {}", + l.first, + l.second + ).c_str() + ); + + found_count++; + } + + c->Message( + Chat::White, + fmt::format( + "{} Language{} found matching '{}'.", + found_count, + found_count != 1 ? "s" : "", + sep->argplus[2] + ).c_str() + ); +} + diff --git a/zone/gm_commands/find/npctype.cpp b/zone/gm_commands/find/npctype.cpp new file mode 100644 index 000000000..bf8fc95d6 --- /dev/null +++ b/zone/gm_commands/find/npctype.cpp @@ -0,0 +1,94 @@ +#include "../../client.h" + +void FindNPCType(Client *c, const Seperator *sep) +{ + std::string query = "SELECT `id`, `name` FROM npc_types WHERE "; + const std::string& search_criteria = sep->argplus[2]; + if (sep->IsNumber(2)) { + const auto npc_id = Strings::ToUnsignedInt(sep->arg[2]); + + query += fmt::format( + "id = {}", + npc_id + ); + } else { + query += fmt::format( + "`name` LIKE '%%{}%%'", + Strings::Escape(search_criteria) + ); + } + + query += " ORDER BY `id` ASC LIMIT 50"; + + auto results = content_db.QueryDatabase(query); + if (!results.Success() || !results.RowCount()) { + c->Message( + Chat::White, + fmt::format( + "No NPCs matching '{}' were found.", + search_criteria + ).c_str() + ); + + return; + } + + const auto can_spawn_npcs = c->Admin() >= GetCommandStatus(c, "#npctypespawn"); + + auto found_count = 0; + + for (auto row : results) { + auto found_number = (found_count + 1); + if (found_count == 50) { + break; + } + + c->Message( + Chat::White, + fmt::format( + "NPC {} | {}{}", + Strings::Commify(row[0]), + row[1], + ( + can_spawn_npcs ? + fmt::format( + " | {}", + Saylink::Silent( + fmt::format( + "#npctypespawn {}", + row[0] + ), + "Spawn" + ) + ) : + "" + ) + ).c_str() + ); + + found_count++; + } + + if (found_count == 50) { + c->Message( + Chat::White, + fmt::format( + "50 NPCs found matching '{}', max reached.", + search_criteria + ).c_str() + ); + + return; + } + + c->Message( + Chat::White, + fmt::format( + "{} NPC{} found matching '{}'.", + found_count, + found_count != 1 ? "s" : "", + search_criteria + ).c_str() + ); +} + diff --git a/zone/gm_commands/find/race.cpp b/zone/gm_commands/find/race.cpp new file mode 100644 index 000000000..1b9fb23e7 --- /dev/null +++ b/zone/gm_commands/find/race.cpp @@ -0,0 +1,96 @@ +#include "../../client.h" + +void FindRace(Client *c, const Seperator *sep) +{ + if (sep->IsNumber(2)) { + const auto race_id = static_cast(Strings::ToUnsignedInt(sep->arg[2])); + const std::string& race_name = GetRaceIDName(race_id); + if (EQ::ValueWithin(race_id, RACE_HUMAN_1, RACE_PEGASUS_732)) { + c->Message( + Chat::White, + fmt::format( + "Race {} | {}{}", + race_id, + race_name, + ( + IsPlayerRace(race_id) ? + fmt::format( + " ({})", + Strings::Commify(GetPlayerRaceBit(race_id)) + ) : + "" + ) + ).c_str() + ); + + return; + } + + c->Message( + Chat::White, + fmt::format( + "Race ID {} was not found.", + race_id + ).c_str() + ); + + return; + } + + const auto& search_criteria = Strings::ToLower(sep->argplus[2]); + + auto found_count = 0; + + for (uint16 race_id = RACE_HUMAN_1; race_id <= RACE_PEGASUS_732; race_id++) { + std::string race_name = GetRaceIDName(race_id); + auto race_name_lower = Strings::ToLower(race_name); + if (!Strings::Contains(race_name_lower, search_criteria)) { + continue; + } + + c->Message( + Chat::White, + fmt::format( + "Race {} | {}{}", + race_id, + race_name, + ( + IsPlayerRace(race_id) ? + fmt::format( + " ({})", + Strings::Commify(GetPlayerRaceBit(race_id)) + ) : + "" + ) + ).c_str() + ); + + found_count++; + + if (found_count == 50) { + break; + } + } + + if (found_count == 50) { + c->Message( + Chat::White, + fmt::format( + "50 Races found matching '{}', max reached.", + sep->argplus[2] + ).c_str() + ); + + return; + } + + c->Message( + Chat::White, + fmt::format( + "{} Race{} found matching '{}'.", + found_count, + found_count != 1 ? "s" : "", + sep->argplus[2] + ).c_str() + ); +} diff --git a/zone/gm_commands/find/recipe.cpp b/zone/gm_commands/find/recipe.cpp new file mode 100644 index 000000000..2a675dc26 --- /dev/null +++ b/zone/gm_commands/find/recipe.cpp @@ -0,0 +1,130 @@ +#include "../../client.h" +#include "../../command.h" +#include "../../common/repositories/tradeskill_recipe_repository.h" + +void FindRecipe(Client *c, const Seperator *sep) +{ + const auto can_view_recipes = c->Admin() >= GetCommandStatus(c, "viewrecipe"); + + if (sep->IsNumber(2)) { + const auto recipe_id = static_cast(Strings::ToUnsignedInt(sep->arg[2])); + + const auto& l = TradeskillRecipeRepository::GetWhere( + database, + fmt::format("id = {}", recipe_id) + ); + + if (l.empty() || !l[0].id) { + c->Message( + Chat::White, + fmt::format( + "Recipe ID {} could not be found.", + Strings::Commify(recipe_id) + ).c_str() + ); + return; + } + + c->Message( + Chat::White, + fmt::format( + "Recipe {} | {}{}", + Strings::Commify(recipe_id), + l[0].name, + ( + can_view_recipes ? + fmt::format( + " | {}", + Saylink::Silent( + fmt::format( + "#viewrecipe {}", + l[0].id + ), + "View" + ) + ) : + "" + ) + ).c_str() + ); + + return; + } + + const auto& search_criteria = Strings::ToLower(sep->argplus[2]); + + auto found_count = 0; + + const auto& l = TradeskillRecipeRepository::GetWhere( + database, + fmt::format( + "LOWER(`name`) LIKE '%%{}%%' ORDER BY `id` ASC", + search_criteria + ) + ); + + if (l.empty() || !l[0].id) { + c->Message( + Chat::White, + fmt::format( + "No recipes were found matching '{}'.", + sep->argplus[2] + ).c_str() + ); + + return; + } + + for (const auto& e : l) { + c->Message( + Chat::White, + fmt::format( + "Recipe {} | {}{}", + Strings::Commify(e.id), + e.name, + ( + can_view_recipes ? + fmt::format( + " | {}", + Saylink::Silent( + fmt::format( + "#viewrecipe {}", + e.id + ), + "View" + ) + ) : + "" + ) + ).c_str() + ); + + if (found_count == 50) { + break; + } + + found_count++; + } + + if (found_count == 50) { + c->Message( + Chat::White, + fmt::format( + "50 Recipes found matching '{}', max reached.", + sep->argplus[2] + ).c_str() + ); + + return; + } + + c->Message( + Chat::White, + fmt::format( + "{} Recipe{} found matching '{}'.", + found_count, + found_count != 1 ? "s" : "", + sep->argplus[2] + ).c_str() + ); +} diff --git a/zone/gm_commands/find/skill.cpp b/zone/gm_commands/find/skill.cpp new file mode 100644 index 000000000..7c92f4359 --- /dev/null +++ b/zone/gm_commands/find/skill.cpp @@ -0,0 +1,83 @@ +#include "../../client.h" + +void FindSkill(Client *c, const Seperator *sep) +{ + if (sep->IsNumber(2)) { + const auto skill_id = Strings::ToInt(sep->arg[2]); + if (EQ::ValueWithin(skill_id, EQ::skills::Skill1HBlunt, EQ::skills::SkillCount)) { + for (const auto& s : EQ::skills::GetSkillTypeMap()) { + if (skill_id == s.first) { + c->Message( + Chat::White, + fmt::format( + "Skill {} | {}", + s.first, + s.second + ).c_str() + ); + break; + } + } + + return; + } + + c->Message( + Chat::White, + fmt::format( + "Skill ID {} was not found.", + skill_id + ).c_str() + ); + + return; + } + + const auto& search_criteria = Strings::ToLower(sep->argplus[2]); + + auto found_count = 0; + + for (const auto& s : EQ::skills::GetSkillTypeMap()) { + const auto& skill_name_lower = Strings::ToLower(s.second); + if (!Strings::Contains(skill_name_lower, sep->argplus[2])) { + continue; + } + + c->Message( + Chat::White, + fmt::format( + "Skill {} | {}", + s.first, + s.second + ).c_str() + ); + + found_count++; + + if (found_count == 50) { + break; + } + } + + if (found_count == 50) { + c->Message( + Chat::White, + fmt::format( + "50 Skills were found matching '{}', max reached.", + sep->argplus[2] + ).c_str() + ); + + return; + } + + c->Message( + Chat::White, + fmt::format( + "{} Skill{} found matching '{}'.", + found_count, + found_count != 1 ? "s" : "", + sep->argplus[2] + ).c_str() + ); +} diff --git a/zone/gm_commands/find/spell.cpp b/zone/gm_commands/find/spell.cpp new file mode 100644 index 000000000..5aa157cbc --- /dev/null +++ b/zone/gm_commands/find/spell.cpp @@ -0,0 +1,104 @@ +#include "../../client.h" + +void FindSpell(Client *c, const Seperator *sep) +{ + if (SPDAT_RECORDS <= 0) { + c->Message(Chat::White, "Spells not loaded."); + return; + } + + const auto can_cast_spells = c->Admin() >= GetCommandStatus(c, "castspell"); + + if (sep->IsNumber(2)) { + const auto spell_id = Strings::ToUnsignedInt(sep->arg[2]); + if (!IsValidSpell(spell_id)) { + c->Message( + Chat::White, + fmt::format( + "Spell ID {} was not found.", + Strings::Commify(spell_id) + ).c_str() + ); + + return; + } + + c->Message( + Chat::White, + fmt::format( + "Spell {} | {}", + Strings::Commify(spell_id), + spells[spell_id].name + ).c_str() + ); + + return; + } + + const auto& search_criteria = Strings::ToLower(sep->argplus[2]); + + auto found_count = 0; + + for (uint32 spell_id = 0; spell_id < SPDAT_RECORDS; spell_id++) { + if (IsValidSpell(spell_id)) { + const auto& current_spell = spells[spell_id]; + + const std::string& spell_name = current_spell.name; + const auto& spell_name_lower = Strings::ToLower(spell_name); + if (!Strings::Contains(spell_name_lower, search_criteria)) { + continue; + } + + c->Message( + Chat::White, + fmt::format( + "Spell {} | {}{}", + Strings::Commify(spell_id), + spell_name, + ( + can_cast_spells ? + fmt::format( + " | {}", + Saylink::Silent( + fmt::format( + "#castspell {}", + spell_id + ), + "Cast" + ) + ) : + "" + ) + ).c_str() + ); + + found_count++; + + if (found_count == 50) { + break; + } + } + } + + if (found_count == 50) { + c->Message( + Chat::White, + fmt::format( + "50 Spells found matching '{}', max reached.", + sep->argplus[2] + ).c_str() + ); + + return; + } + + c->Message( + Chat::White, + fmt::format( + "{} Spell{} found matching '{}'.", + found_count, + found_count != 1 ? "s" : "", + sep->argplus[2] + ).c_str() + ); +} diff --git a/zone/gm_commands/find/task.cpp b/zone/gm_commands/find/task.cpp new file mode 100644 index 000000000..dd38433ca --- /dev/null +++ b/zone/gm_commands/find/task.cpp @@ -0,0 +1,109 @@ +#include "../../client.h" + +void FindTask(Client *c, const Seperator *sep) +{ + if (!RuleB(TaskSystem, EnableTaskSystem)) { + c->Message(Chat::White, "This command cannot be used while the Task system is disabled."); + return; + } + + const auto can_assign_tasks = c->Admin() >= GetCommandStatus(c, "task"); + + if (sep->IsNumber(2)) { + const auto task_id = Strings::ToUnsignedInt(sep->arg[2]); + const auto& task_name = task_manager->GetTaskName(task_id); + + if (task_name.empty()) { + c->Message( + Chat::White, + fmt::format( + "Task ID {} was not found.", + Strings::Commify(task_id) + ).c_str() + ); + + return; + } + + c->Message( + Chat::White, + fmt::format( + "Task {} | {}", + Strings::Commify(task_id), + task_name + ).c_str() + ); + + return; + } + + const auto& search_criteria = Strings::ToLower(sep->argplus[2]); + + auto found_count = 0; + + for (const auto& t : task_manager->GetTaskData()) { + const auto& task_name = t.second.title; + const auto& task_name_lower = Strings::ToLower(task_name); + if (!Strings::Contains(task_name_lower, search_criteria)) { + continue; + } + + c->Message( + Chat::White, + fmt::format( + "Task {} | {}{}", + Strings::Commify(t.first), + task_name, + ( + can_assign_tasks ? + fmt::format( + " | {}{}", + Saylink::Silent( + fmt::format( + "#task assign {}", + t.first + ), + "Assign" + ), + Saylink::Silent( + fmt::format( + "#task uncomplete {}", + t.first + ), + "Uncomplete" + ) + ) : + "" + ) + ).c_str() + ); + + found_count++; + + if (found_count == 50) { + break; + } + } + + if (found_count == 50) { + c->Message( + Chat::White, + fmt::format( + "50 Tasks were found matching '{}', max reached.", + sep->argplus[2] + ).c_str() + ); + + return; + } + + c->Message( + Chat::White, + fmt::format( + "{} Task{} found matching '{}'.", + found_count, + found_count != 1 ? "s" : "", + sep->argplus[2] + ).c_str() + ); +} diff --git a/zone/gm_commands/find/zone.cpp b/zone/gm_commands/find/zone.cpp new file mode 100644 index 000000000..92cb55968 --- /dev/null +++ b/zone/gm_commands/find/zone.cpp @@ -0,0 +1,132 @@ +#include "../../client.h" +#include "../../common/content/world_content_service.h" + +void FindZone(Client *c, const Seperator *sep) +{ + std::string query = "SELECT zoneidnumber, short_name, long_name, version FROM zone WHERE "; + + const auto is_expansion_search = !strcasecmp(sep->arg[2], "expansion"); + const auto is_id_search = Strings::IsNumber(sep->arg[2]); + const auto is_short_name_search = !is_expansion_search && !is_id_search; + + std::string search_string; + std::string search_type; + + if (is_expansion_search) { + query += fmt::format( + "expansion = {}", + Strings::ToInt(sep->arg[3]) + ); + + search_string = Expansion::ExpansionName[Strings::ToInt(sep->arg[3])]; + search_type = "Expansion"; + } else if (is_id_search) { + query += fmt::format( + "zoneidnumber = {}", + Strings::ToUnsignedInt(sep->arg[2]) + ); + + search_string = sep->arg[2]; + search_type = "Expansion"; + } else if (is_short_name_search) { + query += fmt::format( + "LOWER(`long_name`) LIKE '%%{}%%' OR LOWER(`short_name`) LIKE '%%{}%%'", + Strings::Escape(Strings::ToLower(sep->argplus[2])), + Strings::Escape(Strings::ToLower(sep->argplus[2])) + ); + + search_string = sep->argplus[2]; + search_type = "Expansion"; + } + + query += " ORDER BY `zoneidnumber` ASC LIMIT 50"; + + auto results = content_db.QueryDatabase(query); + if (!results.Success() || !results.RowCount()) { + c->Message(Chat::White, "No zones were found matching your search criteria."); + c->Message(Chat::White, query.c_str()); + return; + } + + auto found_count = 0; + + for (auto row : results) { + const auto zone_id = Strings::ToUnsignedInt(row[0]); + const std::string& short_name = row[1]; + const std::string& long_name = row[2]; + const auto version = Strings::ToInt(row[3]); + + c->Message( + Chat::White, + fmt::format( + "{}{} {} ({}) (ID {}){}", + ( + version == 0 ? + fmt::format( + "{} | ", + Saylink::Silent( + fmt::format( + "#zone {}", + short_name + ), + "Zone" + ) + ) : + "" + ), + fmt::format( + "{} |", + Saylink::Silent( + fmt::format( + "#gmzone {} {}", + short_name, + version + ), + "GM Zone" + ) + ), + long_name, + short_name, + zone_id, + ( + version != 0 ? + fmt::format( + " (Version {})", + version + ) : + "" + ) + ).c_str() + ); + + found_count++; + + if (found_count == 50) { + break; + } + } + + if (found_count == 50) { + c->Message( + Chat::White, + fmt::format( + "50 Zones found matching '{}' of '{}'.", + search_type, + search_string + ).c_str() + ); + + return; + } + + c->Message( + Chat::White, + fmt::format( + "{} Zone{} found matching '{}' of '{}'.", + found_count, + found_count != 1 ? "s" : "", + search_type, + search_string + ).c_str() + ); +} diff --git a/zone/gm_commands/findaa.cpp b/zone/gm_commands/findaa.cpp deleted file mode 100755 index 3a0640153..000000000 --- a/zone/gm_commands/findaa.cpp +++ /dev/null @@ -1,100 +0,0 @@ -#include "../client.h" - -void command_findaa(Client *c, const Seperator *sep) -{ - auto arguments = sep->argnum; - if (!arguments) { - c->Message(Chat::White, "Command Syntax: #findaa [Search Criteria]"); - return; - } - - if (sep->IsNumber(1)) { - int aa_id = Strings::ToInt(sep->arg[1]); - auto aa_name = zone->GetAAName(aa_id); - if (!aa_name.empty()) { - c->Message( - Chat::White, - fmt::format( - "AA {}: {}", - aa_id, - aa_name - ).c_str() - ); - } else { - c->Message( - Chat::White, - fmt::format( - "AA ID {} was not found.", - aa_id - ).c_str() - ); - } - } else { - const auto search_criteria = Strings::ToLower(sep->argplus[1]); - if (!search_criteria.empty()) { - std::map ordered_aas; - - for (const auto& a : zone->aa_abilities) { - ordered_aas[a.second.get()->first->id] = a.second.get()->name; - } - - int found_count = 0; - for (const auto& a : ordered_aas) { - auto aa_name = zone->GetAAName(a.first); - if (!aa_name.empty()) { - auto aa_name_lower = Strings::ToLower(aa_name); - if (aa_name_lower.find(search_criteria) == std::string::npos) { - continue; - } - - c->Message( - Chat::White, - fmt::format( - "AA {}: {}", - a.first, - aa_name - ).c_str() - ); - found_count++; - - if (found_count == 50) { - break; - } - } - } - - if (!found_count) { - c->Message( - Chat::White, - fmt::format( - "No AAs were found matching '{}'.", - search_criteria - ).c_str() - ); - return; - } - - if (found_count == 50) { - c->Message( - Chat::White, - fmt::format( - "50 AAs were found matching '{}', max reached.", - search_criteria - ).c_str() - ); - } else { - auto skill_message = found_count == 1 ? "An AA was" : fmt::format("{} AAs were", found_count); - - c->Message( - Chat::White, - fmt::format( - "{} found matching '{}'.", - skill_message, - search_criteria - ).c_str() - ); - } - } - } -} - diff --git a/zone/gm_commands/findcharacter.cpp b/zone/gm_commands/findcharacter.cpp deleted file mode 100755 index fccd7bf20..000000000 --- a/zone/gm_commands/findcharacter.cpp +++ /dev/null @@ -1,93 +0,0 @@ -#include "../client.h" -#include "../../common/repositories/character_data_repository.h" - -void command_findcharacter(Client *c, const Seperator *sep) -{ - const auto arguments = sep->argnum; - if (!arguments) { - c->Message(Chat::White, "Usage: #findcharacter [Search Criteria]"); - return; - } - - if (sep->IsNumber(1)) { - const auto character_id = Strings::ToUnsignedInt(sep->arg[1]); - - const auto& e = CharacterDataRepository::FindOne(content_db, character_id); - if (!e.id) { - c->Message( - Chat::White, - fmt::format( - "Character ID {} does not exist or is invalid.", - character_id - ).c_str() - ); - return; - } - - c->Message( - Chat::White, - fmt::format( - "Character ID {} | {}", - character_id, - e.name - ).c_str() - ); - } else { - const auto search_criteria = Strings::ToLower(sep->argplus[1]); - const auto& l = CharacterDataRepository::GetWhere( - content_db, - fmt::format( - "LOWER(`name`) LIKE '%%{}%%'", - search_criteria - ).c_str() - ); - if (l.empty()) { - c->Message( - Chat::White, - fmt::format( - "No characters found matching '{}'.", - sep->argplus[1] - ).c_str() - ); - } - - auto found_count = 0; - for (const auto& e : l) { - c->Message( - Chat::White, - fmt::format( - "Character ID {} | {}", - e.id, - e.name - ).c_str() - ); - - found_count++; - - if (found_count == 50) { - break; - } - } - - if (found_count == 50) { - c->Message( - Chat::White, - fmt::format( - "50 Characters found matching '{}', max reached.", - sep->argplus[1] - ).c_str() - ); - } else { - c->Message( - Chat::White, - fmt::format( - "{} Character{} found matching '{}'.", - found_count, - found_count != 1 ? "s" : "", - sep->argplus[1] - ).c_str() - ); - } - } -} - diff --git a/zone/gm_commands/findclass.cpp b/zone/gm_commands/findclass.cpp deleted file mode 100755 index a1ddaa18f..000000000 --- a/zone/gm_commands/findclass.cpp +++ /dev/null @@ -1,92 +0,0 @@ -#include "../client.h" - -void command_findclass(Client *c, const Seperator *sep) -{ - int arguments = sep->argnum; - if (!arguments) { - c->Message(Chat::White, "Command Syntax: #findclass [Search Criteria]"); - return; - } - - if (sep->IsNumber(1)) { - int class_id = Strings::ToInt(sep->arg[1]); - if (class_id >= WARRIOR && class_id <= MERCENARY_MASTER) { - std::string class_name = GetClassIDName(class_id); - c->Message( - Chat::White, - fmt::format( - "Class {} | {}{}", - class_id, - class_name, - ( - c->IsPlayerClass(class_id) ? - fmt::format( - " ({})", - GetPlayerClassBit(class_id) - ) : - "" - ) - ).c_str() - ); - } - else { - c->Message( - Chat::White, - fmt::format( - "Class ID {} was not found.", - class_id - ).c_str() - ); - } - } else { - auto search_criteria = Strings::ToLower(sep->argplus[1]); - int found_count = 0; - for (uint16 class_id = WARRIOR; class_id <= MERCENARY_MASTER; class_id++) { - std::string class_name = GetClassIDName(class_id); - auto class_name_lower = Strings::ToLower(class_name); - if ( - search_criteria.length() && - class_name_lower.find(search_criteria) == std::string::npos - ) { - continue; - } - - c->Message( - Chat::White, - fmt::format( - "Class {} | {}{}", - class_id, - class_name, - ( - c->IsPlayerClass(class_id) ? - fmt::format( - " ({})", - GetPlayerClassBit(class_id) - ) : - "" - ) - ).c_str() - ); - - found_count++; - - if (found_count == 50) { - break; - } - } - - if (found_count == 50) { - c->Message(Chat::White, "50 Classes found, max reached."); - } else { - c->Message( - Chat::White, - fmt::format( - "{} Class{} found.", - found_count, - found_count != 1 ? "es" : "" - ).c_str() - ); - } - } -} - diff --git a/zone/gm_commands/findcurrency.cpp b/zone/gm_commands/findcurrency.cpp deleted file mode 100755 index b5ad64c5a..000000000 --- a/zone/gm_commands/findcurrency.cpp +++ /dev/null @@ -1,134 +0,0 @@ -#include "../client.h" - -void command_findcurrency(Client *c, const Seperator *sep) -{ - const auto arguments = sep->argnum; - if (!arguments) { - c->Message(Chat::White, "Usage: #findcurrency [Search Criteria]"); - return; - } - - const auto can_summon_items = c->Admin() >= GetCommandStatus(c, "summonitem"); - - if (sep->IsNumber(1)) { - const auto item_id = Strings::ToUnsignedInt(sep->arg[1]); - const auto currency_id = zone->GetCurrencyID(item_id); - - if (!currency_id) { - c->Message( - Chat::White, - fmt::format( - "There is no currency with an item ID of {}.", - item_id - ).c_str() - ); - - return; - } - - const auto item_data = database.GetItem(item_id); - if (!item_data) { - c->Message( - Chat::White, - fmt::format( - "Item ID {} does not exist.", - item_id - ).c_str() - ); - - return; - } - - c->Message( - Chat::White, - fmt::format( - "Currency {} | {} ({}){}", - currency_id, - database.CreateItemLink(item_id), - item_id, - ( - can_summon_items ? - fmt::format( - " | {}", - Saylink::Silent( - fmt::format( - "#summonitem {} {}", - item_id, - item_data->StackSize - ), - "Summon" - ) - ) : - "" - ) - ).c_str() - ); - - return; - } - - const std::string search_criteria = sep->argplus[1]; - - uint32 found_count = 0; - - for (const auto& e : zone->AlternateCurrencies) { - const auto item_data = database.GetItem(e.item_id); - if (!item_data) { - continue; - } - - const std::string item_name = Strings::ToLower(item_data->Name); - - if (Strings::Contains(item_name, Strings::ToLower(search_criteria))) { - c->Message( - Chat::White, - fmt::format( - "Currency {} | {} ({}){}", - e.id, - database.CreateItemLink(e.item_id), - e.item_id, - ( - can_summon_items ? - fmt::format( - " | {}", - Saylink::Silent( - fmt::format( - "#summonitem {} {}", - e.item_id, - item_data->StackSize - ), - "Summon" - ) - ) : - "" - ) - ).c_str() - ); - - found_count++; - } - } - - if (!found_count) { - c->Message( - Chat::White, - fmt::format( - "No currencies were found matching '{}'.", - search_criteria - ).c_str() - ); - - return; - } - - c->Message( - Chat::White, - fmt::format( - "{} currenc{} found matching '{}'.", - found_count, - found_count != 1 ? "ies were" : "y was", - search_criteria - ).c_str() - ); -} - diff --git a/zone/gm_commands/findfaction.cpp b/zone/gm_commands/findfaction.cpp deleted file mode 100755 index a6d75874d..000000000 --- a/zone/gm_commands/findfaction.cpp +++ /dev/null @@ -1,89 +0,0 @@ -#include "../client.h" - -void command_findfaction(Client *c, const Seperator *sep) -{ - int arguments = sep->argnum; - - if (arguments == 0) { - c->Message(Chat::White, "Command Syntax: #findfaction [search criteria]"); - return; - } - - if (sep->IsNumber(1)) { - int faction_id = Strings::ToInt(sep->arg[1]); - auto faction_name = content_db.GetFactionName(faction_id); - if (!faction_name.empty()) { - c->Message( - Chat::White, - fmt::format( - "Faction {}: {}", - faction_id, - faction_name - ).c_str() - ); - } - else { - c->Message( - Chat::White, - fmt::format( - "Faction ID {} was not found.", - faction_id - ).c_str() - ); - } - } - else { - std::string search_criteria = Strings::ToLower(sep->argplus[1]); - int found_count = 0; - int max_faction_id = content_db.GetMaxFaction(); - for (int faction_id = 0; faction_id < max_faction_id; faction_id++) { - std::string faction_name = content_db.GetFactionName(faction_id); - std::string faction_name_lower = Strings::ToLower(faction_name); - if (faction_name.empty()) { - continue; - } - - if (faction_name.find(search_criteria) == std::string::npos) { - continue; - } - - c->Message( - Chat::White, - fmt::format( - "Faction {}: {}", - faction_id, - faction_name - ).c_str() - ); - found_count++; - - if (found_count == 20) { - break; - } - } - - if (found_count == 20) { - c->Message(Chat::White, "20 Factions found... max reached."); - } - else { - auto faction_message = ( - found_count > 0 ? - ( - found_count == 1 ? - "A Faction was" : - fmt::format("{} Factions were", found_count) - ) : - "No Factions were" - ); - - c->Message( - Chat::White, - fmt::format( - "{} found.", - faction_message - ).c_str() - ); - } - } -} - diff --git a/zone/gm_commands/findnpctype.cpp b/zone/gm_commands/findnpctype.cpp deleted file mode 100755 index 991bd8f18..000000000 --- a/zone/gm_commands/findnpctype.cpp +++ /dev/null @@ -1,77 +0,0 @@ -#include "../client.h" - -void command_findnpctype(Client *c, const Seperator *sep) -{ - int arguments = sep->argnum; - if (!arguments) { - c->Message(Chat::White, "Usage: #findnpctype [Search Criteria]"); - return; - } - - std::string query; - std::string search_criteria = sep->arg[1]; - if (sep->IsNumber(1)) { - query = fmt::format( - "SELECT id, name FROM npc_types WHERE id = {}", - search_criteria - ); - } - else { - query = fmt::format( - "SELECT id, name FROM npc_types WHERE name LIKE '%%{}%%'", - search_criteria - ); - } - - auto results = content_db.QueryDatabase(query); - if (!results.Success() || !results.RowCount()) { - c->Message( - Chat::White, - fmt::format( - "No matches found for '{}'.", - search_criteria - ).c_str() - ); - return; - } - - int found_count = 0; - - for (auto row : results) { - int found_number = (found_count + 1); - if (found_count == 20) { - break; - } - - c->Message( - Chat::White, - fmt::format( - "NPC {} | {} ({})", - found_number, - row[1], - row[0] - ).c_str() - ); - found_count++; - } - - if (found_count == 20) { - c->Message(Chat::White, "20 NPCs were found, max reached."); - } - else { - auto npc_message = ( - found_count == 1 ? - "An NPC was" : - fmt::format("{} NPCs were", found_count) - ); - - c->Message( - Chat::White, - fmt::format( - "{} found.", - npc_message - ).c_str() - ); - } -} - diff --git a/zone/gm_commands/findrace.cpp b/zone/gm_commands/findrace.cpp deleted file mode 100755 index b0bee13c1..000000000 --- a/zone/gm_commands/findrace.cpp +++ /dev/null @@ -1,94 +0,0 @@ -#include "../client.h" - -void command_findrace(Client *c, const Seperator *sep) -{ - int arguments = sep->argnum; - if (!arguments) { - c->Message(Chat::White, "Command Syntax: #findrace [Search Criteria]"); - return; - } - - if (sep->IsNumber(1)) { - auto race_id = static_cast(Strings::ToUnsignedInt(sep->arg[1])); - std::string race_name = GetRaceIDName(race_id); - if ( - race_id >= RACE_HUMAN_1 && - race_id <= RACE_PEGASUS_732 - ) { - c->Message( - Chat::White, - fmt::format( - "Race {} | {}{}", - race_id, - race_name, - ( - c->IsPlayerRace(race_id) ? - fmt::format( - " ({})", - GetPlayerRaceBit(race_id) - ) : - "" - ) - ).c_str() - ); - } else { - c->Message( - Chat::White, - fmt::format( - "Race ID {} was not found.", - race_id - ).c_str() - ); - } - } else { - auto search_criteria = Strings::ToLower(sep->argplus[1]); - int found_count = 0; - for (uint16 race_id = RACE_HUMAN_1; race_id <= RACE_PEGASUS_732; race_id++) { - std::string race_name = GetRaceIDName(race_id); - auto race_name_lower = Strings::ToLower(race_name); - if ( - search_criteria.length() && - race_name_lower.find(search_criteria) == std::string::npos - ) { - continue; - } - - c->Message( - Chat::White, - fmt::format( - "Race {} | {}{}", - race_id, - race_name, - ( - c->IsPlayerRace(race_id) ? - fmt::format( - " ({})", - GetPlayerRaceBit(race_id) - ) : - "" - ) - ).c_str() - ); - - found_count++; - - if (found_count == 50) { - break; - } - } - - if (found_count == 50) { - c->Message(Chat::White, "50 Races found, max reached."); - } else { - c->Message( - Chat::White, - fmt::format( - "{} Race{} found.", - found_count, - found_count != 1 ? "s" : "" - ).c_str() - ); - } - } -} - diff --git a/zone/gm_commands/findrecipe.cpp b/zone/gm_commands/findrecipe.cpp deleted file mode 100755 index 4b3593ea9..000000000 --- a/zone/gm_commands/findrecipe.cpp +++ /dev/null @@ -1,96 +0,0 @@ -#include "../client.h" -#include "../command.h" -#include "../../common/repositories/tradeskill_recipe_repository.h" - -void command_findrecipe(Client *c, const Seperator *sep) -{ - int arguments = sep->argnum; - if (!arguments) { - c->Message(Chat::White, "Command Syntax: #findrecipe [Search Criteria]"); - return; - } - - if (sep->IsNumber(1)) { - auto recipe_id = static_cast(Strings::ToUnsignedInt(sep->arg[1])); - auto r = TradeskillRecipeRepository::GetWhere( - database, - fmt::format("id = {}", recipe_id) - ); - - if (r.empty() || !r[0].id) { - c->Message( - Chat::White, - fmt::format( - "Recipe ID {} could not be found.", - Strings::Commify(std::to_string(recipe_id)) - ).c_str() - ); - return; - } - - bool can_view_recipes = c->Admin() >= GetCommandStatus(c, "viewrecipe"); - - c->Message( - Chat::White, - fmt::format( - "Recipe {} | {}{}", - Strings::Commify(std::to_string(recipe_id)), - r[0].name, - can_view_recipes ? fmt::format(" | {}", Saylink::Silent(fmt::format("#viewrecipe {}", r[0].id), "View")) : "" - ).c_str() - ); - } else { - auto search_criteria = Strings::ToLower(sep->argplus[1]); - int found_count = 0; - - auto rl = TradeskillRecipeRepository::GetWhere( - database, - fmt::format("`name` LIKE '%{}%' ORDER BY `id` ASC", search_criteria) - ); - - if (rl.empty() || !rl[0].id) { - c->Message( - Chat::White, - fmt::format( - "No recipes were found matching '{}'.", - search_criteria - ).c_str() - ); - return; - } - - bool can_view_recipes = c->Admin() >= GetCommandStatus(c, "viewrecipe"); - - for (const auto& r : rl) { - c->Message( - Chat::White, - fmt::format( - "Recipe {} | {}{}", - Strings::Commify(std::to_string(r.id)), - r.name, - can_view_recipes ? fmt::format(" | {}", Saylink::Silent(fmt::format("#viewrecipe {}", r.id), "View")) : "" - ).c_str() - ); - - if (found_count == 50) { - break; - } - - found_count++; - } - - if (found_count == 50) { - c->Message(Chat::White, "50 Recipes found, max reached."); - } else { - c->Message( - Chat::White, - fmt::format( - "{} Recipe{} found.", - found_count, - found_count != 1 ? "s" : "" - ).c_str() - ); - } - } -} - diff --git a/zone/gm_commands/findskill.cpp b/zone/gm_commands/findskill.cpp deleted file mode 100755 index 68231200f..000000000 --- a/zone/gm_commands/findskill.cpp +++ /dev/null @@ -1,90 +0,0 @@ -#include "../client.h" - -void command_findskill(Client *c, const Seperator *sep) -{ - int arguments = sep->argnum; - - if (arguments == 0) { - c->Message(Chat::White, "Command Syntax: #findskill [search criteria]"); - return; - } - - std::map skills = EQ::skills::GetSkillTypeMap(); - if (sep->IsNumber(1)) { - int skill_id = Strings::ToInt(sep->arg[1]); - if (skill_id >= EQ::skills::Skill1HBlunt && skill_id < EQ::skills::SkillCount) { - for (auto skill : skills) { - if (skill_id == skill.first) { - c->Message( - Chat::White, - fmt::format( - "Skill {}: {}", - skill.first, - skill.second - ).c_str() - ); - break; - } - } - } - else { - c->Message( - Chat::White, - fmt::format( - "Skill ID {} was not found.", - skill_id - ).c_str() - ); - } - } - else { - std::string search_criteria = Strings::ToLower(sep->argplus[1]); - if (!search_criteria.empty()) { - int found_count = 0; - for (auto skill : skills) { - std::string skill_name_lower = Strings::ToLower(skill.second); - if (skill_name_lower.find(search_criteria) == std::string::npos) { - continue; - } - - c->Message( - Chat::White, - fmt::format( - "Skill {}: {}", - skill.first, - skill.second - ).c_str() - ); - found_count++; - - if (found_count == 20) { - break; - } - } - - if (found_count == 20) { - c->Message(Chat::White, "20 Skills were found, max reached."); - } - else { - auto skill_message = ( - found_count > 0 ? - ( - found_count == 1 ? - "A Skill was" : - fmt::format("{} Skills were", found_count) - ) : - "No Skills were" - ); - - c->Message( - Chat::White, - fmt::format( - "{} found.", - skill_message - ).c_str() - ); - } - } - } -} - diff --git a/zone/gm_commands/findspell.cpp b/zone/gm_commands/findspell.cpp deleted file mode 100755 index 1ec4f1d10..000000000 --- a/zone/gm_commands/findspell.cpp +++ /dev/null @@ -1,90 +0,0 @@ -#include "../client.h" - -void command_findspell(Client *c, const Seperator *sep) -{ - if (SPDAT_RECORDS <= 0) { - c->Message(Chat::White, "Spells not loaded"); - return; - } - - int arguments = sep->argnum; - - if (arguments == 0) { - c->Message(Chat::White, "Command Syntax: #findspell [search criteria]"); - return; - } - - if (sep->IsNumber(1)) { - int spell_id = Strings::ToInt(sep->arg[1]); - if (!IsValidSpell(spell_id)) { - c->Message( - Chat::White, - fmt::format( - "Spell ID {} was not found.", - spell_id - ).c_str() - ); - } - else { - c->Message( - Chat::White, - fmt::format( - "Spell {}: {}", - spell_id, - spells[spell_id].name - ).c_str() - ); - } - } - else { - std::string search_criteria = Strings::ToLower(sep->argplus[1]); - int found_count = 0; - for (int spell_id = 0; spell_id < SPDAT_RECORDS; spell_id++) { - auto current_spell = spells[spell_id]; - if (current_spell.name[0] != 0) { - std::string spell_name = current_spell.name; - std::string spell_name_lower = Strings::ToLower(spell_name); - if (search_criteria.length() > 0 && spell_name_lower.find(search_criteria) == std::string::npos) { - continue; - } - - c->Message( - Chat::White, - fmt::format( - "Spell {}: {}", - spell_id, - spell_name - ).c_str() - ); - found_count++; - - if (found_count == 20) { - break; - } - } - } - - if (found_count == 20) { - c->Message(Chat::White, "20 Spells found... max reached."); - } - else { - auto spell_message = ( - found_count > 0 ? - ( - found_count == 1 ? - "A Spell was" : - fmt::format("{} Spells were", found_count) - ) : - "No Spells were" - ); - - c->Message( - Chat::White, - fmt::format( - "{} found.", - spell_message - ).c_str() - ); - } - } -} diff --git a/zone/gm_commands/findtask.cpp b/zone/gm_commands/findtask.cpp deleted file mode 100755 index 78556a158..000000000 --- a/zone/gm_commands/findtask.cpp +++ /dev/null @@ -1,90 +0,0 @@ -#include "../client.h" - -void command_findtask(Client *c, const Seperator *sep) -{ - if (RuleB(TaskSystem, EnableTaskSystem)) { - int arguments = sep->argnum; - - if (arguments == 0) { - c->Message(Chat::White, "Command Syntax: #findtask [search criteria]"); - return; - } - - if (sep->IsNumber(1)) { - auto task_id = Strings::ToUnsignedInt(sep->arg[1]); - auto task_name = task_manager->GetTaskName(task_id); - - std::string task_message = ( - !task_name.empty() ? - fmt::format( - "Task {}: {}", - task_id, - task_name - ) : - fmt::format( - "Task ID {} was not found.", - task_id - ) - ); - - c->Message( - Chat::White, - task_message.c_str() - ); - } - else { - std::string search_criteria = Strings::ToLower(sep->argplus[1]); - if (!search_criteria.empty()) { - int found_count = 0; - for (const auto &task: task_manager->GetTaskData()) { - auto task_name = task.second.title; - std::string task_name_lower = Strings::ToLower(task_name); - if (task_name_lower.find(search_criteria) == std::string::npos) { - continue; - } - - c->Message( - Chat::White, - fmt::format( - "Task {}: {}", - task.first, - task_name - ).c_str() - ); - found_count++; - - if (found_count == 20) { - break; - } - } - - if (found_count == 20) { - c->Message(Chat::White, "20 Tasks were found, max reached."); - } - else { - auto task_message = ( - found_count > 0 ? - ( - found_count == 1 ? - "A Task was" : - fmt::format("{} Tasks were", found_count) - ) : - "No Tasks were" - ); - - c->Message( - Chat::White, - fmt::format( - "{} found.", - task_message - ).c_str() - ); - } - } - } - } - else { - c->Message(Chat::White, "This command cannot be used while the Task system is disabled."); - } -} - diff --git a/zone/gm_commands/findzone.cpp b/zone/gm_commands/findzone.cpp deleted file mode 100755 index baba6b63a..000000000 --- a/zone/gm_commands/findzone.cpp +++ /dev/null @@ -1,98 +0,0 @@ -#include "../client.h" - -void command_findzone(Client *c, const Seperator *sep) -{ - if (sep->arg[1][0] == 0) { - c->Message(Chat::White, "Usage: #findzone [search criteria]"); - c->Message(Chat::White, "Usage: #findzone expansion [expansion number]"); - return; - } - - std::string query; - int id = Strings::ToInt((const char *) sep->arg[1]); - - std::string arg1 = sep->arg[1]; - - if (arg1 == "expansion") { - query = fmt::format( - "SELECT zoneidnumber, short_name, long_name, version FROM zone WHERE expansion = {}", - sep->arg[2] - ); - } - else { - - /** - * If id evaluates to 0, then search as if user entered a string - */ - if (id == 0) { - query = fmt::format( - "SELECT zoneidnumber, short_name, long_name, version FROM zone WHERE long_name LIKE '%{}%' OR `short_name` LIKE '%{}%'", - Strings::Escape(sep->arg[1]), - Strings::Escape(sep->arg[1]) - ); - } - else { - query = fmt::format( - "SELECT zoneidnumber, short_name, long_name, version FROM zone WHERE zoneidnumber = {}", - id - ); - } - } - - auto results = content_db.QueryDatabase(query); - if (!results.Success()) { - c->Message(Chat::White, "Error querying database."); - c->Message(Chat::White, query.c_str()); - return; - } - - int count = 0; - const int maxrows = 100; - - for (auto row = results.begin(); row != results.end(); ++row) { - std::string zone_id = row[0]; - std::string short_name = row[1]; - std::string long_name = row[2]; - int version = Strings::ToInt(row[3]); - - if (++count > maxrows) { - c->Message(Chat::White, "%i zones shown. Too many results.", maxrows); - break; - } - - std::string command_zone = Saylink::Silent("#zone " + short_name, "zone"); - std::string command_gmzone = Saylink::Silent( - fmt::format( - "#gmzone {} {}", - short_name, - version - ), - "gmzone" - ); - - c->Message( - Chat::White, - fmt::format( - "[{}] [{}] [{}] ID ({}) Version ({}) [{}]", - (version == 0 ? command_zone : "zone"), - command_gmzone, - short_name, - zone_id, - version, - long_name - ).c_str() - ); - } - - if (count <= maxrows) { - c->Message( - Chat::White, - "Query complete. %i rows shown. %s", - count, - (arg1 == "expansion" ? "(expansion search)" : "")); - } - else if (count == 0) { - c->Message(Chat::White, "No matches found for %s.", sep->arg[1]); - } -} - diff --git a/zone/gm_commands/flags.cpp b/zone/gm_commands/flags.cpp deleted file mode 100755 index 8b28c7d69..000000000 --- a/zone/gm_commands/flags.cpp +++ /dev/null @@ -1,17 +0,0 @@ -#include "../client.h" - -void command_flags(Client *c, const Seperator *sep) -{ - Client *target = c; - - if ( - c->GetTarget() && - c->GetTarget()->IsClient() && - c->Admin() >= minStatusToSeeOthersZoneFlags - ) { - target = c->GetTarget()->CastToClient(); - } - - target->SendZoneFlagInfo(c); -} - diff --git a/zone/gm_commands/fov.cpp b/zone/gm_commands/fov.cpp deleted file mode 100755 index bfb8397c3..000000000 --- a/zone/gm_commands/fov.cpp +++ /dev/null @@ -1,43 +0,0 @@ -#include "../client.h" - -void command_fov(Client *c, const Seperator *sep) -{ - if (!c->GetTarget()) { - c->Message(Chat::White, "You must have a target to use this command."); - return; - } - - auto target = c->GetTarget(); - - std::string behind_message = ( - c->BehindMob( - target, - c->GetX(), - c->GetY() - ) ? - "behind" : - "not behind" - ); - - std::string gender_message = ( - target->GetGender() == MALE ? - "he" : - ( - target->GetGender() == FEMALE ? - "she" : - "it" - ) - ); - - c->Message( - Chat::White, - fmt::format( - "You are {} {}, {} has a heading of {}.", - behind_message, - c->GetTargetDescription(target), - gender_message, - target->GetHeading() - ).c_str() - ); -} - diff --git a/zone/gm_commands/getplayerburiedcorpsecount.cpp b/zone/gm_commands/getplayerburiedcorpsecount.cpp deleted file mode 100755 index 8692c7d3e..000000000 --- a/zone/gm_commands/getplayerburiedcorpsecount.cpp +++ /dev/null @@ -1,26 +0,0 @@ -#include "../client.h" -#include "../corpse.h" - -void command_getplayerburiedcorpsecount(Client *c, const Seperator *sep) -{ - Client *target = c; - if (c->GetTarget() && c->GetTarget()->IsClient() && c->GetGM()) { - target = c->GetTarget()->CastToClient(); - } - - uint32 corpse_count = database.GetCharacterBuriedCorpseCount(target->CharacterID()); - c->Message( - Chat::White, - fmt::format( - "{} {} {} buried corpse{}.", - c->GetTargetDescription(target, TargetDescriptionType::UCYou), - c == target ? "have" : "has", - ( - corpse_count ? - std::to_string(corpse_count) : - "no" - ), - corpse_count != 1 ? "s" : "" - ).c_str() - ); -} diff --git a/zone/gm_commands/getvariable.cpp b/zone/gm_commands/getvariable.cpp deleted file mode 100755 index 7b26ccfb0..000000000 --- a/zone/gm_commands/getvariable.cpp +++ /dev/null @@ -1,31 +0,0 @@ -#include "../client.h" - -void command_getvariable(Client *c, const Seperator *sep) -{ - std::string variable = sep->argplus[1]; - if (variable.empty()) { - c->Message(Chat::White, "Usage: #getvariable [Variable Name]"); - return; - } - - std::string message; - std::string value; - if (database.GetVariable(variable, value)) { - message = fmt::format( - "Variable {}: {}", - variable, - value - ); - } else { - message = fmt::format( - "Variable '{}' does not exist.", - variable - ); - } - - c->Message( - Chat::White, - message.c_str() - ); -} - diff --git a/zone/gm_commands/ginfo.cpp b/zone/gm_commands/ginfo.cpp deleted file mode 100755 index 3850c6b91..000000000 --- a/zone/gm_commands/ginfo.cpp +++ /dev/null @@ -1,78 +0,0 @@ -#include "../client.h" -#include "../groups.h" - -void command_ginfo(Client *c, const Seperator *sep) -{ - Client *target = c; - if (c->GetTarget() && c->GetTarget()->IsClient()) { - target = c->GetTarget()->CastToClient(); - } - - auto target_group = target->GetGroup(); - if (!target_group) { - c->Message( - Chat::White, - fmt::format( - "{} {} not in a group.", - c->GetTargetDescription(target, TargetDescriptionType::UCYou), - c == target ? "are" : "is" - ).c_str() - ); - return; - } - - std::string popup_title = fmt::format( - "Group Info for {}", - c->GetTargetDescription(target, TargetDescriptionType::UCSelf) - ); - std::string popup_text = ""; - popup_text += fmt::format( - "", - target_group->GetID(), - target_group->GroupCount() - ); - popup_text += "

"; - popup_text += ""; - popup_text += ""; - popup_text += ""; - popup_text += ""; - popup_text += ""; - popup_text += ""; - popup_text += ""; - popup_text += ""; - - for (int group_member = 0; group_member < MAX_GROUP_MEMBERS; group_member++) { - if (target_group->membername[group_member][0] == '\0') { - continue; - } - - bool is_assist = target_group->MemberRoles[group_member] & RoleAssist; - bool is_puller = target_group->MemberRoles[group_member] & RolePuller; - bool is_tank = target_group->MemberRoles[group_member] & RoleTank; - - popup_text += fmt::format( - "", - group_member, - ( - strcmp(target_group->membername[group_member], c->GetCleanName()) ? - target_group->membername[group_member] : - fmt::format( - "{} (You)", - target_group->membername[group_member] - ) - ), - target_group->members[group_member] ? "Y" : "N", - is_assist ? "Y" : "N", - is_puller ? "Y" : "N", - is_tank ? "Y" : "N" - ); - } - - popup_text += "
Group ID{}Members{}
IndexNameIn ZoneAssistPullerTank
{}{}{}{}{}{}
"; - - c->SendPopupToClient( - popup_title.c_str(), - popup_text.c_str() - ); -} - diff --git a/zone/gm_commands/globalview.cpp b/zone/gm_commands/globalview.cpp deleted file mode 100755 index 948ecd353..000000000 --- a/zone/gm_commands/globalview.cpp +++ /dev/null @@ -1,80 +0,0 @@ -#include "../client.h" - -void command_globalview(Client *c, const Seperator *sep) -{ - NPC *npcmob = nullptr; - - if (c->GetTarget() && c->GetTarget()->IsNPC()) { - npcmob = c->GetTarget()->CastToNPC(); - QGlobalCache *npc_c = nullptr; - QGlobalCache *char_c = nullptr; - QGlobalCache *zone_c = nullptr; - - if (npcmob) { - npc_c = npcmob->GetQGlobals(); - } - - char_c = c->GetQGlobals(); - zone_c = zone->GetQGlobals(); - - std::list globalMap; - uint32 ntype = 0; - - if (npcmob) { - ntype = npcmob->GetNPCTypeID(); - } - - if (npc_c) { - QGlobalCache::Combine(globalMap, npc_c->GetBucket(), ntype, c->CharacterID(), zone->GetZoneID()); - } - - if (char_c) { - QGlobalCache::Combine(globalMap, char_c->GetBucket(), ntype, c->CharacterID(), zone->GetZoneID()); - } - - if (zone_c) { - QGlobalCache::Combine(globalMap, zone_c->GetBucket(), ntype, c->CharacterID(), zone->GetZoneID()); - } - - auto iter = globalMap.begin(); - uint32 gcount = 0; - - c->Message(Chat::White, "Name, Value"); - while (iter != globalMap.end()) { - c->Message(Chat::White, "%s %s", (*iter).name.c_str(), (*iter).value.c_str()); - ++iter; - ++gcount; - } - c->Message(Chat::White, "%u globals loaded.", gcount); - } - else { - QGlobalCache *char_c = nullptr; - QGlobalCache *zone_c = nullptr; - - char_c = c->GetQGlobals(); - zone_c = zone->GetQGlobals(); - - std::list globalMap; - uint32 ntype = 0; - - if (char_c) { - QGlobalCache::Combine(globalMap, char_c->GetBucket(), ntype, c->CharacterID(), zone->GetZoneID()); - } - - if (zone_c) { - QGlobalCache::Combine(globalMap, zone_c->GetBucket(), ntype, c->CharacterID(), zone->GetZoneID()); - } - - auto iter = globalMap.begin(); - uint32 gcount = 0; - - c->Message(Chat::White, "Name, Value"); - while (iter != globalMap.end()) { - c->Message(Chat::White, "%s %s", (*iter).name.c_str(), (*iter).value.c_str()); - ++iter; - ++gcount; - } - c->Message(Chat::White, "%u globals loaded.", gcount); - } -} - diff --git a/zone/gm_commands/iplookup.cpp b/zone/gm_commands/iplookup.cpp deleted file mode 100755 index 1595a5ee6..000000000 --- a/zone/gm_commands/iplookup.cpp +++ /dev/null @@ -1,23 +0,0 @@ -#include "../client.h" -#include "../worldserver.h" - -extern WorldServer worldserver; - -void command_iplookup(Client *c, const Seperator *sep) -{ - auto pack = - new ServerPacket( - ServerOP_IPLookup, - sizeof(ServerGenericWorldQuery_Struct) + - strlen(sep->argplus[1]) + 1 - ); - ServerGenericWorldQuery_Struct *s = (ServerGenericWorldQuery_Struct *) pack->pBuffer; - strcpy(s->from, c->GetName()); - s->admin = c->Admin(); - if (sep->argplus[1][0] != 0) { - strcpy(s->query, sep->argplus[1]); - } - worldserver.SendPacket(pack); - safe_delete(pack); -} - diff --git a/zone/gm_commands/itemsearch.cpp b/zone/gm_commands/itemsearch.cpp deleted file mode 100755 index 084b38833..000000000 --- a/zone/gm_commands/itemsearch.cpp +++ /dev/null @@ -1,121 +0,0 @@ -#include "../client.h" - -void command_itemsearch(Client *c, const Seperator *sep) -{ - if (sep->arg[1][0] == 0) { - c->Message(Chat::White, "Usage: #itemsearch [search string]"); - } - else { - const char *search_criteria = sep->argplus[1]; - - const EQ::ItemData *item = nullptr; - EQ::SayLinkEngine linker; - linker.SetLinkType(EQ::saylink::SayLinkItemData); - - if (Seperator::IsNumber(search_criteria)) { - item = database.GetItem(Strings::ToInt(search_criteria)); - if (item) { - linker.SetItemData(item); - std::string item_id = std::to_string(item->ID); - std::string saylink_commands = - "[" + - Saylink::Silent( - "#si " + item_id, - "X" - ) + - "] "; - - if (item->Stackable && item->StackSize > 1) { - std::string stack_size = std::to_string(item->StackSize); - saylink_commands += - "[" + - Saylink::Silent( - "#si " + item_id + " " + stack_size, - stack_size - ) + - "]"; - } - - c->Message( - Chat::White, - fmt::format( - " Summon {} [{}] [{}]", - saylink_commands, - linker.GenerateLink(), - item->ID - ).c_str() - ); - } - else { - c->Message( - Chat::White, - fmt::format( - "Item {} not found", - search_criteria - ).c_str() - ); - } - - return; - } - - int count = 0; - char sName[64]; - char sCriteria[255]; - strn0cpy(sCriteria, search_criteria, sizeof(sCriteria)); - strupr(sCriteria); - char *pdest; - uint32 it = 0; - while ((item = database.IterateItems(&it))) { - strn0cpy(sName, item->Name, sizeof(sName)); - strupr(sName); - pdest = strstr(sName, sCriteria); - if (pdest != nullptr) { - linker.SetItemData(item); - std::string item_id = std::to_string(item->ID); - std::string saylink_commands = - "[" + - Saylink::Silent( - "#si " + item_id, - "X" - ) + - "] "; - if (item->Stackable && item->StackSize > 1) { - std::string stack_size = std::to_string(item->StackSize); - saylink_commands += - "[" + - Saylink::Silent( - "#si " + item_id + " " + stack_size, - stack_size - ) + - "]"; - } - - c->Message( - Chat::White, - fmt::format( - " Summon {} [{}] [{}]", - saylink_commands, - linker.GenerateLink(), - item->ID - ).c_str() - ); - - ++count; - } - - if (count == 50) { - break; - } - } - - if (count == 50) { - c->Message(Chat::White, "50 items shown...too many results."); - } - else { - c->Message(Chat::White, "%i items found", count); - } - - } -} - diff --git a/zone/gm_commands/listpetition.cpp b/zone/gm_commands/listpetition.cpp deleted file mode 100755 index 110809deb..000000000 --- a/zone/gm_commands/listpetition.cpp +++ /dev/null @@ -1,22 +0,0 @@ -#include "../client.h" - -void command_listpetition(Client *c, const Seperator *sep) -{ - std::string query = "SELECT petid, charname, accountname FROM petitions ORDER BY petid"; - auto results = database.QueryDatabase(query); - if (!results.Success()) { - return; - } - - LogInfo("Petition list requested by [{}]", c->GetName()); - - if (results.RowCount() == 0) { - return; - } - - c->Message(Chat::Red, " ID : Character Name , Account Name"); - - for (auto row = results.begin(); row != results.end(); ++row) - c->Message(Chat::Yellow, " %s: %s , %s ", row[0], row[1], row[2]); -} - diff --git a/zone/gm_commands/mystats.cpp b/zone/gm_commands/mystats.cpp index e5a781d8a..69343b304 100755 --- a/zone/gm_commands/mystats.cpp +++ b/zone/gm_commands/mystats.cpp @@ -2,16 +2,19 @@ void command_mystats(Client *c, const Seperator *sep) { - if (c->GetTarget() && c->GetPet()) { - if (c->GetTarget()->IsPet() && c->GetTarget() == c->GetPet()) { - c->GetTarget()->ShowStats(c); - } - else { - c->ShowStats(c); - } + Mob* t = c; + if (c->GetTarget()) { + t = c->GetTarget(); } - else { - c->ShowStats(c); + + if ( + (t->IsPet() && t == c->GetPet()) || + (t->IsBot() && t->CastToBot()->GetOwner() && t->CastToBot()->GetOwner() == c) + ) { + t->ShowStats(c); + return; } + + c->ShowStats(c); } diff --git a/zone/gm_commands/netstats.cpp b/zone/gm_commands/netstats.cpp deleted file mode 100755 index 87fd11a4c..000000000 --- a/zone/gm_commands/netstats.cpp +++ /dev/null @@ -1,169 +0,0 @@ -#include "../client.h" - -void command_netstats(Client *c, const Seperator *sep) -{ - bool is_full = !strcasecmp(sep->arg[1], "full"); - bool is_reset = !strcasecmp(sep->arg[1], "reset"); - - if (is_reset) { - auto connection = c->Connection(); - c->Message(Chat::White, "Resetting client stats (packet loss will not read correctly after reset)."); - connection->ResetStats(); - return; - } - - auto connection = c->Connection(); - auto opts = connection->GetManager()->GetOptions(); - auto eqs_stats = connection->GetStats(); - auto &stats = eqs_stats.DaybreakStats; - auto now = EQ::Net::Clock::now(); - auto sec_since_stats_reset = std::chrono::duration_cast>( - now - stats.created - ).count(); - - std::string popup_text = ""; - - popup_text += fmt::format( - "", - stats.sent_bytes, - stats.sent_bytes / sec_since_stats_reset - ); - - popup_text += fmt::format( - "", - stats.recv_bytes, - stats.recv_bytes / sec_since_stats_reset - ); - - popup_text += "

"; - - popup_text += fmt::format( - "", - stats.bytes_before_encode, - static_cast(stats.bytes_before_encode - stats.sent_bytes) / - static_cast(stats.bytes_before_encode) * 100.0 - ); - - popup_text += fmt::format( - "", - stats.bytes_after_decode, - static_cast(stats.bytes_after_decode - stats.recv_bytes) / - static_cast(stats.bytes_after_decode) * 100.0 - ); - - popup_text += "

"; - - popup_text += fmt::format("
", stats.min_ping); - popup_text += fmt::format("", stats.max_ping); - popup_text += fmt::format("", stats.last_ping); - popup_text += fmt::format("", stats.avg_ping); - - popup_text += "

"; - - popup_text += fmt::format( - "", - stats.recv_packets, - stats.recv_packets / sec_since_stats_reset - ); - - popup_text += fmt::format( - "", - stats.sent_packets, - stats.sent_packets / sec_since_stats_reset - ); - - popup_text += "

"; - - popup_text += fmt::format("", stats.sync_recv_packets); - popup_text += fmt::format("", stats.sync_sent_packets); - popup_text += fmt::format("", stats.sync_remote_recv_packets); - popup_text += fmt::format("", stats.sync_remote_sent_packets); - - popup_text += "

"; - - popup_text += fmt::format( - "", - (100.0 * (1.0 - static_cast(stats.sync_recv_packets) / static_cast(stats.sync_remote_sent_packets))) - ); - - popup_text += fmt::format( - "", - (100.0 * (1.0 - static_cast(stats.sync_remote_recv_packets) / static_cast(stats.sync_sent_packets))) - ); - - popup_text += "

"; - - popup_text += fmt::format( - "
", - stats.resent_packets, - stats.resent_packets / sec_since_stats_reset - ); - - popup_text += fmt::format( - "", - stats.resent_fragments, - stats.resent_fragments / sec_since_stats_reset - ); - - popup_text += fmt::format( - "", - stats.resent_full, - stats.resent_full / sec_since_stats_reset - ); - - popup_text += "

"; - - popup_text += fmt::format( - "", - stats.dropped_datarate_packets, - stats.dropped_datarate_packets / sec_since_stats_reset - ); - - if (opts.daybreak_options.outgoing_data_rate > 0.0) { - popup_text += fmt::format( - "", - (100.0 * (1.0 - ((opts.daybreak_options.outgoing_data_rate - stats.datarate_remaining) / opts.daybreak_options.outgoing_data_rate))), - opts.daybreak_options.outgoing_data_rate - ); - } - - if (is_full) { - popup_text += "

"; - - popup_text += ""; - for (auto i = 0; i < _maxEmuOpcode; ++i) { - auto cnt = eqs_stats.SentCount[i]; - if (cnt > 0) { - popup_text += fmt::format( - "", - OpcodeNames[i], - cnt, - cnt / sec_since_stats_reset - ); - } - } - - popup_text += "

"; - - popup_text += ""; - for (auto i = 0; i < _maxEmuOpcode; ++i) { - auto cnt = eqs_stats.RecvCount[i]; - if (cnt > 0) { - popup_text += fmt::format( - "", - OpcodeNames[i], - cnt, - cnt / sec_since_stats_reset - ); - } - } - } - - popup_text += "
Sent Bytes{} ({:.2f} Per Second)
Received Bytes{} ({:.2f} Per Second)
Bytes Before Encode (Sent){}Compression Rate{:.2f}%%
Bytes After Decode (Received){}Compression Rate{:.2f}%%
Min Ping{}
Max Ping{}
Last Ping{}
Average Ping{}
(Realtime) Received Packets{} ({:.2f} Per Second)
(Realtime) Sent Packets{} ({:.2f} Per Second)
(Sync) Received Packets{}
(Sync) Sent Packets{}
(Sync) Remote Received Packets{}
(Sync) Remote Sent Packets{}
Packet Loss In{:.2f}%%
Packet Loss Out{:.2f}%%
Resent Packets{} ({:.2f} Per Second)
Resent Fragments{} ({:.2f} Per Second)
Resent Non-Fragments{} ({:.2f} Per Second)
Dropped Datarate Packets{} ({:.2f} Per Second)
Outgoing Link Saturation{:.2f}%% ({:.2f}kb Per Second)
Sent Packet Types
{}{} ({:.2f} Per Second)
Received Packet Types
{}{} ({:.2f} Per Second)
"; - - c->SendPopupToClient( - "Network Statistics", - popup_text.c_str() - ); -} - diff --git a/zone/gm_commands/network.cpp b/zone/gm_commands/network.cpp deleted file mode 100755 index 7f18e86ac..000000000 --- a/zone/gm_commands/network.cpp +++ /dev/null @@ -1,175 +0,0 @@ -#include "../client.h" - -void command_network(Client *c, const Seperator *sep) -{ - if (!strcasecmp(sep->arg[1], "getopt")) { - auto eqsi = c->Connection(); - auto manager = eqsi->GetManager(); - auto opts = manager->GetOptions(); - - if (!strcasecmp(sep->arg[2], "all")) { - c->Message(Chat::White, "max_packet_size: %llu", (uint64_t) opts.daybreak_options.max_packet_size); - c->Message( - Chat::White, - "max_connection_count: %llu", - (uint64_t) opts.daybreak_options.max_connection_count - ); - c->Message(Chat::White, "keepalive_delay_ms: %llu", (uint64_t) opts.daybreak_options.keepalive_delay_ms); - c->Message(Chat::White, "resend_delay_factor: %.2f", opts.daybreak_options.resend_delay_factor); - c->Message(Chat::White, "resend_delay_ms: %llu", (uint64_t) opts.daybreak_options.resend_delay_ms); - c->Message(Chat::White, "resend_delay_min: %llu", (uint64_t) opts.daybreak_options.resend_delay_min); - c->Message(Chat::White, "resend_delay_max: %llu", (uint64_t) opts.daybreak_options.resend_delay_max); - c->Message(Chat::White, "connect_delay_ms: %llu", (uint64_t) opts.daybreak_options.connect_delay_ms); - c->Message(Chat::White, "connect_stale_ms: %llu", (uint64_t) opts.daybreak_options.connect_stale_ms); - c->Message(Chat::White, "stale_connection_ms: %llu", (uint64_t) opts.daybreak_options.stale_connection_ms); - c->Message(Chat::White, "crc_length: %llu", (uint64_t) opts.daybreak_options.crc_length); - c->Message(Chat::White, "hold_size: %llu", (uint64_t) opts.daybreak_options.hold_size); - c->Message(Chat::White, "hold_length_ms: %llu", (uint64_t) opts.daybreak_options.hold_length_ms); - c->Message( - Chat::White, - "simulated_in_packet_loss: %llu", - (uint64_t) opts.daybreak_options.simulated_in_packet_loss - ); - c->Message( - Chat::White, - "simulated_out_packet_loss: %llu", - (uint64_t) opts.daybreak_options.simulated_out_packet_loss - ); - c->Message(Chat::White, "tic_rate_hertz: %.2f", opts.daybreak_options.tic_rate_hertz); - c->Message(Chat::White, "resend_timeout: %llu", (uint64_t) opts.daybreak_options.resend_timeout); - c->Message( - Chat::White, - "connection_close_time: %llu", - (uint64_t) opts.daybreak_options.connection_close_time - ); - c->Message(Chat::White, "encode_passes[0]: %llu", (uint64_t) opts.daybreak_options.encode_passes[0]); - c->Message(Chat::White, "encode_passes[1]: %llu", (uint64_t) opts.daybreak_options.encode_passes[1]); - c->Message(Chat::White, "port: %llu", (uint64_t) opts.daybreak_options.port); - } - else { - c->Message(Chat::White, "Unknown get option: %s", sep->arg[2]); - c->Message(Chat::White, "Available options:"); - //Todo the rest of these when im less lazy. - //c->Message(Chat::White, "max_packet_size"); - //c->Message(Chat::White, "max_connection_count"); - //c->Message(Chat::White, "keepalive_delay_ms"); - //c->Message(Chat::White, "resend_delay_factor"); - //c->Message(Chat::White, "resend_delay_ms"); - //c->Message(Chat::White, "resend_delay_min"); - //c->Message(Chat::White, "resend_delay_max"); - //c->Message(Chat::White, "connect_delay_ms"); - //c->Message(Chat::White, "connect_stale_ms"); - //c->Message(Chat::White, "stale_connection_ms"); - //c->Message(Chat::White, "crc_length"); - //c->Message(Chat::White, "hold_size"); - //c->Message(Chat::White, "hold_length_ms"); - //c->Message(Chat::White, "simulated_in_packet_loss"); - //c->Message(Chat::White, "simulated_out_packet_loss"); - //c->Message(Chat::White, "tic_rate_hertz"); - //c->Message(Chat::White, "resend_timeout"); - //c->Message(Chat::White, "connection_close_time"); - //c->Message(Chat::White, "encode_passes[0]"); - //c->Message(Chat::White, "encode_passes[1]"); - //c->Message(Chat::White, "port"); - c->Message(Chat::White, "all"); - } - } - else if (!strcasecmp(sep->arg[1], "setopt")) { - auto eqsi = c->Connection(); - auto manager = eqsi->GetManager(); - auto opts = manager->GetOptions(); - - if (!strcasecmp(sep->arg[3], "")) { - c->Message(Chat::White, "Missing value for set"); - return; - } - - std::string value = sep->arg[3]; - if (!strcasecmp(sep->arg[2], "max_connection_count")) { - opts.daybreak_options.max_connection_count = Strings::ToUnsignedBigInt(value); - manager->SetOptions(opts); - } - else if (!strcasecmp(sep->arg[2], "keepalive_delay_ms")) { - opts.daybreak_options.keepalive_delay_ms = Strings::ToUnsignedBigInt(value); - manager->SetOptions(opts); - } - else if (!strcasecmp(sep->arg[2], "resend_delay_factor")) { - opts.daybreak_options.resend_delay_factor = std::stod(value); - manager->SetOptions(opts); - } - else if (!strcasecmp(sep->arg[2], "resend_delay_ms")) { - opts.daybreak_options.resend_delay_ms = Strings::ToUnsignedBigInt(value); - manager->SetOptions(opts); - } - else if (!strcasecmp(sep->arg[2], "resend_delay_min")) { - opts.daybreak_options.resend_delay_min = Strings::ToUnsignedBigInt(value); - manager->SetOptions(opts); - } - else if (!strcasecmp(sep->arg[2], "resend_delay_max")) { - opts.daybreak_options.resend_delay_max = Strings::ToUnsignedBigInt(value); - manager->SetOptions(opts); - } - else if (!strcasecmp(sep->arg[2], "connect_delay_ms")) { - opts.daybreak_options.connect_delay_ms = Strings::ToUnsignedBigInt(value); - manager->SetOptions(opts); - } - else if (!strcasecmp(sep->arg[2], "connect_stale_ms")) { - opts.daybreak_options.connect_stale_ms = Strings::ToUnsignedBigInt(value); - manager->SetOptions(opts); - } - else if (!strcasecmp(sep->arg[2], "stale_connection_ms")) { - opts.daybreak_options.stale_connection_ms = Strings::ToUnsignedBigInt(value); - manager->SetOptions(opts); - } - else if (!strcasecmp(sep->arg[2], "hold_size")) { - opts.daybreak_options.hold_size = Strings::ToUnsignedBigInt(value); - manager->SetOptions(opts); - } - else if (!strcasecmp(sep->arg[2], "hold_length_ms")) { - opts.daybreak_options.hold_length_ms = Strings::ToUnsignedBigInt(value); - manager->SetOptions(opts); - } - else if (!strcasecmp(sep->arg[2], "simulated_in_packet_loss")) { - opts.daybreak_options.simulated_in_packet_loss = Strings::ToUnsignedBigInt(value); - manager->SetOptions(opts); - } - else if (!strcasecmp(sep->arg[2], "simulated_out_packet_loss")) { - opts.daybreak_options.simulated_out_packet_loss = Strings::ToUnsignedBigInt(value); - manager->SetOptions(opts); - } - else if (!strcasecmp(sep->arg[2], "resend_timeout")) { - opts.daybreak_options.resend_timeout = Strings::ToUnsignedBigInt(value); - manager->SetOptions(opts); - } - else if (!strcasecmp(sep->arg[2], "connection_close_time")) { - opts.daybreak_options.connection_close_time = Strings::ToUnsignedBigInt(value); - manager->SetOptions(opts); - } - else { - c->Message(Chat::White, "Unknown set option: %s", sep->arg[2]); - c->Message(Chat::White, "Available options:"); - c->Message(Chat::White, "max_connection_count"); - c->Message(Chat::White, "keepalive_delay_ms"); - c->Message(Chat::White, "resend_delay_factor"); - c->Message(Chat::White, "resend_delay_ms"); - c->Message(Chat::White, "resend_delay_min"); - c->Message(Chat::White, "resend_delay_max"); - c->Message(Chat::White, "connect_delay_ms"); - c->Message(Chat::White, "connect_stale_ms"); - c->Message(Chat::White, "stale_connection_ms"); - c->Message(Chat::White, "hold_size"); - c->Message(Chat::White, "hold_length_ms"); - c->Message(Chat::White, "simulated_in_packet_loss"); - c->Message(Chat::White, "simulated_out_packet_loss"); - c->Message(Chat::White, "resend_timeout"); - c->Message(Chat::White, "connection_close_time"); - } - } - else { - c->Message(Chat::White, "Unknown command: %s", sep->arg[1]); - c->Message(Chat::White, "Network commands avail:"); - c->Message(Chat::White, "getopt optname - Retrieve the current option value set."); - c->Message(Chat::White, "setopt optname - Set the current option allowed."); - } -} - diff --git a/zone/gm_commands/npcstats.cpp b/zone/gm_commands/npcstats.cpp deleted file mode 100755 index 9f903d1f7..000000000 --- a/zone/gm_commands/npcstats.cpp +++ /dev/null @@ -1,18 +0,0 @@ -#include "../client.h" - -void command_npcstats(Client *c, const Seperator *sep) -{ - if (c->GetTarget() && c->GetTarget()->IsNPC()) { - NPC *target = c->GetTarget()->CastToNPC(); - - // Stats - target->ShowStats(c); - - // Loot Data - target->QueryLoot(c); - } - else { - c->Message(Chat::White, "You must target an NPC to use this command."); - } -} - diff --git a/zone/gm_commands/peqzone_flags.cpp b/zone/gm_commands/peqzone_flags.cpp deleted file mode 100644 index cde3eb4cd..000000000 --- a/zone/gm_commands/peqzone_flags.cpp +++ /dev/null @@ -1,17 +0,0 @@ -#include "../client.h" - -void command_peqzone_flags(Client *c, const Seperator *sep) -{ - Client *target = c; - - if ( - c->GetTarget() && - c->GetTarget()->IsClient() && - c->Admin() >= minStatusToSeeOthersZoneFlags - ) { - target = c->GetTarget()->CastToClient(); - } - - target->SendPEQZoneFlagInfo(c); -} - diff --git a/zone/gm_commands/petitioninfo.cpp b/zone/gm_commands/petitioninfo.cpp deleted file mode 100755 index c9c1e49f5..000000000 --- a/zone/gm_commands/petitioninfo.cpp +++ /dev/null @@ -1,39 +0,0 @@ -#include "../client.h" - -void command_petitioninfo(Client *c, const Seperator *sep) -{ - if (sep->arg[1][0] == 0) { - c->Message(Chat::White, "Usage: #petitioninfo (petition number) Type #listpetition for a list"); - return; - } - - std::string query = "SELECT petid, charname, accountname, zone, charclass, charrace, charlevel FROM petitions ORDER BY petid"; - auto results = database.QueryDatabase(query); - if (!results.Success()) { - return; - } - - LogInfo("Petition information request from [{}], petition number:", c->GetName(), Strings::ToInt(sep->argplus[1])); - - if (results.RowCount() == 0) { - c->Message(Chat::Red, "There was an error in your request: ID not found! Please check the Id and try again."); - return; - } - - for (auto row = results.begin(); row != results.end(); ++row) - if (strcasecmp(row[0], sep->argplus[1]) == 0) { - c->Message( - Chat::Red, - " ID : %s Character Name: %s Account Name: %s Zone: %s Character Class: %s Character Race: %s Character Level: %s", - row[0], - row[1], - row[2], - row[3], - row[4], - row[5], - row[6] - ); - } - -} - diff --git a/zone/gm_commands/proximity.cpp b/zone/gm_commands/proximity.cpp deleted file mode 100755 index 3db0a714e..000000000 --- a/zone/gm_commands/proximity.cpp +++ /dev/null @@ -1,74 +0,0 @@ -#include "../client.h" - -void command_proximity(Client *c, const Seperator *sep) -{ - if (!c->GetTarget() || (c->GetTarget() && !c->GetTarget()->IsNPC())) { - c->Message(Chat::White, "You must target an NPC"); - return; - } - - for (auto &iter : entity_list.GetNPCList()) { - auto npc = iter.second; - std::string name = npc->GetName(); - - if (name.find("Proximity") != std::string::npos) { - npc->Depop(); - } - } - - NPC *npc = c->GetTarget()->CastToNPC(); - - std::vector points; - - FindPerson_Point p{}; - - if (npc->IsProximitySet()) { - glm::vec4 position; - position.w = npc->GetHeading(); - position.x = npc->GetProximityMinX(); - position.y = npc->GetProximityMinY(); - position.z = npc->GetZ(); - - position.x = npc->GetProximityMinX(); - position.y = npc->GetProximityMinY(); - NPC::SpawnNodeNPC("Proximity", "", position); - - position.x = npc->GetProximityMinX(); - position.y = npc->GetProximityMaxY(); - NPC::SpawnNodeNPC("Proximity", "", position); - - position.x = npc->GetProximityMaxX(); - position.y = npc->GetProximityMinY(); - NPC::SpawnNodeNPC("Proximity", "", position); - - position.x = npc->GetProximityMaxX(); - position.y = npc->GetProximityMaxY(); - NPC::SpawnNodeNPC("Proximity", "", position); - - p.x = npc->GetProximityMinX(); - p.y = npc->GetProximityMinY(); - p.z = npc->GetZ(); - points.push_back(p); - - p.x = npc->GetProximityMinX(); - p.y = npc->GetProximityMaxY(); - points.push_back(p); - - p.x = npc->GetProximityMaxX(); - p.y = npc->GetProximityMaxY(); - points.push_back(p); - - p.x = npc->GetProximityMaxX(); - p.y = npc->GetProximityMinY(); - points.push_back(p); - - p.x = npc->GetProximityMinX(); - p.y = npc->GetProximityMinY(); - points.push_back(p); - } - - if (c->ClientVersion() >= EQ::versions::ClientVersion::RoF) { - c->SendPathPacket(points); - } -} - diff --git a/zone/gm_commands/questerrors.cpp b/zone/gm_commands/questerrors.cpp deleted file mode 100755 index 4be3b19a3..000000000 --- a/zone/gm_commands/questerrors.cpp +++ /dev/null @@ -1,33 +0,0 @@ -#include "../client.h" -#include "../quest_parser_collection.h" - -void command_questerrors(Client *c, const Seperator *sep) -{ - std::list quest_errors; - parse->GetErrors(quest_errors); - - if (quest_errors.size()) { - c->Message(Chat::White, "Quest errors currently are as follows:"); - - int error_index = 0; - for (auto quest_error : quest_errors) { - if (error_index >= RuleI(World, MaximumQuestErrors)) { - c->Message( - Chat::White, - fmt::format( - "Maximum of {} error{} shown.", - RuleI(World, MaximumQuestErrors), - RuleI(World, MaximumQuestErrors) != 1 ? "s" : "" - ).c_str() - ); - break; - } - - c->Message(Chat::White, quest_error.c_str()); - error_index++; - } - } else { - c->Message(Chat::White, "There are no Quest errors currently."); - } -} - diff --git a/zone/gm_commands/serverinfo.cpp b/zone/gm_commands/serverinfo.cpp deleted file mode 100755 index 3832aa7d3..000000000 --- a/zone/gm_commands/serverinfo.cpp +++ /dev/null @@ -1,126 +0,0 @@ -#include "../client.h" -#include "../dialogue_window.h" -#include "../../common/serverinfo.h" - -void command_serverinfo(Client *c, const Seperator *sep) -{ - auto os = EQ::GetOS(); - auto cpus = EQ::GetCPUs(); - auto process_id = EQ::GetPID(); - auto rss = EQ::GetRSS() / 1048576.0; - auto uptime = static_cast(EQ::GetUptime()); - - std::string popup_table; - auto popup_text = DialogueWindow::CenterMessage( - DialogueWindow::ColorMessage("green", "Operating System Information") - ); - - popup_table.append( - DialogueWindow::TableRow( - DialogueWindow::TableCell("Machine") + - DialogueWindow::TableCell(os.machine) - ).c_str() - ); - - popup_table.append( - DialogueWindow::TableRow( - DialogueWindow::TableCell("System") + - DialogueWindow::TableCell(os.sysname) - ).c_str() - ); - - popup_table.append( - DialogueWindow::TableRow( - DialogueWindow::TableCell("Release") + - DialogueWindow::TableCell(os.release) - ).c_str() - ); - - popup_table.append( - DialogueWindow::TableRow( - DialogueWindow::TableCell("Uptime") + - DialogueWindow::TableCell(Strings::SecondsToTime(uptime)) - ).c_str() - ); - - popup_table.append( - DialogueWindow::TableRow( - DialogueWindow::TableCell("Version") + - DialogueWindow::TableCell(os.version) - ).c_str() - ); - - popup_text.append(DialogueWindow::Table(popup_table)); - - popup_table = std::string(); - - popup_text.append(DialogueWindow::Break()); - - popup_text.append( - DialogueWindow::CenterMessage( - DialogueWindow::ColorMessage("green", "CPU Information") - ) - ); - - for (size_t cpu = 0; cpu < cpus.size(); ++cpu) { - auto ¤t_cpu = cpus[cpu]; - popup_table.append( - DialogueWindow::TableRow( - DialogueWindow::TableCell( - fmt::format( - "CPU {}", - cpu - ) - ) + - DialogueWindow::TableCell( - fmt::format( - "{} ({:.2f}GHz)", - current_cpu.model, - current_cpu.speed - ) - ) - ) - ); - } - - popup_text.append(DialogueWindow::Table(popup_table)); - - popup_table = std::string(); - - popup_text.append(DialogueWindow::Break()); - - popup_text.append( - DialogueWindow::CenterMessage( - DialogueWindow::ColorMessage("green", "CPU Information") - ) - ); - - popup_text.append(""); - - popup_table.append( - DialogueWindow::TableRow( - DialogueWindow::TableCell("Process ID") + - DialogueWindow::TableCell(std::to_string(process_id)) - ) - ); - - popup_table.append( - DialogueWindow::TableRow( - DialogueWindow::TableCell("RSS") + - DialogueWindow::TableCell( - fmt::format( - "{:.2f} MB", - rss - ) - ) - ) - ); - - popup_text.append(DialogueWindow::Table(popup_table)); - - c->SendPopupToClient( - "Server Information", - popup_text.c_str() - ); -} - diff --git a/zone/gm_commands/show.cpp b/zone/gm_commands/show.cpp new file mode 100755 index 000000000..d88410984 --- /dev/null +++ b/zone/gm_commands/show.cpp @@ -0,0 +1,142 @@ +#include "../client.h" +#include "show/aggro.cpp" +#include "show/buffs.cpp" +#include "show/buried_corpse_count.cpp" +#include "show/client_version_summary.cpp" +#include "show/currencies.cpp" +#include "show/distance.cpp" +#include "show/emotes.cpp" +#include "show/field_of_view.cpp" +#include "show/flags.cpp" +#include "show/group_info.cpp" +#include "show/hatelist.cpp" +#include "show/inventory.cpp" +#include "show/ip_lookup.cpp" +#include "show/line_of_sight.cpp" +#include "show/network.cpp" +#include "show/network_stats.cpp" +#include "show/npc_global_loot.cpp" +#include "show/npc_stats.cpp" +#include "show/npc_type.cpp" +#include "show/peqzone_flags.cpp" +#include "show/petition.cpp" +#include "show/petition_info.cpp" +#include "show/proximity.cpp" +#include "show/quest_errors.cpp" +#include "show/quest_globals.cpp" +#include "show/recipe.cpp" +#include "show/server_info.cpp" +#include "show/skills.cpp" +#include "show/spawn_status.cpp" +#include "show/spells.cpp" +#include "show/spells_list.cpp" +#include "show/stats.cpp" +#include "show/timers.cpp" +#include "show/traps.cpp" +#include "show/uptime.cpp" +#include "show/variable.cpp" +#include "show/version.cpp" +#include "show/waypoints.cpp" +#include "show/who.cpp" +#include "show/xtargets.cpp" +#include "show/zone_data.cpp" +#include "show/zone_global_loot.cpp" +#include "show/zone_loot.cpp" +#include "show/zone_points.cpp" +#include "show/zone_status.cpp" + +void command_show(Client *c, const Seperator *sep) +{ + struct Cmd { + std::string cmd{}; // command + std::string u{}; // usage + void (*fn)(Client *c, const Seperator *sep) = nullptr; // function + std::vector a{}; // aliases + }; + + std::vector commands = { + Cmd{.cmd = "aggro", .u = "aggro [Distance] [-v] (-v is verbose Faction Information)", .fn = ShowAggro, .a = {"#aggro"}}, + Cmd{.cmd = "buffs", .u = "buffs", .fn = ShowBuffs, .a = {"#showbuffs"}}, + Cmd{.cmd = "buried_corpse_count", .u = "buried_corpse_count", .fn = ShowBuriedCorpseCount, .a = {"#getplayerburiedcorpsecount"}}, + Cmd{.cmd = "client_version_summary", .u = "client_version_summary", .fn = ShowClientVersionSummary, .a = {"#cvs"}}, + Cmd{.cmd = "currencies", .u = "currencies", .fn = ShowCurrencies, .a = {"#viewcurrencies"}}, + Cmd{.cmd = "distance", .u = "distance", .fn = ShowDistance, .a = {"#distance"}}, + Cmd{.cmd = "emotes", .u = "emotes", .fn = ShowEmotes, .a = {"#emoteview"}}, + Cmd{.cmd = "field_of_view", .u = "field_of_view", .fn = ShowFieldOfView, .a = {"#fov"}}, + Cmd{.cmd = "flags", .u = "flags", .fn = ShowFlags, .a = {"#flags"}}, + Cmd{.cmd = "group_info", .u = "group_info", .fn = ShowGroupInfo, .a = {"#ginfo"}}, + Cmd{.cmd = "hatelist", .u = "hatelist", .fn = ShowHateList, .a = {"#hatelist"}}, + Cmd{.cmd = "inventory", .u = "inventory", .fn = ShowInventory, .a = {"#peekinv"}}, + Cmd{.cmd = "ip_lookup", .u = "ip_lookup", .fn = ShowIPLookup, .a = {"#iplookup"}}, + Cmd{.cmd = "line_of_sight", .u = "line_of_sight", .fn = ShowLineOfSight, .a = {"#checklos"}}, + Cmd{.cmd = "network", .u = "network", .fn = ShowNetwork, .a = {"#network"}}, + Cmd{.cmd = "network_stats", .u = "network_stats", .fn = ShowNetworkStats, .a = {"#netstats"}}, + Cmd{.cmd = "npc_global_loot", .u = "npc_global_loot", .fn = ShowNPCGlobalLoot, .a = {"#shownpcgloballoot"}}, + Cmd{.cmd = "npc_stats", .u = "npc_stats", .fn = ShowNPCStats, .a = {"#npcstats"}}, + Cmd{.cmd = "npc_type", .u = "npc_type [NPC ID]", .fn = ShowNPCType, .a = {"#viewnpctype"}}, + Cmd{.cmd = "peqzone_flags", .u = "peqzone_flags", .fn = ShowPEQZoneFlags, .a = {"#peqzone_flags"}}, + Cmd{.cmd = "petition", .u = "petition", .fn = ShowPetition, .a = {"#listpetition", "#viewpetition"}}, + Cmd{.cmd = "petition_info", .u = "petition_info", .fn = ShowPetitionInfo, .a = {"#petitioninfo"}}, + Cmd{.cmd = "proximity", .u = "proximity", .fn = ShowProximity, .a = {"#proximity"}}, + Cmd{.cmd = "quest_errors", .u = "quest_errors", .fn = ShowQuestErrors, .a = {"#questerrors"}}, + Cmd{.cmd = "quest_globals", .u = "quest_globals", .fn = ShowQuestGlobals, .a = {"#globalview"}}, + Cmd{.cmd = "recipe", .u = "recipe [Recipe ID]", .fn = ShowRecipe, .a = {"#viewrecipe"}}, + Cmd{.cmd = "server_info", .u = "server_info", .fn = ShowServerInfo, .a = {"#serverinfo"}}, + Cmd{.cmd = "skills", .u = "skills", .fn = ShowSkills, .a = {"#showskills"}}, + Cmd{.cmd = "spawn_status", .u = "spawn_status [all|disabled|enabled|Spawn ID]", .fn = ShowSpawnStatus, .a = {"#spawnstatus"}}, + Cmd{.cmd = "spells", .u = "spells [disciplines|spells]", .fn = ShowSpells, .a = {"#showspells"}}, + Cmd{.cmd = "spells_list", .u = "spells_list", .fn = ShowSpellsList, .a = {"#showspellslist"}}, + Cmd{.cmd = "stats", .u = "stats", .fn = ShowStats, .a = {"#showstats"}}, + Cmd{.cmd = "timers", .u = "timers", .fn = ShowTimers, .a = {"#timers"}}, + Cmd{.cmd = "traps", .u = "traps", .fn = ShowTraps, .a = {"#trapinfo"}}, + Cmd{.cmd = "uptime", .u = "uptime [Zone Server ID] (Zone Server ID is optional)", .fn = ShowUptime, .a = {"#uptime"}}, + Cmd{.cmd = "variable", .u = "variable [Variable Name]", .fn = ShowVariable, .a = {"#getvariable"}}, + Cmd{.cmd = "version", .u = "version", .fn = ShowVersion, .a = {"#version"}}, + Cmd{.cmd = "waypoints", .u = "waypoints", .fn = ShowWaypoints, .a = {"#wpinfo"}}, + Cmd{.cmd = "who", .u = "who [Search Criteria] (Search criteria is optional)", .fn = ShowWho, .a = {"#who"}}, + Cmd{.cmd = "xtargets", .u = "xtargets [Amount] (Amount is optional)", .fn = ShowXTargets, .a = {"#xtargets"}}, + Cmd{.cmd = "zone_data", .u = "zone_data", .fn = ShowZoneData, .a = {"#zstats"}}, + Cmd{.cmd = "zone_global_loot", .u = "zone_global_loot", .fn = ShowZoneGlobalLoot, .a = {"#showzonegloballoot"}}, + Cmd{.cmd = "zone_loot", .u = "zone_loot", .fn = ShowZoneLoot, .a = {"#viewzoneloot"}}, + Cmd{.cmd = "zone_points", .u = "zone_points", .fn = ShowZonePoints, .a = {"#showzonepoints"}}, + Cmd{.cmd = "zone_status", .u = "zone_status", .fn = ShowZoneStatus, .a = {"#zonestatus"}}, + }; + + // Check for arguments + const auto arguments = sep->argnum; + + // look for alias or command + for (const auto &cmd: commands) { + // Check for alias first + for (const auto &alias: cmd.a) { + if (!alias.empty() && Strings::EqualFold(alias, sep->arg[0])) { + // build string from sep args + std::vector args = {}; + + // skip the first arg + for (auto i = 1; i <= arguments; i++) { + args.emplace_back(sep->arg[i]); + } + + // build the rewrite string + const std::string& rewrite = fmt::format("#show {} {}", cmd.cmd, Strings::Join(args, " ")); + + // rewrite to #show + c->SendGMCommand(rewrite); + return; + } + } + + // Check for command + if (cmd.cmd == Strings::ToLower(sep->arg[1])) { + cmd.fn(c, sep); + return; + } + } + + // Command not found + c->Message(Chat::White, "Command not found. Usage: #show [command]"); + for (const auto &cmd: commands) { + c->Message(Chat::White, fmt::format("Usage: #show {}", cmd.u).c_str()); + } +} diff --git a/zone/gm_commands/show/aggro.cpp b/zone/gm_commands/show/aggro.cpp new file mode 100755 index 000000000..c579dc4c3 --- /dev/null +++ b/zone/gm_commands/show/aggro.cpp @@ -0,0 +1,22 @@ +#include "../../client.h" + +void ShowAggro(Client *c, const Seperator *sep) +{ + const auto arguments = sep->argnum; + if (arguments < 2 || !sep->IsNumber(2)) { + c->Message(Chat::White, "Usage: #show aggro [Distance] [-v] (-v is verbose Faction Information)"); + return; + } + + if (!c->GetTarget() || !c->GetTarget()->IsNPC()) { + c->Message(Chat::White, "You must target an NPC to use this command."); + return; + } + + const auto t = c->GetTarget()->CastToNPC(); + + const float distance = Strings::ToFloat(sep->arg[2]); + const bool is_verbose = Strings::EqualFold(sep->arg[3], "-v"); + + entity_list.DescribeAggro(c, t, distance, is_verbose); +} diff --git a/zone/gm_commands/show/buffs.cpp b/zone/gm_commands/show/buffs.cpp new file mode 100644 index 000000000..eec2451d6 --- /dev/null +++ b/zone/gm_commands/show/buffs.cpp @@ -0,0 +1,11 @@ +#include "../../client.h" + +void ShowBuffs(Client *c, const Seperator *sep) +{ + Mob* t = c; + if (c->GetTarget()) { + t = c->GetTarget(); + } + + t->ShowBuffs(c); +} diff --git a/zone/gm_commands/show/buried_corpse_count.cpp b/zone/gm_commands/show/buried_corpse_count.cpp new file mode 100644 index 000000000..863abc18a --- /dev/null +++ b/zone/gm_commands/show/buried_corpse_count.cpp @@ -0,0 +1,23 @@ +#include "../../client.h" +#include "../../corpse.h" + +void ShowBuriedCorpseCount(Client *c, const Seperator *sep) +{ + auto t = c; + if (c->GetTarget() && c->GetTarget()->IsClient() && c->GetGM()) { + t = c->GetTarget()->CastToClient(); + } + + const uint32 corpse_count = database.GetCharacterBuriedCorpseCount(t->CharacterID()); + + c->Message( + Chat::White, + fmt::format( + "{} {} {} buried corpse{}.", + c->GetTargetDescription(t, TargetDescriptionType::UCYou), + c == t ? "have" : "has", + corpse_count, + corpse_count != 1 ? "s" : "" + ).c_str() + ); +} diff --git a/zone/gm_commands/show/client_version_summary.cpp b/zone/gm_commands/show/client_version_summary.cpp new file mode 100644 index 000000000..98b5d4f52 --- /dev/null +++ b/zone/gm_commands/show/client_version_summary.cpp @@ -0,0 +1,16 @@ +#include "../../client.h" +#include "../../worldserver.h" + +extern WorldServer worldserver; + +void ShowClientVersionSummary(Client *c, const Seperator *sep) +{ + auto pack = new ServerPacket(ServerOP_ClientVersionSummary, sizeof(ServerRequestClientVersionSummary_Struct)); + + auto s = (ServerRequestClientVersionSummary_Struct *) pack->pBuffer; + strn0cpy(s->Name, c->GetName(), sizeof(s->Name)); + + worldserver.SendPacket(pack); + safe_delete(pack); +} + diff --git a/zone/gm_commands/show/currencies.cpp b/zone/gm_commands/show/currencies.cpp new file mode 100644 index 000000000..affda79bc --- /dev/null +++ b/zone/gm_commands/show/currencies.cpp @@ -0,0 +1,136 @@ +#include "../../client.h" +#include "../../dialogue_window.h" + +void ShowCurrencies(Client *c, const Seperator *sep) +{ + auto t = c; + if (c->GetTarget() && c->GetTarget()->IsClient()) { + t = c->GetTarget()->CastToClient(); + } + + const uint32 platinum = ( + t->GetMoney(3, 0) + + t->GetMoney(3, 1) + + t->GetMoney(3, 2) + + t->GetMoney(3, 3) + ); + + const uint32 gold = ( + t->GetMoney(2, 0) + + t->GetMoney(2, 1) + + t->GetMoney(2, 2) + ); + + const uint32 silver = ( + t->GetMoney(1, 0) + + t->GetMoney(1, 1) + + t->GetMoney(1, 2) + ); + + const uint32 copper = ( + t->GetMoney(0, 0) + + t->GetMoney(0, 1) + + t->GetMoney(0, 2) + ); + + std::string currency_table; + + bool has_currency = false; + + currency_table += DialogueWindow::TableRow( + DialogueWindow::TableCell("Currency") + + DialogueWindow::TableCell("Amount") + ); + + if ( + platinum || + gold || + silver || + copper + ) { + currency_table += DialogueWindow::TableRow( + DialogueWindow::TableCell("Money") + + DialogueWindow::TableCell(Strings::Money(platinum, gold, silver, copper)) + ); + + has_currency = true; + } + + const uint32 ebon_crystals = t->GetEbonCrystals(); + if (ebon_crystals) { + currency_table += DialogueWindow::TableRow( + DialogueWindow::TableCell("Ebon Crystals") + + DialogueWindow::TableCell(Strings::Commify(ebon_crystals)) + ); + + has_currency = true; + } + + const uint32 radiant_crystals = t->GetRadiantCrystals(); + if (radiant_crystals) { + currency_table += DialogueWindow::TableRow( + DialogueWindow::TableCell("Radiant Crystals") + + DialogueWindow::TableCell(Strings::Commify(radiant_crystals)) + ); + + has_currency = true; + } + + for (const auto& a : zone->AlternateCurrencies) { + const uint32 currency_value = t->GetAlternateCurrencyValue(a.id); + if (currency_value) { + const auto* d = database.GetItem(a.item_id); + currency_table += DialogueWindow::TableRow( + DialogueWindow::TableCell(d->Name) + + DialogueWindow::TableCell(Strings::Commify(currency_value)) + ); + + has_currency = true; + } + } + + for (const auto& l : EQ::constants::GetLDoNThemeMap()) { + const uint32 ldon_currency_value = t->GetLDoNPointsTheme(l.first); + if (ldon_currency_value) { + currency_table += DialogueWindow::TableRow( + DialogueWindow::TableCell(l.second) + + DialogueWindow::TableCell(Strings::Commify(ldon_currency_value)) + ); + + has_currency = true; + } + } + + const uint32 pvp_points = t->GetPVPPoints(); + if (pvp_points) { + currency_table += DialogueWindow::TableRow( + DialogueWindow::TableCell("PVP Points") + + DialogueWindow::TableCell(Strings::Commify(pvp_points)) + ); + + has_currency = true; + } + + currency_table = DialogueWindow::Table(currency_table); + + if (!has_currency) { + c->Message( + Chat::White, + fmt::format( + "{} {} not have any currencies.", + c->GetTargetDescription(t, TargetDescriptionType::UCYou), + c == t ? "do" : "does" + ).c_str() + ); + + return; + } + + c->SendPopupToClient( + fmt::format( + "Currency for {}", + c->GetTargetDescription(t, TargetDescriptionType::UCSelf) + ).c_str(), + currency_table.c_str() + ); +} diff --git a/zone/gm_commands/show/distance.cpp b/zone/gm_commands/show/distance.cpp new file mode 100644 index 000000000..aece8494e --- /dev/null +++ b/zone/gm_commands/show/distance.cpp @@ -0,0 +1,23 @@ +#include "../../client.h" + +void ShowDistance(Client *c, const Seperator *sep) +{ + if (!c->GetTarget() || c->GetTarget() == c) { + c->Message(Chat::White, "You must have a target to use this command."); + return; + } + + const auto t = c->GetTarget(); + + c->Message( + Chat::White, + fmt::format( + "{} is {:.2f} units from you.", + c->GetTargetDescription(t), + Distance( + c->GetPosition(), + t->GetPosition() + ) + ).c_str() + ); +} diff --git a/zone/gm_commands/emoteview.cpp b/zone/gm_commands/show/emotes.cpp old mode 100755 new mode 100644 similarity index 62% rename from zone/gm_commands/emoteview.cpp rename to zone/gm_commands/show/emotes.cpp index c1116f026..9e7e58e74 --- a/zone/gm_commands/emoteview.cpp +++ b/zone/gm_commands/show/emotes.cpp @@ -1,29 +1,27 @@ -#include "../client.h" +#include "../../client.h" -void command_emoteview(Client *c, const Seperator *sep) +void ShowEmotes(Client *c, const Seperator *sep) { if (!c->GetTarget() || !c->GetTarget()->IsNPC()) { c->Message(Chat::White, "You must target an NPC to view their emotes."); return; } - auto target = c->GetTarget()->CastToNPC(); + const auto t = c->GetTarget()->CastToNPC(); - auto emote_count = 0; - auto emote_id = target->GetEmoteID(); - - auto emote_number = 1; + uint32 emote_count = 0; + const uint32 emote_id = t->GetEmoteID(); LinkedListIterator iterator(zone->NPCEmoteList); iterator.Reset(); while (iterator.MoreElements()) { - auto &e = iterator.GetData(); + const auto& e = iterator.GetData(); if (emote_id == e->emoteid) { c->Message( Chat::White, fmt::format( "Emote {} | Event: {} ({}) Type: {} ({})", - emote_number, + e->emoteid, EQ::constants::GetEmoteEventTypeName(e->event_), e->event_, EQ::constants::GetEmoteTypeName(e->type), @@ -35,35 +33,22 @@ void command_emoteview(Client *c, const Seperator *sep) Chat::White, fmt::format( "Emote {} | Text: {}", - emote_number, + e->emoteid, e->text ).c_str() ); emote_count++; - emote_number++; } iterator.Advance(); } - if (!emote_count) { - c->Message( - Chat::White, - fmt::format( - "{} has no emotes on Emote ID {}.", - c->GetTargetDescription(target), - emote_id - ).c_str() - ); - return; - } - c->Message( Chat::White, fmt::format( "{} has {} emote{} on Emote ID {}.", - c->GetTargetDescription(target), + c->GetTargetDescription(t), emote_count, emote_count != 1 ? "s" : "", emote_id diff --git a/zone/gm_commands/show/field_of_view.cpp b/zone/gm_commands/show/field_of_view.cpp new file mode 100644 index 000000000..dfa617a35 --- /dev/null +++ b/zone/gm_commands/show/field_of_view.cpp @@ -0,0 +1,23 @@ +#include "../../client.h" + +void ShowFieldOfView(Client *c, const Seperator *sep) +{ + if (!c->GetTarget() || c->GetTarget() == c) { + c->Message(Chat::White, "You must have a target to use this command."); + return; + } + + const auto t = c->GetTarget(); + + const bool is_behind = c->BehindMob(t, c->GetX(), c->GetY()); + + c->Message( + Chat::White, + fmt::format( + "You are {}behind {}, they have a heading of {}.", + is_behind ? "" : "not ", + c->GetTargetDescription(t), + t->GetHeading() + ).c_str() + ); +} diff --git a/zone/gm_commands/show/flags.cpp b/zone/gm_commands/show/flags.cpp new file mode 100644 index 000000000..27a4345ef --- /dev/null +++ b/zone/gm_commands/show/flags.cpp @@ -0,0 +1,16 @@ +#include "../../client.h" + +void ShowFlags(Client *c, const Seperator *sep) +{ + auto t = c; + + if ( + c->GetTarget() && + c->GetTarget()->IsClient() && + c->Admin() >= minStatusToSeeOthersZoneFlags + ) { + t = c->GetTarget()->CastToClient(); + } + + t->SendZoneFlagInfo(c); +} diff --git a/zone/gm_commands/show/group_info.cpp b/zone/gm_commands/show/group_info.cpp new file mode 100644 index 000000000..7aab3464c --- /dev/null +++ b/zone/gm_commands/show/group_info.cpp @@ -0,0 +1,89 @@ +#include "../../client.h" +#include "../../dialogue_window.h" +#include "../../groups.h" + +void ShowGroupInfo(Client *c, const Seperator *sep) +{ + auto t = c; + if (c->GetTarget() && c->GetTarget()->IsClient()) { + t = c->GetTarget()->CastToClient(); + } + + auto g = t->GetGroup(); + if (!g) { + c->Message( + Chat::White, + fmt::format( + "{} {} not in a group.", + c->GetTargetDescription(t, TargetDescriptionType::UCYou), + c == t ? "are" : "is" + ).c_str() + ); + return; + } + + std::string popup_table; + + popup_table += DialogueWindow::TableRow( + DialogueWindow::TableCell("Group ID") + + DialogueWindow::TableCell(Strings::Commify(g->GetID())) + ); + + popup_table += DialogueWindow::TableRow( + DialogueWindow::TableCell("Members") + + DialogueWindow::TableCell(std::to_string(g->GroupCount())) + ); + + popup_table += DialogueWindow::Break(2); + + popup_table += DialogueWindow::TableRow( + DialogueWindow::TableCell("Index") + + DialogueWindow::TableCell("Name") + + DialogueWindow::TableCell("In Zone") + + DialogueWindow::TableCell("Assist") + + DialogueWindow::TableCell("Puller") + + DialogueWindow::TableCell("Tank") + ); + + const std::string yes = DialogueWindow::ColorMessage("forest_green", "Y"); + const std::string no = DialogueWindow::ColorMessage("red1", "N"); + + for (int group_member = 0; group_member < MAX_GROUP_MEMBERS; group_member++) { + if (g->membername[group_member][0] == '\0') { + continue; + } + + const bool is_assist = g->MemberRoles[group_member] & RoleAssist; + const bool is_puller = g->MemberRoles[group_member] & RolePuller; + const bool is_tank = g->MemberRoles[group_member] & RoleTank; + + popup_table += DialogueWindow::TableRow( + fmt::format( + "{}{}{}{}{}{}", + group_member, + ( + strcmp(g->membername[group_member], c->GetCleanName()) ? + g->membername[group_member] : + fmt::format( + "{} (You)", + g->membername[group_member] + ) + ), + g->members[group_member] ? yes : no, + is_assist ? yes : no, + is_puller ? yes : no, + is_tank ? yes : no + ) + ); + } + + popup_table = DialogueWindow::Table(popup_table); + + c->SendPopupToClient( + fmt::format( + "Group Info for {}", + c->GetTargetDescription(t, TargetDescriptionType::UCSelf) + ).c_str(), + popup_table.c_str() + ); +} diff --git a/zone/gm_commands/hatelist.cpp b/zone/gm_commands/show/hatelist.cpp old mode 100755 new mode 100644 similarity index 50% rename from zone/gm_commands/hatelist.cpp rename to zone/gm_commands/show/hatelist.cpp index 83fe75e20..225ad16f4 --- a/zone/gm_commands/hatelist.cpp +++ b/zone/gm_commands/show/hatelist.cpp @@ -1,13 +1,13 @@ -#include "../client.h" +#include "../../client.h" -void command_hatelist(Client *c, const Seperator *sep) +void ShowHateList(Client *c, const Seperator *sep) { if (!c->GetTarget() || !c->GetTarget()->IsNPC()) { c->Message(Chat::White, "You must target an NPC to use this command."); return; } - auto target = c->GetTarget(); + const auto t = c->GetTarget(); - target->PrintHateListToClient(c); + t->PrintHateListToClient(c); } diff --git a/zone/gm_commands/peekinv.cpp b/zone/gm_commands/show/inventory.cpp old mode 100755 new mode 100644 similarity index 81% rename from zone/gm_commands/peekinv.cpp rename to zone/gm_commands/show/inventory.cpp index 596ad27bc..cbb5a03fc --- a/zone/gm_commands/peekinv.cpp +++ b/zone/gm_commands/show/inventory.cpp @@ -1,11 +1,11 @@ -#include "../client.h" -#include "../object.h" +#include "../../client.h" +#include "../../object.h" -void command_peekinv(Client *c, const Seperator *sep) +void ShowInventory(Client *c, const Seperator *sep) { - auto arguments = sep->argnum; - if (!arguments) { - SendPeekInvSubCommands(c); + const auto arguments = sep->argnum; + if (arguments < 2) { + SendShowInventorySubCommands(c); return; } @@ -50,19 +50,19 @@ void command_peekinv(Client *c, const Seperator *sep) int scope_mask = peekNone; - const bool is_all = !strcasecmp(sep->arg[1], "all"); - const bool is_all_bank = !strcasecmp(sep->arg[1], "allbank"); - const bool is_bank = !strcasecmp(sep->arg[1], "bank"); - const bool is_cursor = !strcasecmp(sep->arg[1], "cursor"); - const bool is_cursor_limbo = !strcasecmp(sep->arg[1], "curlimbo"); - const bool is_equipment = !strcasecmp(sep->arg[1], "equip"); - const bool is_general = !strcasecmp(sep->arg[1], "gen"); - const bool is_limbo = !strcasecmp(sep->arg[1], "limbo"); - const bool is_possessions = !strcasecmp(sep->arg[1], "poss"); - const bool is_shared_bank = !strcasecmp(sep->arg[1], "shbank"); - const bool is_trade = !strcasecmp(sep->arg[1], "trade"); - const bool is_tribute = !strcasecmp(sep->arg[1], "trib"); - const bool is_world = !strcasecmp(sep->arg[1], "world"); + const bool is_all = !strcasecmp(sep->arg[2], "all"); + const bool is_all_bank = !strcasecmp(sep->arg[2], "allbank"); + const bool is_bank = !strcasecmp(sep->arg[2], "bank"); + const bool is_cursor = !strcasecmp(sep->arg[2], "cursor"); + const bool is_cursor_limbo = !strcasecmp(sep->arg[2], "curlimbo"); + const bool is_equipment = !strcasecmp(sep->arg[2], "equip"); + const bool is_general = !strcasecmp(sep->arg[2], "gen"); + const bool is_limbo = !strcasecmp(sep->arg[2], "limbo"); + const bool is_possessions = !strcasecmp(sep->arg[2], "poss"); + const bool is_shared_bank = !strcasecmp(sep->arg[2], "shbank"); + const bool is_trade = !strcasecmp(sep->arg[2], "trade"); + const bool is_tribute = !strcasecmp(sep->arg[2], "trib"); + const bool is_world = !strcasecmp(sep->arg[2], "world"); if (is_all) { scope_mask = (peekOutOfScope - 1); @@ -91,7 +91,7 @@ void command_peekinv(Client *c, const Seperator *sep) } else if (is_world) { scope_mask |= peekWorld; } else { - SendPeekInvSubCommands(c); + SendShowInventorySubCommands(c); return; } @@ -433,18 +433,18 @@ void command_peekinv(Client *c, const Seperator *sep) } } -void SendPeekInvSubCommands(Client* c) { - c->Message(Chat::White, "Usage: #peekinv equip - Shows items in Equipment slots"); - c->Message(Chat::White, "Usage: #peekinv gen - Shows items in General slots"); - c->Message(Chat::White, "Usage: #peekinv cursor - Shows items in Cursor slots"); - c->Message(Chat::White, "Usage: #peekinv poss - Shows items in Equipment, General, and Cursor slots"); - c->Message(Chat::White, "Usage: #peekinv limbo - Shows items in Limbo slots"); - c->Message(Chat::White, "Usage: #peekinv curlim - Shows items in Cursor and Limbo slots"); - c->Message(Chat::White, "Usage: #peekinv trib - Shows items in Tribute slots"); - c->Message(Chat::White, "Usage: #peekinv bank - Shows items in Bank slots"); - c->Message(Chat::White, "Usage: #peekinv shbank - Shows items in Shared Bank slots"); - c->Message(Chat::White, "Usage: #peekinv allbank - Shows items in Bank and Shared Bank slots"); - c->Message(Chat::White, "Usage: #peekinv trade - Shows items in Trade slots"); - c->Message(Chat::White, "Usage: #peekinv world - Shows items in World slots"); - c->Message(Chat::White, "Usage: #peekinv all - Shows items in all slots"); +void SendShowInventorySubCommands(Client* c) { + c->Message(Chat::White, "Usage: #show inventory equip - Shows items in Equipment slots"); + c->Message(Chat::White, "Usage: #show inventory gen - Shows items in General slots"); + c->Message(Chat::White, "Usage: #show inventory cursor - Shows items in Cursor slots"); + c->Message(Chat::White, "Usage: #show inventory poss - Shows items in Equipment, General, and Cursor slots"); + c->Message(Chat::White, "Usage: #show inventory limbo - Shows items in Limbo slots"); + c->Message(Chat::White, "Usage: #show inventory curlim - Shows items in Cursor and Limbo slots"); + c->Message(Chat::White, "Usage: #show inventory trib - Shows items in Tribute slots"); + c->Message(Chat::White, "Usage: #show inventory bank - Shows items in Bank slots"); + c->Message(Chat::White, "Usage: #show inventory shbank - Shows items in Shared Bank slots"); + c->Message(Chat::White, "Usage: #show inventory allbank - Shows items in Bank and Shared Bank slots"); + c->Message(Chat::White, "Usage: #show inventory trade - Shows items in Trade slots"); + c->Message(Chat::White, "Usage: #show inventory world - Shows items in World slots"); + c->Message(Chat::White, "Usage: #show inventory all - Shows items in all slots"); } diff --git a/zone/gm_commands/show/ip_lookup.cpp b/zone/gm_commands/show/ip_lookup.cpp new file mode 100644 index 000000000..b020541b4 --- /dev/null +++ b/zone/gm_commands/show/ip_lookup.cpp @@ -0,0 +1,25 @@ +#include "../../client.h" +#include "../../worldserver.h" + +extern WorldServer worldserver; + +void ShowIPLookup(Client *c, const Seperator *sep) +{ + const uint32 ip_length = strlen(sep->argplus[2]); + + auto pack = new ServerPacket( + ServerOP_IPLookup, + sizeof(ServerGenericWorldQuery_Struct) + ip_length + 1 + ); + + auto s = (ServerGenericWorldQuery_Struct *) pack->pBuffer; + strn0cpy(s->from, c->GetName(), sizeof(s->from)); + s->admin = c->Admin(); + + if (ip_length) { + strcpy(s->query, sep->argplus[2]); + } + + worldserver.SendPacket(pack); + safe_delete(pack); +} diff --git a/zone/gm_commands/show/line_of_sight.cpp b/zone/gm_commands/show/line_of_sight.cpp new file mode 100644 index 000000000..bf56c8866 --- /dev/null +++ b/zone/gm_commands/show/line_of_sight.cpp @@ -0,0 +1,22 @@ +#include "../../client.h" + +void ShowLineOfSight(Client *c, const Seperator *sep) +{ + if (!c->GetTarget() || c->GetTarget() == c) { + c->Message(Chat::White, "You must have a target to use this command."); + return; + } + + const auto t = c->GetTarget(); + + const bool has_los = c->CheckLosFN(t); + + c->Message( + Chat::White, + fmt::format( + "You {}have line of sight to {}.", + has_los ? "" : "do not ", + c->GetTargetDescription(t) + ).c_str() + ); +} diff --git a/zone/gm_commands/show/network.cpp b/zone/gm_commands/show/network.cpp new file mode 100644 index 000000000..d9eff2c16 --- /dev/null +++ b/zone/gm_commands/show/network.cpp @@ -0,0 +1,138 @@ +#include "../../client.h" +#include "../../dialogue_window.h" + +void ShowNetwork(Client *c, const Seperator *sep) +{ + auto eqsi = c->Connection(); + auto manager = eqsi->GetManager(); + auto opts = manager->GetOptions(); + + std::string popup_table; + + popup_table += DialogueWindow::TableRow( + DialogueWindow::TableCell("Option") + + DialogueWindow::TableCell("Value") + ); + + popup_table += DialogueWindow::TableRow( + DialogueWindow::TableCell("Max Packet Size") + + DialogueWindow::TableCell(Strings::Commify(opts.daybreak_options.max_packet_size)) + ); + + popup_table += DialogueWindow::TableRow( + DialogueWindow::TableCell("Max Connection Count") + + DialogueWindow::TableCell(Strings::Commify(opts.daybreak_options.max_connection_count)) + ); + + popup_table += DialogueWindow::TableRow( + DialogueWindow::TableCell("Keep Alive Delay") + + DialogueWindow::TableCell(Strings::MillisecondsToTime(opts.daybreak_options.keepalive_delay_ms)) + ); + + popup_table += DialogueWindow::TableRow( + DialogueWindow::TableCell("Resend Delay Factor") + + DialogueWindow::TableCell( + fmt::format( + "{:.2f}", + opts.daybreak_options.resend_delay_factor + ) + ) + ); + + popup_table += DialogueWindow::TableRow( + DialogueWindow::TableCell("Resend Delay") + + DialogueWindow::TableCell(Strings::MillisecondsToTime(opts.daybreak_options.resend_delay_ms)) + ); + + popup_table += DialogueWindow::TableRow( + DialogueWindow::TableCell("Resend Delay Minimum") + + DialogueWindow::TableCell(Strings::MillisecondsToTime(opts.daybreak_options.resend_delay_min)) + ); + + popup_table += DialogueWindow::TableRow( + DialogueWindow::TableCell("Resend Delay Maximum") + + DialogueWindow::TableCell(Strings::MillisecondsToTime(opts.daybreak_options.resend_delay_max)) + ); + + popup_table += DialogueWindow::TableRow( + DialogueWindow::TableCell("Connect Delay") + + DialogueWindow::TableCell(Strings::MillisecondsToTime(opts.daybreak_options.connect_delay_ms)) + ); + + popup_table += DialogueWindow::TableRow( + DialogueWindow::TableCell("Connect Stale") + + DialogueWindow::TableCell(Strings::MillisecondsToTime(opts.daybreak_options.connect_stale_ms)) + ); + + popup_table += DialogueWindow::TableRow( + DialogueWindow::TableCell("Stale Connection") + + DialogueWindow::TableCell(Strings::MillisecondsToTime(opts.daybreak_options.stale_connection_ms)) + ); + + popup_table += DialogueWindow::TableRow( + DialogueWindow::TableCell("CRC Length") + + DialogueWindow::TableCell(Strings::Commify(opts.daybreak_options.crc_length)) + ); + + popup_table += DialogueWindow::TableRow( + DialogueWindow::TableCell("Hold Size") + + DialogueWindow::TableCell(Strings::Commify(opts.daybreak_options.hold_size)) + ); + + popup_table += DialogueWindow::TableRow( + DialogueWindow::TableCell("Hold Length") + + DialogueWindow::TableCell(Strings::MillisecondsToTime(opts.daybreak_options.hold_length_ms)) + ); + + popup_table += DialogueWindow::TableRow( + DialogueWindow::TableCell("Simulated In Packet Loss") + + DialogueWindow::TableCell(std::to_string(opts.daybreak_options.simulated_in_packet_loss)) + ); + + popup_table += DialogueWindow::TableRow( + DialogueWindow::TableCell("Simulated Out Packet Loss") + + DialogueWindow::TableCell(std::to_string(opts.daybreak_options.simulated_out_packet_loss)) + ); + + popup_table += DialogueWindow::TableRow( + DialogueWindow::TableCell("Tic Rate (Hz)") + + DialogueWindow::TableCell( + fmt::format( + "{:.2f}", + opts.daybreak_options.tic_rate_hertz + ) + ) + ); + + popup_table += DialogueWindow::TableRow( + DialogueWindow::TableCell("Resend Timeout") + + DialogueWindow::TableCell(Strings::MillisecondsToTime(opts.daybreak_options.resend_timeout)) + ); + + popup_table += DialogueWindow::TableRow( + DialogueWindow::TableCell("Connection Close Time") + + DialogueWindow::TableCell(Strings::MillisecondsToTime(opts.daybreak_options.connection_close_time)) + ); + + popup_table += DialogueWindow::TableRow( + DialogueWindow::TableCell("Encode Passes (1)") + + DialogueWindow::TableCell(Strings::Commify(opts.daybreak_options.encode_passes[0])) + ); + + popup_table += DialogueWindow::TableRow( + DialogueWindow::TableCell("Encode Passes (2)") + + DialogueWindow::TableCell(Strings::Commify(opts.daybreak_options.encode_passes[1])) + ); + + popup_table += DialogueWindow::TableRow( + DialogueWindow::TableCell("Port") + + DialogueWindow::TableCell(Strings::Commify(opts.daybreak_options.port)) + ); + + popup_table = DialogueWindow::Table(popup_table); + + c->SendPopupToClient( + "Network Information", + popup_table.c_str() + ); +} diff --git a/zone/gm_commands/show/network_stats.cpp b/zone/gm_commands/show/network_stats.cpp new file mode 100644 index 000000000..8d51e8f69 --- /dev/null +++ b/zone/gm_commands/show/network_stats.cpp @@ -0,0 +1,297 @@ +#include "../../client.h" +#include "../../dialogue_window.h" + +void ShowNetworkStats(Client *c, const Seperator *sep) +{ + const auto connection = c->Connection(); + const auto opts = connection->GetManager()->GetOptions(); + const auto eqs_stats = connection->GetStats(); + + const auto& stats = eqs_stats.DaybreakStats; + + const auto sec_since_stats_reset = std::chrono::duration_cast>( + EQ::Net::Clock::now() - stats.created + ).count(); + + std::string popup_table; + + popup_table += DialogueWindow::TableRow( + DialogueWindow::TableCell("Sent Bytes") + + DialogueWindow::TableCell( + fmt::format( + "{} ({:.2f} Per Second)", + Strings::Commify(stats.sent_bytes), + stats.sent_bytes / sec_since_stats_reset + ) + ) + ); + + popup_table += DialogueWindow::TableRow( + DialogueWindow::TableCell("Received Bytes") + + DialogueWindow::TableCell( + fmt::format( + "{} ({:.2f} Per Second)", + Strings::Commify(stats.recv_bytes), + stats.recv_bytes / sec_since_stats_reset + ) + ) + ); + + popup_table += DialogueWindow::Break(2); + + popup_table += DialogueWindow::TableRow( + DialogueWindow::TableCell("Sent Bytes Before Encode") + + DialogueWindow::TableCell(Strings::Commify(stats.bytes_before_encode)) + + DialogueWindow::TableCell("Compression Rate") + + DialogueWindow::TableCell( + fmt::format( + "{:.2f}%%", + static_cast(stats.bytes_before_encode - stats.sent_bytes) / + static_cast(stats.bytes_before_encode) * 100.0 + ) + ) + ); + + popup_table += DialogueWindow::TableRow( + DialogueWindow::TableCell("Sent Bytes After Encode") + + DialogueWindow::TableCell(Strings::Commify(stats.bytes_after_decode)) + + DialogueWindow::TableCell("Compression Rate") + + DialogueWindow::TableCell( + fmt::format( + "{:.2f}%%", + static_cast(stats.bytes_after_decode - stats.recv_bytes) / + static_cast(stats.bytes_after_decode) * 100.0 + ) + ) + ); + + popup_table += DialogueWindow::Break(2); + + popup_table += DialogueWindow::TableRow( + DialogueWindow::TableCell("Minimum Ping") + + DialogueWindow::TableCell(Strings::Commify(stats.min_ping)) + ); + + popup_table += DialogueWindow::TableRow( + DialogueWindow::TableCell("Maximum Ping") + + DialogueWindow::TableCell(Strings::Commify(stats.max_ping)) + ); + + popup_table += DialogueWindow::TableRow( + DialogueWindow::TableCell("Last Ping") + + DialogueWindow::TableCell(Strings::Commify(stats.last_ping)) + ); + + popup_table += DialogueWindow::TableRow( + DialogueWindow::TableCell("Average Ping") + + DialogueWindow::TableCell(Strings::Commify(stats.avg_ping)) + ); + + popup_table += DialogueWindow::Break(2); + + popup_table += DialogueWindow::TableRow( + DialogueWindow::TableCell("Real Time Received Packets") + + DialogueWindow::TableCell( + fmt::format( + "{} ({:.2f} Per Second)", + Strings::Commify(stats.recv_packets), + stats.recv_packets / sec_since_stats_reset + ) + ) + ); + + popup_table += DialogueWindow::TableRow( + DialogueWindow::TableCell("Real Time Sent Packets") + + DialogueWindow::TableCell( + fmt::format( + "{} ({:.2f} Per Second)", + Strings::Commify(stats.sent_packets), + stats.sent_packets / sec_since_stats_reset + ) + ) + ); + + popup_table += DialogueWindow::Break(2); + + popup_table += DialogueWindow::TableRow( + DialogueWindow::TableCell("Sync Received Packets") + + DialogueWindow::TableCell(Strings::Commify(stats.sync_recv_packets)) + ); + + popup_table += DialogueWindow::TableRow( + DialogueWindow::TableCell("Sync Sent Packets") + + DialogueWindow::TableCell(Strings::Commify(stats.sync_sent_packets)) + ); + + popup_table += DialogueWindow::TableRow( + DialogueWindow::TableCell("Sync Remote Received Packets") + + DialogueWindow::TableCell(Strings::Commify(stats.sync_remote_recv_packets)) + ); + + popup_table += DialogueWindow::TableRow( + DialogueWindow::TableCell("Sync Remote Sent Packets") + + DialogueWindow::TableCell(Strings::Commify(stats.sync_remote_sent_packets)) + ); + + popup_table += DialogueWindow::Break(2); + + popup_table += DialogueWindow::TableRow( + DialogueWindow::TableCell("Packet Loss In") + + DialogueWindow::TableCell( + fmt::format( + "{:.2f}%%", + ( + 100.0 * + ( + 1.0 - + static_cast(stats.sync_recv_packets) / + static_cast(stats.sync_remote_sent_packets) + ) + ) + ) + ) + ); + + popup_table += DialogueWindow::TableRow( + DialogueWindow::TableCell("Packet Loss Out") + + DialogueWindow::TableCell( + fmt::format( + "{:.2f}%%", + ( + 100.0 * + ( + 1.0 - + static_cast(stats.sync_remote_recv_packets) / + static_cast(stats.sync_sent_packets) + ) + ) + ) + ) + ); + + popup_table += DialogueWindow::Break(2); + + popup_table += DialogueWindow::TableRow( + DialogueWindow::TableCell("Resent Packets") + + DialogueWindow::TableCell( + fmt::format( + "{} ({:.2f} Per Second)", + Strings::Commify(stats.resent_packets), + stats.resent_packets / sec_since_stats_reset + ) + ) + ); + + popup_table += DialogueWindow::TableRow( + DialogueWindow::TableCell("Resent Fragments") + + DialogueWindow::TableCell( + fmt::format( + "{} ({:.2f} Per Second)", + Strings::Commify(stats.resent_fragments), + stats.resent_fragments / sec_since_stats_reset + ) + ) + ); + + popup_table += DialogueWindow::TableRow( + DialogueWindow::TableCell("Resent Non-Fragments") + + DialogueWindow::TableCell( + fmt::format( + "{} ({:.2f} Per Second)", + Strings::Commify(stats.resent_full), + stats.resent_full / sec_since_stats_reset + ) + ) + ); + + popup_table += DialogueWindow::Break(2); + + popup_table += DialogueWindow::TableRow( + DialogueWindow::TableCell("Dropped Datarate Packets") + + DialogueWindow::TableCell( + fmt::format( + "{} ({:.2f} Per Second)", + Strings::Commify(stats.dropped_datarate_packets), + stats.dropped_datarate_packets / sec_since_stats_reset + ) + ) + ); + + if (opts.daybreak_options.outgoing_data_rate > 0.0) { + popup_table += DialogueWindow::TableRow( + DialogueWindow::TableCell("Outgoing Link Saturation") + + DialogueWindow::TableCell( + fmt::format( + "{:.2f}%% ({:.2f}kb Per Second)", + ( + 100.0 * + ( + 1.0 - + ( + ( + opts.daybreak_options.outgoing_data_rate - + stats.datarate_remaining + ) / + opts.daybreak_options.outgoing_data_rate + ) + ) + ), + opts.daybreak_options.outgoing_data_rate + ) + ) + ); + } + + popup_table += DialogueWindow::Break(2); + + std::string sent_rows; + + for (int i = 0; i < _maxEmuOpcode; ++i) { + const int count = eqs_stats.SentCount[i]; + if (count) { + sent_rows += DialogueWindow::TableRow( + DialogueWindow::TableCell(OpcodeNames[i]) + + DialogueWindow::TableCell( + fmt::format( + "{} ({:.2f} Per Second)", + Strings::Commify(count), + count / sec_since_stats_reset + ) + ) + ); + } + } + + std::string recv_rows; + + for (int i = 0; i < _maxEmuOpcode; ++i) { + const int count = eqs_stats.RecvCount[i]; + if (count) { + recv_rows += DialogueWindow::TableRow( + DialogueWindow::TableCell(OpcodeNames[i]) + + DialogueWindow::TableCell( + fmt::format( + "{} ({:.2f} Per Second)", + Strings::Commify(count), + count / sec_since_stats_reset + ) + ) + ); + } + } + + popup_table += DialogueWindow::TableRow(DialogueWindow::TableCell("Sent Packet Types")); + + popup_table += sent_rows; + + popup_table += DialogueWindow::TableRow(DialogueWindow::TableCell("Received Packet Types")); + + popup_table += recv_rows; + + popup_table = DialogueWindow::Table(popup_table); + + c->SendPopupToClient( + "Network Statistics", + popup_table.c_str() + ); +} diff --git a/zone/gm_commands/shownpcgloballoot.cpp b/zone/gm_commands/show/npc_global_loot.cpp old mode 100755 new mode 100644 similarity index 71% rename from zone/gm_commands/shownpcgloballoot.cpp rename to zone/gm_commands/show/npc_global_loot.cpp index e8c1026cd..6167550c2 --- a/zone/gm_commands/shownpcgloballoot.cpp +++ b/zone/gm_commands/show/npc_global_loot.cpp @@ -1,6 +1,6 @@ -#include "../client.h" +#include "../../client.h" -void command_shownpcgloballoot(Client *c, const Seperator *sep) +void ShowNPCGlobalLoot(Client *c, const Seperator *sep) { if (!c->GetTarget() || !c->GetTarget()->IsNPC()) { c->Message(Chat::White, "You must target an NPC to use this command."); @@ -11,4 +11,3 @@ void command_shownpcgloballoot(Client *c, const Seperator *sep) zone->ShowNPCGlobalLoot(c, t); } - diff --git a/zone/gm_commands/show/npc_stats.cpp b/zone/gm_commands/show/npc_stats.cpp new file mode 100644 index 000000000..65254e3bb --- /dev/null +++ b/zone/gm_commands/show/npc_stats.cpp @@ -0,0 +1,17 @@ +#include "../../client.h" + +void ShowNPCStats(Client *c, const Seperator *sep) +{ + if (!c->GetTarget() || !c->GetTarget()->IsNPC()) { + c->Message(Chat::White, "You must target an NPC to use this command."); + return; + } + + const auto t = c->GetTarget()->CastToNPC(); + + // Stats + t->ShowStats(c); + + // Loot Data + t->QueryLoot(c); +} diff --git a/zone/gm_commands/show/npc_type.cpp b/zone/gm_commands/show/npc_type.cpp new file mode 100644 index 000000000..f70b19e88 --- /dev/null +++ b/zone/gm_commands/show/npc_type.cpp @@ -0,0 +1,35 @@ +#include "../../client.h" + +void ShowNPCType(Client *c, const Seperator *sep) +{ + if (!sep->IsNumber(2)) { + c->Message(Chat::White, "Usage: #show npc_type [NPC ID]"); + return; + } + + const uint32 npc_id = Strings::ToUnsignedInt(sep->arg[2]); + const auto d = content_db.LoadNPCTypesData(npc_id); + + if (!d) { + c->Message( + Chat::White, + fmt::format( + "NPC ID {} was not found.", + npc_id + ).c_str() + ); + + return; + } + + auto npc = new NPC( + d, + nullptr, + c->GetPosition(), + GravityBehavior::Water + ); + + npc->ShowStats(c); + + safe_delete(npc); +} diff --git a/zone/gm_commands/show/peqzone_flags.cpp b/zone/gm_commands/show/peqzone_flags.cpp new file mode 100644 index 000000000..9efa6e09f --- /dev/null +++ b/zone/gm_commands/show/peqzone_flags.cpp @@ -0,0 +1,15 @@ +#include "../../client.h" + +void ShowPEQZoneFlags(Client *c, const Seperator *sep) +{ + auto t = c; + if ( + c->GetTarget() && + c->GetTarget()->IsClient() && + c->Admin() >= minStatusToSeeOthersZoneFlags + ) { + t = c->GetTarget()->CastToClient(); + } + + t->SendPEQZoneFlagInfo(c); +} diff --git a/zone/gm_commands/show/petition.cpp b/zone/gm_commands/show/petition.cpp new file mode 100644 index 000000000..501000520 --- /dev/null +++ b/zone/gm_commands/show/petition.cpp @@ -0,0 +1,69 @@ +#include "../../client.h" +#include "../../common/repositories/petitions_repository.h" + +void ShowPetition(Client *c, const Seperator *sep) +{ + if (!sep->IsNumber(2)) { + const auto& l = PetitionsRepository::All(database); + + uint32 found_count = 0; + + for (const auto& e : l) { + c->Message( + Chat::White, + fmt::format( + "Petition {} | Name: {} Text: {}", + e.petid, + e.charname, + e.petitiontext + ).c_str() + ); + + found_count++; + + if (found_count == 50) { + break; + } + } + + if (found_count == 50) { + c->Message(Chat::White, "50 Petitions found, max reached."); + } + + c->Message( + Chat::White, + fmt::format( + "{} Petition{} found.", + found_count, + found_count != 1 ? "s" : "" + ).c_str() + ); + + return; + } + + const uint32 petition_id = Strings::ToUnsignedInt(sep->arg[2]); + + const auto& l = PetitionsRepository::GetWhere(database, fmt::format("petition_id = {}", petition_id)); + if (l.empty()) { + c->Message( + Chat::White, + fmt::format( + "Petition ID {} was not found.", + petition_id + ).c_str() + ); + + return; + } + + c->Message( + Chat::White, + fmt::format( + "Petition {} | Name: {} Text: {}", + l[0].petid, + l[0].charname, + l[0].petitiontext + ).c_str() + ); +} diff --git a/zone/gm_commands/show/petition_info.cpp b/zone/gm_commands/show/petition_info.cpp new file mode 100644 index 000000000..68cd11cf2 --- /dev/null +++ b/zone/gm_commands/show/petition_info.cpp @@ -0,0 +1,79 @@ +#include "../../client.h" +#include "../../common/repositories/petitions_repository.h" + +void ShowPetitionInfo(Client *c, const Seperator *sep) +{ + if (!sep->IsNumber(2)) { + const auto& l = PetitionsRepository::All(database); + + uint32 found_count = 0; + + for (const auto& e : l) { + c->Message( + Chat::White, + fmt::format( + "Petition {} | Name: {} Text: {} Account: {} Zone: {} Class: {} Race: {} Level: {}", + e.petid, + e.charname, + e.petitiontext, + e.accountname, + e.zone, + GetClassIDName(static_cast(e.charclass)), + GetRaceIDName(static_cast(e.charrace)), + e.charlevel + ).c_str() + ); + + found_count++; + + if (found_count == 50) { + break; + } + } + + if (found_count == 50) { + c->Message(Chat::White, "50 Petitions found, max reached."); + } + + c->Message( + Chat::White, + fmt::format( + "{} Petition{} found.", + found_count, + found_count != 1 ? "s" : "" + ).c_str() + ); + + return; + } + + const uint32 petition_id = Strings::ToUnsignedInt(sep->arg[2]); + + const auto& l = PetitionsRepository::GetWhere(database, fmt::format("petition_id = {}", petition_id)); + if (l.empty()) { + c->Message( + Chat::White, + fmt::format( + "Petition ID {} was not found.", + petition_id + ).c_str() + ); + + return; + } + + c->Message( + Chat::White, + fmt::format( + "Petition {} | Name: {} Text: {} Account: {} Zone: {} Class: {} Race: {} Level: {}", + l[0].petid, + l[0].charname, + l[0].petitiontext, + l[0].accountname, + l[0].zone, + GetClassIDName(static_cast(l[0].charclass)), + GetRaceIDName(static_cast(l[0].charrace)), + l[0].charlevel + ).c_str() + ); +} diff --git a/zone/gm_commands/show/proximity.cpp b/zone/gm_commands/show/proximity.cpp new file mode 100644 index 000000000..3b8076d29 --- /dev/null +++ b/zone/gm_commands/show/proximity.cpp @@ -0,0 +1,73 @@ +#include "../../client.h" + +void ShowProximity(Client *c, const Seperator *sep) +{ + if (!c->GetTarget() || !c->GetTarget()->IsNPC()) { + c->Message(Chat::White, "You must target an NPC to use this command."); + return; + } + + for (const auto& n : entity_list.GetNPCList()) { + if ( + n.second && + Strings::Contains(n.second->GetName(), "Proximity") + ) { + n.second->Depop(); + } + } + + const auto t = c->GetTarget()->CastToNPC(); + + std::vector v; + + FindPerson_Point p {}; + + if (t->IsProximitySet()) { + glm::vec4 position; + position.w = t->GetHeading(); + position.x = t->GetProximityMinX(); + position.y = t->GetProximityMinY(); + position.z = t->GetZ(); + + position.x = t->GetProximityMinX(); + position.y = t->GetProximityMinY(); + NPC::SpawnNodeNPC("Proximity", "", position); + + position.x = t->GetProximityMinX(); + position.y = t->GetProximityMaxY(); + NPC::SpawnNodeNPC("Proximity", "", position); + + position.x = t->GetProximityMaxX(); + position.y = t->GetProximityMinY(); + NPC::SpawnNodeNPC("Proximity", "", position); + + position.x = t->GetProximityMaxX(); + position.y = t->GetProximityMaxY(); + NPC::SpawnNodeNPC("Proximity", "", position); + + p.x = t->GetProximityMinX(); + p.y = t->GetProximityMinY(); + p.z = t->GetZ(); + v.push_back(p); + + p.x = t->GetProximityMinX(); + p.y = t->GetProximityMaxY(); + v.push_back(p); + + p.x = t->GetProximityMaxX(); + p.y = t->GetProximityMaxY(); + v.push_back(p); + + p.x = t->GetProximityMaxX(); + p.y = t->GetProximityMinY(); + v.push_back(p); + + p.x = t->GetProximityMinX(); + p.y = t->GetProximityMinY(); + v.push_back(p); + } + + if (c->ClientVersion() >= EQ::versions::ClientVersion::RoF) { + c->SendPathPacket(v); + } +} diff --git a/zone/gm_commands/show/quest_errors.cpp b/zone/gm_commands/show/quest_errors.cpp new file mode 100644 index 000000000..7a1bf4d9b --- /dev/null +++ b/zone/gm_commands/show/quest_errors.cpp @@ -0,0 +1,35 @@ +#include "../../client.h" +#include "../../quest_parser_collection.h" + +void ShowQuestErrors(Client *c, const Seperator *sep) +{ + std::list l; + parse->GetErrors(l); + + if (!l.size()) { + c->Message(Chat::White, "There are no Quest errors currently."); + return; + } + + c->Message(Chat::White, "Quest errors currently are as follows:"); + + uint32 error_count = 0; + + for (const auto& e : l) { + if (error_count >= RuleI(World, MaximumQuestErrors)) { + c->Message( + Chat::White, + fmt::format( + "Maximum of {} error{} shown.", + RuleI(World, MaximumQuestErrors), + RuleI(World, MaximumQuestErrors) != 1 ? "s" : "" + ).c_str() + ); + break; + } + + c->Message(Chat::White, e.c_str()); + + error_count++; + } +} diff --git a/zone/gm_commands/show/quest_globals.cpp b/zone/gm_commands/show/quest_globals.cpp new file mode 100644 index 000000000..63396352b --- /dev/null +++ b/zone/gm_commands/show/quest_globals.cpp @@ -0,0 +1,76 @@ +#include "../../client.h" + +void ShowQuestGlobals(Client *c, const Seperator *sep) +{ + Mob* t = c; + if (c->GetTarget()) { + t = c->GetTarget(); + } + + QGlobalCache* char_cache = c->GetQGlobals(); + QGlobalCache* npc_cache = t->IsNPC() ? t->CastToNPC()->GetQGlobals() : nullptr; + QGlobalCache* zone_cache = zone->GetQGlobals(); + + std::list global_map; + + uint32 character_id = c->CharacterID(); + uint32 npc_id = t->IsNPC() ? t->CastToNPC()->GetNPCTypeID() : 0; + uint32 zone_id = zone->GetZoneID(); + + if (npc_cache) { + QGlobalCache::Combine( + global_map, + npc_cache->GetBucket(), + npc_id, + character_id, + zone_id + ); + } + + if (char_cache) { + QGlobalCache::Combine( + global_map, + char_cache->GetBucket(), + npc_id, + character_id, + zone_id + ); + } + + if (zone_cache) { + QGlobalCache::Combine( + global_map, + zone_cache->GetBucket(), + npc_id, + character_id, + zone_id + ); + } + + uint32 global_count = 0; + uint32 global_number = 1; + + for (const auto& g : global_map) { + c->Message( + Chat::White, + fmt::format( + "Quest Global {} | Name: {} Value: {}", + global_number, + g.name, + g.value + ).c_str() + ); + + global_count++; + global_number++; + } + + c->Message( + Chat::White, + fmt::format( + "{} Quest Global{} found.", + global_count, + global_count != 1 ? "s" : "" + ).c_str() + ); +} diff --git a/zone/gm_commands/viewrecipe.cpp b/zone/gm_commands/show/recipe.cpp old mode 100755 new mode 100644 similarity index 62% rename from zone/gm_commands/viewrecipe.cpp rename to zone/gm_commands/show/recipe.cpp index 74035de2a..0bc980316 --- a/zone/gm_commands/viewrecipe.cpp +++ b/zone/gm_commands/show/recipe.cpp @@ -1,32 +1,33 @@ -#include "../client.h" -#include "../command.h" +#include "../../client.h" +#include "../../command.h" #include "../../common/repositories/tradeskill_recipe_repository.h" #include "../../common/repositories/tradeskill_recipe_entries_repository.h" -void command_viewrecipe(Client *c, const Seperator *sep) +void ShowRecipe(Client *c, const Seperator *sep) { - int arguments = sep->argnum; - if (!arguments || !sep->IsNumber(1)) { - c->Message(Chat::White, "Command Syntax: #viewrecipe [Recipe ID]"); + if (!sep->IsNumber(2)) { + c->Message(Chat::White, "Command Syntax: #show recipe [Recipe ID]"); return; } - auto recipe_id = static_cast(Strings::ToUnsignedInt(sep->arg[1])); - auto re = TradeskillRecipeEntriesRepository::GetWhere( + const uint16 recipe_id = static_cast(Strings::ToUnsignedInt(sep->arg[2])); + + const auto& re = TradeskillRecipeEntriesRepository::GetWhere( database, fmt::format("recipe_id = {} ORDER BY id ASC", recipe_id) ); - auto r = TradeskillRecipeRepository::GetWhere( + + const auto& r = TradeskillRecipeRepository::GetWhere( database, fmt::format("id = {}", recipe_id) ); - if (re.empty() || r.empty() || !re[0].id || !r[0].id) { + if (re.empty() || r.empty()) { c->Message( Chat::White, fmt::format( "Recipe ID {} has no entries or could not be found.", - Strings::Commify(std::to_string(recipe_id)) + Strings::Commify(recipe_id) ).c_str() ); return; @@ -36,13 +37,13 @@ void command_viewrecipe(Client *c, const Seperator *sep) Chat::White, fmt::format( "Recipe {} | {}", - Strings::Commify(std::to_string(recipe_id)), + Strings::Commify(recipe_id), r[0].name ).c_str() ); - auto entry_number = 1; - bool can_summon_items = c->Admin() >= GetCommandStatus(c, "summonitem"); + uint32 entry_number = 1; + const bool can_summon_items = c->Admin() >= GetCommandStatus(c, "summonitem"); for (const auto& e : re) { c->Message( @@ -51,8 +52,22 @@ void command_viewrecipe(Client *c, const Seperator *sep) "Entry {}{} | {}{}", entry_number, e.iscontainer > 0 ? " (Container)" : "", - e.item_id > 1000 ? database.CreateItemLink(e.item_id) : EQ::constants::GetObjectTypeName(e.item_id), - can_summon_items && e.item_id > 1000 ? fmt::format(" | {}", Saylink::Silent(fmt::format("#si {}", e.item_id), "Summon")) : "" + ( + e.item_id > 1000 ? + database.CreateItemLink(e.item_id) : + EQ::constants::GetObjectTypeName(e.item_id) + ), + ( + can_summon_items && e.item_id > 1000 ? + fmt::format( + " | {}", + Saylink::Silent( + fmt::format("#si {}", e.item_id), + "Summon" + ) + ) : + "" + ) ).c_str() ); @@ -117,4 +132,3 @@ void command_viewrecipe(Client *c, const Seperator *sep) entry_number++; } } - diff --git a/zone/gm_commands/show/server_info.cpp b/zone/gm_commands/show/server_info.cpp new file mode 100644 index 000000000..ff3070aa7 --- /dev/null +++ b/zone/gm_commands/show/server_info.cpp @@ -0,0 +1,106 @@ +#include "../../client.h" +#include "../../dialogue_window.h" +#include "../../common/serverinfo.h" + +void ShowServerInfo(Client *c, const Seperator *sep) +{ + auto os = EQ::GetOS(); + auto cpus = EQ::GetCPUs(); + const uint32 process_id = EQ::GetPID(); + const double rss = EQ::GetRSS() / 1048576.0; + const uint32 uptime = static_cast(EQ::GetUptime()); + + std::string popup_table; + + std::string popup_text; + + popup_text += DialogueWindow::CenterMessage( + DialogueWindow::ColorMessage("green", "Operating System Information") + ); + + popup_table += DialogueWindow::TableRow( + DialogueWindow::TableCell("Machine") + + DialogueWindow::TableCell(os.machine) + ); + + popup_table += DialogueWindow::TableRow( + DialogueWindow::TableCell("System") + + DialogueWindow::TableCell(os.sysname) + ); + + popup_table += DialogueWindow::TableRow( + DialogueWindow::TableCell("Release") + + DialogueWindow::TableCell(os.release) + ); + + popup_table += DialogueWindow::TableRow( + DialogueWindow::TableCell("Uptime") + + DialogueWindow::TableCell(Strings::SecondsToTime(uptime)) + ); + + popup_table += DialogueWindow::TableRow( + DialogueWindow::TableCell("Version") + + DialogueWindow::TableCell(os.version) + ); + + popup_text += DialogueWindow::Table(popup_table); + + popup_table = std::string(); + + popup_text += DialogueWindow::Break(); + + popup_text += DialogueWindow::CenterMessage( + DialogueWindow::ColorMessage("green", "CPU Information") + ); + + for (size_t cpu = 0; cpu < cpus.size(); ++cpu) { + auto ¤t_cpu = cpus[cpu]; + popup_table += DialogueWindow::TableRow( + DialogueWindow::TableCell( + fmt::format( + "CPU {}", + cpu + ) + ) + + DialogueWindow::TableCell( + fmt::format( + "{} ({:.2f}GHz)", + current_cpu.model, + current_cpu.speed + ) + ) + ); + } + + popup_text += DialogueWindow::Table(popup_table); + + popup_table = std::string(); + + popup_text += DialogueWindow::Break(); + + popup_text += DialogueWindow::CenterMessage( + DialogueWindow::ColorMessage("green", "CPU Information") + ); + + popup_table += DialogueWindow::TableRow( + DialogueWindow::TableCell("Process ID") + + DialogueWindow::TableCell(Strings::Commify(process_id)) + ); + + popup_table += DialogueWindow::TableRow( + DialogueWindow::TableCell("RSS") + + DialogueWindow::TableCell( + fmt::format( + "{:.2f} MB", + rss + ) + ) + ); + + popup_text += DialogueWindow::Table(popup_table); + + c->SendPopupToClient( + "Server Information", + popup_text.c_str() + ); +} diff --git a/zone/gm_commands/show/skills.cpp b/zone/gm_commands/show/skills.cpp new file mode 100644 index 000000000..20705ac16 --- /dev/null +++ b/zone/gm_commands/show/skills.cpp @@ -0,0 +1,42 @@ +#include "../../client.h" +#include "../../dialogue_window.h" + +void ShowSkills(Client *c, const Seperator *sep) +{ + auto t = c; + if (c->GetTarget() && c->GetTarget()->IsClient()) { + t = c->GetTarget()->CastToClient(); + } + + std::string popup_table; + + popup_table += DialogueWindow::TableRow( + DialogueWindow::TableCell("ID") + + DialogueWindow::TableCell("Name") + + DialogueWindow::TableCell("Current") + + DialogueWindow::TableCell("Max") + + DialogueWindow::TableCell("Raw") + ); + + for (const auto& s : EQ::skills::GetSkillTypeMap()) { + if (t->CanHaveSkill(s.first) && t->MaxSkill(s.first)) { + popup_table += DialogueWindow::TableRow( + DialogueWindow::TableCell(std::to_string(s.first)) + + DialogueWindow::TableCell(s.second) + + DialogueWindow::TableCell(std::to_string(t->GetSkill(s.first))) + + DialogueWindow::TableCell(std::to_string(t->MaxSkill(s.first))) + + DialogueWindow::TableCell(std::to_string(t->GetRawSkill(s.first))) + ); + } + } + + popup_table = DialogueWindow::Table(popup_table); + + c->SendPopupToClient( + fmt::format( + "Skills for {}", + c->GetTargetDescription(t, TargetDescriptionType::UCSelf) + ).c_str(), + popup_table.c_str() + ); +} diff --git a/zone/gm_commands/show/spawn_status.cpp b/zone/gm_commands/show/spawn_status.cpp new file mode 100644 index 000000000..1fd59a20f --- /dev/null +++ b/zone/gm_commands/show/spawn_status.cpp @@ -0,0 +1,147 @@ +#include "../../client.h" + +void ShowSpawnStatus(Client *c, const Seperator *sep) +{ + const auto arguments = sep->argnum; + if (arguments < 2) { + c->Message(Chat::White, "Usage: #show spawn_status all - Show all spawn statuses for your current zone"); + c->Message(Chat::White, "Usage: #show spawn_status disabled - Show all disabled spawn statuses for your current zone"); + c->Message(Chat::White, "Usage: #show spawn_status enabled - Show all enabled spawn statuses for your current zone"); + c->Message(Chat::White, "Usage: #show spawn_status [Spawn ID] - Show spawn status by ID for your current zone"); + return; + } + + const bool is_all = !strcasecmp(sep->arg[2], "all"); + const bool is_disabled = !strcasecmp(sep->arg[2], "disabled"); + const bool is_enabled = !strcasecmp(sep->arg[2], "enabled"); + const bool is_search = sep->IsNumber(2); + + if ( + !is_all && + !is_disabled && + !is_enabled && + !is_search + ) { + c->Message(Chat::White, "Usage: #show spawn_status all - Show all spawn statuses for your current zone"); + c->Message(Chat::White, "Usage: #show spawn_status disabled - Show all disabled spawn statuses for your current zone"); + c->Message(Chat::White, "Usage: #show spawn_status enabled - Show all enabled spawn statuses for your current zone"); + c->Message(Chat::White, "Usage: #show spawn_status [Spawn ID] - Show spawn status by ID for your current zone"); + return; + } + + std::string filter_type; + if (is_disabled) { + filter_type = "Disabled"; + } else if (is_enabled) { + filter_type = "Enabled"; + } + + const uint32 spawn_id = ( + is_search ? + Strings::ToUnsignedInt(sep->arg[2]) : + 0 + ); + + LinkedListIterator iterator(zone->spawn2_list); + iterator.Reset(); + + uint32 filtered_count = 0; + uint32 spawn_count = 0; + uint32 spawn_number = 1; + + while (iterator.MoreElements()) { + const auto& e = iterator.GetData(); + + const uint32 time_remaining = e->GetTimer().GetRemainingTime(); + + if ( + is_all || + ( + is_disabled && + time_remaining == UINT32_MAX + ) || + ( + is_enabled && + time_remaining != UINT32_MAX + ) || + ( + is_search && + e->GetID() == spawn_id + ) + ) { + c->Message( + Chat::White, + fmt::format( + "Spawn {} | ID: {} Coordinates: {:.2f}, {:.2f}, {:.2f}, {:.2f}", + spawn_number, + e->GetID(), + e->GetX(), + e->GetY(), + e->GetZ(), + e->GetHeading() + ).c_str() + ); + + if (time_remaining != UINT32_MAX) { + const uint32 seconds_remaining = (time_remaining / 1000); + + c->Message( + Chat::White, + fmt::format( + "Spawn {} | Respawn: {}", + spawn_number, + Strings::SecondsToTime(seconds_remaining) + ).c_str() + ); + } + + filtered_count++; + spawn_number++; + } + + spawn_count++; + iterator.Advance(); + } + + if (!spawn_count) { + c->Message(Chat::White, "No spawns were found."); + return; + } + + if ( + (is_disabled || is_enabled) && + !filtered_count + ) { + c->Message( + Chat::White, + fmt::format( + "No {} spawns were found.", + filter_type + ).c_str() + ); + return; + } + + if (is_all) { + c->Message( + Chat::White, + fmt::format( + "{} Spawn{} found.", + spawn_count, + spawn_count != 1 ? "s" : "" + ).c_str() + ); + + return; + } + + c->Message( + Chat::White, + fmt::format( + "{} of {} spawn{} found.", + filtered_count, + spawn_count, + spawn_count != 1 ? "s" : "" + ).c_str() + ); +} diff --git a/zone/gm_commands/show/spells.cpp b/zone/gm_commands/show/spells.cpp new file mode 100644 index 000000000..7d522be95 --- /dev/null +++ b/zone/gm_commands/show/spells.cpp @@ -0,0 +1,30 @@ +#include "../../client.h" + +void ShowSpells(Client *c, const Seperator *sep) +{ + auto t = c; + if (c->GetTarget() && c->GetTarget()->IsClient()) { + t = c->GetTarget()->CastToClient(); + } + + const auto is_disciplines = !strcasecmp(sep->arg[2], "disciplines"); + const auto is_spells = !strcasecmp(sep->arg[2], "spells"); + if ( + !is_disciplines && + !is_spells + ) { + c->Message(Chat::White, "Usages: #show spells disciplines - Show your or your target's learned disciplines"); + c->Message(Chat::White, "Usages: #show spells spells - Show your or your target's memorized spells"); + return; + } + + ShowSpellType show_spell_type; + + if (is_disciplines) { + show_spell_type = ShowSpellType::Disciplines; + } else if (is_spells) { + show_spell_type = ShowSpellType::Spells; + } + + t->ShowSpells(c, show_spell_type); +} diff --git a/zone/gm_commands/show/spells_list.cpp b/zone/gm_commands/show/spells_list.cpp new file mode 100644 index 000000000..fb94306c1 --- /dev/null +++ b/zone/gm_commands/show/spells_list.cpp @@ -0,0 +1,13 @@ +#include "../../client.h" + +void ShowSpellsList(Client *c, const Seperator *sep) +{ + if (!c->GetTarget() || !c->GetTarget()->IsNPC()) { + c->Message(Chat::White, "You must target an NPC to use this command."); + return; + } + + const auto t = c->GetTarget()->CastToNPC(); + + t->AISpellsList(c); +} diff --git a/zone/gm_commands/show/stats.cpp b/zone/gm_commands/show/stats.cpp new file mode 100644 index 000000000..be1f4d40d --- /dev/null +++ b/zone/gm_commands/show/stats.cpp @@ -0,0 +1,11 @@ +#include "../../client.h" + +void ShowStats(Client *c, const Seperator *sep) +{ + Mob* t = c; + if (c->GetTarget()) { + t = c->GetTarget(); + } + + t->ShowStats(c); +} diff --git a/zone/gm_commands/timers.cpp b/zone/gm_commands/show/timers.cpp old mode 100755 new mode 100644 similarity index 57% rename from zone/gm_commands/timers.cpp rename to zone/gm_commands/show/timers.cpp index efee6da55..b31d8eac4 --- a/zone/gm_commands/timers.cpp +++ b/zone/gm_commands/show/timers.cpp @@ -1,7 +1,7 @@ -#include "../client.h" -#include "../dialogue_window.h" +#include "../../client.h" +#include "../../dialogue_window.h" -void command_timers(Client *c, const Seperator *sep) +void ShowTimers(Client *c, const Seperator *sep) { auto t = c; if (c->GetTarget() && c->GetTarget()->IsClient()) { @@ -23,26 +23,30 @@ void command_timers(Client *c, const Seperator *sep) return; } - auto m = DialogueWindow::TableRow( + std::string popup_table; + + popup_table += DialogueWindow::TableRow( DialogueWindow::TableCell("Timer ID") + DialogueWindow::TableCell("Remaining Time") ); for (const auto& e : l) { - auto r = e.second->GetRemainingTime(); - if (r) { - m += DialogueWindow::TableRow( - DialogueWindow::TableCell(std::to_string(e.first)) + - DialogueWindow::TableCell(Strings::SecondsToTime(r)) + const uint32 remaining_time = e.second->GetRemainingTime(); + if (remaining_time) { + popup_table += DialogueWindow::TableRow( + DialogueWindow::TableCell(Strings::Commify(e.first)) + + DialogueWindow::TableCell(Strings::SecondsToTime(remaining_time)) ); } } + popup_table = DialogueWindow::Table(popup_table); + c->SendPopupToClient( fmt::format( "Recast Timers for {}", c->GetTargetDescription(t, TargetDescriptionType::UCSelf) ).c_str(), - DialogueWindow::Table(m).c_str() + popup_table.c_str() ); } diff --git a/zone/gm_commands/show/traps.cpp b/zone/gm_commands/show/traps.cpp new file mode 100644 index 000000000..28a6215d7 --- /dev/null +++ b/zone/gm_commands/show/traps.cpp @@ -0,0 +1,6 @@ +#include "../../client.h" + +void ShowTraps(Client *c, const Seperator *sep) +{ + entity_list.GetTrapInfo(c); +} diff --git a/zone/gm_commands/show/uptime.cpp b/zone/gm_commands/show/uptime.cpp new file mode 100644 index 000000000..c95bcff2a --- /dev/null +++ b/zone/gm_commands/show/uptime.cpp @@ -0,0 +1,19 @@ +#include "../../client.h" +#include "../../worldserver.h" + +extern WorldServer worldserver; + +void ShowUptime(Client *c, const Seperator *sep) +{ + auto pack = new ServerPacket(ServerOP_Uptime, sizeof(ServerUptime_Struct)); + + auto s = (ServerUptime_Struct *) pack->pBuffer; + strn0cpy(s->adminname, c->GetName(), sizeof(s->adminname)); + + if (sep->IsNumber(2) && Strings::ToUnsignedInt(sep->arg[2]) > 0) { + s->zoneserverid = Strings::ToUnsignedInt(sep->arg[2]); + } + + worldserver.SendPacket(pack); + safe_delete(pack); +} diff --git a/zone/gm_commands/show/variable.cpp b/zone/gm_commands/show/variable.cpp new file mode 100644 index 000000000..98418c14b --- /dev/null +++ b/zone/gm_commands/show/variable.cpp @@ -0,0 +1,33 @@ +#include "../../client.h" + +void ShowVariable(Client *c, const Seperator *sep) +{ + const auto arguments = sep->argnum; + if (arguments < 2) { + c->Message(Chat::White, "Usage: #show variable [Variable Name]"); + return; + } + + const std::string& variable = sep->argplus[2]; + + std::string value; + if (!database.GetVariable(variable, value)) { + c->Message( + Chat::White, + fmt::format( + "Variable '{}' was not found.", + variable + ).c_str() + ); + return; + } + + c->Message( + Chat::White, + fmt::format( + "Variable {} | {}", + variable, + value + ).c_str() + ); +} diff --git a/zone/gm_commands/show/version.cpp b/zone/gm_commands/show/version.cpp new file mode 100644 index 000000000..e9b55d549 --- /dev/null +++ b/zone/gm_commands/show/version.cpp @@ -0,0 +1,35 @@ +#include "../../client.h" +#include "../../dialogue_window.h" + +void ShowVersion(Client *c, const Seperator *sep) +{ + std::string popup_table; + + popup_table += DialogueWindow::TableRow( + DialogueWindow::TableCell("Version") + + DialogueWindow::TableCell(CURRENT_VERSION) + ); + + popup_table += DialogueWindow::TableRow( + DialogueWindow::TableCell("Compiled") + + DialogueWindow::TableCell( + fmt::format( + "{} {}", + COMPILE_DATE, + COMPILE_TIME + ) + ) + ); + + popup_table += DialogueWindow::TableRow( + DialogueWindow::TableCell("Last Modified") + + DialogueWindow::TableCell(LAST_MODIFIED) + ); + + popup_table = DialogueWindow::Table(popup_table); + + c->SendPopupToClient( + "Server Version", + popup_table.c_str() + ); +} diff --git a/zone/gm_commands/wpinfo.cpp b/zone/gm_commands/show/waypoints.cpp old mode 100755 new mode 100644 similarity index 54% rename from zone/gm_commands/wpinfo.cpp rename to zone/gm_commands/show/waypoints.cpp index 4c1774c08..262489fca --- a/zone/gm_commands/wpinfo.cpp +++ b/zone/gm_commands/show/waypoints.cpp @@ -1,25 +1,25 @@ -#include "../client.h" +#include "../../client.h" -void command_wpinfo(Client *c, const Seperator *sep) +void ShowWaypoints(Client *c, const Seperator *sep) { if (!c->GetTarget() || !c->GetTarget()->IsNPC()) { c->Message(Chat::White, "You must target an NPC to use this command."); return; } - auto target = c->GetTarget()->CastToNPC(); + auto t = c->GetTarget()->CastToNPC(); - if (!target->GetGrid()) { + if (!t->GetGrid()) { c->Message( Chat::White, fmt::format( "{} is not a part of any grid.", - c->GetTargetDescription(target) + c->GetTargetDescription(t) ).c_str() ); + return; } - target->DisplayWaypointInfo(c); + t->DisplayWaypointInfo(c); } - diff --git a/zone/gm_commands/show/who.cpp b/zone/gm_commands/show/who.cpp new file mode 100755 index 000000000..003a2af70 --- /dev/null +++ b/zone/gm_commands/show/who.cpp @@ -0,0 +1,235 @@ +#include "../../client.h" + +void ShowWho(Client *c, const Seperator *sep) +{ + const std::string& query = SQL( + SELECT + character_data.name, + character_data.zone_id, + character_data.zone_instance, + COALESCE( + ( + SELECT guilds.name FROM guilds WHERE id = ( + ( + SELECT guild_id FROM guild_members WHERE char_id = character_data.id + ) + ) + ), + "" + ) AS guild_name, + character_data.level, + character_data.race, + character_data.class, + COALESCE( + ( + SELECT account.status FROM account WHERE account.id = character_data.account_id LIMIT 1 + ), + 0 + ) AS account_status, + COALESCE( + ( + SELECT account.name FROM account WHERE account.id = character_data.account_id LIMIT 1 + ), + 0 + ) AS account_name, + COALESCE( + ( + SELECT account_ip.ip FROM account_ip WHERE account_ip.accid = character_data.account_id ORDER BY account_ip.lastused DESC LIMIT 1 + ), + "" + ) AS account_ip + FROM + character_data + WHERE + last_login > (UNIX_TIMESTAMP() - 600) + ORDER BY + character_data.name; + ); + + auto results = database.QueryDatabase(query); + if (!results.Success() || !results.RowCount()) { + return; + } + + bool is_filtered = false; + + std::string search_criteria; + + if (sep->arg[2]) { + search_criteria = Strings::ToLower(sep->arg[2]); + } + + uint32 found_count = 0; + + c->Message(Chat::Who, "Players in EverQuest:"); + c->Message(Chat::Who, "------------------------------"); + + for (auto row : results) { + const std::string& player_name = row[0]; + const uint32 zone_id = Strings::ToUnsignedInt(row[1]); + const std::string& zone_short_name = ZoneName(zone_id); + const std::string& zone_long_name = ZoneLongName(zone_id); + const uint8 zone_instance = Strings::ToUnsignedInt(row[2]); + const std::string& guild_name = row[3]; + const uint8 player_level = Strings::ToUnsignedInt(row[4]); + const uint16 player_race = Strings::ToUnsignedInt(row[5]); + const uint8 player_class = Strings::ToUnsignedInt(row[6]); + const uint8 account_status = Strings::ToUnsignedInt(row[7]); + const std::string& account_name = row[8]; + const std::string& account_ip = row[9]; + const std::string& base_class_name = GetClassIDName(player_class); + const std::string& displayed_race_name = GetRaceIDName(player_race); + + if (!search_criteria.empty()) { + is_filtered = true; + + const bool found = ( + Strings::Contains(Strings::ToLower(player_name), search_criteria) || + Strings::Contains(Strings::ToLower(zone_short_name), search_criteria) || + Strings::Contains(Strings::ToLower(displayed_race_name), search_criteria) || + Strings::Contains(Strings::ToLower(base_class_name), search_criteria) || + Strings::Contains(Strings::ToLower(guild_name), search_criteria) || + Strings::Contains(Strings::ToLower(account_name), search_criteria) || + Strings::Contains(Strings::ToLower(account_ip), search_criteria) + ); + + if (!found) { + continue; + } + } + + std::string displayed_guild_name; + if (!guild_name.empty()) { + displayed_guild_name = Saylink::Silent( + fmt::format( + "#who \"{}\"", + guild_name + ), + fmt::format( + "<{}>", + guild_name + ) + ); + } + + const std::string& goto_saylink = Saylink::Silent( + fmt::format( + "#goto {}", + player_name + ), + "Goto" + ); + + const std::string& summon_saylink = Saylink::Silent( + fmt::format( + "#summon {}", + player_name + ), + "Summon" + ); + + const std::string& display_class_name = GetClassIDName(player_class, player_level); + + const std::string& class_saylink = Saylink::Silent( + fmt::format( + "#who {}", + base_class_name + ), + display_class_name + ); + + const std::string& race_saylink = Saylink::Silent( + fmt::format( + "#who {}", + displayed_race_name + ), + displayed_race_name + ); + + const std::string& zone_saylink = Saylink::Silent( + fmt::format( + "#who {}", + zone_short_name + ), + zone_long_name + ); + + const std::string& account_saylink = Saylink::Silent( + fmt::format( + "#who {}", + account_name + ), + account_name + ); + + const std::string& account_ip_saylink = Saylink::Silent( + fmt::format( + "#who {}", + account_ip + ), + account_ip + ); + + const std::string& status_level = ( + account_status ? + fmt::format( + "* {} * ", + EQ::constants::GetAccountStatusName(account_status) + ) : + "" + ); + + const std::string& version_string = ( + zone_instance ? + fmt::format( + " ({})", + zone_instance + ) : + "" + ); + + c->Message( + Chat::Who, + fmt::format( + "{}[{} {} ({})] {} ({}) ({}) ({}) {} ZONE: {}{} ({} | {})", + status_level, + player_level, + class_saylink, + base_class_name, + player_name, + race_saylink, + account_saylink, + account_ip_saylink, + displayed_guild_name, + zone_saylink, + version_string, + goto_saylink, + summon_saylink + ).c_str() + ); + + found_count++; + } + + const std::string& filter_string = is_filtered ? " that match those filters" : ""; + + const std::string& message = ( + found_count ? + fmt::format( + "There {} {} player{} in EverQuest{}.", + found_count != 1 ? "are" : "is", + found_count, + found_count != 1 ? "s" : "", + filter_string + ) : + fmt::format( + "There are no players in EverQuest{}.", + filter_string + ) + ); + + c->Message( + Chat::Who, + message.c_str() + ); +} diff --git a/zone/gm_commands/xtargets.cpp b/zone/gm_commands/show/xtargets.cpp old mode 100755 new mode 100644 similarity index 78% rename from zone/gm_commands/xtargets.cpp rename to zone/gm_commands/show/xtargets.cpp index 3ae8a6236..b3416b561 --- a/zone/gm_commands/xtargets.cpp +++ b/zone/gm_commands/show/xtargets.cpp @@ -1,20 +1,20 @@ -#include "../client.h" +#include "../../client.h" #include "../../common/data_verification.h" -void command_xtargets(Client *c, const Seperator *sep) +void ShowXTargets(Client *c, const Seperator *sep) { auto t = c; if (c->GetTarget() && c->GetTarget()->IsClient()) { t = c->GetTarget()->CastToClient(); } - auto arguments = sep->argnum; - if (!arguments || !sep->IsNumber(1)) { + const auto arguments = sep->argnum; + if (arguments < 2 || !sep->IsNumber(2)) { t->ShowXTargets(c); return; } - const auto new_max = static_cast(Strings::ToUnsignedInt(sep->arg[1])); + const auto new_max = static_cast(Strings::ToUnsignedInt(sep->arg[2])); if (!EQ::ValueWithin(new_max, 5, XTARGET_HARDCAP)) { c->Message( diff --git a/zone/gm_commands/show/zone_data.cpp b/zone/gm_commands/show/zone_data.cpp new file mode 100644 index 000000000..1e8e2c7ff --- /dev/null +++ b/zone/gm_commands/show/zone_data.cpp @@ -0,0 +1,276 @@ +#include "../../client.h" +#include "../../dialogue_window.h" + +void ShowZoneData(Client *c, const Seperator *sep) +{ + std::string popup_table; + + popup_table += DialogueWindow::TableRow( + DialogueWindow::TableCell("Type") + + DialogueWindow::TableCell(std::to_string(zone->newzone_data.ztype)) + ); + + for (uint8 fog_index = 0; fog_index < 4; fog_index++) { + const uint8 fog_number = (fog_index + 1); + + popup_table += DialogueWindow::TableRow( + DialogueWindow::TableCell( + fmt::format( + "Fog {} Colors", + fog_number + ) + ) + + DialogueWindow::TableCell( + fmt::format( + "{} {} {}", + DialogueWindow::ColorMessage( + "red1", + std::to_string(zone->newzone_data.fog_red[fog_index]) + ), + DialogueWindow::ColorMessage( + "forest_green", + std::to_string(zone->newzone_data.fog_green[fog_index]) + ), + DialogueWindow::ColorMessage( + "royal_blue", + std::to_string(zone->newzone_data.fog_blue[fog_index]) + ) + ) + ) + ); + + popup_table += DialogueWindow::TableRow( + DialogueWindow::TableCell( + fmt::format( + "Fog {} Clipping", + fog_number + ) + ) + + DialogueWindow::TableCell( + fmt::format( + "{} to {}", + zone->newzone_data.fog_minclip[fog_index], + zone->newzone_data.fog_maxclip[fog_index] + ) + ) + ); + } + + popup_table += DialogueWindow::TableRow( + DialogueWindow::TableCell("Fog Density") + + DialogueWindow::TableCell( + fmt::format( + "{:.2f}", + zone->newzone_data.fog_density + ) + ) + ); + + popup_table += DialogueWindow::TableRow( + DialogueWindow::TableCell("Gravity") + + DialogueWindow::TableCell( + fmt::format( + "{:.2f}", + zone->newzone_data.gravity + ) + ) + ); + + popup_table += DialogueWindow::TableRow( + DialogueWindow::TableCell("Time Type") + + DialogueWindow::TableCell(std::to_string(zone->newzone_data.time_type)) + ); + + popup_table += DialogueWindow::TableRow( + DialogueWindow::TableCell("Time Type") + + DialogueWindow::TableCell(std::to_string(zone->newzone_data.time_type)) + ); + + popup_table += DialogueWindow::TableRow( + DialogueWindow::TableCell("Experience Multiplier") + + DialogueWindow::TableCell( + fmt::format( + "{:.2f}%%", + (zone->newzone_data.zone_exp_multiplier * 100) + ) + ) + ); + + popup_table += DialogueWindow::TableRow( + DialogueWindow::TableCell("Safe Coordinates") + + DialogueWindow::TableCell( + fmt::format( + "{:.2f}, {:.2f}, {:.2f}", + zone->newzone_data.safe_x, + zone->newzone_data.safe_y, + zone->newzone_data.safe_z + ) + ) + ); + + popup_table += DialogueWindow::TableRow( + DialogueWindow::TableCell("Max Z") + + DialogueWindow::TableCell( + fmt::format( + "{:.2f}", + zone->newzone_data.max_z + ) + ) + ); + + popup_table += DialogueWindow::TableRow( + DialogueWindow::TableCell("Underworld Z") + + DialogueWindow::TableCell( + fmt::format( + "{:.2f}", + zone->newzone_data.underworld + ) + ) + ); + + popup_table += DialogueWindow::TableRow( + DialogueWindow::TableCell("Clipping Distance") + + DialogueWindow::TableCell( + fmt::format( + "{} to {}", + zone->newzone_data.minclip, + zone->newzone_data.maxclip + ) + ) + ); + + // Weather Data + for (uint8 weather_index = 0; weather_index < 4; weather_index++) { + const uint8 weather_number = (weather_index + 1); + + if ( + zone->newzone_data.rain_chance[weather_index] || + zone->newzone_data.rain_duration[weather_index] + ) { + popup_table += DialogueWindow::TableRow( + DialogueWindow::TableCell( + fmt::format( + "Rain {}", + weather_number + ) + ) + + DialogueWindow::TableCell( + fmt::format( + "Chance: {}", + zone->newzone_data.rain_chance[weather_index] + ) + ) + + DialogueWindow::TableCell( + fmt::format( + "Duration: {}", + zone->newzone_data.rain_duration[weather_index] + ) + ) + ); + } + + if ( + zone->newzone_data.snow_chance[weather_index] || + zone->newzone_data.snow_duration[weather_index] + ) { + popup_table += DialogueWindow::TableRow( + DialogueWindow::TableCell( + fmt::format( + "Snow {}", + weather_number + ) + ) + + DialogueWindow::TableCell( + fmt::format( + "Chance: {}", + zone->newzone_data.snow_chance[weather_index] + ) + ) + + DialogueWindow::TableCell( + fmt::format( + "Duration: {}", + zone->newzone_data.snow_duration[weather_index] + ) + ) + ); + } + } + + popup_table += DialogueWindow::TableRow( + DialogueWindow::TableCell("Sky") + + DialogueWindow::TableCell(std::to_string(zone->newzone_data.sky)) + ); + + popup_table += DialogueWindow::TableRow( + DialogueWindow::TableCell("Suspend Buffs") + + DialogueWindow::TableCell( + zone->newzone_data.suspend_buffs ? + DialogueWindow::ColorMessage("forest_green", "Y") : + DialogueWindow::ColorMessage("red1", "N") + ) + ); + + popup_table += DialogueWindow::TableRow( + DialogueWindow::TableCell("Health Regen") + + DialogueWindow::TableCell( + fmt::format( + "{} ({})", + Strings::Commify(zone->newzone_data.fast_regen_hp), + Strings::SecondsToTime(zone->newzone_data.fast_regen_hp) + ) + ) + ); + + popup_table += DialogueWindow::TableRow( + DialogueWindow::TableCell("Mana Regen") + + DialogueWindow::TableCell( + fmt::format( + "{} ({})", + Strings::Commify(zone->newzone_data.fast_regen_mana), + Strings::SecondsToTime(zone->newzone_data.fast_regen_mana) + ) + ) + ); + + popup_table += DialogueWindow::TableRow( + DialogueWindow::TableCell("Endurance Regen") + + DialogueWindow::TableCell( + fmt::format( + "{} ({})", + Strings::Commify(zone->newzone_data.fast_regen_endurance), + Strings::SecondsToTime(zone->newzone_data.fast_regen_endurance) + ) + ) + ); + + popup_table += DialogueWindow::TableRow( + DialogueWindow::TableCell("Maximum Aggro Distance") + + DialogueWindow::TableCell(Strings::Commify(zone->newzone_data.npc_aggro_max_dist)) + ); + + popup_table += DialogueWindow::TableRow( + DialogueWindow::TableCell("Underworld Teleport Index") + + DialogueWindow::TableCell(Strings::Commify(zone->newzone_data.underworld_teleport_index)) + ); + + popup_table += DialogueWindow::TableRow( + DialogueWindow::TableCell("Lava Damage") + + DialogueWindow::TableCell( + fmt::format( + "{} to {}", + Strings::Commify(zone->newzone_data.min_lava_damage), + Strings::Commify(zone->newzone_data.lava_damage) + ) + ) + ); + + popup_table = DialogueWindow::Table(popup_table); + + c->SendPopupToClient( + fmt::format( + "Zone Data for {}", + zone->GetZoneDescription() + ).c_str(), + popup_table.c_str() + ); +} diff --git a/zone/gm_commands/show/zone_global_loot.cpp b/zone/gm_commands/show/zone_global_loot.cpp new file mode 100644 index 000000000..6a05fdc19 --- /dev/null +++ b/zone/gm_commands/show/zone_global_loot.cpp @@ -0,0 +1,6 @@ +#include "../../client.h" + +void ShowZoneGlobalLoot(Client *c, const Seperator *sep) +{ + zone->ShowZoneGlobalLoot(c); +} diff --git a/zone/gm_commands/show/zone_loot.cpp b/zone/gm_commands/show/zone_loot.cpp new file mode 100644 index 000000000..53222cf45 --- /dev/null +++ b/zone/gm_commands/show/zone_loot.cpp @@ -0,0 +1,102 @@ +#include "../../client.h" + +void ShowZoneLoot(Client *c, const Seperator *sep) +{ + if (!sep->IsNumber(2)) { + c->Message( + Chat::White, + "Usage: #show zone_loot [Item ID]" + ); + return; + } + + const uint32 search_item_id = Strings::ToUnsignedInt(sep->arg[2]); + + std::vector> v; + + uint32 loot_count = 0; + uint32 loot_number = 1; + + for (auto npc_entity: entity_list.GetNPCList()) { + auto il = npc_entity.second->GetItemList(); + v.emplace_back(std::make_pair(npc_entity.second, il)); + } + + for (const auto &e: v) { + NPC *n = e.first; + const auto &l = e.second; + + std::string npc_link; + if (n) { + const uint32 instance_id = zone->GetInstanceID(); + const uint32 zone_id = zone->GetZoneID(); + + const std::string &command_link = Saylink::Silent( + fmt::format( + "#{} {} {} {} {}", + (instance_id != 0 ? "zoneinstance" : "zone"), + (instance_id != 0 ? instance_id : zone_id), + n->GetX(), + n->GetY(), + n->GetZ() + ), + "Goto" + ); + + npc_link = fmt::format( + "NPC: {} (ID {}) [{}]", + n->GetCleanName(), + n->GetID(), + command_link + ); + } + + for (const auto &i: l) { + if (!search_item_id || i->item_id == search_item_id) { + EQ::SayLinkEngine linker; + linker.SetLinkType(EQ::saylink::SayLinkLootItem); + linker.SetLootData(i); + + c->Message( + Chat::White, + fmt::format( + "{}. {} ({}) {}", + loot_number, + linker.GenerateLink(), + Strings::Commify(i->item_id), + npc_link + ).c_str() + ); + + loot_number++; + loot_count++; + } + } + } + + + if (search_item_id) { + c->Message( + Chat::White, + fmt::format( + "{} ({}) is dropping in {} place{}.", + database.CreateItemLink(search_item_id), + Strings::Commify(search_item_id), + loot_count, + loot_count != 1 ? "s" : "" + ).c_str() + ); + + return; + } + + c->Message( + Chat::White, + fmt::format( + "{} Item {} {} dropping.", + loot_count, + loot_count != 1 ? "s" : "", + loot_count != 1 ? "are" : "is" + ).c_str() + ); +} diff --git a/zone/gm_commands/showzonepoints.cpp b/zone/gm_commands/show/zone_points.cpp old mode 100755 new mode 100644 similarity index 57% rename from zone/gm_commands/showzonepoints.cpp rename to zone/gm_commands/show/zone_points.cpp index 4b98217a0..447370231 --- a/zone/gm_commands/showzonepoints.cpp +++ b/zone/gm_commands/show/zone_points.cpp @@ -1,24 +1,24 @@ -#include "../client.h" +#include "../../client.h" -void command_showzonepoints(Client *c, const Seperator *sep) +void ShowZonePoints(Client *c, const Seperator *sep) { - auto &mob_list = entity_list.GetMobList(); - for (auto itr : mob_list) { - Mob *mob = itr.second; + for (const auto& m : entity_list.GetMobList()) { + Mob* mob = m.second; if (mob->IsNPC() && mob->GetRace() == RACE_NODE_2254) { mob->Depop(); } } - int found_zone_points = 0; + uint32 found_count = 0; c->Message(Chat::White, "Listing zone points..."); + c->SendChatLineBreak(); for (auto &p : zone->virtual_zone_point_list) { - std::string zone_long_name = ZoneLongName(p.target_zone_id); + const std::string& zone_long_name = ZoneLongName(p.target_zone_id); - std::string saylink = fmt::format( + const std::string& saylink = fmt::format( "#goto {:.0f} {:.0f} {:.0f}", p.x, p.y, @@ -45,83 +45,92 @@ void command_showzonepoints(Client *c, const Seperator *sep) ).c_str() ); - std::string node_name = fmt::format("ZonePoint To [{}]", zone_long_name); + const std::string& node_name = fmt::format("ZonePoint To [{}]", zone_long_name); float half_width = ((float) p.width / 2); NPC::SpawnZonePointNodeNPC( node_name, glm::vec4( - (float) p.x + half_width, - (float) p.y + half_width, + p.x + half_width, + p.y + half_width, p.z, p.heading - )); + ) + ); NPC::SpawnZonePointNodeNPC( node_name, glm::vec4( - (float) p.x + half_width, - (float) p.y - half_width, + p.x + half_width, + p.y - half_width, p.z, p.heading - )); + ) + ); NPC::SpawnZonePointNodeNPC( node_name, glm::vec4( - (float) p.x - half_width, - (float) p.y - half_width, + p.x - half_width, + p.y - half_width, p.z, p.heading - )); + ) + ); NPC::SpawnZonePointNodeNPC( node_name, glm::vec4( - (float) p.x - half_width, - (float) p.y + half_width, + p.x - half_width, + p.y + half_width, p.z, p.heading - )); + ) + ); NPC::SpawnZonePointNodeNPC( node_name, glm::vec4( - (float) p.x + half_width, - (float) p.y + half_width, - (float) p.z + (float) p.height, + p.x + half_width, + p.y + half_width, + p.z + static_cast(p.height), p.heading - )); + ) + ); NPC::SpawnZonePointNodeNPC( node_name, glm::vec4( - (float) p.x + half_width, - (float) p.y - half_width, - (float) p.z + (float) p.height, + p.x + half_width, + p.y - half_width, + p.z + static_cast(p.height), p.heading - )); + ) + ); NPC::SpawnZonePointNodeNPC( node_name, glm::vec4( - (float) p.x - half_width, - (float) p.y - half_width, - (float) p.z + (float) p.height, + p.x - half_width, + p.y - half_width, + p.z + static_cast(p.height), p.heading - )); + ) + ); NPC::SpawnZonePointNodeNPC( node_name, glm::vec4( - (float) p.x - half_width, - (float) p.y + half_width, - (float) p.z + (float) p.height, + p.x - half_width, + p.y + half_width, + p.z + static_cast(p.height), p.heading - )); + ) + ); - found_zone_points++; + found_count++; } LinkedListIterator iterator(zone->zone_point_list); iterator.Reset(); while (iterator.MoreElements()) { - ZonePoint *p = iterator.GetData(); - std::string zone_long_name = ZoneLongName(p->target_zone_id); - std::string node_name = fmt::format("ZonePoint To [{}]", zone_long_name); + const auto &p = iterator.GetData(); + + const std::string& zone_long_name = ZoneLongName(p->target_zone_id); + const std::string& node_name = fmt::format("ZonePoint To [{}]", zone_long_name); NPC::SpawnZonePointNodeNPC( node_name, glm::vec4( @@ -132,9 +141,7 @@ void command_showzonepoints(Client *c, const Seperator *sep) ) ); - // {:.0f} - - std::string saylink = fmt::format( + const std::string& saylink = fmt::format( "#goto {:.0f} {:.0f} {:.0f}", p->x, p->y, @@ -145,13 +152,13 @@ void command_showzonepoints(Client *c, const Seperator *sep) Chat::White, fmt::format( "Client Side Zone Point [{}] x [{}] y [{}] z [{}] h [{}] number [{}] | To [{}] ({}) x [{}] y [{}] z [{}] h [{}]", - Saylink::Silent(saylink, "Goto").c_str(), + Saylink::Silent(saylink, "Goto"), p->x, p->y, p->z, p->heading, p->number, - zone_long_name.c_str(), + zone_long_name, p->target_zone_id, p->target_x, p->target_y, @@ -162,14 +169,12 @@ void command_showzonepoints(Client *c, const Seperator *sep) iterator.Advance(); - found_zone_points++; + found_count++; } - if (found_zone_points == 0) { - c->Message(Chat::White, "There were no zone points found..."); + if (!found_count) { + c->Message(Chat::White, "There were no zone points found."); } c->SendChatLineBreak(); - } - diff --git a/zone/gm_commands/show/zone_status.cpp b/zone/gm_commands/show/zone_status.cpp new file mode 100644 index 000000000..4ad2ea0ef --- /dev/null +++ b/zone/gm_commands/show/zone_status.cpp @@ -0,0 +1,16 @@ +#include "../../client.h" +#include "../../worldserver.h" + +extern WorldServer worldserver; + +void ShowZoneStatus(Client *c, const Seperator *sep) +{ + auto pack = new ServerPacket(ServerOP_ZoneStatus, sizeof(ServerZoneStatus_Struct)); + + auto z = (ServerZoneStatus_Struct *) pack->pBuffer; + z->admin = c->Admin(); + strn0cpy(z->name, c->GetName(), sizeof(z->name)); + + worldserver.SendPacket(pack); + delete pack; +} diff --git a/zone/gm_commands/showbuffs.cpp b/zone/gm_commands/showbuffs.cpp deleted file mode 100755 index bd8e558d6..000000000 --- a/zone/gm_commands/showbuffs.cpp +++ /dev/null @@ -1,12 +0,0 @@ -#include "../client.h" - -void command_showbuffs(Client *c, const Seperator *sep) -{ - if (c->GetTarget() == 0) { - c->CastToMob()->ShowBuffs(c); - } - else { - c->GetTarget()->CastToMob()->ShowBuffs(c); - } -} - diff --git a/zone/gm_commands/shownumhits.cpp b/zone/gm_commands/shownumhits.cpp deleted file mode 100755 index b8b06867b..000000000 --- a/zone/gm_commands/shownumhits.cpp +++ /dev/null @@ -1,8 +0,0 @@ -#include "../client.h" - -void command_shownumhits(Client *c, const Seperator *sep) -{ - c->ShowNumHits(); - return; -} - diff --git a/zone/gm_commands/showskills.cpp b/zone/gm_commands/showskills.cpp deleted file mode 100755 index d70df9974..000000000 --- a/zone/gm_commands/showskills.cpp +++ /dev/null @@ -1,98 +0,0 @@ -#include "../client.h" - -void command_showskills(Client *c, const Seperator *sep) -{ - auto target = c; - if (c->GetTarget() && c->GetTarget()->IsClient()) { - target = c->GetTarget()->CastToClient(); - } - - uint32 start_skill_id = 0; - if (sep->IsNumber(1)) { - start_skill_id = Strings::ToUnsignedInt(sep->arg[1]); - } - - bool show_all = !strcasecmp(sep->arg[2], "all"); - - uint32 max_skill_id = (start_skill_id + 49); - - std::string popup_text = "
"; - - popup_text += ""; - - for ( - EQ::skills::SkillType skill_id = (EQ::skills::SkillType) start_skill_id; - skill_id <= (EQ::skills::SkillType) max_skill_id; - skill_id = (EQ::skills::SkillType) (skill_id + 1) - ) { - if ((EQ::skills::SkillType) skill_id >= EQ::skills::SkillCount) { - max_skill_id = (EQ::skills::SkillCount - 1); - break; - } - - if (show_all || (target->CanHaveSkill(skill_id) && target->MaxSkill(skill_id))) { - popup_text += fmt::format( - "", - skill_id, - EQ::skills::GetSkillName(skill_id), - target->GetSkill(skill_id), - target->MaxSkill(skill_id), - target->GetRawSkill(skill_id) - ); - } - } - - popup_text += "
IDNameCurrentMaxRaw
{}{}{}{}{}
"; - - std::string popup_title = fmt::format( - "Skills for {} [{} to {}]", - c->GetTargetDescription(target, TargetDescriptionType::UCSelf), - start_skill_id, - max_skill_id - ); - - c->SendPopupToClient( - popup_title.c_str(), - popup_text.c_str() - ); - - - c->Message( - Chat::White, - fmt::format( - "Viewing skill levels from {} ({}) to {} ({}) for {}.", - EQ::skills::GetSkillName((EQ::skills::SkillType) start_skill_id), - start_skill_id, - EQ::skills::GetSkillName((EQ::skills::SkillType) max_skill_id), - max_skill_id, - c->GetTargetDescription(target) - ).c_str() - ); - - int next_skill_id = (max_skill_id + 1); - if ((EQ::skills::SkillType) next_skill_id < EQ::skills::SkillCount) { - auto next_list_string = fmt::format( - "#showskills {}", - next_skill_id - ); - - auto next_list_link = Saylink::Silent(next_list_string, next_list_string); - - auto next_list_all_string = fmt::format( - "#showskills {} all", - next_skill_id - ); - - auto next_list_all_link = Saylink::Silent(next_list_all_string, next_list_all_string); - - c->Message( - Chat::White, - fmt::format( - "To view the next 50 skill levels, you can use {} or {} to show skills the player cannot normally have.", - next_list_link, - next_list_all_link - ).c_str() - ); - } -} - diff --git a/zone/gm_commands/showspells.cpp b/zone/gm_commands/showspells.cpp deleted file mode 100755 index 3cfbe8cd7..000000000 --- a/zone/gm_commands/showspells.cpp +++ /dev/null @@ -1,37 +0,0 @@ -#include "../client.h" - -void command_showspells(Client *c, const Seperator *sep) -{ - const auto arguments = sep->argnum; - if (!arguments) { - c->Message(Chat::White, "Usages: #showspells disciplines - Show your or your target's learned disciplines"); - c->Message(Chat::White, "Usages: #showspells spells - Show your or your target's memorized spells"); - return; - } - - auto t = c; - if (c->GetTarget() && c->GetTarget()->IsClient()) { - t = c->GetTarget()->CastToClient(); - } - - const auto is_disciplines = !strcasecmp(sep->arg[1], "disciplines"); - const auto is_spells = !strcasecmp(sep->arg[1], "spells"); - if ( - !is_disciplines && - !is_spells - ) { - c->Message(Chat::White, "Usages: #showspells disciplines - Show your or your target's learned disciplines"); - c->Message(Chat::White, "Usages: #showspells spells - Show your or your target's memorized spells"); - } - - ShowSpellType show_spell_type; - - if (is_disciplines) { - show_spell_type = ShowSpellType::Disciplines; - } else if (is_spells) { - show_spell_type = ShowSpellType::Spells; - } - - t->ShowSpells(c, show_spell_type); -} - diff --git a/zone/gm_commands/showspellslist.cpp b/zone/gm_commands/showspellslist.cpp deleted file mode 100755 index 2b50864e6..000000000 --- a/zone/gm_commands/showspellslist.cpp +++ /dev/null @@ -1,13 +0,0 @@ -#include "../client.h" - -void command_showspellslist(Client *c, const Seperator *sep) -{ - Mob *target = c->GetTarget(); - if (!target || !target->IsNPC()) { - c->Message(Chat::White, "You must target an NPC to use this command."); - return; - } - target->CastToNPC()->AISpellsList(c); - return; -} - diff --git a/zone/gm_commands/showstats.cpp b/zone/gm_commands/showstats.cpp deleted file mode 100755 index cae9609c2..000000000 --- a/zone/gm_commands/showstats.cpp +++ /dev/null @@ -1,12 +0,0 @@ -#include "../client.h" - -void command_showstats(Client *c, const Seperator *sep) -{ - if (c->GetTarget() != 0) { - c->GetTarget()->ShowStats(c); - } - else { - c->ShowStats(c); - } -} - diff --git a/zone/gm_commands/showzonegloballoot.cpp b/zone/gm_commands/showzonegloballoot.cpp deleted file mode 100755 index 95e364d24..000000000 --- a/zone/gm_commands/showzonegloballoot.cpp +++ /dev/null @@ -1,7 +0,0 @@ -#include "../client.h" - -void command_showzonegloballoot(Client *c, const Seperator *sep) -{ - zone->ShowZoneGlobalLoot(c); -} - diff --git a/zone/gm_commands/spawnstatus.cpp b/zone/gm_commands/spawnstatus.cpp deleted file mode 100755 index 5b88e6c50..000000000 --- a/zone/gm_commands/spawnstatus.cpp +++ /dev/null @@ -1,137 +0,0 @@ -#include "../client.h" - -void command_spawnstatus(Client *c, const Seperator *sep) -{ - int arguments = sep->argnum; - if (!arguments) { - c->Message(Chat::White, "Usage: #spawnstatus all - Show all spawn statuses for your current zone"); - c->Message(Chat::White, "Usage: #spawnstatus disabled - Show all disabled spawn statuses for your current zone"); - c->Message(Chat::White, "Usage: #spawnstatus enabled - Show all enabled spawn statuses for your current zone"); - c->Message(Chat::White, "Usage: #spawnstatus [Spawn ID] - Show spawn status by ID for your current zone"); - return; - } - - bool is_all = !strcasecmp(sep->arg[1], "all"); - bool is_disabled = !strcasecmp(sep->arg[1], "disabled"); - bool is_enabled = !strcasecmp(sep->arg[1], "enabled"); - bool is_search = sep->IsNumber(1); - - if ( - !is_all && - !is_disabled && - !is_enabled && - !is_search - ) { - c->Message(Chat::White, "Usage: #spawnstatus all - Show all spawn statuses for your current zone"); - c->Message(Chat::White, "Usage: #spawnstatus disabled - Show all disabled spawn statuses for your current zone"); - c->Message(Chat::White, "Usage: #spawnstatus enabled - Show all enabled spawn statuses for your current zone"); - c->Message(Chat::White, "Usage: #spawnstatus [Spawn ID] - Show spawn status by ID for your current zone"); - return; - } - - std::string filter_type; - if (is_disabled) { - filter_type = "Disabled"; - } else if (is_enabled) { - filter_type = "Enabled"; - } - - uint32 spawn_id = 0; - if (is_search) { - spawn_id = Strings::ToUnsignedInt(sep->arg[1]); - } - - LinkedListIterator iterator(zone->spawn2_list); - iterator.Reset(); - - uint32 filtered_count = 0; - uint32 spawn_count = 0; - uint32 spawn_number = 1; - while (iterator.MoreElements()) { - auto e = iterator.GetData(); - auto time_remaining = e->GetTimer().GetRemainingTime(); - if ( - is_all || - ( - is_disabled && - time_remaining == 0xFFFFFFFF - ) || - ( - is_enabled && - time_remaining != 0xFFFFFFFF - ) || - ( - is_search && - e->GetID() == spawn_id - ) - ) { - c->Message( - Chat::White, - fmt::format( - "Spawn {} | ID: {} Coordinates: {:.2f}, {:.2f}, {:.2f}, {:.2f}", - spawn_number, - e->GetID(), - e->GetX(), - e->GetY(), - e->GetZ(), - e->GetHeading() - ).c_str() - ); - if (time_remaining != 0xFFFFFFFF) { - auto seconds_remaining = (time_remaining / 1000); - c->Message( - Chat::White, - fmt::format( - "Spawn {} | Respawn: {} ({} Second{})", - spawn_number, - Strings::SecondsToTime(seconds_remaining), - seconds_remaining, - seconds_remaining != 1 ? "s" : "" - ).c_str() - ); - } - filtered_count++; - spawn_number++; - } - spawn_count++; - iterator.Advance(); - } - - if (!spawn_count) { - c->Message(Chat::White, "No spawns were found in this zone."); - return; - } - - if (!is_all && !is_search && !filtered_count) { - c->Message( - Chat::White, - fmt::format( - "No {} spawns were found in this zone.", - filter_type - ).c_str() - ); - return; - } - - if (is_all) { - c->Message( - Chat::White, - fmt::format( - "{} spawn{} listed.", - spawn_count, - spawn_count != 1 ? "s" : "" - ).c_str() - ); - } else { - c->Message( - Chat::White, - fmt::format( - "{} of {} spawn{} listed.", - filtered_count, - spawn_count, - spawn_count != 1 ? "s" : "" - ).c_str() - ); - } -} - diff --git a/zone/gm_commands/texture.cpp b/zone/gm_commands/texture.cpp index 24dde1f0f..518b91549 100755 --- a/zone/gm_commands/texture.cpp +++ b/zone/gm_commands/texture.cpp @@ -20,7 +20,7 @@ void command_texture(Client *c, const Seperator *sep) target = c->GetTarget(); } - if (Mob::IsPlayerRace(target->GetModel())) { // Player Races Wear Armor, so Wearchange is sent instead + if (IsPlayerRace(target->GetModel())) { // Player Races Wear Armor, so Wearchange is sent instead for ( int texture_slot = EQ::textures::textureBegin; texture_slot <= EQ::textures::LastTintableTexture; @@ -44,7 +44,7 @@ void command_texture(Client *c, const Seperator *sep) c->GetTargetDescription(target, TargetDescriptionType::UCSelf), texture, ( - Mob::IsPlayerRace(target->GetModel()) ? + IsPlayerRace(target->GetModel()) ? "" : fmt::format( " Helmet Texture: {}", diff --git a/zone/gm_commands/trapinfo.cpp b/zone/gm_commands/trapinfo.cpp deleted file mode 100755 index 6d2d8fcf1..000000000 --- a/zone/gm_commands/trapinfo.cpp +++ /dev/null @@ -1,7 +0,0 @@ -#include "../client.h" - -void command_trapinfo(Client *c, const Seperator *sep) -{ - entity_list.GetTrapInfo(c); -} - diff --git a/zone/gm_commands/uptime.cpp b/zone/gm_commands/uptime.cpp deleted file mode 100755 index 00b247d9f..000000000 --- a/zone/gm_commands/uptime.cpp +++ /dev/null @@ -1,22 +0,0 @@ -#include "../client.h" -#include "../worldserver.h" - -extern WorldServer worldserver; - -void command_uptime(Client *c, const Seperator *sep) -{ - if (!worldserver.Connected()) { - c->Message(Chat::White, "Error: World server disconnected"); - } - else { - auto pack = new ServerPacket(ServerOP_Uptime, sizeof(ServerUptime_Struct)); - ServerUptime_Struct *sus = (ServerUptime_Struct *) pack->pBuffer; - strcpy(sus->adminname, c->GetName()); - if (sep->IsNumber(1) && Strings::ToInt(sep->arg[1]) > 0) { - sus->zoneserverid = Strings::ToInt(sep->arg[1]); - } - worldserver.SendPacket(pack); - safe_delete(pack); - } -} - diff --git a/zone/gm_commands/version.cpp b/zone/gm_commands/version.cpp deleted file mode 100755 index cc5d0a531..000000000 --- a/zone/gm_commands/version.cpp +++ /dev/null @@ -1,18 +0,0 @@ -#include "../client.h" - -void command_version(Client *c, const Seperator *sep) -{ - std::string popup_text = ""; - - popup_text += fmt::format("", CURRENT_VERSION); - popup_text += fmt::format("", COMPILE_DATE, COMPILE_TIME); - popup_text += fmt::format("", LAST_MODIFIED); - - popup_text += "
Version{}
Compiled{} {}
Last Modified{}
"; - - c->SendPopupToClient( - "Server Version Information", - popup_text.c_str() - ); -} - diff --git a/zone/gm_commands/viewcurrencies.cpp b/zone/gm_commands/viewcurrencies.cpp deleted file mode 100644 index a19c72ffe..000000000 --- a/zone/gm_commands/viewcurrencies.cpp +++ /dev/null @@ -1,127 +0,0 @@ -#include "../client.h" - -void command_viewcurrencies(Client *c, const Seperator *sep) -{ - Client *target = c; - if (c->GetTarget() && c->GetTarget()->IsClient()) { - target = c->GetTarget()->CastToClient(); - } - - auto platinum = ( - target->GetMoney(3, 0) + - target->GetMoney(3, 1) + - target->GetMoney(3, 2) + - target->GetMoney(3, 3) - ); - - auto gold = ( - target->GetMoney(2, 0) + - target->GetMoney(2, 1) + - target->GetMoney(2, 2) - ); - - auto silver = ( - target->GetMoney(1, 0) + - target->GetMoney(1, 1) + - target->GetMoney(1, 2) - ); - - auto copper = ( - target->GetMoney(0, 0) + - target->GetMoney(0, 1) + - target->GetMoney(0, 2) - ); - - if ( - platinum || - gold || - silver || - copper - ) { - c->Message( - Chat::White, - fmt::format( - "Money for {} | {}", - c->GetTargetDescription(target, TargetDescriptionType::UCSelf), - Strings::Money( - platinum, - gold, - silver, - copper - ) - ).c_str() - ); - } - - auto ebon_crystals = target->GetEbonCrystals(); - if (ebon_crystals) { - c->Message( - Chat::White, - fmt::format( - "{} for {} | {}", - database.CreateItemLink(RuleI(Zone, EbonCrystalItemID)), - c->GetTargetDescription(target, TargetDescriptionType::UCSelf), - ebon_crystals - ).c_str() - ); - } - - auto radiant_crystals = target->GetRadiantCrystals(); - if (radiant_crystals) { - c->Message( - Chat::White, - fmt::format( - "{} for {} | {}", - database.CreateItemLink(RuleI(Zone, RadiantCrystalItemID)), - c->GetTargetDescription(target, TargetDescriptionType::UCSelf), - radiant_crystals - ).c_str() - ); - } - - for (const auto& ac : zone->AlternateCurrencies) { - auto currency_value = target->GetAlternateCurrencyValue(ac.id); - if (currency_value) { - c->Message( - Chat::White, - fmt::format( - "{} for {} | {}", - database.CreateItemLink(ac.item_id), - c->GetTargetDescription(target, TargetDescriptionType::UCSelf), - currency_value - ).c_str() - ); - } - } - - for ( - uint32 ldon_currency_id = LDoNThemes::GUK; - ldon_currency_id <= LDoNThemes::TAK; - ldon_currency_id++ - ) { - auto ldon_currency_value = target->GetLDoNPointsTheme(ldon_currency_id); - if (ldon_currency_value) { - c->Message( - Chat::White, - fmt::format( - "{} for {} | {}", - EQ::constants::GetLDoNThemeName(ldon_currency_id), - c->GetTargetDescription(target, TargetDescriptionType::UCSelf), - ldon_currency_value - ).c_str() - ); - } - } - - auto pvp_points = target->GetPVPPoints(); - if (pvp_points) { - c->Message( - Chat::White, - fmt::format( - "PVP Points for {} | {}", - c->GetTargetDescription(target, TargetDescriptionType::UCSelf), - pvp_points - ).c_str() - ); - } -} diff --git a/zone/gm_commands/viewnpctype.cpp b/zone/gm_commands/viewnpctype.cpp deleted file mode 100755 index 80c73bfef..000000000 --- a/zone/gm_commands/viewnpctype.cpp +++ /dev/null @@ -1,32 +0,0 @@ -#include "../client.h" - -void command_viewnpctype(Client *c, const Seperator *sep) -{ - if (sep->IsNumber(1)) { - uint32 npc_id = Strings::ToUnsignedInt(sep->arg[1]); - const NPCType *npc_type_data = content_db.LoadNPCTypesData(npc_id); - if (npc_type_data) { - auto npc = new NPC( - npc_type_data, - nullptr, - c->GetPosition(), - GravityBehavior::Water - ); - npc->ShowStats(c); - safe_delete(npc); - } - else { - c->Message( - Chat::White, - fmt::format( - "NPC ID {} was not found.", - npc_id - ).c_str() - ); - } - } - else { - c->Message(Chat::White, "Usage: #viewnpctype [NPC ID]"); - } -} - diff --git a/zone/gm_commands/viewpetition.cpp b/zone/gm_commands/viewpetition.cpp deleted file mode 100755 index eaff518a9..000000000 --- a/zone/gm_commands/viewpetition.cpp +++ /dev/null @@ -1,31 +0,0 @@ -#include "../client.h" - -void command_viewpetition(Client *c, const Seperator *sep) -{ - if (sep->arg[1][0] == 0) { - c->Message(Chat::White, "Usage: #viewpetition (petition number) Type #listpetition for a list"); - return; - } - - c->Message(Chat::Red, " ID : Character Name , Petition Text"); - - std::string query = "SELECT petid, charname, petitiontext FROM petitions ORDER BY petid"; - auto results = database.QueryDatabase(query); - if (!results.Success()) { - return; - } - - LogInfo("View petition request from [{}], petition number: [{}]", c->GetName(), Strings::ToInt(sep->argplus[1])); - - if (results.RowCount() == 0) { - c->Message(Chat::Red, "There was an error in your request: ID not found! Please check the Id and try again."); - return; - } - - for (auto row = results.begin(); row != results.end(); ++row) - if (strcasecmp(row[0], sep->argplus[1]) == 0) { - c->Message(Chat::Yellow, " %s: %s , %s ", row[0], row[1], row[2]); - } - -} - diff --git a/zone/gm_commands/viewzoneloot.cpp b/zone/gm_commands/viewzoneloot.cpp deleted file mode 100755 index 3f48a3847..000000000 --- a/zone/gm_commands/viewzoneloot.cpp +++ /dev/null @@ -1,116 +0,0 @@ -#include "../client.h" - -void command_viewzoneloot(Client *c, const Seperator *sep) -{ - std::map zone_loot_list; - auto npc_list = entity_list.GetNPCList(); - uint32 loot_amount = 0, loot_id = 1, search_item_id = 0; - if (sep->argnum == 1 && sep->IsNumber(1)) { - search_item_id = Strings::ToInt(sep->arg[1]); - } - else if (sep->argnum == 1 && !sep->IsNumber(1)) { - c->Message( - Chat::Yellow, - "Usage: #viewzoneloot [item id]" - ); - return; - } - - for (auto npc_entity : npc_list) { - auto current_npc_item_list = npc_entity.second->GetItemList(); - zone_loot_list.insert({npc_entity.second->GetID(), current_npc_item_list}); - } - - for (auto loot_item : zone_loot_list) { - uint32 current_entity_id = loot_item.first; - auto current_item_list = loot_item.second; - auto current_npc = entity_list.GetNPCByID(current_entity_id); - std::string npc_link; - if (current_npc) { - std::string npc_name = current_npc->GetCleanName(); - uint32 instance_id = zone->GetInstanceID(); - uint32 zone_id = zone->GetZoneID(); - std::string command_link = Saylink::Silent( - fmt::format( - "#{} {} {} {} {}", - (instance_id != 0 ? "zoneinstance" : "zone"), - (instance_id != 0 ? instance_id : zone_id), - current_npc->GetX(), - current_npc->GetY(), - current_npc->GetZ() - ), - "Goto" - ); - npc_link = fmt::format( - " NPC: {} (ID {}) [{}]", - npc_name, - current_entity_id, - command_link - ); - } - - for (auto current_item : current_item_list) { - if (search_item_id == 0 || current_item->item_id == search_item_id) { - EQ::SayLinkEngine linker; - linker.SetLinkType(EQ::saylink::SayLinkLootItem); - linker.SetLootData(current_item); - c->Message( - Chat::White, - fmt::format( - "{}. {} ({}){}", - loot_id, - linker.GenerateLink(), - current_item->item_id, - npc_link - ).c_str() - ); - loot_id++; - loot_amount++; - } - } - } - - - if (search_item_id != 0) { - std::string drop_string = ( - loot_amount > 0 ? - fmt::format( - "dropping in {} {}", - loot_amount, - (loot_amount > 1 ? "places" : "place") - ) : - "not dropping" - ); - - c->Message( - Chat::White, - fmt::format( - "{} ({}) is {}.", - database.CreateItemLink(search_item_id), - search_item_id, - drop_string - ).c_str() - ); - } - else { - std::string drop_string = ( - loot_amount > 0 ? - fmt::format( - "{} {} dropping", - (loot_amount > 1 ? "items" : "item"), - (loot_amount > 1 ? "are" : "is") - ) : - "items are dropping" - ); - - c->Message( - Chat::White, - fmt::format( - "{} {}.", - loot_amount, - drop_string - ).c_str() - ); - } -} - diff --git a/zone/gm_commands/who.cpp b/zone/gm_commands/who.cpp deleted file mode 100755 index a67cc2799..000000000 --- a/zone/gm_commands/who.cpp +++ /dev/null @@ -1,233 +0,0 @@ -#include "../client.h" - -void command_who(Client *c, const Seperator *sep) -{ - std::string query = SQL( - SELECT - character_data.account_id, - character_data.name, - character_data.zone_id, - character_data.zone_instance, - COALESCE( - ( - SELECT guilds.name FROM guilds WHERE id = ( - ( - SELECT guild_id FROM guild_members WHERE char_id = character_data.id - ) - ) - ), - "" - ) AS guild_name, - character_data.level, - character_data.race, - character_data.class, - COALESCE( - ( - SELECT account.status FROM account WHERE account.id = character_data.account_id LIMIT 1 - ), - 0 - ) AS account_status, - COALESCE( - ( - SELECT account.name FROM account WHERE account.id = character_data.account_id LIMIT 1 - ), - 0 - ) AS account_name, - COALESCE( - ( - SELECT account_ip.ip FROM account_ip WHERE account_ip.accid = character_data.account_id ORDER BY account_ip.lastused DESC LIMIT 1 - ), - "" - ) AS account_ip - FROM - character_data - WHERE - last_login > (UNIX_TIMESTAMP() - 600) - ORDER BY - character_data.name; - ); - - auto results = database.QueryDatabase(query); - if (!results.Success() || !results.RowCount()) { - return; - } - - std::string search_string; - - if (sep->arg[1]) { - search_string = Strings::ToLower(sep->arg[1]); - } - - int found_count = 0; - - c->Message(Chat::Who, "Players in EverQuest:"); - c->Message(Chat::Who, "------------------------------"); - - for (auto row : results) { - auto account_id = Strings::ToUnsignedInt(row[0]); - std::string player_name = row[1]; - auto zone_id = Strings::ToUnsignedInt(row[2]); - std::string zone_short_name = ZoneName(zone_id); - std::string zone_long_name = ZoneLongName(zone_id); - auto zone_instance = Strings::ToUnsignedInt(row[3]); - std::string guild_name = row[4]; - auto player_level = Strings::ToUnsignedInt(row[5]); - auto player_race = Strings::ToUnsignedInt(row[6]); - auto player_class = Strings::ToUnsignedInt(row[7]); - auto account_status = Strings::ToUnsignedInt(row[8]); - std::string account_name = row[9]; - std::string account_ip = row[10]; - std::string base_class_name = GetClassIDName(static_cast(player_class)); - std::string displayed_race_name = GetRaceIDName(static_cast(player_race)); - - if (search_string.length()) { - bool found_search_term = ( - Strings::ToLower(player_name).find(search_string) != std::string::npos || - Strings::ToLower(zone_short_name).find(search_string) != std::string::npos || - Strings::ToLower(displayed_race_name).find(search_string) != std::string::npos || - Strings::ToLower(base_class_name).find(search_string) != std::string::npos || - Strings::ToLower(guild_name).find(search_string) != std::string::npos || - Strings::ToLower(account_name).find(search_string) != std::string::npos || - Strings::ToLower(account_ip).find(search_string) != std::string::npos - ); - - if (!found_search_term) { - continue; - } - } - - std::string displayed_guild_name; - if (guild_name.length()) { - displayed_guild_name = Saylink::Silent( - fmt::format( - "#who \"{}\"", - guild_name - ), - fmt::format( - "<{}>", - guild_name - ) - ); - } - - auto goto_saylink = Saylink::Silent( - fmt::format( - "#goto {}", - player_name - ), - "Goto" - ); - - auto summon_saylink = Saylink::Silent( - fmt::format( - "#summon {}", - player_name - ), - "Summon" - ); - - std::string display_class_name = GetClassIDName( - static_cast(player_class), - static_cast(player_level) - ); - - auto class_saylink = Saylink::Silent( - fmt::format( - "#who {}", - base_class_name - ), - display_class_name - ); - - auto race_saylink = Saylink::Silent( - fmt::format( - "#who %s", - displayed_race_name - ), - displayed_race_name - ); - - auto zone_saylink = Saylink::Silent( - fmt::format( - "#who {}", - zone_short_name - ), - zone_long_name - ); - - auto account_saylink = Saylink::Silent( - fmt::format( - "#who {}", - account_name - ), - account_name - ); - - auto account_ip_saylink = Saylink::Silent( - fmt::format( - "#who {}", - account_ip - ), - account_ip - ); - - auto status_level = ( - account_status ? - fmt::format( - "* {} * ", - EQ::constants::GetAccountStatusName(account_status) - ) : - "" - ); - - auto version_string = ( - zone_instance ? - fmt::format( - " ({})", - zone_instance - ) : - "" - ); - - c->Message( - Chat::Who, - fmt::format( - "{}[{} {} ({})] {} ({}) ({}) ({}) {} ZONE: {}{} ({} | {})", - status_level, - player_level, - class_saylink, - base_class_name, - player_name, - race_saylink, - account_saylink, - account_ip_saylink, - displayed_guild_name, - zone_saylink, - version_string, - goto_saylink, - summon_saylink - ).c_str() - ); - - found_count++; - } - - std::string count_string = found_count == 1 ? "is" : "are"; - - std::string message = ( - found_count ? - fmt::format( - "There {} {} player{} in EverQuest.", - count_string, - found_count, - found_count > 1 ? "s" : "" - ) : - "There are no players in EverQuest that match those filters." - ); - - c->Message( - Chat::Who, - message.c_str() - ); -} - diff --git a/zone/gm_commands/zonestatus.cpp b/zone/gm_commands/zonestatus.cpp deleted file mode 100755 index 51c5f763e..000000000 --- a/zone/gm_commands/zonestatus.cpp +++ /dev/null @@ -1,19 +0,0 @@ -#include "../client.h" -#include "../worldserver.h" - -extern WorldServer worldserver; - -void command_zonestatus(Client *c, const Seperator *sep) -{ - if (!worldserver.Connected()) { - c->Message(Chat::White, "Error: World server disconnected"); - } - else { - auto pack = new ServerPacket(ServerOP_ZoneStatus, strlen(c->GetName()) + 2); - memset(pack->pBuffer, (uint8) c->Admin(), 1); - strcpy((char *) &pack->pBuffer[1], c->GetName()); - worldserver.SendPacket(pack); - delete pack; - } -} - diff --git a/zone/gm_commands/zstats.cpp b/zone/gm_commands/zstats.cpp deleted file mode 100755 index ab9c65ec9..000000000 --- a/zone/gm_commands/zstats.cpp +++ /dev/null @@ -1,205 +0,0 @@ -#include "../client.h" - -void command_zstats(Client *c, const Seperator *sep) -{ - // Zone - c->Message( - Chat::White, - fmt::format( - "Zone | {}", - zone->GetZoneDescription() - ).c_str() - ); - - // Type - c->Message( - Chat::White, - fmt::format( - "Type: {}", - zone->newzone_data.ztype - ).c_str() - ); - - // Fog Data - for (int fog_index = 0; fog_index < 4; fog_index++) { - int fog_number = (fog_index + 1); - c->Message( - Chat::White, - fmt::format( - "Fog {} Colors | Red: {} Blue: {} Green: {} ", - fog_number, - zone->newzone_data.fog_red[fog_index], - zone->newzone_data.fog_green[fog_index], - zone->newzone_data.fog_blue[fog_index] - ).c_str() - ); - - c->Message( - Chat::White, - fmt::format( - "Fog {} Clipping Distance | Min: {} Max: {}", - fog_number, - zone->newzone_data.fog_minclip[fog_index], - zone->newzone_data.fog_maxclip[fog_index] - ).c_str() - ); - } - - // Fog Density - c->Message( - Chat::White, - fmt::format( - "Fog Density: {}", - zone->newzone_data.fog_density - ).c_str() - ); - - - // Gravity - c->Message( - Chat::White, - fmt::format( - "Gravity: {}", - zone->newzone_data.gravity - ).c_str() - ); - - // Time Type - c->Message( - Chat::White, - fmt::format( - "Time Type: {}", - zone->newzone_data.time_type - ).c_str() - ); - - // Experience Multiplier - c->Message( - Chat::White, - fmt::format( - "Experience Multiplier: {}", - zone->newzone_data.zone_exp_multiplier - ).c_str() - ); - - // Safe Coordinates - c->Message( - Chat::White, - fmt::format( - "Safe Coordinates: {}, {}, {}", - zone->newzone_data.safe_x, - zone->newzone_data.safe_y, - zone->newzone_data.safe_z - ).c_str() - ); - - // Max Z - c->Message( - Chat::White, - fmt::format( - "Max Z: {}", - zone->newzone_data.max_z - ).c_str() - ); - - // Underworld Z - c->Message( - Chat::White, - fmt::format( - "Underworld Z: {}", - zone->newzone_data.underworld - ).c_str() - ); - - // Clipping Distance - c->Message( - Chat::White, - fmt::format( - "Clipping Distance | Min: {} Max: {}", - zone->newzone_data.minclip, - zone->newzone_data.maxclip - ).c_str() - ); - - // Weather Data - for (int weather_index = 0; weather_index < 4; weather_index++) { - int weather_number = (weather_index + 1); - c->Message( - Chat::White, - fmt::format( - "Rain {} | Chance: {} Duration: {} ", - weather_number, - zone->newzone_data.rain_chance[weather_index], - zone->newzone_data.rain_duration[weather_index] - ).c_str() - ); - - c->Message( - Chat::White, - fmt::format( - "Snow {} | Chance: {} Duration: {}", - weather_number, - zone->newzone_data.snow_chance[weather_index], - zone->newzone_data.snow_duration[weather_index] - ).c_str() - ); - } - - // Sky Type - c->Message( - Chat::White, - fmt::format( - "Sky Type: {}", - zone->newzone_data.sky - ).c_str() - ); - - // Suspend Buffs - c->Message( - Chat::White, - fmt::format( - "Suspend Buffs: {}", - zone->newzone_data.suspend_buffs - ).c_str() - ); - - // Regeneration Data - c->Message( - Chat::White, - fmt::format( - "Regen | Health: {} Mana: {} Endurance: {}", - zone->newzone_data.fast_regen_hp, - zone->newzone_data.fast_regen_mana, - zone->newzone_data.fast_regen_endurance - ).c_str() - ); - - // NPC Max Aggro Distance - c->Message( - Chat::White, - fmt::format( - "NPC Max Aggro Distance: {}", - zone->newzone_data.npc_aggro_max_dist - ).c_str() - ); - - // Underworld Teleport Index - c->Message( - Chat::White, - fmt::format( - "Underworld Teleport Index: {}", - zone->newzone_data.underworld_teleport_index - ).c_str() - ); - - // Lava Damage - c->Message( - Chat::White, - fmt::format( - "Lava Damage | Min: {} Max: {}", - zone->newzone_data.min_lava_damage, - zone->newzone_data.lava_damage - ).c_str() - ); -} - diff --git a/zone/loottables.cpp b/zone/loottables.cpp index 45b1017bf..f1e947b33 100644 --- a/zone/loottables.cpp +++ b/zone/loottables.cpp @@ -299,7 +299,7 @@ void NPC::AddLootDrop( uint32 aug6 ) { - if (item2 == nullptr) { + if (!item2) { return; } @@ -363,11 +363,27 @@ void NPC::AddLootDrop( bool found = false; // track if we found an empty slot we fit into + int foundslot = INVALID_INDEX; // for multi-slot items + + const auto* inst = database.CreateItem( + item2->ID, + loot_drop.item_charges, + aug1, + aug2, + aug3, + aug4, + aug5, + aug6 + ); + + if (!inst) { + return; + } + if (loot_drop.equip_item > 0) { uint8 eslot = 0xFF; char newid[20]; const EQ::ItemData* compitem = nullptr; - int32 foundslot = -1; // for multi-slot items // Equip rules are as follows: // If the item has the NoPet flag set it will not be equipped. @@ -511,10 +527,15 @@ void NPC::AddLootDrop( } } - if (itemlist != nullptr) { + if (itemlist) { + if (foundslot != INVALID_INDEX) { + GetInv().PutItem(foundslot, *inst); + } + itemlist->push_back(item); + } else { + safe_delete(item); } - else safe_delete(item); if (found) { CalcBonuses(); diff --git a/zone/lua_bot.cpp b/zone/lua_bot.cpp index 6ebf88836..6d24896b5 100644 --- a/zone/lua_bot.cpp +++ b/zone/lua_bot.cpp @@ -494,6 +494,16 @@ void Lua_Bot::AddItem(const luabind::object& item_table) { } } +std::string Lua_Bot::GetClassAbbreviation() { + Lua_Safe_Call_String(); + return GetPlayerClassAbbreviation(self->GetClass()); +} + +std::string Lua_Bot::GetRaceAbbreviation() { + Lua_Safe_Call_String(); + return GetPlayerRaceAbbreviation(self->GetBaseRace()); +} + luabind::scope lua_register_bot() { return luabind::class_("Bot") .def(luabind::constructor<>()) @@ -541,6 +551,7 @@ luabind::scope lua_register_bot() { .def("GetBotID", (uint32(Lua_Bot::*)(void))&Lua_Bot::GetBotID) .def("GetBotItem", (Lua_ItemInst(Lua_Bot::*)(uint16))&Lua_Bot::GetBotItem) .def("GetBotItemIDBySlot", (uint32(Lua_Bot::*)(uint16))&Lua_Bot::GetBotItemIDBySlot) + .def("GetClassAbbreviation", (std::string(Lua_Bot::*)(void))&Lua_Bot::GetClassAbbreviation) .def("GetExpansionBitmask", (int(Lua_Bot::*)(void))&Lua_Bot::GetExpansionBitmask) .def("GetGroup", (Lua_Group(Lua_Bot::*)(void))&Lua_Bot::GetGroup) .def("GetHealAmount", (int(Lua_Bot::*)(void))&Lua_Bot::GetHealAmount) @@ -548,6 +559,7 @@ luabind::scope lua_register_bot() { .def("GetItemAt", (Lua_ItemInst(Lua_Bot::*)(int16))&Lua_Bot::GetItemAt) .def("GetItemIDAt", (int(Lua_Bot::*)(int16))&Lua_Bot::GetItemIDAt) .def("GetOwner", (Lua_Mob(Lua_Bot::*)(void))&Lua_Bot::GetOwner) + .def("GetRaceAbbreviation", (std::string(Lua_Bot::*)(void))&Lua_Bot::GetRaceAbbreviation) .def("GetRawItemAC", (int(Lua_Bot::*)(void))&Lua_Bot::GetRawItemAC) .def("GetSpellDamage", (int(Lua_Bot::*)(void))&Lua_Bot::GetSpellDamage) .def("HasAugmentEquippedByID", (bool(Lua_Bot::*)(uint32))&Lua_Bot::HasAugmentEquippedByID) diff --git a/zone/lua_bot.h b/zone/lua_bot.h index 908ee5d86..c035d14b0 100644 --- a/zone/lua_bot.h +++ b/zone/lua_bot.h @@ -1,3 +1,4 @@ +\ #ifndef EQEMU_LUA_BOT_H #define EQEMU_LUA_BOT_H #ifdef LUA_EQEMU @@ -65,6 +66,8 @@ public: Lua_ItemInst GetItemAt(int16 slot_id); int GetItemIDAt(int16 slot_id); void SendSpellAnim(uint16 target_id, uint16 spell_id); + std::string GetClassAbbreviation(); + std::string GetRaceAbbreviation(); void ApplySpell(int spell_id); void ApplySpell(int spell_id, int duration); diff --git a/zone/lua_client.cpp b/zone/lua_client.cpp index 60f0cdf3c..f757f5f8a 100644 --- a/zone/lua_client.cpp +++ b/zone/lua_client.cpp @@ -1449,7 +1449,7 @@ void Lua_Client::UnFreeze() { self->SendAppearancePacket(AT_Anim, ANIM_STAND); } -int Lua_Client::GetAggroCount() { +uint32 Lua_Client::GetAggroCount() { Lua_Safe_Call_Int(); return self->GetAggroCount(); } @@ -1509,16 +1509,36 @@ bool Lua_Client::HasSpellScribed(int spell_id) { return self->HasSpellScribed(spell_id); } -void Lua_Client::SetAccountFlag(std::string flag, std::string val) { +void Lua_Client::ClearAccountFlag(const std::string& flag) { Lua_Safe_Call_Void(); - self->SetAccountFlag(flag, val); + self->ClearAccountFlag(flag); } -std::string Lua_Client::GetAccountFlag(std::string flag) { +void Lua_Client::SetAccountFlag(const std::string& flag, const std::string& value) { + Lua_Safe_Call_Void(); + self->SetAccountFlag(flag, value); +} + +std::string Lua_Client::GetAccountFlag(const std::string& flag) { Lua_Safe_Call_String(); return self->GetAccountFlag(flag); } +luabind::object Lua_Client::GetAccountFlags(lua_State* L) { + auto t = luabind::newtable(L); + if (d_) { + auto self = reinterpret_cast(d_); + auto l = self->GetAccountFlags(); + int i = 1; + for (const auto& e : l) { + t[i] = e; + i++; + } + } + + return t; +} + Lua_Group Lua_Client::GetGroup() { Lua_Safe_Call_Class(Lua_Group); return self->GetGroup(); @@ -2831,7 +2851,7 @@ luabind::object Lua_Client::GetPEQZoneFlags(lua_State* L) { if (d_) { auto self = reinterpret_cast(d_); auto l = self->GetPEQZoneFlags(); - auto i = 1; + int i = 1; for (const auto& f : l) { t[i] = f; i++; @@ -2846,7 +2866,7 @@ luabind::object Lua_Client::GetZoneFlags(lua_State* L) { if (d_) { auto self = reinterpret_cast(d_); auto l = self->GetZoneFlags(); - auto i = 1; + int i = 1; for (const auto& f : l) { t[i] = f; i++; @@ -3060,6 +3080,18 @@ uint32 Lua_Client::GetEXPForLevel(uint16 check_level) return self->GetEXPForLevel(check_level); } +std::string Lua_Client::GetClassAbbreviation() +{ + Lua_Safe_Call_String(); + return GetPlayerClassAbbreviation(self->GetBaseClass()); +} + +std::string Lua_Client::GetRaceAbbreviation() +{ + Lua_Safe_Call_String(); + return GetPlayerRaceAbbreviation(self->GetBaseRace()); +} + luabind::scope lua_register_client() { return luabind::class_("Client") .def(luabind::constructor<>()) @@ -3124,6 +3156,7 @@ luabind::scope lua_register_client() { .def("CheckIncreaseSkill", (void(Lua_Client::*)(int,Lua_Mob,int))&Lua_Client::CheckIncreaseSkill) .def("CheckSpecializeIncrease", (void(Lua_Client::*)(int))&Lua_Client::CheckSpecializeIncrease) .def("ClearCompassMark",(void(Lua_Client::*)(void))&Lua_Client::ClearCompassMark) + .def("ClearAccountFlag", (void(Lua_Client::*)(const std::string&))&Lua_Client::ClearAccountFlag) .def("ClearPEQZoneFlag", (void(Lua_Client::*)(uint32))&Lua_Client::ClearPEQZoneFlag) .def("ClearZoneFlag", (void(Lua_Client::*)(uint32))&Lua_Client::ClearZoneFlag) .def("Connected", (bool(Lua_Client::*)(void))&Lua_Client::Connected) @@ -3178,8 +3211,9 @@ luabind::scope lua_register_client() { .def("GetAAPoints", (int(Lua_Client::*)(void))&Lua_Client::GetAAPoints) .def("GetAFK", (int(Lua_Client::*)(void))&Lua_Client::GetAFK) .def("GetAccountAge", (int(Lua_Client::*)(void))&Lua_Client::GetAccountAge) - .def("GetAccountFlag", (std::string(Lua_Client::*)(std::string))&Lua_Client::GetAccountFlag) - .def("GetAggroCount", (int(Lua_Client::*)(void))&Lua_Client::GetAggroCount) + .def("GetAccountFlag", (std::string(Lua_Client::*)(const std::string&))&Lua_Client::GetAccountFlag) + .def("GetAccountFlags", (luabind::object(Lua_Client::*)(lua_State*))&Lua_Client::GetAccountFlags) + .def("GetAggroCount", (uint32(Lua_Client::*)(void))&Lua_Client::GetAggroCount) .def("GetAllMoney", (uint64(Lua_Client::*)(void))&Lua_Client::GetAllMoney) .def("GetAlternateCurrencyValue", (int(Lua_Client::*)(uint32))&Lua_Client::GetAlternateCurrencyValue) .def("GetAnon", (int(Lua_Client::*)(void))&Lua_Client::GetAnon) @@ -3212,6 +3246,7 @@ luabind::scope lua_register_client() { .def("GetCarriedMoney", (uint64(Lua_Client::*)(void))&Lua_Client::GetCarriedMoney) .def("GetCarriedPlatinum", (uint32(Lua_Client::*)(void))&Lua_Client::GetCarriedPlatinum) .def("GetCharacterFactionLevel", (int(Lua_Client::*)(int))&Lua_Client::GetCharacterFactionLevel) + .def("GetClassAbbreviation", (std::string(Lua_Client::*)(void))&Lua_Client::GetClassAbbreviation) .def("GetClassBitmask", (int(Lua_Client::*)(void))&Lua_Client::GetClassBitmask) .def("GetClientMaxLevel", (int(Lua_Client::*)(void))&Lua_Client::GetClientMaxLevel) .def("GetClientVersion", (int(Lua_Client::*)(void))&Lua_Client::GetClientVersion) @@ -3278,6 +3313,7 @@ luabind::scope lua_register_client() { .def("GetRadiantCrystals", (uint32(Lua_Client::*)(void))&Lua_Client::GetRadiantCrystals) .def("GetRaid", (Lua_Raid(Lua_Client::*)(void))&Lua_Client::GetRaid) .def("GetRaidPoints", (uint32(Lua_Client::*)(void))&Lua_Client::GetRaidPoints) + .def("GetRaceAbbreviation", (std::string(Lua_Client::*)(void))&Lua_Client::GetRaceAbbreviation) .def("GetRawItemAC", (int(Lua_Client::*)(void))&Lua_Client::GetRawItemAC) .def("GetRawSkill", (int(Lua_Client::*)(int))&Lua_Client::GetRawSkill) .def("GetRecipeMadeCount", (int(Lua_Client::*)(uint32))&Lua_Client::GetRecipeMadeCount) @@ -3456,8 +3492,7 @@ luabind::scope lua_register_client() { .def("SetAATitle", (void(Lua_Client::*)(std::string))&Lua_Client::SetAATitle) .def("SetAATitle", (void(Lua_Client::*)(std::string,bool))&Lua_Client::SetAATitle) .def("SetAFK", (void(Lua_Client::*)(uint8))&Lua_Client::SetAFK) - .def("SetAccountFlag", (void(Lua_Client::*)(std::string,std::string))&Lua_Client::SetAccountFlag) - .def("SetAccountFlag", (void(Lua_Client::*)(std::string,std::string))&Lua_Client::SetAccountFlag) + .def("SetAccountFlag", (void(Lua_Client::*)(const std::string&,const std::string&))&Lua_Client::SetAccountFlag) .def("SetAlternateCurrencyValue", (void(Lua_Client::*)(uint32,int))&Lua_Client::SetAlternateCurrencyValue) .def("SetAnon", (void(Lua_Client::*)(uint8))&Lua_Client::SetAnon) .def("SetBaseClass", (void(Lua_Client::*)(int))&Lua_Client::SetBaseClass) diff --git a/zone/lua_client.h b/zone/lua_client.h index 569a3124d..3bc385f57 100644 --- a/zone/lua_client.h +++ b/zone/lua_client.h @@ -367,7 +367,7 @@ public: void AssignToInstance(int instance_id); void Freeze(); void UnFreeze(); - int GetAggroCount(); + uint32 GetAggroCount(); uint64 GetCarriedMoney(); uint32 GetCarriedPlatinum(); uint64 GetAllMoney(); @@ -380,8 +380,10 @@ public: int GetAlternateCurrencyValue(uint32 currency); void SendWebLink(const char *site); bool HasSpellScribed(int spell_id); - void SetAccountFlag(std::string flag, std::string val); - std::string GetAccountFlag(std::string flag); + void ClearAccountFlag(const std::string& flag); + void SetAccountFlag(const std::string& flag, const std::string& value); + std::string GetAccountFlag(const std::string& flag); + luabind::object GetAccountFlags(lua_State* L); int GetAccountAge(); Lua_Group GetGroup(); Lua_Raid GetRaid(); @@ -469,6 +471,8 @@ public: bool IsAutoAttackEnabled(); bool IsAutoFireEnabled(); uint32 GetEXPForLevel(uint16 check_level); + std::string GetClassAbbreviation(); + std::string GetRaceAbbreviation(); void ApplySpell(int spell_id); void ApplySpell(int spell_id, int duration); diff --git a/zone/lua_entity_list.cpp b/zone/lua_entity_list.cpp index 0b9438fd3..1a334fc99 100644 --- a/zone/lua_entity_list.cpp +++ b/zone/lua_entity_list.cpp @@ -635,6 +635,62 @@ Lua_Bot Lua_EntityList::GetRandomBot(float x, float y, float z, float distance, return self->GetRandomBot(glm::vec3(x, y, z), distance, exclude_bot); } +Lua_Mob_List Lua_EntityList::GetCloseMobList(Lua_Mob mob) { + Lua_Safe_Call_Class(Lua_Mob_List); + + Lua_Mob_List ret; + + const auto& l = self->GetCloseMobList(mob); + + ret.entries.reserve(l.size()); + + for (const auto& e : l) { + ret.entries.emplace_back(Lua_Mob(e.second)); + } + + return ret; +} + +Lua_Mob_List Lua_EntityList::GetCloseMobList(Lua_Mob mob, float distance) { + Lua_Safe_Call_Class(Lua_Mob_List); + + Lua_Mob_List ret; + + const auto& l = self->GetCloseMobList(mob); + + ret.entries.reserve(l.size()); + + for (const auto& e : l) { + if (mob.CalculateDistance(e.second) <= distance) { + ret.entries.emplace_back(Lua_Mob(e.second)); + } + } + + return ret; +} + +Lua_Mob_List Lua_EntityList::GetCloseMobList(Lua_Mob mob, float distance, bool ignore_self) { + Lua_Safe_Call_Class(Lua_Mob_List); + + Lua_Mob_List ret; + + const auto& l = self->GetCloseMobList(mob); + + ret.entries.reserve(l.size()); + + for (const auto& e : l) { + if (ignore_self && e.second == mob) { + continue; + } + + if (mob.CalculateDistance(e.second) <= distance) { + ret.entries.emplace_back(Lua_Mob(e.second)); + } + } + + return ret; +} + luabind::scope lua_register_entity_list() { return luabind::class_("EntityList") .def(luabind::constructor<>()) @@ -665,6 +721,8 @@ luabind::scope lua_register_entity_list() { .def("GetClientByName", (Lua_Client(Lua_EntityList::*)(const char*))&Lua_EntityList::GetClientByName) .def("GetClientByWID", (Lua_Client(Lua_EntityList::*)(uint32))&Lua_EntityList::GetClientByWID) .def("GetClientList", (Lua_Client_List(Lua_EntityList::*)(void))&Lua_EntityList::GetClientList) + .def("GetCloseMobList", (Lua_Mob_List(Lua_EntityList::*)(Lua_Mob))&Lua_EntityList::GetCloseMobList) + .def("GetCloseMobList", (Lua_Mob_List(Lua_EntityList::*)(Lua_Mob,float))&Lua_EntityList::GetCloseMobList) .def("GetCorpseByID", (Lua_Corpse(Lua_EntityList::*)(int))&Lua_EntityList::GetCorpseByID) .def("GetCorpseByName", (Lua_Corpse(Lua_EntityList::*)(const char*))&Lua_EntityList::GetCorpseByName) .def("GetCorpseByOwner", (Lua_Corpse(Lua_EntityList::*)(Lua_Client))&Lua_EntityList::GetCorpseByOwner) diff --git a/zone/lua_entity_list.h b/zone/lua_entity_list.h index 11dac40a9..b20019ecb 100644 --- a/zone/lua_entity_list.h +++ b/zone/lua_entity_list.h @@ -139,6 +139,9 @@ public: void SignalAllBotsByOwnerName(std::string owner_name, int signal_id); void SignalBotByBotID(uint32 bot_id, int signal_id); void SignalBotByBotName(std::string bot_name, int signal_id); + Lua_Mob_List GetCloseMobList(Lua_Mob mob); + Lua_Mob_List GetCloseMobList(Lua_Mob mob, float distance); + Lua_Mob_List GetCloseMobList(Lua_Mob mob, float distance, bool ignore_self); }; #endif diff --git a/zone/lua_hate_list.cpp b/zone/lua_hate_list.cpp index 9adb9afdd..4ca52a5b1 100644 --- a/zone/lua_hate_list.cpp +++ b/zone/lua_hate_list.cpp @@ -37,8 +37,8 @@ void Lua_HateEntry::SetHate(int64 value) { self->stored_hate_amount = value; } -int Lua_HateEntry::GetFrenzy() { - Lua_Safe_Call_Int(); +bool Lua_HateEntry::GetFrenzy() { + Lua_Safe_Call_Bool(); return self->is_entity_frenzy; } diff --git a/zone/lua_hate_list.h b/zone/lua_hate_list.h index 2a9bb4818..036bd775a 100644 --- a/zone/lua_hate_list.h +++ b/zone/lua_hate_list.h @@ -24,7 +24,7 @@ public: void SetDamage(int64 value); int64 GetHate(); void SetHate(int64 value); - int GetFrenzy(); + bool GetFrenzy(); void SetFrenzy(bool value); }; diff --git a/zone/lua_item.cpp b/zone/lua_item.cpp index ac4f8a871..514c062d0 100644 --- a/zone/lua_item.cpp +++ b/zone/lua_item.cpp @@ -475,34 +475,34 @@ uint32 Lua_Item::GetAugType() { return self->AugType; } -int Lua_Item::GetAugSlotType(int i) { +int Lua_Item::GetAugSlotType(uint8 slot_id) { Lua_Safe_Call_Int(); - if(i >= 5 || i < 0) { + if (!EQ::ValueWithin(slot_id, EQ::invaug::SOCKET_BEGIN, EQ::invaug::SOCKET_END)) { return 0; } - return self->AugSlotType[i]; + return self->AugSlotType[slot_id]; } -int Lua_Item::GetAugSlotVisible(int i) { +int Lua_Item::GetAugSlotVisible(uint8 slot_id) { Lua_Safe_Call_Int(); - if(i >= 5 || i < 0) { + if (!EQ::ValueWithin(slot_id, EQ::invaug::SOCKET_BEGIN, EQ::invaug::SOCKET_END)) { return 0; } - return self->AugSlotVisible[i]; + return self->AugSlotVisible[slot_id]; } -int Lua_Item::GetAugSlotUnk2(int i) { +int Lua_Item::GetAugSlotUnk2(uint8 slot_id) { Lua_Safe_Call_Int(); - if(i >= 5 || i < 0) { + if (!EQ::ValueWithin(slot_id, EQ::invaug::SOCKET_BEGIN, EQ::invaug::SOCKET_END)) { return 0; } - return self->AugSlotUnk2[i]; + return self->AugSlotUnk2[slot_id]; } uint32 Lua_Item::GetLDoNTheme() { diff --git a/zone/lua_item.h b/zone/lua_item.h index ec7e33dac..2b1ef1112 100644 --- a/zone/lua_item.h +++ b/zone/lua_item.h @@ -121,9 +121,9 @@ public: int GetFactionAmt4(); const char *GetCharmFile(); uint32 GetAugType(); - int GetAugSlotType(int i); - int GetAugSlotVisible(int i); - int GetAugSlotUnk2(int i); + int GetAugSlotType(uint8 slot_id); + int GetAugSlotVisible(uint8 slot_id); + int GetAugSlotUnk2(uint8 slot_id); uint32 GetLDoNTheme(); uint32 GetLDoNPrice(); uint32 GetLDoNSold(); diff --git a/zone/lua_iteminst.cpp b/zone/lua_iteminst.cpp index 105e634b9..f4effac39 100644 --- a/zone/lua_iteminst.cpp +++ b/zone/lua_iteminst.cpp @@ -3,6 +3,7 @@ #include #include +#include "../common/languages.h" #include "masterentity.h" #include "lua_iteminst.h" #include "lua_item.h" @@ -55,12 +56,12 @@ bool Lua_ItemInst::IsStackable() { return self->IsStackable(); } -bool Lua_ItemInst::IsEquipable(int race, int class_) { +bool Lua_ItemInst::IsEquipable(uint16 race_bitmask, uint16 class_bitmask) { Lua_Safe_Call_Bool(); - return self->IsEquipable(race, class_); + return self->IsEquipable(race_bitmask, class_bitmask); } -bool Lua_ItemInst::IsEquipable(int slot_id) { +bool Lua_ItemInst::IsEquipable(int16 slot_id) { Lua_Safe_Call_Bool(); return self->IsEquipable(slot_id); } @@ -80,9 +81,9 @@ bool Lua_ItemInst::IsExpendable() { return self->IsExpendable(); } -Lua_ItemInst Lua_ItemInst::GetItem(int slot) { +Lua_ItemInst Lua_ItemInst::GetItem(uint8 slot_id) { Lua_Safe_Call_Class(Lua_ItemInst); - return Lua_ItemInst(self->GetItem(slot)); + return Lua_ItemInst(self->GetItem(slot_id)); } Lua_Item Lua_ItemInst::GetItem() { @@ -90,29 +91,29 @@ Lua_Item Lua_ItemInst::GetItem() { return Lua_Item(self->GetItem()); } -Lua_Item Lua_ItemInst::GetUnscaledItem(int slot) { +Lua_Item Lua_ItemInst::GetUnscaledItem() { Lua_Safe_Call_Class(Lua_Item); return self->GetUnscaledItem(); } -uint32 Lua_ItemInst::GetItemID(int slot) { +uint32 Lua_ItemInst::GetItemID(uint8 slot_id) { Lua_Safe_Call_Int(); - return self->GetItemID(slot); + return self->GetItemID(slot_id); } -int Lua_ItemInst::GetTotalItemCount() { +uint8 Lua_ItemInst::GetTotalItemCount() { Lua_Safe_Call_Int(); return self->GetTotalItemCount(); } -Lua_ItemInst Lua_ItemInst::GetAugment(int slot) { +Lua_ItemInst Lua_ItemInst::GetAugment(uint8 slot_id) { Lua_Safe_Call_Class(Lua_ItemInst); - return self->GetAugment(slot); + return self->GetAugment(slot_id); } -uint32 Lua_ItemInst::GetAugmentItemID(int slot) { +uint32 Lua_ItemInst::GetAugmentItemID(uint8 slot_id) { Lua_Safe_Call_Int(); - return self->GetAugmentItemID(slot); + return self->GetAugmentItemID(slot_id); } bool Lua_ItemInst::IsAugmented() { @@ -175,11 +176,21 @@ bool Lua_ItemInst::IsInstNoDrop() { return self->IsAttuned(); } +bool Lua_ItemInst::IsAttuned() { + Lua_Safe_Call_Bool(); + return self->IsAttuned(); +} + void Lua_ItemInst::SetInstNoDrop(bool flag) { Lua_Safe_Call_Void(); return self->SetAttuned(flag); } +void Lua_ItemInst::SetAttuned(bool flag) { + Lua_Safe_Call_Void(); + return self->SetAttuned(flag); +} + std::string Lua_ItemInst::GetCustomDataString() { Lua_Safe_Call_String(); return self->GetCustomDataString(); @@ -240,12 +251,12 @@ void Lua_ItemInst::AddExp(uint32 exp) { self->AddExp(exp); } -int Lua_ItemInst::GetMaxEvolveLvl() { +int8 Lua_ItemInst::GetMaxEvolveLvl() { Lua_Safe_Call_Int(); return self->GetMaxEvolveLvl(); } -uint32 Lua_ItemInst::GetKillsNeeded(int current_level) { +uint32 Lua_ItemInst::GetKillsNeeded(uint8 current_level) { Lua_Safe_Call_Int(); return self->GetKillsNeeded(current_level); } @@ -290,6 +301,23 @@ int Lua_ItemInst::RemoveTaskDeliveredItems() { return self->RemoveTaskDeliveredItems(); } +std::string Lua_ItemInst::GetName() { + Lua_Safe_Call_String(); + return self->GetItem()->Name; +} + +void Lua_ItemInst::ItemSay(const char* text) // @categories Inventory and Items +{ + Lua_Safe_Call_Void(); + quest_manager.GetInitiator()->ChannelMessageSend(self->GetItem()->Name, 0, ChatChannel_Say, LANG_COMMON_TONGUE, MAX_LANGUAGE_SKILL, text); +} + +void Lua_ItemInst::ItemSay(const char* text, uint8 language_id) // @categories Inventory and Items +{ + Lua_Safe_Call_Void(); + quest_manager.GetInitiator()->ChannelMessageSend(self->GetItem()->Name, 0, ChatChannel_Say, language_id, MAX_LANGUAGE_SKILL, text); +} + luabind::scope lua_register_iteminst() { return luabind::class_("ItemInst") .def(luabind::constructor<>()) @@ -313,26 +341,31 @@ luabind::scope lua_register_iteminst() { .def("GetExp", (uint32(Lua_ItemInst::*)(void))&Lua_ItemInst::GetExp) .def("GetID", (uint32(Lua_ItemInst::*)(void))&Lua_ItemInst::GetID) .def("GetItem", (Lua_Item(Lua_ItemInst::*)(void))&Lua_ItemInst::GetItem) - .def("GetItem", (Lua_ItemInst(Lua_ItemInst::*)(int))&Lua_ItemInst::GetItem) + .def("GetItem", (Lua_ItemInst(Lua_ItemInst::*)(uint8))&Lua_ItemInst::GetItem) .def("GetItemID", (uint32(Lua_ItemInst::*)(int))&Lua_ItemInst::GetItemID) .def("GetItemScriptID", (uint32(Lua_ItemInst::*)(void))&Lua_ItemInst::GetItemScriptID) .def("GetKillsNeeded", (uint32(Lua_ItemInst::*)(int))&Lua_ItemInst::GetKillsNeeded) .def("GetMaxEvolveLvl", (int(Lua_ItemInst::*)(void))&Lua_ItemInst::GetMaxEvolveLvl) + .def("GetName", (std::string(Lua_ItemInst::*)(void))&Lua_ItemInst::GetName) .def("GetPrice", (uint32(Lua_ItemInst::*)(void))&Lua_ItemInst::GetPrice) .def("GetTaskDeliveredCount", &Lua_ItemInst::GetTaskDeliveredCount) - .def("GetTotalItemCount", (int(Lua_ItemInst::*)(void))&Lua_ItemInst::GetTotalItemCount) + .def("GetTotalItemCount", (uint8(Lua_ItemInst::*)(void))&Lua_ItemInst::GetTotalItemCount) .def("GetUnscaledItem", (Lua_ItemInst(Lua_ItemInst::*)(int))&Lua_ItemInst::GetUnscaledItem) .def("IsAmmo", (bool(Lua_ItemInst::*)(void))&Lua_ItemInst::IsAmmo) + .def("IsAttuned", (bool(Lua_ItemInst::*)(void))&Lua_ItemInst::IsAttuned) .def("IsAugmentable", (bool(Lua_ItemInst::*)(void))&Lua_ItemInst::IsAugmentable) .def("IsAugmented", (bool(Lua_ItemInst::*)(void))&Lua_ItemInst::IsAugmented) - .def("IsEquipable", (bool(Lua_ItemInst::*)(int))&Lua_ItemInst::IsEquipable) - .def("IsEquipable", (bool(Lua_ItemInst::*)(int,int))&Lua_ItemInst::IsEquipable) + .def("IsEquipable", (bool(Lua_ItemInst::*)(int16))&Lua_ItemInst::IsEquipable) + .def("IsEquipable", (bool(Lua_ItemInst::*)(uint16,uint16))&Lua_ItemInst::IsEquipable) .def("IsExpendable", (bool(Lua_ItemInst::*)(void))&Lua_ItemInst::IsExpendable) .def("IsInstNoDrop", (bool(Lua_ItemInst::*)(void))&Lua_ItemInst::IsInstNoDrop) .def("IsStackable", (bool(Lua_ItemInst::*)(void))&Lua_ItemInst::IsStackable) .def("IsType", (bool(Lua_ItemInst::*)(int))&Lua_ItemInst::IsType) .def("IsWeapon", (bool(Lua_ItemInst::*)(void))&Lua_ItemInst::IsWeapon) + .def("ItemSay", (void(Lua_ItemInst::*)(const char*))&Lua_ItemInst::ItemSay) + .def("ItemSay", (void(Lua_ItemInst::*)(const char*, uint8))&Lua_ItemInst::ItemSay) .def("RemoveTaskDeliveredItems", &Lua_ItemInst::RemoveTaskDeliveredItems) + .def("SetAttuned", (void(Lua_ItemInst::*)(bool))&Lua_ItemInst::SetAttuned) .def("SetCharges", (void(Lua_ItemInst::*)(int))&Lua_ItemInst::SetCharges) .def("SetColor", (void(Lua_ItemInst::*)(uint32))&Lua_ItemInst::SetColor) .def("SetCustomData", (void(Lua_ItemInst::*)(const std::string&,bool))&Lua_ItemInst::SetCustomData) diff --git a/zone/lua_iteminst.h b/zone/lua_iteminst.h index bf5bd1853..f120fbc14 100644 --- a/zone/lua_iteminst.h +++ b/zone/lua_iteminst.h @@ -37,19 +37,18 @@ public: bool IsType(int item_class); bool IsStackable(); - bool IsEquipable(int race, int class_); - bool IsEquipable(int slot_id); + bool IsEquipable(uint16 race_bitmask, uint16 class_bitmask); + bool IsEquipable(int16 slot_id); bool IsAugmentable(); int GetAugmentType(); bool IsExpendable(); - Lua_ItemInst GetItem(int slot); + Lua_ItemInst GetItem(uint8 slot_id); Lua_Item GetItem(); - void SetItem(Lua_Item item); - Lua_Item GetUnscaledItem(int slot); - uint32 GetItemID(int slot); - int GetTotalItemCount(); - Lua_ItemInst GetAugment(int slot); - uint32 GetAugmentItemID(int slot); + Lua_Item GetUnscaledItem(); + uint32 GetItemID(uint8 slot_id); + uint8 GetTotalItemCount(); + Lua_ItemInst GetAugment(uint8 slot_id); + uint32 GetAugmentItemID(uint8 slot_id); bool IsAugmented(); bool IsWeapon(); bool IsAmmo(); @@ -62,7 +61,9 @@ public: void SetColor(uint32 color); uint32 GetColor(); bool IsInstNoDrop(); + bool IsAttuned(); void SetInstNoDrop(bool flag); + void SetAttuned(bool flag); std::string GetCustomDataString(); void SetCustomData(const std::string &identifier, const std::string &value); void SetCustomData(const std::string &identifier, int value); @@ -75,8 +76,8 @@ public: uint32 GetExp(); void SetExp(uint32 exp); void AddExp(uint32 exp); - int GetMaxEvolveLvl(); - uint32 GetKillsNeeded(int current_level); + int8 GetMaxEvolveLvl(); + uint32 GetKillsNeeded(uint8 current_level); Lua_ItemInst Clone(); void SetTimer(std::string name, uint32 time); void StopTimer(std::string name); @@ -85,6 +86,9 @@ public: int CountAugmentByID(uint32 item_id); int GetTaskDeliveredCount(); int RemoveTaskDeliveredItems(); + std::string GetName(); + void ItemSay(const char* text); + void ItemSay(const char* text, uint8 language_id); private: bool cloned_; diff --git a/zone/lua_mob.cpp b/zone/lua_mob.cpp index 121948e89..d707ee2eb 100644 --- a/zone/lua_mob.cpp +++ b/zone/lua_mob.cpp @@ -18,6 +18,10 @@ struct SpecialAbilities { }; +struct Lua_Mob_List { + std::vector entries; +}; + const char *Lua_Mob::GetName() { Lua_Safe_Call_String(); return self->GetName(); @@ -1265,6 +1269,11 @@ float Lua_Mob::CalculateDistance(double x, double y, double z) { return self->CalculateDistance(static_cast(x), static_cast(y), static_cast(z)); } +float Lua_Mob::CalculateDistance(Lua_Mob mob) { + Lua_Safe_Call_Real(); + return self->CalculateDistance(mob); +} + void Lua_Mob::SendTo(double x, double y, double z) { Lua_Safe_Call_Void(); self->SendTo(static_cast(x), static_cast(y), static_cast(z)); @@ -2744,7 +2753,7 @@ luabind::object Lua_Mob::GetEntityVariables(lua_State* L) { if (d_) { auto self = reinterpret_cast(d_); auto l = self->GetEntityVariables(); - auto i = 1; + int i = 1; for (const auto& v : l) { t[i] = v; i++; @@ -3035,7 +3044,7 @@ luabind::object Lua_Mob::GetBuffSpellIDs(lua_State* L) { if (d_) { auto self = reinterpret_cast(d_); auto l = self->GetBuffSpellIDs(); - auto i = 1; + int i = 1; for (const auto& v : l) { t[i] = v; i++; @@ -3050,6 +3059,74 @@ bool Lua_Mob::HasSpellEffect(int effect_id) { return self->HasSpellEffect(effect_id); } +Lua_Mob_List Lua_Mob::GetCloseMobList() { + Lua_Safe_Call_Class(Lua_Mob_List); + + Lua_Mob_List ret; + + const auto& l = entity_list.GetCloseMobList(self); + + ret.entries.reserve(l.size()); + + for (const auto& e : l) { + ret.entries.emplace_back(Lua_Mob(e.second)); + } + + return ret; +} + +Lua_Mob_List Lua_Mob::GetCloseMobList(float distance) { + Lua_Safe_Call_Class(Lua_Mob_List); + + Lua_Mob_List ret; + + const auto& l = entity_list.GetCloseMobList(self); + + ret.entries.reserve(l.size()); + + for (const auto& e : l) { + if (self->CalculateDistance(e.second) <= distance) { + ret.entries.emplace_back(Lua_Mob(e.second)); + } + } + + return ret; +} + +Lua_Mob_List Lua_Mob::GetCloseMobList(float distance, bool ignore_self) { + Lua_Safe_Call_Class(Lua_Mob_List); + + Lua_Mob_List ret; + + const auto& l = entity_list.GetCloseMobList(self); + + ret.entries.reserve(l.size()); + + for (const auto& e : l) { + if (ignore_self && e.second == self) { + continue; + } + + if (self->CalculateDistance(e.second) <= distance) { + ret.entries.emplace_back(Lua_Mob(e.second)); + } + } + + return ret; +} + +std::string Lua_Mob::GetClassPlural() +{ + Lua_Safe_Call_String(); + return self->GetClassPlural(); +} + +std::string Lua_Mob::GetRacePlural() +{ + Lua_Safe_Call_String(); + return self->GetRacePlural(); +} + luabind::scope lua_register_mob() { return luabind::class_("Mob") .def(luabind::constructor<>()) @@ -3083,6 +3160,7 @@ luabind::scope lua_register_mob() { .def("BuffFadeBySlot", (void(Lua_Mob::*)(int,bool))&Lua_Mob::BuffFadeBySlot) .def("BuffFadeBySpellID", (void(Lua_Mob::*)(int))&Lua_Mob::BuffFadeBySpellID) .def("CalculateDistance", (float(Lua_Mob::*)(double,double,double))&Lua_Mob::CalculateDistance) + .def("CalculateDistance", (float(Lua_Mob::*)(Lua_Mob))&Lua_Mob::CalculateDistance) .def("CalculateHeadingToTarget", (double(Lua_Mob::*)(double,double))&Lua_Mob::CalculateHeadingToTarget) .def("CameraEffect", (void(Lua_Mob::*)(uint32,float))&Lua_Mob::CameraEffect) .def("CameraEffect", (void(Lua_Mob::*)(uint32,float,Lua_Client))&Lua_Mob::CameraEffect) @@ -3257,7 +3335,11 @@ luabind::scope lua_register_mob() { .def("GetCasterLevel", &Lua_Mob::GetCasterLevel) .def("GetClass", &Lua_Mob::GetClass) .def("GetClassName", &Lua_Mob::GetClassName) + .def("GetClassPlural", &Lua_Mob::GetClassPlural) .def("GetCleanName", &Lua_Mob::GetCleanName) + .def("GetCloseMobList", (Lua_Mob_List(Lua_Mob::*)(void))&Lua_Mob::GetCloseMobList) + .def("GetCloseMobList", (Lua_Mob_List(Lua_Mob::*)(float))&Lua_Mob::GetCloseMobList) + .def("GetCloseMobList", (Lua_Mob_List(Lua_Mob::*)(float,bool))&Lua_Mob::GetCloseMobList) .def("GetCorruption", &Lua_Mob::GetCorruption) .def("GetDEX", &Lua_Mob::GetDEX) .def("GetDR", &Lua_Mob::GetDR) @@ -3357,6 +3439,7 @@ luabind::scope lua_register_mob() { .def("GetPhR", &Lua_Mob::GetPhR) .def("GetRace", &Lua_Mob::GetRace) .def("GetRaceName", &Lua_Mob::GetRaceName) + .def("GetRacePlural", &Lua_Mob::GetRacePlural) .def("GetRemainingTimeMS", &Lua_Mob::GetRemainingTimeMS) .def("GetResist", (int(Lua_Mob::*)(int))&Lua_Mob::GetResist) .def("GetReverseFactionCon", (int(Lua_Mob::*)(Lua_Mob))&Lua_Mob::GetReverseFactionCon) diff --git a/zone/lua_mob.h b/zone/lua_mob.h index 954717869..0d5a5e1d0 100644 --- a/zone/lua_mob.h +++ b/zone/lua_mob.h @@ -12,6 +12,7 @@ class Lua_StatBonuses; class Lua_Bot; class Lua_NPC; class Lua_Client; +struct Lua_Mob_List; namespace luabind { struct scope; @@ -287,6 +288,7 @@ public: void NavigateTo(double x, double y, double z); void StopNavigation(); float CalculateDistance(double x, double y, double z); + float CalculateDistance(Lua_Mob mob); void SendTo(double x, double y, double z); void SendToFixZ(double x, double y, double z); void NPCSpecialAttacks(const char *parse, int perm); @@ -549,6 +551,11 @@ public: void StopTimer(const char* timer_name); luabind::object GetBuffSpellIDs(lua_State* L); bool HasSpellEffect(int effect_id); + Lua_Mob_List GetCloseMobList(); + Lua_Mob_List GetCloseMobList(float distance); + Lua_Mob_List GetCloseMobList(float distance, bool ignore_self); + std::string GetClassPlural(); + std::string GetRacePlural(); }; #endif diff --git a/zone/lua_object.cpp b/zone/lua_object.cpp index 6ebae11f3..bed74f4eb 100644 --- a/zone/lua_object.cpp +++ b/zone/lua_object.cpp @@ -173,7 +173,7 @@ luabind::object Lua_Object::GetEntityVariables(lua_State* L) { if (d_) { auto self = reinterpret_cast(d_); auto l = self->GetEntityVariables(); - auto i = 1; + int i = 1; for (const auto& v : l) { t[i] = v; i++; diff --git a/zone/lua_parser.cpp b/zone/lua_parser.cpp index bcb8cf0e7..6d26e53a9 100644 --- a/zone/lua_parser.cpp +++ b/zone/lua_parser.cpp @@ -272,7 +272,7 @@ LuaParser::LuaParser() { PlayerArgumentDispatch[EVENT_EQUIP_ITEM_CLIENT] = handle_player_equip_item; PlayerArgumentDispatch[EVENT_UNEQUIP_ITEM_CLIENT] = handle_player_equip_item; PlayerArgumentDispatch[EVENT_SKILL_UP] = handle_player_skill_up; - PlayerArgumentDispatch[EVENT_LANGUAGE_SKILL_UP] = handle_player_skill_up; + PlayerArgumentDispatch[EVENT_LANGUAGE_SKILL_UP] = handle_player_language_skill_up; PlayerArgumentDispatch[EVENT_ALT_CURRENCY_MERCHANT_BUY] = handle_player_alt_currency_merchant; PlayerArgumentDispatch[EVENT_ALT_CURRENCY_MERCHANT_SELL] = handle_player_alt_currency_merchant; PlayerArgumentDispatch[EVENT_MERCHANT_BUY] = handle_player_merchant; diff --git a/zone/lua_parser_events.cpp b/zone/lua_parser_events.cpp index 9954f4aff..089201512 100644 --- a/zone/lua_parser_events.cpp +++ b/zone/lua_parser_events.cpp @@ -163,21 +163,6 @@ void handle_npc_single_client( lua_setfield(L, -2, "other"); } -void handle_npc_single_npc( - QuestInterface *parse, - lua_State* L, - NPC* npc, - Mob *init, - std::string data, - uint32 extra_data, - std::vector *extra_pointers -) { - Lua_NPC l_npc(reinterpret_cast(init)); - luabind::adl::object l_npc_o = luabind::adl::object(L, l_npc); - l_npc_o.push(L); - lua_setfield(L, -2, "other"); -} - void handle_npc_task_accepted( QuestInterface *parse, lua_State* L, diff --git a/zone/lua_parser_events.h b/zone/lua_parser_events.h index b48fa2f03..caca824d2 100644 --- a/zone/lua_parser_events.h +++ b/zone/lua_parser_events.h @@ -60,16 +60,6 @@ void handle_npc_single_client( std::vector *extra_pointers ); -void handle_npc_single_npc( - QuestInterface *parse, - lua_State* L, - NPC* npc, - Mob *init, - std::string data, - uint32 extra_data, - std::vector *extra_pointers -); - void handle_npc_task_accepted( QuestInterface *parse, lua_State* L, diff --git a/zone/merc.h b/zone/merc.h index 0c9983b5c..4b6f260fc 100644 --- a/zone/merc.h +++ b/zone/merc.h @@ -285,7 +285,6 @@ protected: private: int32 CalcAC(); - int32 GetACAvoid(); int32 CalcATK(); //int CalcHaste(); diff --git a/zone/mob.cpp b/zone/mob.cpp index e8220cf4b..8aa0a71a7 100644 --- a/zone/mob.cpp +++ b/zone/mob.cpp @@ -1269,7 +1269,7 @@ void Mob::FillSpawnStruct(NewSpawn_Struct* ns, Mob* ForWho) //for (i = 0; i < _MaterialCount; i++) for (i = 0; i < 9; i++) { // Only Player Races Wear Armor - if (Mob::IsPlayerRace(race) || i > 6) { + if (IsPlayerRace(race) || i > 6) { ns->spawn.equipment.Slot[i].Material = GetEquipmentMaterial(i); ns->spawn.equipment.Slot[i].EliteModel = IsEliteMaterialItem(i); ns->spawn.equipment.Slot[i].HerosForgeModel = GetHerosForgeModel(i); @@ -1627,13 +1627,1130 @@ void Mob::MakeSpawnUpdate(PlayerPositionUpdateServer_Struct* spu) { spu->delta_heading = FloatToEQ10(m_Delta.w); } -void Mob::ShowStats(Client* client) +void Mob::SendStatsWindow(Client* c, bool use_window) { + if (!IsOfClientBot()) { + return; + } + + const std::string& color_red = "red_1"; + const std::string& color_blue = "royal_blue"; + const std::string& color_green = "forest_green"; + const std::string& bright_green = "green"; + const std::string& bright_red = "red"; + const std::string& heroic_color = "gold"; + + // Health, Mana, and Endurance + std::string HME_row; + std::string hme_color; + std::string cur_field; + std::string total_field; + std::string cur_name; + std::string cur_color; + + auto hme_rows = 3; // Rows in display + + for (auto hme_row_counter = 0; hme_row_counter < hme_rows; hme_row_counter++) { + switch (hme_row_counter) { + case 0: { + cur_name = "Health "; + cur_field = Strings::Commify(GetHP()); + total_field = Strings::Commify(GetMaxHP()); + hme_color = color_red; + break; + } + case 1: { + if (CalcMaxMana()) { + cur_name = "Mana "; + cur_field = Strings::Commify(GetMana()); + total_field = Strings::Commify(GetMaxMana()); + hme_color = color_blue; + } else { + continue; + } + + break; + } + case 2: { + cur_name = "Endurance "; + cur_field = Strings::Commify(GetEndurance()); + total_field = Strings::Commify(GetMaxEndurance()); + hme_color = color_green; + break; + } + default: { + break; + } + } + + if (!cur_field.compare(total_field)) { + cur_color = bright_green; + } else { + cur_color = bright_red; + } + + HME_row += DialogueWindow::TableRow( + fmt::format( + "{}{}", + DialogueWindow::TableCell(DialogueWindow::ColorMessage(hme_color, cur_name)), + DialogueWindow::TableCell( + fmt::format( + "{} / {}", + DialogueWindow::ColorMessage(cur_color, cur_field), + DialogueWindow::ColorMessage(bright_green, total_field) + ) + ) + ) + ); + } + + // Regen + std::string regen_string; + std::string regen_row_header; + std::string regen_row_color; + std::string base_regen_field; + std::string item_regen_field; + std::string cap_regen_field; + std::string spell_regen_field; + std::string aa_regen_field; + std::string total_regen_field; + + auto regen_rows = 3; + + for (auto regen_row_counter = 0; regen_row_counter < regen_rows; regen_row_counter++) { + switch (regen_row_counter) { + case 0: { + regen_row_header = "Health"; + regen_row_color = color_red; + + if (IsBot()) { + base_regen_field = Strings::Commify(CastToBot()->LevelRegen()); + } else if (IsClient()) { + base_regen_field = Strings::Commify(CastToClient()->LevelRegen()); + } + + item_regen_field = Strings::Commify(itembonuses.HPRegen + itembonuses.heroic_hp_regen); + cap_regen_field = Strings::Commify(CalcHPRegenCap()); + spell_regen_field = Strings::Commify(spellbonuses.HPRegen); + aa_regen_field = Strings::Commify(aabonuses.HPRegen); + + if (IsBot()) { + total_regen_field = Strings::Commify(CastToBot()->CalcHPRegen()); + } else if (IsClient()) { + total_regen_field = Strings::Commify(CastToClient()->CalcHPRegen(true)); + } + + break; + } + case 1: { + if (GetMaxMana() > 0) { + regen_row_header = "Mana"; + regen_row_color = color_blue; + + if (IsBot()) { + base_regen_field = std::to_string(0); + } else if (IsClient()) { + base_regen_field = Strings::Commify(CastToClient()->CalcBaseManaRegen()); + } + + item_regen_field = Strings::Commify(itembonuses.ManaRegen + itembonuses.heroic_mana_regen); + cap_regen_field = Strings::Commify(CalcManaRegenCap()); + spell_regen_field = Strings::Commify(spellbonuses.ManaRegen); + aa_regen_field = Strings::Commify(aabonuses.ManaRegen); + + if (IsBot()) { + total_regen_field = Strings::Commify(CastToBot()->CalcManaRegen()); + } else if (IsClient()) { + total_regen_field = Strings::Commify(CastToClient()->CalcManaRegen(true)); + } + } else { + continue; + } + + break; + } + case 2: { + regen_row_header = "Endurance"; + regen_row_color = color_green; + + base_regen_field = Strings::Commify(((GetLevel() * 4 / 10) + 2)); + item_regen_field = Strings::Commify(itembonuses.EnduranceRegen + itembonuses.heroic_end_regen); + cap_regen_field = Strings::Commify(CalcEnduranceRegenCap()); + spell_regen_field = Strings::Commify(spellbonuses.EnduranceRegen); + aa_regen_field = Strings::Commify(aabonuses.EnduranceRegen); + + if (IsBot()) { + total_regen_field = Strings::Commify(CastToBot()->CalcEnduranceRegen()); + } else if (IsClient()) { + total_regen_field = Strings::Commify(CastToClient()->CalcEnduranceRegen(true)); + } + + break; + } + default: { + break; + } + } + + regen_string += DialogueWindow::TableRow( + DialogueWindow::TableCell(DialogueWindow::ColorMessage(regen_row_color, regen_row_header)) + + DialogueWindow::TableCell(DialogueWindow::ColorMessage(regen_row_color, base_regen_field)) + + DialogueWindow::TableCell(DialogueWindow::ColorMessage(regen_row_color, fmt::format("{} ({})", item_regen_field, cap_regen_field))) + + DialogueWindow::TableCell(DialogueWindow::ColorMessage(regen_row_color, spell_regen_field)) + + DialogueWindow::TableCell(DialogueWindow::ColorMessage(regen_row_color, aa_regen_field)) + + DialogueWindow::TableCell(DialogueWindow::ColorMessage(regen_row_color, total_regen_field)) + ); + } + + // Stats + std::string stat_table; + std::string a_stat; + std::string a_stat_name; + std::string h_stat; + std::string a_resist; + std::string a_resist_name; + std::string h_resist_field; + + auto stat_rows = 7; + + for (auto stat_row_counter = 0; stat_row_counter < stat_rows; stat_row_counter++) { + switch (stat_row_counter) { + case 0: { + a_stat_name = "Agility"; + a_resist_name = "Cold"; + + a_stat = Strings::Commify(GetAGI()); + h_stat = Strings::Commify(GetHeroicAGI()); + a_resist = Strings::Commify(GetCR()); + h_resist_field = Strings::Commify(GetHeroicCR()); + break; + } + case 1: { + a_stat_name = "Charisma"; + a_resist_name = "Corruption"; + + a_stat = Strings::Commify(GetCHA()); + h_stat = Strings::Commify(GetHeroicCHA()); + a_resist = Strings::Commify(GetCorrup()); + + if (IsBot()) { + h_resist_field = Strings::Commify(CastToBot()->GetHeroicCorrup()); + } else if (IsClient()) { + h_resist_field = Strings::Commify(CastToClient()->GetHeroicCorrup()); + } + + break; + } + case 2: { + a_stat_name = "Dexterity"; + a_resist_name = "Disease"; + + a_stat = Strings::Commify(GetDEX()); + h_stat = Strings::Commify(GetHeroicDEX()); + a_resist = Strings::Commify(GetDR()); + h_resist_field = Strings::Commify(GetHeroicDR()); + break; + } + case 3: { + a_stat_name = "Intelligence"; + a_resist_name = "Fire"; + + a_stat = Strings::Commify(GetINT()); + h_stat = Strings::Commify(GetHeroicINT()); + a_resist = Strings::Commify(GetFR()); + h_resist_field = Strings::Commify(GetHeroicFR()); + break; + } + case 4: { + a_stat_name = "Stamina"; + a_resist_name = "Magic"; + + a_stat = Strings::Commify(GetSTA()); + h_stat = Strings::Commify(GetHeroicSTA()); + a_resist = Strings::Commify(GetMR()); + h_resist_field = Strings::Commify(GetHeroicMR()); + break; + } + case 5: { + a_stat_name = "Strength"; + a_resist_name = "Physical"; + + a_stat = Strings::Commify(GetSTR()); + h_stat = Strings::Commify(GetHeroicSTR()); + a_resist = Strings::Commify(GetPhR()); + + if (IsBot()) { + h_resist_field = std::to_string(0); + } else if (IsClient()) { + h_resist_field = Strings::Commify(CastToClient()->GetHeroicPhR()); + } + + break; + } + case 6: { + a_stat_name = "Wisdom"; + a_resist_name = "Poison"; + + a_stat = Strings::Commify(GetWIS()); + h_stat = Strings::Commify(GetHeroicWIS()); + a_resist = Strings::Commify(GetPR()); + h_resist_field = Strings::Commify(GetHeroicPR()); + + break; + } + default: { + break; + } + } + + stat_table += DialogueWindow::TableRow( + DialogueWindow::TableCell(a_stat_name) + + DialogueWindow::TableCell( + fmt::format( + "{} {}", + a_stat, + DialogueWindow::ColorMessage(heroic_color, fmt::format("+{}", h_stat)) + ) + ) + + DialogueWindow::TableCell(a_resist_name) + + DialogueWindow::TableCell( + fmt::format( + "{} {}", + a_resist, + DialogueWindow::ColorMessage(heroic_color, fmt::format("+{}", h_resist_field)) + ) + ) + ); + } + + // Mod2 + std::string mod2_table; + std::string mod2a; + std::string mod2a_name; + std::string mod2a_cap; + std::string mod2b; + std::string mod2b_name; + std::string mod2b_cap; + + auto mod2_rows = 4; + + for (auto mod2_row_counter = 0; mod2_row_counter < mod2_rows; mod2_row_counter++) { + switch (mod2_row_counter) { + case 0: { + mod2a_name = "Avoidance"; + mod2b_name = "Combat Effects"; + mod2a_cap = Strings::Commify(RuleI(Character, ItemAvoidanceCap)); + mod2b_cap = Strings::Commify(RuleI(Character, ItemCombatEffectsCap)); + + if (IsBot()) { + mod2a = Strings::Commify(CastToBot()->GetAvoidance()); + } else if (IsClient()) { + mod2a = Strings::Commify(CastToClient()->GetAvoidance()); + } + + if (IsBot()) { + mod2b = Strings::Commify(CastToBot()->GetCombatEffects()); + } else if (IsClient()) { + mod2b = Strings::Commify(CastToClient()->GetCombatEffects()); + } + + break; + } + case 1: { + mod2a_name = "Accuracy"; + mod2b_name = "Strikethrough"; + mod2a_cap = Strings::Commify(RuleI(Character, ItemAccuracyCap)); + mod2b_cap = Strings::Commify(RuleI(Character, ItemStrikethroughCap)); + + if (IsBot()) { + mod2a = Strings::Commify(CastToBot()->GetAccuracy()); + } else if (IsClient()) { + mod2a = Strings::Commify(CastToClient()->GetAccuracy()); + } + + if (IsBot()) { + mod2b = Strings::Commify(CastToBot()->GetStrikeThrough()); + } else if (IsClient()) { + mod2b = Strings::Commify(CastToClient()->GetStrikeThrough()); + } + + break; + } + case 2: { + mod2a_name = "Shielding"; + mod2b_name = "Spell Shielding"; + mod2a_cap = Strings::Commify(RuleI(Character, ItemShieldingCap)); + mod2b_cap = Strings::Commify(RuleI(Character, ItemSpellShieldingCap)); + + if (IsBot()) { + mod2a = Strings::Commify(CastToBot()->GetShielding()); + } else if (IsClient()) { + mod2a = Strings::Commify(CastToClient()->GetShielding()); + } + + + if (IsBot()) { + mod2b = Strings::Commify(CastToBot()->GetSpellShield()); + } else if (IsClient()) { + mod2b = Strings::Commify(CastToClient()->GetSpellShield()); + } + + break; + } + case 3: { + mod2a_name = "Stun Resist"; + mod2b_name = "DOT Shielding"; + mod2a_cap = Strings::Commify(RuleI(Character, ItemStunResistCap)); + mod2b_cap = Strings::Commify(RuleI(Character, ItemDoTShieldingCap)); + + if (IsBot()) { + mod2a = Strings::Commify(CastToBot()->GetStunResist()); + } else if (IsClient()) { + mod2a = Strings::Commify(CastToClient()->GetStunResist()); + } + + if (IsBot()) { + mod2b = Strings::Commify(CastToBot()->GetDoTShield()); + } else if (IsClient()) { + mod2b = Strings::Commify(CastToClient()->GetDoTShield()); + } + + break; + } + } + + mod2_table += DialogueWindow::TableRow( + DialogueWindow::TableCell( + fmt::format( + "{}: {} / {}", + mod2a_name, + Strings::Commify(mod2a), + Strings::Commify(mod2a_cap) + ) + ) + + DialogueWindow::TableCell( + fmt::format( + "{}: {} / {}", + mod2b_name, + Strings::Commify(mod2b), + Strings::Commify(mod2b_cap) + ) + ) + ); + } + + uint32 rune_number = 0; + uint32 magic_rune_number = 0; + + for (auto i = 0; i < GetMaxTotalSlots(); i++) { + if (IsValidSpell(buffs[i].spellid)) { + if (buffs[i].melee_rune > 0) { + rune_number += buffs[i].melee_rune; + } + + if (buffs[i].magic_rune > 0) { + magic_rune_number += buffs[i].magic_rune; + } + } + } + + auto shield_ac = 0; + + if (IsBot()) { + CastToBot()->GetRawACNoShield(shield_ac); + } else if (IsClient()) { + CastToClient()->GetRawACNoShield(shield_ac); + } + + std::string skill_mods; + + for (auto j = 0; j <= EQ::skills::HIGHEST_SKILL; j++) { + if (itembonuses.skillmod[j] != 0) { + const std::string& sign = itembonuses.skillmod[j] >= 0 ? "+" : "-"; + + skill_mods += fmt::format( + "{}: {}{}%%{}", + EQ::skills::GetSkillName(static_cast(j)), + sign, + Strings::Commify(itembonuses.skillmod[j]), + DialogueWindow::Break(1) + ); + } + } + + std::string skill_dmgs; + + for (auto j = 0; j <= EQ::skills::HIGHEST_SKILL; j++) { + if ((itembonuses.SkillDamageAmount[j] + spellbonuses.SkillDamageAmount[j]) != 0) { + const std::string& sign = (itembonuses.SkillDamageAmount[j] + spellbonuses.SkillDamageAmount[j]) >= 0 ? "+" : "-"; + + skill_dmgs += fmt::format( + "{}: {}{}{}", + EQ::skills::GetSkillName(static_cast(j)), + sign, + Strings::Commify(itembonuses.SkillDamageAmount[j] + spellbonuses.SkillDamageAmount[j]), + DialogueWindow::Break(1) + ); + } + } + + std::string faction_item_string; + + for (const auto& f : item_faction_bonuses) { + if (f.second != 0) { + const auto &faction_name = content_db.GetFactionName(f.first); + const std::string& sign = f.second >= 0 ? "+" : "-"; + + faction_item_string += fmt::format( + "{}: {}{}{}", + !faction_name.empty() ? faction_name : "Unknown Faction", + sign, + Strings::Commify(f.second), + DialogueWindow::Break(1) + ); + } + } + + std::string bard_info; + + if (GetClass() == BARD) { + const auto brass_mod = IsBot() ? CastToBot()->GetBrassMod() : CastToClient()->GetBrassMod(); + const auto perc_mod = IsBot() ? CastToBot()->GetPercMod() : CastToClient()->GetPercMod(); + const auto sing_mod = IsBot() ? CastToBot()->GetSingMod() : CastToClient()->GetSingMod(); + const auto string_mod = IsBot() ? CastToBot()->GetStringMod() : CastToClient()->GetStringMod(); + const auto wind_mod = IsBot() ? CastToBot()->GetWindMod() : CastToClient()->GetWindMod(); + + if (brass_mod) { + bard_info += fmt::format( + "Brass: {}{}", + Strings::Commify(brass_mod), + DialogueWindow::Break(1) + ); + } + + if (perc_mod) { + bard_info += fmt::format( + "Percussion: {}{}", + Strings::Commify(perc_mod), + DialogueWindow::Break(1) + ); + } + + if (sing_mod) { + bard_info += fmt::format( + "Singing: {}{}", + Strings::Commify(sing_mod), + DialogueWindow::Break(1) + ); + } + + if (string_mod) { + bard_info += fmt::format( + "String: {}{}", + Strings::Commify(string_mod), + DialogueWindow::Break(1) + ); + } + + if (wind_mod) { + bard_info += fmt::format( + "Wind: {}{}", + Strings::Commify(wind_mod), + DialogueWindow::Break(1) + ); + } + } + + auto skill = EQ::skills::SkillHandtoHand; + auto *inst = GetInv().GetItem(EQ::invslot::slotPrimary); + + if (inst && inst->IsClassCommon()) { + switch (inst->GetItem()->ItemType) { + case EQ::item::ItemType1HSlash: + skill = EQ::skills::Skill1HSlashing; + break; + case EQ::item::ItemType2HSlash: + skill = EQ::skills::Skill2HSlashing; + break; + case EQ::item::ItemType1HPiercing: + skill = EQ::skills::Skill1HPiercing; + break; + case EQ::item::ItemType1HBlunt: + skill = EQ::skills::Skill1HBlunt; + break; + case EQ::item::ItemType2HBlunt: + skill = EQ::skills::Skill2HBlunt; + break; + case EQ::item::ItemType2HPiercing: + if (IsClient() && CastToClient()->ClientVersion() < EQ::versions::ClientVersion::RoF2) { + skill = EQ::skills::Skill1HPiercing; + } else { + skill = EQ::skills::Skill2HPiercing; + } + + break; + default: + break; + } + } + + std::string final_string; + + // Class, Level, and Race + final_string += DialogueWindow::Table( + DialogueWindow::TableRow( + DialogueWindow::TableCell(fmt::format("Race: {}", GetPlayerRaceAbbreviation(GetBaseRace()))) + + DialogueWindow::TableCell(fmt::format("Class: {}", GetPlayerClassAbbreviation(GetClass()))) + + DialogueWindow::TableCell(fmt::format("Level: {}", std::to_string(GetLevel()))) + ) + ); + + // Runes + if (rune_number || magic_rune_number) { + final_string += DialogueWindow::Table( + DialogueWindow::TableRow( + DialogueWindow::TableCell( + fmt::format("Rune: {}", rune_number) + ) + + DialogueWindow::TableCell("") + + DialogueWindow::TableCell( + fmt::format("Spell Rune: {}", magic_rune_number) + ) + ) + ); + + final_string += DialogueWindow::Break(1); + } + + // Health, Mana, and Endurance + final_string += DialogueWindow::Table(HME_row); + + // Attack + final_string += DialogueWindow::ColorMessage( + "green_yellow", + fmt::format( + "To Hit: {} / {}", + Strings::Commify(compute_tohit(skill)), + Strings::Commify(GetTotalToHit(skill, 0)) + ) + ); + + final_string += DialogueWindow::Break(1); + + // Attack 2 + final_string += fmt::format( + "Offense: {}{} | {}{}", + Strings::Commify(offense(skill)), + ( + itembonuses.ATK ? + fmt::format( + " | Item: {} / {} | Used: {}", + Strings::Commify(itembonuses.ATK), + Strings::Commify(RuleI(Character, ItemATKCap)), + Strings::Commify(static_cast(itembonuses.ATK * 1.342)) + ) : + "" + ), + spellbonuses.ATK ? fmt::format(" | Spell: {}", Strings::Commify(spellbonuses.ATK)) : "", + DialogueWindow::Break(1) + ); + + // Armor Class + final_string += fmt::format( + "{}{}", + DialogueWindow::ColorMessage( + "green_yellow", + fmt::format( + "Mitigation AC: {}", + Strings::Commify(GetMitigationAC()) + ) + ), + DialogueWindow::Break(1) + ); + + // Armor Class 2 + final_string += fmt::format( + "Defense: {} / {}{}{}{}", + Strings::Commify(compute_defense()), + Strings::Commify(GetTotalDefense()), + spellbonuses.AC ? fmt::format(" | Spell: {}", Strings::Commify(spellbonuses.AC)) : "", + shield_ac ? fmt::format(" | Shield: {}", Strings::Commify(shield_ac)) : "", + DialogueWindow::Break(1) + ); + + // Run Speed + final_string += fmt::format( + "{}{}", + DialogueWindow::ColorMessage( + "green_yellow", + fmt::format( + "Runspeed: {}", + IsBot() ? CastToBot()->GetRunspeed() : CastToClient()->GetRunspeed() + ) + ), + DialogueWindow::Break(1) + ); + + final_string += DialogueWindow::CenterMessage("Haste"); + + // Haste Table + const auto& haste_table = DialogueWindow::Table( + fmt::format( + "{}{}", + DialogueWindow::TableRow( + DialogueWindow::TableCell("Item") + + DialogueWindow::TableCell("Spell") + + DialogueWindow::TableCell("Over") + + DialogueWindow::TableCell("Total (Cap)") + ), + DialogueWindow::TableRow( + DialogueWindow::TableCell(Strings::Commify(itembonuses.haste)) + + DialogueWindow::TableCell(Strings::Commify(spellbonuses.haste + spellbonuses.hastetype2)) + + DialogueWindow::TableCell(Strings::Commify(spellbonuses.hastetype3 + ExtraHaste)) + + DialogueWindow::TableCell( + fmt::format( + "{} ({})", + Strings::Commify(GetHaste()), + Strings::Commify(RuleI(Character, HasteCap)) + ) + ) + ) + ) + ); + + final_string += haste_table; + + // Regen Table + final_string += DialogueWindow::CenterMessage("Regen"); + + const auto& regen_table = DialogueWindow::Table( + DialogueWindow::TableRow( + DialogueWindow::TableCell("Type") + + DialogueWindow::TableCell("Base") + + DialogueWindow::TableCell("Items (Cap)") + + DialogueWindow::TableCell("Spell") + + DialogueWindow::TableCell("AAs") + + DialogueWindow::TableCell("Total") + ) + + regen_string + ); + + // Regen + final_string += regen_table + DialogueWindow::Break(1); + + // Stats + final_string += DialogueWindow::Table(stat_table) + DialogueWindow::Break(1); + + // Mod 2 + final_string += DialogueWindow::Table(mod2_table) + DialogueWindow::Break(1); + + // Heal Amount + if (GetHealAmt()) { + final_string += fmt::format( + "Heal Amount: {} / {}{}", + Strings::Commify(GetHealAmt()), + Strings::Commify(RuleI(Character, ItemHealAmtCap)), + DialogueWindow::Break(1) + ); + } + + // Heal Amount + if (GetSpellDmg()) { + final_string += fmt::format( + "Spell Damage: {} / {}{}", + Strings::Commify(GetSpellDmg()), + Strings::Commify(RuleI(Character, ItemSpellDmgCap)), + DialogueWindow::Break(1) + ); + } + + // Damage Shield + if (itembonuses.DamageShield || spellbonuses.DamageShield) { + final_string += fmt::format( + "Damage Shield: {}{}{}{}", + Strings::Commify(itembonuses.DamageShield + spellbonuses.DamageShield), + ( + spellbonuses.DamageShield ? + fmt::format(" | Spell: {}", Strings::Commify(spellbonuses.DamageShield)) : + "" + ), + ( + itembonuses.DamageShield ? + fmt::format( + " | Item: {} / {}", + Strings::Commify(itembonuses.DamageShield), + Strings::Commify(RuleI(Character, ItemDamageShieldCap)) + ) : + "" + ), + DialogueWindow::Break(2) + ); + } + + // Clairvoyance + const auto clairvoyance = IsBot() ? CastToBot()->GetClair() : CastToClient()->GetClair(); + if (clairvoyance) { + final_string += fmt::format( + "Clairvoyance: {} / {}{}", + Strings::Commify(clairvoyance), + Strings::Commify(RuleI(Character, ItemClairvoyanceCap)), + DialogueWindow::Break(1) + ); + } + + // Damage Shield Mitigation + const auto ds_mitigation = IsBot() ? CastToBot()->GetDSMit() : CastToClient()->GetDSMit(); + if (ds_mitigation) { + final_string += fmt::format( + "DS Mitigation: {} / {}{}", + Strings::Commify(ds_mitigation), + Strings::Commify(RuleI(Character, ItemDSMitigationCap)), + DialogueWindow::Break(1) + ); + } + + if (clairvoyance || ds_mitigation) { + final_string += DialogueWindow::Break(1); + } + + // Bard Modifiers + if (GetClass() == BARD) { + final_string += bard_info + DialogueWindow::Break(1); + } + + // Skill Modifiers + if (!skill_mods.empty()) { + final_string += skill_mods + DialogueWindow::Break(1); + } + + // Skill Damage Modifiers + if (!skill_dmgs.empty()) { + final_string += skill_dmgs + DialogueWindow::Break(1); + } + + // Faction Modifiers + if (!faction_item_string.empty()) { + final_string += faction_item_string; + } + + if (use_window) { + if (final_string.size() < 4096) { + const uint32 popup_buttons = (c->ClientVersion() < EQ::versions::ClientVersion::SoD) ? 0 : 1; + c->SendWindow( + 0, + POPUPID_UPDATE_SHOWSTATSWINDOW, + popup_buttons, + "Close", + "Update", + 0, + 1, + this, + "", + final_string.c_str() + ); + + goto extra_info; + } else { + c->Message(Chat::Yellow, "The window has exceeded its character limit, displaying stats to chat window:"); + } + } + + c->Message( + Chat::White, + fmt::format( + "Statistics Information for {} {}", + GetCleanName(), + GetLastName() + ).c_str() + ); + + c->Message( + Chat::White, + fmt::format( + "Level: {} Class: {} ({}) Race: {} ({}) Damage Shield: {}/{} Size: {:.1f} Run Speed: {} Weight: {:.1f}/{}", + GetLevel(), + GetClassIDName(GetClass()), + GetClass(), + GetRaceIDName(GetRace()), + GetRace(), + IsBot() ? Strings::Commify(CastToBot()->GetDS()) : Strings::Commify(CastToClient()->GetDS()), + Strings::Commify(RuleI(Character, ItemDamageShieldCap)), + GetSize(), + GetRunspeed(), + IsBot() ? static_cast(CastToBot()->CalcCurrentWeight()) / 10.0f : static_cast(CastToClient()->CalcCurrentWeight()) / 10.0f, + Strings::Commify(GetSTR()) + ).c_str() + ); + + c->Message( + Chat::White, + fmt::format( + "Health: {}/{} Regen: {}/{}", + GetHP(), + GetMaxHP(), + IsBot() ? Strings::Commify(CastToBot()->CalcHPRegen()) : Strings::Commify(CastToClient()->CalcHPRegen()), + CalcHPRegenCap() + ).c_str() + ); + + c->Message( + Chat::White, + fmt::format( + "To Hit: {} Total: {}", + Strings::Commify(compute_tohit(skill)), + Strings::Commify(GetTotalToHit(skill, 0)) + ).c_str() + ); + + c->Message( + Chat::White, + fmt::format( + "Defense: {} Total: {}", + Strings::Commify(compute_defense()), + Strings::Commify(GetTotalDefense()) + ).c_str() + ); + + c->Message( + Chat::White, + fmt::format( + "Offense: {} Mitigation AC: {}", + Strings::Commify(offense(skill)), + Strings::Commify(GetMitigationAC()) + ).c_str() + ); + if (IsClient()) { - CastToClient()->SendStatsWindow(client, RuleB(Character, UseNewStatsWindow)); + c->Message( + Chat::White, + fmt::format( + " AFK: {} LFG: {} Anon: {} PVP: {} GM: {} Fly Mode: {} ({}) GM Speed: {} Hide Me: {} Invulnerability: {} LD: {} Client Version: {} Tells Off: {}", + CastToClient()->AFK ? "Yes" : "No", + CastToClient()->LFG ? "Yes" : "No", + CastToClient()->GetAnon() ? "Yes" : "No", + CastToClient()->GetPVP() ? "Yes" : "No", + CastToClient()->GetGM() ? "On" : "Off", + EQ::constants::GetFlyModeName(static_cast(flymode)), + flymode, + CastToClient()->GetGMSpeed() ? "On" : "Off", + CastToClient()->GetHideMe() ? "On" : "Off", + CastToClient()->GetGMInvul() ? "On" : "Off", + CastToClient()->IsLD() ? "Yes" : "No", + CastToClient()->ClientVersionBit(), + CastToClient()->tellsoff ? "Yes" : "No" + ).c_str() + ); + } + + if (CalcMaxMana()) { + c->Message( + Chat::White, + fmt::format( + "Mana: {}/{} Regen: {}/{}", + Strings::Commify(GetMana()), + Strings::Commify(GetMaxMana()), + IsBot() ? Strings::Commify(CastToBot()->CalcManaRegen()) : Strings::Commify(CastToClient()->CalcManaRegen()), + Strings::Commify(CalcManaRegenCap()) + ).c_str() + ); + } + + c->Message( + Chat::White, + fmt::format( + "Endurance: {}/{} Regen: {}/{}", + Strings::Commify(GetEndurance()), + Strings::Commify(GetMaxEndurance()), + IsBot() ? Strings::Commify(CastToBot()->CalcEnduranceRegen()) : Strings::Commify(CastToClient()->CalcEnduranceRegen(true)), + Strings::Commify(CalcEnduranceRegenCap()) + ).c_str() + ); + + c->Message( + Chat::White, + fmt::format( + "Attack: {} Item and Spell Attack: {}/{} Server Side Attack: {}", + IsBot() ? Strings::Commify(CastToBot()->GetTotalATK()) : Strings::Commify(CastToClient()->GetTotalATK()), + Strings::Commify(GetATKBonus()), + Strings::Commify(RuleI(Character, ItemATKCap)), + Strings::Commify(GetATK()) + ).c_str() + ); + + if (GetHaste()) { + c->Message( + Chat::White, + fmt::format( + "Haste: {}/{} (Item: {} + Spell: {} + Over: {})", + Strings::Commify(GetHaste()), + Strings::Commify(RuleI(Character, HasteCap)), + Strings::Commify(itembonuses.haste), + Strings::Commify(spellbonuses.haste + spellbonuses.hastetype2), + Strings::Commify(spellbonuses.hastetype3 + ExtraHaste) + ).c_str() + ); + } + + c->Message( + Chat::White, + fmt::format( + "Statistics | Agility: {} Charisma: {} Dexterity: {} Intelligence: {} Stamina: {} Strength: {} Wisdom: {}", + Strings::Commify(GetAGI()), + Strings::Commify(GetCHA()), + Strings::Commify(GetDEX()), + Strings::Commify(GetINT()), + Strings::Commify(GetSTA()), + Strings::Commify(GetSTR()), + Strings::Commify(GetWIS()) + ).c_str() + ); + + c->Message( + Chat::White, + fmt::format( + "Heroic Statistics | Agility: {} Charisma: {} Dexterity: {} Intelligence: {} Stamina: {} Strength: {} Wisdom: {}", + Strings::Commify(GetHeroicAGI()), + Strings::Commify(GetHeroicCHA()), + Strings::Commify(GetHeroicDEX()), + Strings::Commify(GetHeroicINT()), + Strings::Commify(GetHeroicSTA()), + Strings::Commify(GetHeroicSTR()), + Strings::Commify(GetHeroicWIS()) + ).c_str() + ); + + c->Message( + Chat::White, + fmt::format( + "Resistances | Cold: {} Corruption: {} Disease: {} Fire: {} Magic: {} Poison: {} Physical: {}", + Strings::Commify(GetCR()), + Strings::Commify(GetCorrup()), + Strings::Commify(GetDR()), + Strings::Commify(GetFR()), + Strings::Commify(GetMR()), + Strings::Commify(GetPR()), + Strings::Commify(GetPhR()) + ).c_str() + ); + + c->Message( + Chat::White, + fmt::format( + "Heroic Resistances | Cold: {} Corruption: {} Disease: {} Fire: {} Magic: {} Poison: {}", + GetHeroicCR(), + IsBot() ? Strings::Commify(CastToBot()->GetHeroicCorrup()) : Strings::Commify(CastToClient()->GetHeroicCorrup()), + GetHeroicDR(), + GetHeroicFR(), + GetHeroicMR(), + GetHeroicPR() + ).c_str() + ); + + c->Message( + Chat::White, + fmt::format( + "Accuracy: {} Avoidance: {} Combat Effects: {} DOT Shielding: {} Shielding: {} Spell Shield: {} Strikethrough: {} Stun Resist: {}", + IsBot() ? Strings::Commify(CastToBot()->GetAccuracy()) : Strings::Commify(CastToClient()->GetAccuracy()), + IsBot() ? Strings::Commify(CastToBot()->GetAvoidance()) : Strings::Commify(CastToClient()->GetAvoidance()), + IsBot() ? Strings::Commify(CastToBot()->GetCombatEffects()) : Strings::Commify(CastToClient()->GetCombatEffects()), + IsBot() ? Strings::Commify(CastToBot()->GetDoTShield()) : Strings::Commify(CastToClient()->GetDoTShield()), + IsBot() ? Strings::Commify(CastToBot()->GetShielding()) : Strings::Commify(CastToClient()->GetShielding()), + IsBot() ? Strings::Commify(CastToBot()->GetSpellShield()) : Strings::Commify(CastToClient()->GetSpellShield()), + IsBot() ? Strings::Commify(CastToBot()->GetStrikeThrough()) : Strings::Commify(CastToClient()->GetStrikeThrough()), + IsBot() ? Strings::Commify(CastToBot()->GetStunResist()) : Strings::Commify(CastToClient()->GetStunResist()) + ).c_str() + ); + + if (GetHealAmt() || GetSpellDmg()) { + c->Message( + Chat::White, + fmt::format( + "Heal Amount: {} Spell Damage: {}", + Strings::Commify(GetHealAmt()), + Strings::Commify(GetSpellDmg()) + ).c_str() + ); + } + + if (clairvoyance || ds_mitigation) { + c->Message( + Chat::White, + fmt::format( + "Clairvoyance: {} Damage Shield Mitigation: {}", + Strings::Commify(clairvoyance), + Strings::Commify(ds_mitigation) + ).c_str() + ); + } + + if (GetClass() == BARD) { + const auto brass_mod = IsBot() ? CastToBot()->GetBrassMod() : CastToClient()->GetBrassMod(); + const auto perc_mod = IsBot() ? CastToBot()->GetPercMod() : CastToClient()->GetPercMod(); + const auto sing_mod = IsBot() ? CastToBot()->GetSingMod() : CastToClient()->GetSingMod(); + const auto string_mod = IsBot() ? CastToBot()->GetStringMod() : CastToClient()->GetStringMod(); + const auto wind_mod = IsBot() ? CastToBot()->GetWindMod() : CastToClient()->GetWindMod(); + + if ( + brass_mod || + perc_mod || + sing_mod || + string_mod || + wind_mod + ) { + c->Message( + Chat::White, + fmt::format( + "Brass: {} Percussion: {} Singing: {} String: {} Wind: {}", + Strings::Commify(brass_mod), + Strings::Commify(perc_mod), + Strings::Commify(sing_mod), + Strings::Commify(string_mod), + Strings::Commify(wind_mod) + ).c_str() + ); + } + } + + extra_info: + + c->Message( + Chat::White, + fmt::format( + "Base Race: {} ({}) Gender: {} ({}) Base Gender: {} ({}) Texture: {} Helmet Texture: {}", + GetRaceIDName(GetBaseRace()), + GetBaseRace(), + GetGenderName(GetGender()), + GetGender(), + GetGenderName(GetBaseGender()), + GetBaseGender(), + GetTexture(), + GetHelmTexture() + ).c_str() + ); + + if (c->Admin() >= AccountStatus::GMAdmin) { + c->Message( + Chat::White, + fmt::format( + "ID: {} Entity ID: {} Pet ID: {} Owner ID: {} AI Controlled: {} Targeted: {}", + IsBot() ? CastToBot()->GetBotID() : CastToClient()->CharacterID(), + GetID(), + GetPetID(), + GetOwnerID(), + IsAIControlled() ? "Yes" : "No", + targeted + ).c_str() + ); + } +} + +void Mob::ShowStats(Client* c) +{ + if (IsOfClientBot()) { + SendStatsWindow(c, RuleB(Character, UseNewStatsWindow)); } else if (IsCorpse()) { if (IsPlayerCorpse()) { - client->Message( + c->Message( Chat::White, fmt::format( "Player Corpse | Character ID: {} ID: {}", @@ -1642,7 +2759,7 @@ void Mob::ShowStats(Client* client) ).c_str() ); } else { - client->Message( + c->Message( Chat::White, fmt::format( "NPC Corpse | ID: {}", @@ -1651,24 +2768,26 @@ void Mob::ShowStats(Client* client) ); } } else { - NPC* target = CastToNPC(); - std::string target_name = target->GetCleanName(); - std::string target_last_name = target->GetLastName(); - bool has_charmed_stats = ( - target->GetCharmedAccuracy() != 0 || - target->GetCharmedArmorClass() != 0 || - target->GetCharmedAttack() != 0 || - target->GetCharmedAttackDelay() != 0 || - target->GetCharmedAvoidance() != 0 || - target->GetCharmedMaxDamage() != 0 || - target->GetCharmedMinDamage() != 0 + const auto& t = CastToNPC(); + + const std::string target_name = t->GetCleanName(); + const std::string target_last_name = t->GetLastName(); + + const auto has_charmed_stats = ( + t->GetCharmedAccuracy() != 0 || + t->GetCharmedArmorClass() != 0 || + t->GetCharmedAttack() != 0 || + t->GetCharmedAttackDelay() != 0 || + t->GetCharmedAvoidance() != 0 || + t->GetCharmedMaxDamage() != 0 || + t->GetCharmedMinDamage() != 0 ); // Faction - if (target->GetNPCFactionID()) { - auto faction_id = target->GetPrimaryFaction(); + if (t->GetNPCFactionID()) { + auto faction_id = t->GetPrimaryFaction(); auto faction_name = content_db.GetFactionName(faction_id); - client->Message( + c->Message( Chat::White, fmt::format( "Faction: {} ({})", @@ -1679,147 +2798,148 @@ void Mob::ShowStats(Client* client) } // Adventure Template - if (target->GetAdventureTemplate()) { - client->Message( + if (t->GetAdventureTemplate()) { + c->Message( Chat::White, fmt::format( "Adventure Template: {}", - target->GetAdventureTemplate() + t->GetAdventureTemplate() ).c_str() ); } // Body - auto bodytype_name = EQ::constants::GetBodyTypeName(target->GetBodyType()); - client->Message( + auto bodytype_name = EQ::constants::GetBodyTypeName(t->GetBodyType()); + c->Message( Chat::White, fmt::format( "Body | Size: {:.2f} Type: {}", - target->GetSize(), + t->GetSize(), ( bodytype_name.empty() ? fmt::format( "{}", - target->GetBodyType() + t->GetBodyType() ) : fmt::format( "{} ({})", bodytype_name, - target->GetBodyType() + t->GetBodyType() ) ) ).c_str() ); // Face - client->Message( + c->Message( Chat::White, fmt::format( "Features | Face: {} Eye One: {} Eye Two: {}", - target->GetLuclinFace(), - target->GetEyeColor1(), - target->GetEyeColor2() + t->GetLuclinFace(), + t->GetEyeColor1(), + t->GetEyeColor2() ).c_str() ); // Hair - client->Message( + c->Message( Chat::White, fmt::format( "Features | Hair: {} Hair Color: {}", - target->GetHairStyle(), - target->GetHairColor() + t->GetHairStyle(), + t->GetHairColor() ).c_str() ); // Beard - client->Message( + c->Message( Chat::White, fmt::format( "Features | Beard: {} Beard Color: {}", - target->GetBeard(), - target->GetBeardColor() + t->GetBeard(), + t->GetBeardColor() ).c_str() ); // Drakkin Features - if (target->GetRace() == RACE_DRAKKIN_522) { - client->Message( + if (t->GetRace() == RACE_DRAKKIN_522) { + c->Message( Chat::White, fmt::format( "Drakkin Features | Heritage: {} Tattoo: {} Details: {}", - target->GetDrakkinHeritage(), - target->GetDrakkinTattoo(), - target->GetDrakkinDetails() + t->GetDrakkinHeritage(), + t->GetDrakkinTattoo(), + t->GetDrakkinDetails() ).c_str() ); } // Textures - client->Message( + c->Message( Chat::White, fmt::format( "Textures | Armor: {} Helmet: {}", - target->GetTexture(), - target->GetHelmTexture() + t->GetTexture(), + t->GetHelmTexture() ).c_str() ); if ( - target->GetArmTexture() || - target->GetBracerTexture() || - target->GetHandTexture() + t->GetArmTexture() || + t->GetBracerTexture() || + t->GetHandTexture() ) { - client->Message( + c->Message( Chat::White, fmt::format( "Textures | Arms: {} Bracers: {} Hands: {}", - target->GetArmTexture(), - target->GetBracerTexture(), - target->GetHandTexture() + t->GetArmTexture(), + t->GetBracerTexture(), + t->GetHandTexture() ).c_str() ); } if ( - target->GetFeetTexture() || - target->GetLegTexture() + t->GetFeetTexture() || + t->GetLegTexture() ) { - client->Message( + c->Message( Chat::White, fmt::format( "Textures | Legs: {} Feet: {}", - target->GetLegTexture(), - target->GetFeetTexture() + t->GetLegTexture(), + t->GetFeetTexture() ).c_str() ); } // Hero's Forge - if (target->GetHeroForgeModel()) { - client->Message( + if (t->GetHeroForgeModel()) { + c->Message( Chat::White, fmt::format( "Hero's Forge: {}", - target->GetHeroForgeModel() + t->GetHeroForgeModel() ).c_str() ); } // Owner Data - if (target->GetOwner()) { - auto owner_name = target->GetOwner()->GetCleanName(); + if (t->GetOwner()) { + const auto& o = t->GetOwner(); + auto owner_name = o->GetCleanName(); auto owner_type = ( - target->GetOwner()->IsNPC() ? + o->IsNPC() ? "NPC" : ( - target->GetOwner()->IsClient() ? + o->IsClient() ? "Client" : "Other" ) ); - auto owner_id = target->GetOwnerID(); - client->Message( + auto owner_id = t->GetOwnerID(); + c->Message( Chat::White, fmt::format( "Owner | Name: {} ({}) Type: {}", @@ -1831,10 +2951,10 @@ void Mob::ShowStats(Client* client) } // Pet Data - if (target->GetPet()) { - auto pet_name = target->GetPet()->GetCleanName(); - auto pet_id = target->GetPetID(); - client->Message( + if (t->GetPet()) { + auto pet_name = t->GetPet()->GetCleanName(); + auto pet_id = t->GetPetID(); + c->Message( Chat::White, fmt::format( "Pet | Name: {} ({})", @@ -1845,128 +2965,128 @@ void Mob::ShowStats(Client* client) } // Merchant Data - if (target->MerchantType) { - client->Message( + if (t->MerchantType) { + c->Message( Chat::White, fmt::format( "Merchant | ID: {} Currency Type: {}", - target->MerchantType, - target->GetAltCurrencyType() + t->MerchantType, + t->GetAltCurrencyType() ).c_str() ); } // Spell Data - if (target->AI_HasSpells() || target->AI_HasSpellsEffects()) { - client->Message( + if (t->AI_HasSpells() || t->AI_HasSpellsEffects()) { + c->Message( Chat::White, fmt::format( "Spells | ID: {} Effects ID: {}", - target->GetNPCSpellsID(), - target->GetNPCSpellsEffectsID() + t->GetNPCSpellsID(), + t->GetNPCSpellsEffectsID() ).c_str() ); } // Health - client->Message( + c->Message( Chat::White, fmt::format( "Health: {}/{} ({:.2f}%) Regen: {}", - target->GetHP(), - target->GetMaxHP(), - target->GetHPRatio(), - target->GetHPRegen() + t->GetHP(), + t->GetMaxHP(), + t->GetHPRatio(), + t->GetHPRegen() ).c_str() ); // Mana - if (target->GetMaxMana() > 0) { - client->Message( + if (t->GetMaxMana() > 0) { + c->Message( Chat::White, fmt::format( "Mana: {}/{} ({:.2f}%) Regen: {}", - target->GetMana(), - target->GetMaxMana(), - target->GetManaRatio(), - target->GetManaRegen() + t->GetMana(), + t->GetMaxMana(), + t->GetManaRatio(), + t->GetManaRegen() ).c_str() ); } // Damage - client->Message( + c->Message( Chat::White, fmt::format( "Damage | Min: {} Max: {}", - target->GetMinDMG(), - target->GetMaxDMG() + t->GetMinDMG(), + t->GetMaxDMG() ).c_str() ); // Attack Count / Delay - client->Message( + c->Message( Chat::White, fmt::format( "Attack | Count: {} Delay: {}", - target->GetNumberOfAttacks(), - target->GetAttackDelay() + t->GetNumberOfAttacks(), + t->GetAttackDelay() ).c_str() ); // Weapon Textures - client->Message( + c->Message( Chat::White, fmt::format( "Weapon Textures | Primary: {} Secondary: {} Ammo: {}", - target->GetEquipmentMaterial(EQ::textures::weaponPrimary), - target->GetEquipmentMaterial(EQ::textures::weaponSecondary), - target->GetAmmoIDfile() + t->GetEquipmentMaterial(EQ::textures::weaponPrimary), + t->GetEquipmentMaterial(EQ::textures::weaponSecondary), + t->GetAmmoIDfile() ).c_str() ); // Weapon Types - client->Message( + c->Message( Chat::White, fmt::format( "Weapon Types | Primary: {} ({}) Secondary: {} ({})", - EQ::skills::GetSkillName(static_cast(target->GetPrimSkill())), - target->GetPrimSkill(), - EQ::skills::GetSkillName(static_cast(target->GetSecSkill())), - target->GetSecSkill() + EQ::skills::GetSkillName(static_cast(t->GetPrimSkill())), + t->GetPrimSkill(), + EQ::skills::GetSkillName(static_cast(t->GetSecSkill())), + t->GetSecSkill() ).c_str() ); - client->Message( + c->Message( Chat::White, fmt::format( "Weapon Types | Ranged: {} ({})", - EQ::skills::GetSkillName(static_cast(target->GetRangedSkill())), - target->GetRangedSkill() + EQ::skills::GetSkillName(static_cast(t->GetRangedSkill())), + t->GetRangedSkill() ).c_str() ); // Combat Stats - client->Message( + c->Message( Chat::White, fmt::format( "Combat Stats | Accuracy: {} Armor Class: {} Attack: {}", - target->GetAccuracyRating(), - target->GetAC(), - target->GetATK() + t->GetAccuracyRating(), + t->GetAC(), + t->GetATK() ).c_str() ); - client->Message( + c->Message( Chat::White, fmt::format( "Combat Stats | Avoidance: {} Slow Mitigation: {}", - target->GetAvoidanceRating(), - target->GetSlowMitigation() + t->GetAvoidanceRating(), + t->GetSlowMitigation() ).c_str() ); - client->Message( + c->Message( Chat::White, fmt::format( "Combat Stats | To Hit: {} Total To Hit: {}", @@ -1975,7 +3095,7 @@ void Mob::ShowStats(Client* client) ).c_str() ); - client->Message( + c->Message( Chat::White, fmt::format( "Combat Stats | Defense: {} Total Defense: {}", @@ -1984,7 +3104,7 @@ void Mob::ShowStats(Client* client) ).c_str() ); - client->Message( + c->Message( Chat::White, fmt::format( "Combat Stats | Offense: {} Mitigation Armor Class: {}", @@ -1994,302 +3114,302 @@ void Mob::ShowStats(Client* client) ); // Stats - client->Message( + c->Message( Chat::White, fmt::format( "Stats | Agility: {} Charisma: {} Dexterity: {} Intelligence: {}", - target->GetAGI(), - target->GetCHA(), - target->GetDEX(), - target->GetINT() + t->GetAGI(), + t->GetCHA(), + t->GetDEX(), + t->GetINT() ).c_str() ); - client->Message( + c->Message( Chat::White, fmt::format( "Stats | Stamina: {} Strength: {} Wisdom: {}", - target->GetSTA(), - target->GetSTR(), - target->GetWIS() + t->GetSTA(), + t->GetSTR(), + t->GetWIS() ).c_str() ); // Charmed Stats if (has_charmed_stats) { - client->Message( + c->Message( Chat::White, fmt::format( "Charmed Stats | Attack: {} Attack Delay: {}", - target->GetCharmedAttack(), - target->GetCharmedAttackDelay() + t->GetCharmedAttack(), + t->GetCharmedAttackDelay() ).c_str() ); - client->Message( + c->Message( Chat::White, fmt::format( "Charmed Stats | Accuracy: {} Avoidance: {}", - target->GetCharmedAccuracy(), - target->GetCharmedAvoidance() + t->GetCharmedAccuracy(), + t->GetCharmedAvoidance() ).c_str() ); - client->Message( + c->Message( Chat::White, fmt::format( "Charmed Stats | Min Damage: {} Max Damage: {}", - target->GetCharmedMinDamage(), - target->GetCharmedMaxDamage() + t->GetCharmedMinDamage(), + t->GetCharmedMaxDamage() ).c_str() ); } // Resists - client->Message( + c->Message( Chat::White, fmt::format( "Resists | Cold: {} Disease: {} Fire: {} Magic: {}", - target->GetCR(), - target->GetDR(), - target->GetFR(), - target->GetMR() + t->GetCR(), + t->GetDR(), + t->GetFR(), + t->GetMR() ).c_str() ); - client->Message( + c->Message( Chat::White, fmt::format( "Resists | Poison: {} Corruption: {} Physical: {}", - target->GetPR(), - target->GetCorrup(), - target->GetPhR() + t->GetPR(), + t->GetCorrup(), + t->GetPhR() ).c_str() ); // Scaling - client->Message( + c->Message( Chat::White, fmt::format( "Scaling | Heal: {} Spell: {}", - target->GetHealScale(), - target->GetSpellScale() + t->GetHealScale(), + t->GetSpellScale() ).c_str() ); // See Invisible / Invisible vs. Undead / Hide / Improved Hide - client->Message( + c->Message( Chat::White, fmt::format( "Can See | Invisible: {} Invisible vs. Undead: {}", - target->SeeInvisible() ? "Yes" : "No", - target->SeeInvisibleUndead() ? "Yes" : "No" + t->SeeInvisible() ? "Yes" : "No", + t->SeeInvisibleUndead() ? "Yes" : "No" ).c_str() ); - client->Message( + c->Message( Chat::White, fmt::format( "Can See | Hide: {} Improved Hide: {}", - target->SeeHide() ? "Yes" : "No", - target->SeeImprovedHide() ? "Yes" : "No" + t->SeeHide() ? "Yes" : "No", + t->SeeImprovedHide() ? "Yes" : "No" ).c_str() ); // Aggro / Assist Radius - client->Message( + c->Message( Chat::White, fmt::format( "Radius | Aggro: {} Assist: {}", - target->GetAggroRange(), - target->GetAssistRange() + t->GetAggroRange(), + t->GetAssistRange() ).c_str() ); // Emote - if (target->GetEmoteID()) { - client->Message( + if (t->GetEmoteID()) { + c->Message( Chat::White, fmt::format( "Emote: {}", - target->GetEmoteID() + t->GetEmoteID() ).c_str() ); } // Run/Walk Speed - client->Message( + c->Message( Chat::White, fmt::format( "Speed | Run: {} Walk: {}", - target->GetRunspeed(), - target->GetWalkspeed() + t->GetRunspeed(), + t->GetWalkspeed() ).c_str() ); // Position - client->Message( + c->Message( Chat::White, fmt::format( "Position | {}, {}, {}, {}", - target->GetX(), - target->GetY(), - target->GetZ(), - target->GetHeading() + t->GetX(), + t->GetY(), + t->GetZ(), + t->GetHeading() ).c_str() ); // Experience Modifier - client->Message( + c->Message( Chat::White, fmt::format( "Experience Modifier: {}", - target->GetKillExpMod() + t->GetKillExpMod() ).c_str() ); // Quest Globals - client->Message( + c->Message( Chat::White, fmt::format( "Quest Globals: {}", - target->qglobal ? "Enabled" : "Disabled" + t->qglobal ? "Enabled" : "Disabled" ).c_str() ); // Proximity - if (target->IsProximitySet()) { - client->Message( + if (t->IsProximitySet()) { + c->Message( Chat::White, fmt::format( "Proximity | Say: {}", - target->proximity->say ? "Enabled" : "Disabled" + t->proximity->say ? "Enabled" : "Disabled" ).c_str() ); - client->Message( + c->Message( Chat::White, fmt::format( "Proximity X | Min: {} Max: {} Range: {}", - target->GetProximityMinX(), - target->GetProximityMaxX(), - (target->GetProximityMaxX() - target->GetProximityMinX()) + t->GetProximityMinX(), + t->GetProximityMaxX(), + (t->GetProximityMaxX() - t->GetProximityMinX()) ).c_str() ); - client->Message( + c->Message( Chat::White, fmt::format( "Proximity Y | Min: {} Max: {} Range: {}", - target->GetProximityMinY(), - target->GetProximityMaxY(), - (target->GetProximityMaxY() - target->GetProximityMinY()) + t->GetProximityMinY(), + t->GetProximityMaxY(), + (t->GetProximityMaxY() - t->GetProximityMinY()) ).c_str() ); - client->Message( + c->Message( Chat::White, fmt::format( "Proximity Z | Min: {} Max: {} Range: {}", - target->GetProximityMinZ(), - target->GetProximityMaxZ(), - (target->GetProximityMaxZ() - target->GetProximityMinZ()) + t->GetProximityMinZ(), + t->GetProximityMaxZ(), + (t->GetProximityMaxZ() - t->GetProximityMinZ()) ).c_str() ); } // Spawn Data if ( - target->GetGrid() || - target->GetSpawnGroupId() || - target->GetSpawnPointID() + t->GetGrid() || + t->GetSpawnGroupId() || + t->GetSpawnPointID() ) { - client->Message( + c->Message( Chat::White, fmt::format( "Spawn | Group: {} Point: {} Grid: {}", - target->GetSpawnGroupId(), - target->GetSpawnPointID(), - target->GetGrid() + t->GetSpawnGroupId(), + t->GetSpawnPointID(), + t->GetGrid() ).c_str() ); } - client->Message( + c->Message( Chat::White, fmt::format( "Spawn | Raid: {} Rare: {}", - target->IsRaidTarget() ? "Yes" : "No", - target->IsRareSpawn() ? "Yes" : "No", - target->GetSkipGlobalLoot() ? "Yes" : "No" + t->IsRaidTarget() ? "Yes" : "No", + t->IsRareSpawn() ? "Yes" : "No", + t->GetSkipGlobalLoot() ? "Yes" : "No" ).c_str() ); - client->Message( + c->Message( Chat::White, fmt::format( "Spawn | Skip Global Loot: {} Ignore Despawn: {}", - target->GetSkipGlobalLoot() ? "Yes" : "No", - target->GetIgnoreDespawn() ? "Yes" : "No" + t->GetSkipGlobalLoot() ? "Yes" : "No", + t->GetIgnoreDespawn() ? "Yes" : "No" ).c_str() ); - client->Message( + c->Message( Chat::White, fmt::format( "Spawn | Findable: {} Trackable: {} Underwater: {}", - target->IsFindable() ? "Yes" : "No", - target->IsTrackable() ? "Yes" : "No", - target->IsUnderwaterOnly() ? "Yes" : "No" + t->IsFindable() ? "Yes" : "No", + t->IsTrackable() ? "Yes" : "No", + t->IsUnderwaterOnly() ? "Yes" : "No" ).c_str() ); - client->Message( + c->Message( Chat::White, fmt::format( "Spawn | Stuck Behavior: {} Fly Mode: {}", - target->GetStuckBehavior(), - static_cast(target->GetFlyMode()) + t->GetStuckBehavior(), + static_cast(t->GetFlyMode()) ).c_str() ); - client->Message( + c->Message( Chat::White, fmt::format( "Spawn | Aggro NPCs: {} Always Aggro: {}", - target->GetNPCAggro() ? "Yes" : "No", - target->GetAlwaysAggro() ? "Yes" : "No" + t->GetNPCAggro() ? "Yes" : "No", + t->GetAlwaysAggro() ? "Yes" : "No" ).c_str() ); // Race / Class / Gender - client->Message( + c->Message( Chat::White, fmt::format( "Race: {} ({}) Class: {} ({}) Gender: {} ({})", - GetRaceIDName(target->GetRace()), - target->GetRace(), - GetClassIDName(target->GetClass()), - target->GetClass(), - GetGenderName(target->GetGender()), - target->GetGender() + GetRaceIDName(t->GetRace()), + t->GetRace(), + GetClassIDName(t->GetClass()), + t->GetClass(), + GetGenderName(t->GetGender()), + t->GetGender() ).c_str() ); // NPC - client->Message( + c->Message( Chat::White, fmt::format( "NPC | ID: {} Entity ID: {} Name: {}{} Level: {}", - target->GetNPCTypeID(), - target->GetID(), + t->GetNPCTypeID(), + t->GetID(), target_name, ( !target_last_name.empty() ? fmt::format(" ({})", target_last_name) : "" ), - target->GetLevel() + t->GetLevel() ).c_str() ); } @@ -2321,54 +3441,57 @@ void Mob::DoAnim(const int animation_id, int animation_speed, bool ackreq, eqFil safe_delete(outapp); } -void Mob::ShowBuffs(Client* client) { - if(SPDAT_RECORDS <= 0) +void Mob::ShowBuffs(Client* c) { + if (SPDAT_RECORDS <= 0) { return; - client->Message(Chat::White, "Buffs on: %s", GetName()); - uint32 i; - uint32 buff_count = GetMaxTotalSlots(); - for (i=0; i < buff_count; i++) { - if (IsValidSpell(buffs[i].spellid)) { - if (spells[buffs[i].spellid].buff_duration_formula == DF_Permanent) - client->Message(Chat::White, " %i: %s: Permanent", i, spells[buffs[i].spellid].name); - else - client->Message(Chat::White, " %i: %s: %i tics left", i, spells[buffs[i].spellid].name, buffs[i].ticsremaining); + } + std::string buffs_table; + + buffs_table += DialogueWindow::TableRow( + fmt::format( + "{}{}{}{}{}", + DialogueWindow::TableCell("Slot"), + DialogueWindow::TableCell("Spell"), + DialogueWindow::TableCell("Spell ID"), + DialogueWindow::TableCell("Duration"), + DialogueWindow::TableCell("Hits") + ) + ); + + for (auto i = 0; i < GetMaxTotalSlots(); i++) { + const auto spell_id = buffs[i].spellid; + const auto buff_duration_formula = spells[spell_id].buff_duration_formula; + if (IsValidSpell(spell_id)) { + const auto is_permanent = ( + buff_duration_formula == DF_Aura || + buff_duration_formula == DF_Permanent + ); + + const auto time = Strings::SecondsToTime(buffs[i].ticsremaining * 6); + + buffs_table += DialogueWindow::TableRow( + fmt::format( + "{}{}{}{}{}", + DialogueWindow::TableCell(std::to_string(i)), + DialogueWindow::TableCell(GetSpellName(spell_id)), + DialogueWindow::TableCell(Strings::Commify(spell_id)), + DialogueWindow::TableCell(is_permanent ? "Permanent" : time), + DialogueWindow::TableCell(std::to_string(buffs[i].hit_number)) + ) + ); } } - if (IsClient()){ - client->Message(Chat::White, "itembonuses:"); - client->Message(Chat::White, "Atk:%i Ac:%i HP(%i):%i Mana:%i", itembonuses.ATK, itembonuses.AC, itembonuses.HPRegen, itembonuses.HP, itembonuses.Mana); - client->Message(Chat::White, "Str:%i Sta:%i Dex:%i Agi:%i Int:%i Wis:%i Cha:%i", - itembonuses.STR,itembonuses.STA,itembonuses.DEX,itembonuses.AGI,itembonuses.INT,itembonuses.WIS,itembonuses.CHA); - client->Message(Chat::White, "SvMagic:%i SvFire:%i SvCold:%i SvPoison:%i SvDisease:%i", - itembonuses.MR,itembonuses.FR,itembonuses.CR,itembonuses.PR,itembonuses.DR); - client->Message(Chat::White, "DmgShield:%i Haste:%i", itembonuses.DamageShield, itembonuses.haste ); - client->Message(Chat::White, "spellbonuses:"); - client->Message(Chat::White, "Atk:%i Ac:%i HP(%i):%i Mana:%i", spellbonuses.ATK, spellbonuses.AC, spellbonuses.HPRegen, spellbonuses.HP, spellbonuses.Mana); - client->Message(Chat::White, "Str:%i Sta:%i Dex:%i Agi:%i Int:%i Wis:%i Cha:%i", - spellbonuses.STR,spellbonuses.STA,spellbonuses.DEX,spellbonuses.AGI,spellbonuses.INT,spellbonuses.WIS,spellbonuses.CHA); - client->Message(Chat::White, "SvMagic:%i SvFire:%i SvCold:%i SvPoison:%i SvDisease:%i", - spellbonuses.MR,spellbonuses.FR,spellbonuses.CR,spellbonuses.PR,spellbonuses.DR); - client->Message(Chat::White, "DmgShield:%i Haste:%i", spellbonuses.DamageShield, spellbonuses.haste ); - } -} -void Mob::ShowBuffList(Client* client) { - if(SPDAT_RECORDS <= 0) - return; + buffs_table = DialogueWindow::Table(buffs_table); - client->Message(Chat::White, "Buffs on: %s", GetCleanName()); - uint32 i; - uint32 buff_count = GetMaxTotalSlots(); - for (i = 0; i < buff_count; i++) { - if (IsValidSpell(buffs[i].spellid)) { - if (spells[buffs[i].spellid].buff_duration_formula == DF_Permanent) - client->Message(Chat::White, " %i: %s: Permanent", i, spells[buffs[i].spellid].name); - else - client->Message(Chat::White, " %i: %s: %i tics left", i, spells[buffs[i].spellid].name, buffs[i].ticsremaining); - } - } + c->SendPopupToClient( + fmt::format( + "Buffs on {}", + c->GetTargetDescription(this, TargetDescriptionType::UCSelf) + ).c_str(), + buffs_table.c_str() + ); } void Mob::GMMove(float x, float y, float z, float heading, bool save_guard_spot) { @@ -2803,32 +3926,6 @@ bool Mob::RandomizeFeatures(bool send_illusion, bool set_variables) return false; } -bool Mob::IsPlayerClass(uint16 in_class) { - if ( - in_class >= WARRIOR && - in_class <= BERSERKER - ) { - return true; - } - - return false; -} - -bool Mob::IsPlayerRace(uint16 in_race) { - - if ( - (in_race >= HUMAN && in_race <= GNOME) || - in_race == IKSAR || - in_race == VAHSHIR || - in_race == FROGLOK || - in_race == DRAKKIN - ) { - return true; - } - - return false; -} - uint16 Mob::GetFactionRace() { uint16 current_race = GetRace(); if (IsPlayerRace(current_race) || current_race == TREE || @@ -2842,7 +3939,7 @@ uint16 Mob::GetFactionRace() { uint8 Mob::GetDefaultGender(uint16 in_race, uint8 in_gender) { if ( - Mob::IsPlayerRace(in_race) || + IsPlayerRace(in_race) || in_race == RACE_BROWNIE_15 || in_race == RACE_KERRAN_23 || in_race == RACE_LION_50 || @@ -7144,3 +8241,83 @@ int Mob::DispatchZoneControllerEvent( return ret; } + +std::string Mob::GetRacePlural() +{ + switch (GetBaseRace()) { + case RACE_HUMAN_1: + return "Humans"; + case RACE_BARBARIAN_2: + return "Barbarians"; + case RACE_ERUDITE_3: + return "Erudites"; + case RACE_WOOD_ELF_4: + return "Wood Elves"; + case RACE_HIGH_ELF_5: + return "High Elves"; + case RACE_DARK_ELF_6: + return "Dark Elves"; + case RACE_HALF_ELF_7: + return "Half Elves"; + case RACE_DWARF_8: + return "Dwarves"; + case RACE_TROLL_9: + return "Trolls"; + case RACE_OGRE_10: + return "Ogres"; + case RACE_HALFLING_11: + return "Halflings"; + case RACE_GNOME_12: + return "Gnomes"; + case RACE_IKSAR_128: + return "Iksar"; + case RACE_VAH_SHIR_130: + return "Vah Shir"; + case RACE_FROGLOK_330: + return "Frogloks"; + case RACE_DRAKKIN_522: + return "Drakkin"; + default: + return "Races"; + } +} + +std::string Mob::GetClassPlural() +{ + switch (GetClass()) { + case WARRIOR: + return "Warriors"; + case CLERIC: + return "Clerics"; + case PALADIN: + return "Paladins"; + case RANGER: + return "Rangers"; + case SHADOWKNIGHT: + return "Shadowknights"; + case DRUID: + return "Druids"; + case MONK: + return "Monks"; + case BARD: + return "Bards"; + case ROGUE: + return "Rogues"; + case SHAMAN: + return "Shamans"; + case NECROMANCER: + return "Necromancers"; + case WIZARD: + return "Wizards"; + case MAGICIAN: + return "Magicians"; + case ENCHANTER: + return "Enchanters"; + case BEASTLORD: + return "Beastlords"; + case BERSERKER: + return "Berserkers"; + default: + return "Classes"; + } +} diff --git a/zone/mob.h b/zone/mob.h index 1762d913d..14deb85c4 100644 --- a/zone/mob.h +++ b/zone/mob.h @@ -523,7 +523,7 @@ public: virtual inline uint8 GetBaseGender() const { return base_gender; } virtual uint16 GetFactionRace(); virtual inline uint16 GetDeity() const { return deity; } - virtual EQ::deity::DeityTypeBit GetDeityBit() { return EQ::deity::ConvertDeityTypeToDeityTypeBit((EQ::deity::DeityType)deity); } + virtual EQ::deity::DeityTypeBit GetDeityBit() { return EQ::deity::GetDeityBitmask((EQ::deity::DeityType)deity); } inline uint16 GetRace() const { return race; } inline uint16 GetModel() const { return (use_model == 0) ? race : use_model; } inline uint8 GetGender() const { return gender; } @@ -801,8 +801,6 @@ public: //Util static uint32 RandomTimer(int min, int max); static uint8 GetDefaultGender(uint16 in_race, uint8 in_gender = 0xFF); - static bool IsPlayerClass(uint16 in_class); - static bool IsPlayerRace(uint16 in_race); EQ::skills::SkillType GetSkillByItemType(int ItemType); uint8 GetItemTypeBySkill(EQ::skills::SkillType skill); virtual void MakePet(uint16 spell_id, const char* pettype, const char *petname = nullptr); @@ -811,9 +809,9 @@ public: char GetCasterClass() const; uint8 GetArchetype() const; void SetZone(uint32 zone_id, uint32 instance_id); + void SendStatsWindow(Client* c, bool use_window); void ShowStats(Client* client); - void ShowBuffs(Client* client); - void ShowBuffList(Client* client); + void ShowBuffs(Client* c); bool PlotPositionAroundTarget(Mob* target, float &x_dest, float &y_dest, float &z_dest, bool lookForAftArc = true); bool PlotPositionOnArcInFrontOfTarget(Mob *target, float &x_dest, float &y_dest, float &z_dest, float distance, float min_deg = 5.0f, float max_deg = 150.0f); bool PlotPositionOnArcBehindTarget(Mob *target, float &x_dest, float &y_dest, float &z_dest, float distance); @@ -1205,6 +1203,7 @@ public: void RotateToRunning(float new_heading); void StopNavigation(); float CalculateDistance(float x, float y, float z); + float CalculateDistance(Mob* mob); float GetGroundZ(float new_x, float new_y, float z_offset=0.0); void SendTo(float new_x, float new_y, float new_z); void SendToFixZ(float new_x, float new_y, float new_z); @@ -1332,6 +1331,9 @@ public: bool HasSpellEffect(int effect_id); + std::string GetRacePlural(); + std::string GetClassPlural(); + //Command #Tune functions void TuneGetStats(Mob* defender, Mob *attacker); void TuneGetACByPctMitigation(Mob* defender, Mob *attacker, float pct_mitigation, int interval = 10, int max_loop = 1000, int atk_override = 0, int Msg = 0); diff --git a/zone/npc.cpp b/zone/npc.cpp index 39783a73f..5b3061d0b 100644 --- a/zone/npc.cpp +++ b/zone/npc.cpp @@ -243,7 +243,14 @@ NPC::NPC(const NPCType *npc_type_data, Spawn2 *in_respawn, const glm::vec4 &posi SetMana(GetMaxMana()); MerchantType = npc_type_data->merchanttype; - merchant_open = GetClass() == MERCHANT; + merchant_open = ( + GetClass() == MERCHANT || + GetClass() == DISCORD_MERCHANT || + GetClass() == ADVENTURE_MERCHANT || + GetClass() == NORRATHS_KEEPERS_MERCHANT || + GetClass() == DARK_REIGN_MERCHANT || + GetClass() == ALT_CURRENCY_MERCHANT + ); adventure_template_id = npc_type_data->adventure_template; flymode = iflymode; @@ -441,6 +448,8 @@ NPC::NPC(const NPCType *npc_type_data, Spawn2 *in_respawn, const glm::vec4 &posi m_can_open_doors = false; } + GetInv().SetInventoryVersion(EQ::versions::MobVersion::RoF2); + GetInv().SetGMInventory(false); } float NPC::GetRoamboxMaxX() const @@ -2359,74 +2368,67 @@ void NPC::FillSpawnStruct(NewSpawn_Struct* ns, Mob* ForWho) void NPC::PetOnSpawn(NewSpawn_Struct* ns) { //Basic settings to make sure swarm pets work properly. - Mob *swarmOwner = nullptr; - if (GetSwarmOwner()) - { - swarmOwner = entity_list.GetMobID(GetSwarmOwner()); + Mob *swarm_owner = nullptr; + if (GetSwarmOwner()) { + swarm_owner = entity_list.GetMobID(GetSwarmOwner()); } - if (swarmOwner != nullptr) - { - if(swarmOwner->IsClient()) - { + if (swarm_owner) { + if (swarm_owner->IsClient()) { SetPetOwnerClient(true); //Simple flag to determine if pet belongs to a client SetAllowBeneficial(true);//Allow temp pets to receive buffs and heals if owner is client. //This will allow CLIENT swarm pets NOT to be targeted with F8. - ns->spawn.targetable_with_hotkey = 0; - no_target_hotkey = 1; - } - else - { + ns->spawn.targetable_with_hotkey = false; + no_target_hotkey = true; + } else { //NPC cast swarm pets should still be targetable with F8. - ns->spawn.targetable_with_hotkey = 1; - no_target_hotkey = 0; + ns->spawn.targetable_with_hotkey = true; + no_target_hotkey = false; } SetTempPet(true); //Simple mob flag for checking if temp pet - swarmOwner->SetTempPetsActive(true); //Necessary fail safe flag set if mob ever had a swarm pet to ensure they are removed. - swarmOwner->SetTempPetCount(swarmOwner->GetTempPetCount() + 1); + swarm_owner->SetTempPetsActive(true); //Necessary fail safe flag set if mob ever had a swarm pet to ensure they are removed. + swarm_owner->SetTempPetCount(swarm_owner->GetTempPetCount() + 1); //Not recommended if using above (However, this will work better on older clients). - if (RuleB(Pets, UnTargetableSwarmPet)) - { - ns->spawn.bodytype = 11; - if(!IsCharmed() && swarmOwner->IsClient()) { - std::string tmp_lastname = swarmOwner->GetName(); - tmp_lastname += "'s Pet"; - if (tmp_lastname.size() < sizeof(ns->spawn.lastName)) - strn0cpy(ns->spawn.lastName, tmp_lastname.c_str(), sizeof(ns->spawn.lastName)); + if (RuleB(Pets, UnTargetableSwarmPet)) { + ns->spawn.bodytype = BT_NoTarget; + } + + if ( + !IsCharmed() && + swarm_owner->IsClient() && + RuleB(Pets, ClientPetsUseOwnerNameInLastName) + ) { + const auto& tmp_lastname = fmt::format("{}'s Pet", swarm_owner->GetName()); + if (tmp_lastname.size() < sizeof(ns->spawn.lastName)) { + strn0cpy(ns->spawn.lastName, tmp_lastname.c_str(), sizeof(ns->spawn.lastName)); } } - if (swarmOwner->IsNPC()) { + if (swarm_owner->IsNPC()) { SetPetOwnerNPC(true); } - } - else if(GetOwnerID()) - { + } else if (GetOwnerID()) { ns->spawn.is_pet = 1; - if (!IsCharmed()) - { - Client *client = entity_list.GetClientByID(GetOwnerID()); - if(client) - { + + if (!IsCharmed()) { + const auto c = entity_list.GetClientByID(GetOwnerID()); + if (c) { SetPetOwnerClient(true); - std::string tmp_lastname = client->GetName(); - tmp_lastname += "'s Pet"; - if (tmp_lastname.size() < sizeof(ns->spawn.lastName)) - strn0cpy(ns->spawn.lastName, tmp_lastname.c_str(), sizeof(ns->spawn.lastName)); - } - else - { - if (entity_list.GetNPCByID(GetOwnerID())) - { + if (RuleB(Pets, ClientPetsUseOwnerNameInLastName)) { + const auto& tmp_lastname = fmt::format("{}'s Pet", c->GetName()); + if (tmp_lastname.size() < sizeof(ns->spawn.lastName)) { + strn0cpy(ns->spawn.lastName, tmp_lastname.c_str(), sizeof(ns->spawn.lastName)); + } + } + } else { + if (entity_list.GetNPCByID(GetOwnerID())) { SetPetOwnerNPC(true); } } } - } - else - { + } else { ns->spawn.is_pet = 0; } } diff --git a/zone/perl_bot.cpp b/zone/perl_bot.cpp index f8e0e956e..dd4c40fd4 100644 --- a/zone/perl_bot.cpp +++ b/zone/perl_bot.cpp @@ -445,6 +445,16 @@ void Perl_Bot_AddItem(Bot *self, perl::reference table_ref) } } +std::string Perl_Bot_GetClassAbbreviation(Bot* self) +{ + return GetPlayerClassAbbreviation(self->GetClass()); +} + +std::string Perl_Bot_GetRaceAbbreviation(Bot* self) +{ + return GetPlayerRaceAbbreviation(self->GetBaseRace()); +} + void perl_register_bot() { perl::interpreter state(PERL_GET_THX); @@ -492,6 +502,7 @@ void perl_register_bot() package.add("GetBotID", &Perl_Bot_GetBotID); package.add("GetBotItem", &Perl_Bot_GetBotItem); package.add("GetBotItemIDBySlot", &Perl_Bot_GetBotItemIDBySlot); + package.add("GetClassAbbreviation", &Perl_Bot_GetClassAbbreviation); package.add("GetExpansionBitmask", &Perl_Bot_GetExpansionBitmask); package.add("GetGroup", &Perl_Bot_GetGroup); package.add("GetHealAmount", &Perl_Bot_GetHealAmount); @@ -499,6 +510,7 @@ void perl_register_bot() package.add("GetItemAt", &Perl_Bot_GetItemAt); package.add("GetItemIDAt", &Perl_Bot_GetItemIDAt); package.add("GetOwner", &Perl_Bot_GetOwner); + package.add("GetRaceAbbreviation", &Perl_Bot_GetRaceAbbreviation); package.add("GetRawItemAC", &Perl_Bot_GetRawItemAC); package.add("GetSpellDamage", &Perl_Bot_GetSpellDamage); package.add("HasAugmentEquippedByID", &Perl_Bot_HasAugmentEquippedByID); diff --git a/zone/perl_client.cpp b/zone/perl_client.cpp index 9cb246a3a..56b6db624 100644 --- a/zone/perl_client.cpp +++ b/zone/perl_client.cpp @@ -1432,7 +1432,7 @@ void Perl_Client_UnFreeze(Client* self) self->SendAppearancePacket(AT_Anim, ANIM_STAND); } -int Perl_Client_GetAggroCount(Client* self) // @categories Script Utility, Hate and Aggro +uint32 Perl_Client_GetAggroCount(Client* self) // @categories Script Utility, Hate and Aggro { return self->GetAggroCount(); } @@ -1502,6 +1502,11 @@ bool Perl_Client_HasSpellScribed(Client* self, int spell_id) // @categories Spel return self->HasSpellScribed(spell_id); } +void Perl_Client_ClearAccountFlag(Client* self, std::string flag) // @categories Account and Character +{ + self->ClearAccountFlag(flag); +} + void Perl_Client_SetAccountFlag(Client* self, std::string flag, std::string value) // @categories Account and Character { self->SetAccountFlag(flag, value); @@ -1512,6 +1517,21 @@ std::string Perl_Client_GetAccountFlag(Client* self, std::string flag) // @categ return self->GetAccountFlag(flag); } +perl::array Perl_Client_GetAccountFlags(Client* self) +{ + perl::array result; + + const auto& l = self->GetAccountFlags(); + + result.reserve(l.size()); + + for (const auto& e : l) { + result.push_back(e); + } + + return result; +} + int Perl_Client_GetHunger(Client* self) // @categories Account and Character, Stats and Attributes { return self->GetHunger(); @@ -2917,6 +2937,16 @@ uint32 Perl_Client_GetEXPForLevel(Client* self, uint16 check_level) return self->GetEXPForLevel(check_level); } +std::string Perl_Client_GetClassAbbreviation(Client* self) +{ + return GetPlayerClassAbbreviation(self->GetBaseClass()); +} + +std::string Perl_Client_GetRaceAbbreviation(Client* self) +{ + return GetPlayerRaceAbbreviation(self->GetBaseRace()); +} + void perl_register_client() { perl::interpreter perl(PERL_GET_THX); @@ -2984,6 +3014,7 @@ void perl_register_client() package.add("CheckIncreaseSkill", (bool(*)(Client*, int, int))&Perl_Client_CheckIncreaseSkill); package.add("CheckSpecializeIncrease", &Perl_Client_CheckSpecializeIncrease); package.add("ClearCompassMark", &Perl_Client_ClearCompassMark); + package.add("ClearAccountFlag", &Perl_Client_ClearAccountFlag); package.add("ClearPEQZoneFlag", &Perl_Client_ClearPEQZoneFlag); package.add("ClearZoneFlag", &Perl_Client_ClearZoneFlag); package.add("Connected", &Perl_Client_Connected); @@ -3032,6 +3063,7 @@ void perl_register_client() package.add("GetAFK", &Perl_Client_GetAFK); package.add("GetAccountAge", &Perl_Client_GetAccountAge); package.add("GetAccountFlag", &Perl_Client_GetAccountFlag); + package.add("GetAccountFlags", &Perl_Client_GetAccountFlags); package.add("GetAggroCount", &Perl_Client_GetAggroCount); package.add("GetAllMoney", &Perl_Client_GetAllMoney); package.add("GetAlternateCurrencyValue", &Perl_Client_GetAlternateCurrencyValue); @@ -3067,6 +3099,7 @@ void perl_register_client() package.add("GetCarriedMoney", &Perl_Client_GetCarriedMoney); package.add("GetCarriedPlatinum", &Perl_Client_GetCarriedPlatinum); package.add("GetCharacterFactionLevel", &Perl_Client_GetCharacterFactionLevel); + package.add("GetClassAbbreviation", &Perl_Client_GetClassAbbreviation); package.add("GetClassBitmask", &Perl_Client_GetClassBitmask); package.add("GetClientMaxLevel", &Perl_Client_GetClientMaxLevel); package.add("GetClientVersion", &Perl_Client_GetClientVersion); @@ -3133,6 +3166,7 @@ void perl_register_client() package.add("GetMoney", &Perl_Client_GetMoney); package.add("GetPVP", &Perl_Client_GetPVP); package.add("GetPVPPoints", &Perl_Client_GetPVPPoints); + package.add("GetRaceAbbreviation", &Perl_Client_GetRaceAbbreviation); package.add("GetRaceBitmask", &Perl_Client_GetRaceBitmask); package.add("GetRadiantCrystals", &Perl_Client_GetRadiantCrystals); package.add("GetRaid", &Perl_Client_GetRaid); diff --git a/zone/perl_entity.cpp b/zone/perl_entity.cpp index 65bd2a2fa..025f1d7d2 100644 --- a/zone/perl_entity.cpp +++ b/zone/perl_entity.cpp @@ -4,6 +4,7 @@ #include "embperl.h" #include "entity.h" +#include "mob.h" #include "../common/global_define.h" #include "../common/rulesys.h" #include "../common/say_link.h" @@ -610,6 +611,77 @@ Bot* Perl_EntityList_GetRandomBot(EntityList* self, float x, float y, float z, f return self->GetRandomBot(glm::vec3(x, y, z), distance, exclude_bot); } +perl::array Perl_EntityList_GetCloseMobList(EntityList* self, Mob* mob) +{ + perl::array result; + + const auto& l = self->GetCloseMobList(mob); + + result.reserve(l.size()); + + for (const auto& e : l) { + result.push_back(e.second); + } + + return result; +} + +perl::array Perl_EntityList_GetCloseMobList(EntityList* self, Mob* mob, float distance) +{ + perl::array result; + + const auto& l = self->GetCloseMobList(mob, distance); + + result.reserve(l.size()); + + for (const auto& e : l) { + if (mob->CalculateDistance(e.second) <= distance) { + result.push_back(e.second); + } + } + + return result; +} + +perl::array Perl_EntityList_GetCloseMobList(EntityList* self, Mob* mob, float distance, bool ignore_self) +{ + perl::array result; + + const auto& l = self->GetCloseMobList(mob, distance); + + result.reserve(l.size()); + + for (const auto& e : l) { + if (ignore_self && e.second == mob) { + continue; + } + + if (mob->CalculateDistance(e.second) <= distance) { + result.push_back(e.second); + } + } + + return result; +} + +Spawn2* Perl_EntityList_GetSpawnByID(EntityList* self, uint32 spawn_id) { + return self->GetSpawnByID(spawn_id); +} + +perl::array Perl_EntityList_GetSpawnList(EntityList* self) { + perl::array ret; + + std::list l; + + self->GetSpawnList(l); + + for (const auto& e : l) { + ret.push_back(e); + } + + return ret; +} + void perl_register_entitylist() { perl::interpreter perl(PERL_GET_THX); @@ -639,6 +711,9 @@ void perl_register_entitylist() package.add("GetClientByName", &Perl_EntityList_GetClientByName); package.add("GetClientByWID", &Perl_EntityList_GetClientByWID); package.add("GetClientList", &Perl_EntityList_GetClientList); + package.add("GetCloseMobList", (perl::array(*)(EntityList*, Mob*))&Perl_EntityList_GetCloseMobList); + package.add("GetCloseMobList", (perl::array(*)(EntityList*, Mob*, float))&Perl_EntityList_GetCloseMobList); + package.add("GetCloseMobList", (perl::array(*)(EntityList*, Mob*, float, bool))&Perl_EntityList_GetCloseMobList); package.add("GetCorpseByID", &Perl_EntityList_GetCorpseByID); package.add("GetCorpseByName", &Perl_EntityList_GetCorpseByName); package.add("GetCorpseByOwner", &Perl_EntityList_GetCorpseByOwner); @@ -677,6 +752,8 @@ void perl_register_entitylist() package.add("GetRandomNPC", (NPC*(*)(EntityList*))&Perl_EntityList_GetRandomNPC); package.add("GetRandomNPC", (NPC*(*)(EntityList*, float, float, float, float))&Perl_EntityList_GetRandomNPC); package.add("GetRandomNPC", (NPC*(*)(EntityList*, float, float, float, float, NPC*))&Perl_EntityList_GetRandomNPC); + package.add("GetSpawnByID", (Spawn2*(*)(EntityList*, uint32))&Perl_EntityList_GetSpawnByID); + package.add("GetSpawnList", (perl::array(*)(EntityList*))&Perl_EntityList_GetSpawnList); package.add("HalveAggro", &Perl_EntityList_HalveAggro); package.add("IsMobSpawnedByNpcTypeID", &Perl_EntityList_IsMobSpawnedByNpcTypeID); package.add("MakeNameUnique", &Perl_EntityList_MakeNameUnique); diff --git a/zone/perl_hateentry.cpp b/zone/perl_hateentry.cpp index 0b44143f9..4e813b7b2 100644 --- a/zone/perl_hateentry.cpp +++ b/zone/perl_hateentry.cpp @@ -7,19 +7,44 @@ #include "embperl.h" #include "hate_list.h" +int64_t Perl_HateEntry_GetDamage(struct_HateList* self) // @categories Script Utility, Hate and Aggro +{ + return self->hatelist_damage; +} + Mob* Perl_HateEntry_GetEnt(struct_HateList* self) // @categories Script Utility, Hate and Aggro { return self->entity_on_hatelist; } +bool Perl_HateEntry_GetFrenzy(struct_HateList* self) // @categories Script Utility, Hate and Aggro +{ + return self->is_entity_frenzy; +} + int64_t Perl_HateEntry_GetHate(struct_HateList* self) // @categories Script Utility, Hate and Aggro { return self->stored_hate_amount; } -int64_t Perl_HateEntry_GetDamage(struct_HateList* self) // @categories Script Utility, Hate and Aggro +void Perl_HateEntry_SetDamage(struct_HateList* self, int64 value) // @categories Script Utility, Hate and Aggro { - return self->hatelist_damage; + self->hatelist_damage = value; +} + +void Perl_HateEntry_SetEnt(struct_HateList* self, Mob* mob) // @categories Script Utility, Hate and Aggro +{ + self->entity_on_hatelist = mob; +} + +void Perl_HateEntry_SetFrenzy(struct_HateList* self, bool is_frenzy) // @categories Script Utility, Hate and Aggro +{ + self->is_entity_frenzy = is_frenzy; +} + +void Perl_HateEntry_SetHate(struct_HateList* self, int64 value) // @categories Script Utility, Hate and Aggro +{ + self->stored_hate_amount = value; } void perl_register_hateentry() @@ -29,7 +54,12 @@ void perl_register_hateentry() auto package = perl.new_class("HateEntry"); package.add("GetDamage", &Perl_HateEntry_GetDamage); package.add("GetEnt", &Perl_HateEntry_GetEnt); + package.add("GetFrenzy", &Perl_HateEntry_GetFrenzy); package.add("GetHate", &Perl_HateEntry_GetHate); + package.add("SetDamage", &Perl_HateEntry_SetDamage); + package.add("SetEnt", &Perl_HateEntry_SetEnt); + package.add("SetFrenzy", &Perl_HateEntry_SetFrenzy); + package.add("SetHate", &Perl_HateEntry_SetHate); } #endif //EMBPERL_XS_CLASSES diff --git a/zone/perl_mob.cpp b/zone/perl_mob.cpp index 2316cf110..bb59b33a8 100644 --- a/zone/perl_mob.cpp +++ b/zone/perl_mob.cpp @@ -1374,6 +1374,11 @@ float Perl_Mob_CalculateDistance(Mob* self, float x, float y, float z) // @categ return self->CalculateDistance(x, y, z); } +float Perl_Mob_CalculateDistance(Mob* self, Mob* mob) // @categories Script Utility +{ + return self->CalculateDistance(mob); +} + void Perl_Mob_SendTo(Mob* self, float new_x, float new_y, float new_z) // @categories Script Utility { self->SendTo(new_x, new_y, new_z); @@ -3005,6 +3010,84 @@ bool Perl_Mob_HasSpellEffect(Mob* self, int effect_id) return self->HasSpellEffect(effect_id); } +perl::array Perl_Mob_GetCloseMobList(Mob* self) +{ + perl::array result; + + const auto& l = entity_list.GetCloseMobList(self); + + result.reserve(l.size()); + + for (const auto& e : l) { + result.push_back(e.second); + } + + return result; +} + +perl::array Perl_Mob_GetCloseMobList(Mob* self, float distance) +{ + perl::array result; + + const auto& l = entity_list.GetCloseMobList(self, distance); + + result.reserve(l.size()); + + for (const auto& e : l) { + if (self->CalculateDistance(e.second) <= distance) { + result.push_back(e.second); + } + } + + return result; +} + +perl::array Perl_Mob_GetCloseMobList(Mob* self, float distance, bool ignore_self) +{ + perl::array result; + + const auto& l = entity_list.GetCloseMobList(self, distance); + + result.reserve(l.size()); + + for (const auto& e : l) { + if (ignore_self && e.second == self) { + continue; + } + + if (self->CalculateDistance(e.second) <= distance) { + result.push_back(e.second); + } + } + + return result; +} + +StatBonuses* Perl_Mob_GetAABonuses(Mob* self) +{ + return self->GetAABonusesPtr(); +} + +StatBonuses* Perl_Mob_GetItemBonuses(Mob* self) +{ + return self->GetItemBonusesPtr(); +} + +StatBonuses* Perl_Mob_GetSpellBonuses(Mob* self) +{ + return self->GetSpellBonusesPtr(); +} + +std::string Perl_Mob_GetClassPlural(Mob* self) +{ + return self->GetClassPlural(); +} + +std::string Perl_Mob_GetRacePlural(Mob* self) +{ + return self->GetRacePlural(); +} + void perl_register_mob() { perl::interpreter perl(PERL_GET_THX); @@ -3035,7 +3118,8 @@ void perl_register_mob() package.add("BuffFadeBySlot", (void(*)(Mob*, int))&Perl_Mob_BuffFadeBySlot); package.add("BuffFadeBySlot", (void(*)(Mob*, int, bool))&Perl_Mob_BuffFadeBySlot); package.add("BuffFadeBySpellID", &Perl_Mob_BuffFadeBySpellID); - package.add("CalculateDistance", &Perl_Mob_CalculateDistance); + package.add("CalculateDistance", (float(*)(Mob*, float, float, float))&Perl_Mob_CalculateDistance); + package.add("CalculateDistance", (float(*)(Mob*, Mob*))&Perl_Mob_CalculateDistance); package.add("CalculateHeadingToTarget", &Perl_Mob_CalculateHeadingToTarget); package.add("CameraEffect", (void(*)(Mob*, uint32))&Perl_Mob_CameraEffect); package.add("CameraEffect", (void(*)(Mob*, uint32, float))&Perl_Mob_CameraEffect); @@ -3153,6 +3237,7 @@ void perl_register_mob() package.add("GMMove", (void(*)(Mob*, float, float, float, float))&Perl_Mob_GMMove); package.add("Gate", &Perl_Mob_Gate); package.add("GetAA", &Perl_Mob_GetAA); + package.add("GetAABonuses", &Perl_Mob_GetAABonuses); package.add("GetAAByAAID", &Perl_Mob_GetAAByAAID); package.add("GetAC", &Perl_Mob_GetAC); package.add("GetAGI", &Perl_Mob_GetAGI); @@ -3193,8 +3278,12 @@ void perl_register_mob() package.add("GetCasterLevel", &Perl_Mob_GetCasterLevel); package.add("GetClass", &Perl_Mob_GetClass); package.add("GetClassLevelFactor", &Perl_Mob_GetClassLevelFactor); + package.add("GetClassPlural", &Perl_Mob_GetClassPlural); package.add("GetClassName", &Perl_Mob_GetClassName); package.add("GetCleanName", &Perl_Mob_GetCleanName); + package.add("GetCloseMobList", (perl::array(*)(Mob*))&Perl_Mob_GetCloseMobList); + package.add("GetCloseMobList", (perl::array(*)(Mob*, float))&Perl_Mob_GetCloseMobList); + package.add("GetCloseMobList", (perl::array(*)(Mob*, float, bool))&Perl_Mob_GetCloseMobList); package.add("GetCorruption", &Perl_Mob_GetCorruption); package.add("GetDefaultRaceSize", (float(*)(Mob*))&Perl_Mob_GetDefaultRaceSize); package.add("GetDefaultRaceSize", (float(*)(Mob*, int))&Perl_Mob_GetDefaultRaceSize); @@ -3259,6 +3348,7 @@ void perl_register_mob() package.add("GetInvisibleLevel", &Perl_Mob_GetInvisibleLevel); package.add("GetInvisibleUndeadLevel", &Perl_Mob_GetInvisibleUndeadLevel); package.add("GetInvul", &Perl_Mob_GetInvul); + package.add("GetItemBonuses", &Perl_Mob_GetItemBonuses); package.add("GetItemHPBonuses", &Perl_Mob_GetItemHPBonuses); package.add("GetItemStat", &Perl_Mob_GetItemStat); package.add("GetLastName", &Perl_Mob_GetLastName); @@ -3296,6 +3386,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("GetRacePlural", &Perl_Mob_GetRacePlural); package.add("GetRemainingTimeMS", &Perl_Mob_GetRemainingTimeMS); package.add("GetResist", &Perl_Mob_GetResist); package.add("GetReverseFactionCon", &Perl_Mob_GetReverseFactionCon); @@ -3310,6 +3401,7 @@ void perl_register_mob() package.add("GetSpecialAbility", &Perl_Mob_GetSpecialAbility); package.add("GetSpecialAbilityParam", &Perl_Mob_GetSpecialAbilityParam); package.add("GetSpecializeSkillValue", &Perl_Mob_GetSpecializeSkillValue); + package.add("GetSpellBonuses", &Perl_Mob_GetSpellBonuses); package.add("GetSpellHPBonuses", &Perl_Mob_GetSpellHPBonuses); package.add("GetSpellIDFromSlot", &Perl_Mob_GetSpellIDFromSlot); package.add("GetSpellStat", (int(*)(Mob*, uint32, const char*))&Perl_Mob_GetSpellStat); diff --git a/zone/perl_questitem.cpp b/zone/perl_questitem.cpp index 15a9ddc3a..83bed32c3 100644 --- a/zone/perl_questitem.cpp +++ b/zone/perl_questitem.cpp @@ -1,4 +1,5 @@ #include "../common/features.h" +#include "../common/languages.h" #include "client.h" #ifdef EMBPERL_XS_CLASSES @@ -20,12 +21,12 @@ void Perl_QuestItem_SetScale(EQ::ItemInstance* self, float scale_multiplier) // void Perl_QuestItem_ItemSay(EQ::ItemInstance* self, const char* text) // @categories Inventory and Items { - quest_manager.GetInitiator()->ChannelMessageSend(self->GetItem()->Name, 0, 8, 0, 100, text); + quest_manager.GetInitiator()->ChannelMessageSend(self->GetItem()->Name, 0, ChatChannel_Say, LANG_COMMON_TONGUE, MAX_LANGUAGE_SKILL, text); } -void Perl_QuestItem_ItemSay(EQ::ItemInstance* self, const char* text, int language_id) // @categories Inventory and Items +void Perl_QuestItem_ItemSay(EQ::ItemInstance* self, const char* text, uint8 language_id) // @categories Inventory and Items { - quest_manager.GetInitiator()->ChannelMessageSend(self->GetItem()->Name, 0, 8, language_id, 100, text); + quest_manager.GetInitiator()->ChannelMessageSend(self->GetItem()->Name, 0, ChatChannel_Say, language_id, MAX_LANGUAGE_SKILL, text); } bool Perl_QuestItem_IsType(EQ::ItemInstance* self, int type) // @categories Inventory and Items @@ -38,12 +39,17 @@ bool Perl_QuestItem_IsAttuned(EQ::ItemInstance* self) // @categories Inventory a return self->IsAttuned(); } +bool Perl_QuestItem_IsInstanceNoDrop(EQ::ItemInstance* self) // @categories Inventory and Items +{ + return self->IsAttuned(); +} + int Perl_QuestItem_GetCharges(EQ::ItemInstance* self) // @categories Inventory and Items { return self->GetCharges(); } -EQ::ItemInstance* Perl_QuestItem_GetAugment(EQ::ItemInstance* self, int slot_id) // @categories Inventory and Items +EQ::ItemInstance* Perl_QuestItem_GetAugment(EQ::ItemInstance* self, uint8 slot_id) // @categories Inventory and Items { return self->GetAugment(slot_id); } @@ -82,27 +88,253 @@ int Perl_QuestItem_RemoveTaskDeliveredItems(EQ::ItemInstance* self) { return self->RemoveTaskDeliveredItems(); } +void Perl_QuestItem_AddEXP(EQ::ItemInstance* self, uint32 exp) +{ + self->AddExp(exp); +} + +void Perl_QuestItem_ClearTimers(EQ::ItemInstance* self) +{ + self->ClearTimers(); +} + +EQ::ItemInstance* Perl_QuestItem_Clone(EQ::ItemInstance* self) +{ + return self->Clone(); +} + +void Perl_QuestItem_DeleteCustomData(EQ::ItemInstance* self, std::string identifier) +{ + self->DeleteCustomData(identifier); +} + +uint32 Perl_QuestItem_GetAugmentItemID(EQ::ItemInstance* self, uint8 slot_id) +{ + return self->GetAugmentItemID(slot_id); +} + +int Perl_QuestItem_GetAugmentType(EQ::ItemInstance* self) +{ + return self->GetAugmentType(); +} + +uint32 Perl_QuestItem_GetColor(EQ::ItemInstance* self) +{ + return self->GetColor(); +} + +std::string Perl_QuestItem_GetCustomData(EQ::ItemInstance* self, std::string identifier) +{ + return self->GetCustomData(identifier); +} + +std::string Perl_QuestItem_GetCustomDataString(EQ::ItemInstance* self) +{ + return self->GetCustomDataString(); +} + +uint32 Perl_QuestItem_GetEXP(EQ::ItemInstance* self) +{ + return self->GetExp(); +} + +EQ::ItemInstance* Perl_QuestItem_GetItem(EQ::ItemInstance* self, uint8 slot_id) +{ + return self->GetItem(slot_id); +} + +uint32 Perl_QuestItem_GetItemID(EQ::ItemInstance* self, uint8 slot_id) +{ + return self->GetItemID(slot_id); +} + +uint32 Perl_QuestItem_GetItemScriptID(EQ::ItemInstance* self) +{ + return self->GetItemScriptID(); +} + +uint32 Perl_QuestItem_GetKillsNeeded(EQ::ItemInstance* self, uint8 current_level) +{ + return self->GetKillsNeeded(current_level); +} + +int8 Perl_QuestItem_GetMaxEvolveLevel(EQ::ItemInstance* self) +{ + return self->GetMaxEvolveLvl(); +} + +uint32 Perl_QuestItem_GetPrice(EQ::ItemInstance* self) +{ + return self->GetPrice(); +} + +uint8 Perl_QuestItem_GetTotalItemCount(EQ::ItemInstance* self) +{ + return self->GetTotalItemCount(); +} + +bool Perl_QuestItem_IsAmmo(EQ::ItemInstance* self) +{ + return self->IsAmmo(); +} + +bool Perl_QuestItem_IsAugmentable(EQ::ItemInstance* self) +{ + return self->IsAugmentable(); +} + +bool Perl_QuestItem_IsAugmented(EQ::ItemInstance* self) +{ + return self->IsAugmented(); +} + +bool Perl_QuestItem_IsEquipable(EQ::ItemInstance* self, int16 slot_id) +{ + return self->IsEquipable(slot_id); +} + +bool Perl_QuestItem_IsEquipable(EQ::ItemInstance* self, uint16 race_bitmask, uint16 class_bitmask) +{ + return self->IsEquipable(race_bitmask, class_bitmask); +} + +bool Perl_QuestItem_IsExpendable(EQ::ItemInstance* self) +{ + return self->IsExpendable(); +} + +bool Perl_QuestItem_IsWeapon(EQ::ItemInstance* self) +{ + return self->IsWeapon(); +} + +void Perl_QuestItem_SetAttuned(EQ::ItemInstance* self, bool is_attuned) +{ + self->SetAttuned(is_attuned); +} + +void Perl_QuestItem_SetInstanceNoDrop(EQ::ItemInstance* self, bool is_attuned) +{ + self->SetAttuned(is_attuned); +} + +void Perl_QuestItem_SetColor(EQ::ItemInstance* self, uint32 color) +{ + self->SetColor(color); +} + +void Perl_QuestItem_SetCustomData(EQ::ItemInstance* self, std::string identifier, bool value) +{ + self->SetCustomData(identifier, value); +} + +void Perl_QuestItem_SetCustomData(EQ::ItemInstance* self, std::string identifier, float value) +{ + self->SetCustomData(identifier, value); +} + +void Perl_QuestItem_SetCustomData(EQ::ItemInstance* self, std::string identifier, int value) +{ + self->SetCustomData(identifier, value); +} + +void Perl_QuestItem_SetCustomData(EQ::ItemInstance* self, std::string identifier, std::string value) +{ + self->SetCustomData(identifier, value); +} + +void Perl_QuestItem_SetEXP(EQ::ItemInstance* self, uint32 exp) +{ + self->SetExp(exp); +} + +void Perl_QuestItem_SetPrice(EQ::ItemInstance* self, uint32 price) +{ + self->SetPrice(price); +} + +void Perl_QuestItem_SetScaling(EQ::ItemInstance* self, bool is_scaling) +{ + self->SetScaling(is_scaling); +} + +void Perl_QuestItem_SetTimer(EQ::ItemInstance* self, std::string timer_name, uint32 timer) +{ + self->SetTimer(timer_name, timer); +} + +void Perl_QuestItem_StopTimer(EQ::ItemInstance* self, std::string timer_name) +{ + self->StopTimer(timer_name); +} + +EQ::ItemData* Perl_QuestItem_GetItem(EQ::ItemInstance* self) { + return const_cast(self->GetItem()); +} + +EQ::ItemData* Perl_QuestItem_GetUnscaledItem(EQ::ItemInstance* self) { + return const_cast(self->GetUnscaledItem()); +} void perl_register_questitem() { perl::interpreter perl(PERL_GET_THX); auto package = perl.new_class("QuestItem"); + package.add("AddEXP", &Perl_QuestItem_AddEXP); + package.add("ClearTimers", &Perl_QuestItem_ClearTimers); + package.add("Clone", &Perl_QuestItem_Clone); package.add("ContainsAugmentByID", &Perl_QuestItem_ContainsAugmentByID); package.add("CountAugmentByID", &Perl_QuestItem_CountAugmentByID); + package.add("DeleteCustomData", &Perl_QuestItem_DeleteCustomData); package.add("GetAugment", &Perl_QuestItem_GetAugment); + package.add("GetAugmentItemID", &Perl_QuestItem_GetAugmentItemID); + package.add("GetAugmentType", &Perl_QuestItem_GetAugmentType); package.add("GetCharges", &Perl_QuestItem_GetCharges); + package.add("GetColor", &Perl_QuestItem_GetColor); + package.add("GetCustomData", &Perl_QuestItem_GetCustomData); + package.add("GetCustomDataString", &Perl_QuestItem_GetCustomDataString); + package.add("GetEXP", &Perl_QuestItem_GetEXP); package.add("GetID", &Perl_QuestItem_GetID); + package.add("GetItem", (EQ::ItemData*(*)(EQ::ItemInstance*))&Perl_QuestItem_GetItem); + package.add("GetItem", (EQ::ItemInstance*(*)(EQ::ItemInstance*, uint8))&Perl_QuestItem_GetItem); + package.add("GetItemID", &Perl_QuestItem_GetItemID); + package.add("GetItemScriptID", &Perl_QuestItem_GetItemScriptID); + package.add("GetKillsNeeded", &Perl_QuestItem_GetKillsNeeded); + package.add("GetMaxEvolveLevel", &Perl_QuestItem_GetMaxEvolveLevel); package.add("GetName", &Perl_QuestItem_GetName); + package.add("GetPrice", &Perl_QuestItem_GetPrice); package.add("GetTaskDeliveredCount", &Perl_QuestItem_GetTaskDeliveredCount); + package.add("GetTotalItemCount", &Perl_QuestItem_GetTotalItemCount); + package.add("GetUnscaledItem", &Perl_QuestItem_GetUnscaledItem); + package.add("IsAmmo", &Perl_QuestItem_IsAmmo); package.add("IsAttuned", &Perl_QuestItem_IsAttuned); + package.add("IsAugmentable", &Perl_QuestItem_IsAugmentable); + package.add("IsAugmented", &Perl_QuestItem_IsAugmented); + package.add("IsEquipable", (bool(*)(EQ::ItemInstance*, int16))&Perl_QuestItem_IsEquipable); + package.add("IsEquipable", (bool(*)(EQ::ItemInstance*, uint16, uint16))&Perl_QuestItem_IsEquipable); + package.add("IsExpendable", &Perl_QuestItem_IsExpendable); + package.add("IsInstanceNoDrop", &Perl_QuestItem_IsInstanceNoDrop); package.add("IsStackable", &Perl_QuestItem_IsStackable); package.add("IsType", &Perl_QuestItem_IsType); + package.add("IsWeapon", &Perl_QuestItem_IsWeapon); package.add("ItemSay", (void(*)(EQ::ItemInstance*, const char*))&Perl_QuestItem_ItemSay); - package.add("ItemSay", (void(*)(EQ::ItemInstance*, const char*, int))&Perl_QuestItem_ItemSay); + package.add("ItemSay", (void(*)(EQ::ItemInstance*, const char*, uint8))&Perl_QuestItem_ItemSay); package.add("RemoveTaskDeliveredItems", &Perl_QuestItem_RemoveTaskDeliveredItems); + package.add("SetAttuned", &Perl_QuestItem_SetAttuned); package.add("SetCharges", &Perl_QuestItem_SetCharges); + package.add("SetColor", &Perl_QuestItem_SetColor); + package.add("SetCustomData", (void(*)(EQ::ItemInstance*, std::string, bool))&Perl_QuestItem_SetCustomData); + package.add("SetCustomData", (void(*)(EQ::ItemInstance*, std::string, float))&Perl_QuestItem_SetCustomData); + package.add("SetCustomData", (void(*)(EQ::ItemInstance*, std::string, int))&Perl_QuestItem_SetCustomData); + package.add("SetCustomData", (void(*)(EQ::ItemInstance*, std::string, std::string))&Perl_QuestItem_SetCustomData); + package.add("SetEXP", &Perl_QuestItem_SetEXP); + package.add("SetInstanceNoDrop", &Perl_QuestItem_SetInstanceNoDrop); + package.add("SetPrice", &Perl_QuestItem_SetPrice); package.add("SetScale", &Perl_QuestItem_SetScale); + package.add("SetScaling", &Perl_QuestItem_SetScaling); + package.add("SetTimer", &Perl_QuestItem_SetTimer); + package.add("StopTimer", &Perl_QuestItem_StopTimer); } #endif //EMBPERL_XS_CLASSES diff --git a/zone/perl_questitem_data.cpp b/zone/perl_questitem_data.cpp new file mode 100644 index 000000000..e328cd59a --- /dev/null +++ b/zone/perl_questitem_data.cpp @@ -0,0 +1,1078 @@ +#include "../common/features.h" +#include "client.h" + +#ifdef EMBPERL_XS_CLASSES + +#include "../common/global_define.h" +#include "embperl.h" + +int Perl_QuestItemData_GetMinimumStatus(EQ::ItemData* self) +{ + return self->MinStatus; +} + +int Perl_QuestItemData_GetItemClass(EQ::ItemData* self) +{ + return self->ItemClass; +} + +const char* Perl_QuestItemData_GetName(EQ::ItemData* self) +{ + return self->Name; +} + +const char* Perl_QuestItemData_GetLore(EQ::ItemData* self) +{ + return self->Lore; +} + +const char* Perl_QuestItemData_GetIDFile(EQ::ItemData* self) +{ + return self->IDFile; +} + +uint32 Perl_QuestItemData_GetID(EQ::ItemData* self) +{ + return self->ID; +} + +int Perl_QuestItemData_GetWeight(EQ::ItemData* self) +{ + return self->Weight; +} + +int Perl_QuestItemData_GetNoRent(EQ::ItemData* self) +{ + return self->NoRent; +} + +int Perl_QuestItemData_GetNoDrop(EQ::ItemData* self) +{ + return self->NoDrop; +} + +int Perl_QuestItemData_GetSize(EQ::ItemData* self) +{ + return self->Size; +} + +uint32 Perl_QuestItemData_GetSlots(EQ::ItemData* self) +{ + return self->Slots; +} + +uint32 Perl_QuestItemData_GetPrice(EQ::ItemData* self) +{ + return self->Price; +} + +uint32 Perl_QuestItemData_GetIcon(EQ::ItemData* self) +{ + return self->Icon; +} + +int32 Perl_QuestItemData_GetLoreGroup(EQ::ItemData* self) +{ + return self->LoreGroup; +} + +bool Perl_QuestItemData_GetLoreFlag(EQ::ItemData* self) +{ + return self->LoreFlag; +} + +bool Perl_QuestItemData_GetPendingLoreFlag(EQ::ItemData* self) +{ + return self->PendingLoreFlag; +} + +bool Perl_QuestItemData_GetArtifactFlag(EQ::ItemData* self) +{ + return self->ArtifactFlag; +} + +bool Perl_QuestItemData_GetSummonedFlag(EQ::ItemData* self) +{ + return self->SummonedFlag; +} + +int Perl_QuestItemData_GetFVNoDrop(EQ::ItemData* self) +{ + return self->FVNoDrop; +} + +uint32 Perl_QuestItemData_GetFavor(EQ::ItemData* self) +{ + return self->Favor; +} + +uint32 Perl_QuestItemData_GetGuildFavor(EQ::ItemData* self) +{ + return self->GuildFavor; +} + +uint32 Perl_QuestItemData_GetPointType(EQ::ItemData* self) +{ + return self->PointType; +} + +int Perl_QuestItemData_GetBagType(EQ::ItemData* self) +{ + return self->BagType; +} + +int Perl_QuestItemData_GetBagSlots(EQ::ItemData* self) +{ + return self->BagSlots; +} + +int Perl_QuestItemData_GetBagSize(EQ::ItemData* self) +{ + return self->BagSize; +} + +int Perl_QuestItemData_GetBagWeightReduction(EQ::ItemData* self) +{ + return self->BagWR; +} + +bool Perl_QuestItemData_GetBenefitFlag(EQ::ItemData* self) +{ + return self->BenefitFlag; +} + +bool Perl_QuestItemData_GetTradeskills(EQ::ItemData* self) +{ + return self->Tradeskills; +} + +int Perl_QuestItemData_GetCR(EQ::ItemData* self) +{ + return self->CR; +} + +int Perl_QuestItemData_GetDR(EQ::ItemData* self) +{ + return self->DR; +} + +int Perl_QuestItemData_GetPR(EQ::ItemData* self) +{ + return self->PR; +} + +int Perl_QuestItemData_GetMR(EQ::ItemData* self) +{ + return self->MR; +} + +int Perl_QuestItemData_GetFR(EQ::ItemData* self) +{ + return self->FR; +} + +int Perl_QuestItemData_GetSTR(EQ::ItemData* self) +{ + return self->AStr; +} + +int Perl_QuestItemData_GetSTA(EQ::ItemData* self) +{ + return self->ASta; +} + +int Perl_QuestItemData_GetAGI(EQ::ItemData* self) +{ + return self->AAgi; +} + +int Perl_QuestItemData_GetDEX(EQ::ItemData* self) +{ + return self->ADex; +} + +int Perl_QuestItemData_GetCHA(EQ::ItemData* self) +{ + return self->ACha; +} + +int Perl_QuestItemData_GetINT(EQ::ItemData* self) +{ + return self->AInt; +} + +int Perl_QuestItemData_GetAWis(EQ::ItemData* self) +{ + return self->AWis; +} + +int Perl_QuestItemData_GetHP(EQ::ItemData* self) +{ + return self->HP; +} + +int Perl_QuestItemData_GetMana(EQ::ItemData* self) +{ + return self->Mana; +} + +int Perl_QuestItemData_GetAC(EQ::ItemData* self) +{ + return self->AC; +} + +uint32 Perl_QuestItemData_GetDeity(EQ::ItemData* self) +{ + return self->Deity; +} + +int Perl_QuestItemData_GetSkillModifierValue(EQ::ItemData* self) +{ + return self->SkillModValue; +} + +uint32 Perl_QuestItemData_GetSkillModifierType(EQ::ItemData* self) +{ + return self->SkillModType; +} + +uint32 Perl_QuestItemData_GetBaneDamageRace(EQ::ItemData* self) +{ + return self->BaneDmgRace; +} + +int Perl_QuestItemData_GetBaneDamageAmount(EQ::ItemData* self) +{ + return self->BaneDmgAmt; +} + +uint32 Perl_QuestItemData_GetBaneDamageBody(EQ::ItemData* self) +{ + return self->BaneDmgBody; +} + +bool Perl_QuestItemData_GetMagic(EQ::ItemData* self) +{ + return self->Magic; +} + +int Perl_QuestItemData_GetCastTime_(EQ::ItemData* self) +{ + return self->CastTime_; +} + +int Perl_QuestItemData_GetReqLevel(EQ::ItemData* self) +{ + return self->ReqLevel; +} + +uint32 Perl_QuestItemData_GetBardSkillType(EQ::ItemData* self) +{ + return self->BardType; +} + +int Perl_QuestItemData_GetBardSkillValue(EQ::ItemData* self) +{ + return self->BardValue; +} + +int Perl_QuestItemData_GetLight(EQ::ItemData* self) +{ + return self->Light; +} + +int Perl_QuestItemData_GetDelay(EQ::ItemData* self) +{ + return self->Delay; +} + +int Perl_QuestItemData_GetRecLevel(EQ::ItemData* self) +{ + return self->RecLevel; +} + +int Perl_QuestItemData_GetRecSkill(EQ::ItemData* self) +{ + return self->RecSkill; +} + +int Perl_QuestItemData_GetElementalDamageType(EQ::ItemData* self) +{ + return self->ElemDmgType; +} + +int Perl_QuestItemData_GetElementalDamageAmount(EQ::ItemData* self) +{ + return self->ElemDmgAmt; +} + +int Perl_QuestItemData_GetRange(EQ::ItemData* self) +{ + return self->Range; +} + +uint32 Perl_QuestItemData_GetDamage(EQ::ItemData* self) +{ + return self->Damage; +} + +uint32 Perl_QuestItemData_GetColor(EQ::ItemData* self) +{ + return self->Color; +} + +uint32 Perl_QuestItemData_GetClasses(EQ::ItemData* self) +{ + return self->Classes; +} + +uint32 Perl_QuestItemData_GetRaces(EQ::ItemData* self) +{ + return self->Races; +} + +int Perl_QuestItemData_GetMaximumCharges(EQ::ItemData* self) +{ + return self->MaxCharges; +} + +int Perl_QuestItemData_GetItemType(EQ::ItemData* self) +{ + return self->ItemType; +} + +int Perl_QuestItemData_GetMaterial(EQ::ItemData* self) +{ + return self->Material; +} + +double Perl_QuestItemData_GetSellRate(EQ::ItemData* self) +{ + return self->SellRate; +} + +uint32 Perl_QuestItemData_GetFulfilment(EQ::ItemData* self) +{ + return self->Fulfilment; +} + +int Perl_QuestItemData_GetCastTime(EQ::ItemData* self) +{ + return self->CastTime; +} + +uint32 Perl_QuestItemData_GetEliteMaterial(EQ::ItemData* self) +{ + return self->EliteMaterial; +} + +int Perl_QuestItemData_GetProcRate(EQ::ItemData* self) +{ + return self->ProcRate; +} + +int Perl_QuestItemData_GetCombatEffects(EQ::ItemData* self) +{ + return self->CombatEffects; +} + +int Perl_QuestItemData_GetShielding(EQ::ItemData* self) +{ + return self->Shielding; +} + +int Perl_QuestItemData_GetStunResist(EQ::ItemData* self) +{ + return self->StunResist; +} + +int Perl_QuestItemData_GetStrikeThrough(EQ::ItemData* self) +{ + return self->StrikeThrough; +} + +uint32 Perl_QuestItemData_GetExtraDamageSkill(EQ::ItemData* self) +{ + return self->ExtraDmgSkill; +} + +uint32 Perl_QuestItemData_GetExtraDamageAmount(EQ::ItemData* self) +{ + return self->ExtraDmgAmt; +} + +int Perl_QuestItemData_GetSpellShield(EQ::ItemData* self) +{ + return self->SpellShield; +} + +int Perl_QuestItemData_GetAvoidance(EQ::ItemData* self) +{ + return self->Avoidance; +} + +int Perl_QuestItemData_GetAccuracy(EQ::ItemData* self) +{ + return self->Accuracy; +} + +uint32 Perl_QuestItemData_GetCharmFileID(EQ::ItemData* self) +{ + return self->CharmFileID; +} + +int Perl_QuestItemData_GetFactionModifier1(EQ::ItemData* self) +{ + return self->FactionMod1; +} + +int Perl_QuestItemData_GetFactionModifier2(EQ::ItemData* self) +{ + return self->FactionMod2; +} + +int Perl_QuestItemData_GetFactionModifier3(EQ::ItemData* self) +{ + return self->FactionMod3; +} + +int Perl_QuestItemData_GetFactionModifier4(EQ::ItemData* self) +{ + return self->FactionMod4; +} + +int Perl_QuestItemData_GetFactionAmount1(EQ::ItemData* self) +{ + return self->FactionAmt1; +} + +int Perl_QuestItemData_GetFactionAmount2(EQ::ItemData* self) +{ + return self->FactionAmt2; +} + +int Perl_QuestItemData_GetFactionAmount3(EQ::ItemData* self) +{ + return self->FactionAmt3; +} + +int Perl_QuestItemData_GetFactionAmount4(EQ::ItemData* self) +{ + return self->FactionAmt4; +} + +const char* Perl_QuestItemData_GetCharmFile(EQ::ItemData* self) +{ + return self->CharmFile; +} + +uint32 Perl_QuestItemData_GetAugmentType(EQ::ItemData* self) +{ + return self->AugType; +} + +int Perl_QuestItemData_GetAugmentSlotType(EQ::ItemData* self, uint8 slot_id) +{ + if (!EQ::ValueWithin(slot_id, EQ::invaug::SOCKET_BEGIN, EQ::invaug::SOCKET_END)) { + return 0; + } + + return self->AugSlotType[slot_id]; +} + +int Perl_QuestItemData_GetAugmentSlotVisible(EQ::ItemData* self, uint8 slot_id) +{ + if (!EQ::ValueWithin(slot_id, EQ::invaug::SOCKET_BEGIN, EQ::invaug::SOCKET_END)) { + return 0; + } + + return self->AugSlotVisible[slot_id]; +} + +int Perl_QuestItemData_GetAugmentSlotUnk2(EQ::ItemData* self, uint8 slot_id) +{ + if (!EQ::ValueWithin(slot_id, EQ::invaug::SOCKET_BEGIN, EQ::invaug::SOCKET_END)) { + return 0; + } + + return self->AugSlotUnk2[slot_id]; +} + +uint32 Perl_QuestItemData_GetLDoNTheme(EQ::ItemData* self) +{ + return self->LDoNTheme; +} + +uint32 Perl_QuestItemData_GetLDoNPrice(EQ::ItemData* self) +{ + return self->LDoNPrice; +} + +uint32 Perl_QuestItemData_GetLDoNSold(EQ::ItemData* self) +{ + return self->LDoNSold; +} + +uint32 Perl_QuestItemData_GetBaneDamageRaceAmount(EQ::ItemData* self) +{ + return self->BaneDmgRaceAmt; +} + +uint32 Perl_QuestItemData_GetAugmentRestrict(EQ::ItemData* self) +{ + return self->AugRestrict; +} + +int32 Perl_QuestItemData_GetEndurance(EQ::ItemData* self) +{ + return self->Endur; +} + +int32 Perl_QuestItemData_GetDOTShielding(EQ::ItemData* self) +{ + return self->DotShielding; +} + +int32 Perl_QuestItemData_GetAttack(EQ::ItemData* self) +{ + return self->Attack; +} + +int32 Perl_QuestItemData_GetRegen(EQ::ItemData* self) +{ + return self->Regen; +} + +int32 Perl_QuestItemData_GetManaRegen(EQ::ItemData* self) +{ + return self->ManaRegen; +} + +int32 Perl_QuestItemData_GetEnduranceRegen(EQ::ItemData* self) +{ + return self->EnduranceRegen; +} + +int32 Perl_QuestItemData_GetHaste(EQ::ItemData* self) +{ + return self->Haste; +} + +int32 Perl_QuestItemData_GetDamageShield(EQ::ItemData* self) +{ + return self->DamageShield; +} + +uint32 Perl_QuestItemData_GetRecastDelay(EQ::ItemData* self) +{ + return self->RecastDelay; +} + +uint32 Perl_QuestItemData_GetRecastType(EQ::ItemData* self) +{ + return self->RecastType; +} + +uint32 Perl_QuestItemData_GetAugmentDistiller(EQ::ItemData* self) +{ + return self->AugDistiller; +} + +bool Perl_QuestItemData_GetAttuneable(EQ::ItemData* self) +{ + return self->Attuneable; +} + +bool Perl_QuestItemData_GetNoPet(EQ::ItemData* self) +{ + return self->NoPet; +} + +bool Perl_QuestItemData_GetPotionBelt(EQ::ItemData* self) +{ + return self->PotionBelt; +} + +bool Perl_QuestItemData_GetStackable(EQ::ItemData* self) +{ + return self->Stackable; +} + +bool Perl_QuestItemData_GetNoTransfer(EQ::ItemData* self) +{ + return self->NoTransfer; +} + +bool Perl_QuestItemData_GetQuestItemFlag(EQ::ItemData* self) +{ + return self->QuestItemFlag; +} + +int Perl_QuestItemData_GetStackSize(EQ::ItemData* self) +{ + return self->StackSize; +} + +int Perl_QuestItemData_GetPotionBeltSlots(EQ::ItemData* self) +{ + return self->PotionBeltSlots; +} + +int Perl_QuestItemData_GetClickEffect(EQ::ItemData* self) +{ + return self->Click.Effect; +} + +int Perl_QuestItemData_GetClickType(EQ::ItemData* self) +{ + return self->Click.Type; +} + +int Perl_QuestItemData_GetClickLevel(EQ::ItemData* self) +{ + return self->Click.Level; +} + +int Perl_QuestItemData_GetClickLevel2(EQ::ItemData* self) +{ + return self->Click.Level2; +} + +int Perl_QuestItemData_GetProcEffect(EQ::ItemData* self) +{ + return self->Proc.Effect; +} + +int Perl_QuestItemData_GetProcType(EQ::ItemData* self) +{ + return self->Proc.Type; +} + +int Perl_QuestItemData_GetProcLevel(EQ::ItemData* self) +{ + return self->Proc.Level; +} + +int Perl_QuestItemData_GetProcLevel2(EQ::ItemData* self) +{ + return self->Proc.Level2; +} + +int Perl_QuestItemData_GetWornEffect(EQ::ItemData* self) +{ + return self->Worn.Effect; +} + +int Perl_QuestItemData_GetWornType(EQ::ItemData* self) +{ + return self->Worn.Type; +} + +int Perl_QuestItemData_GetWornLevel(EQ::ItemData* self) +{ + return self->Worn.Level; +} + +int Perl_QuestItemData_GetWornLevel2(EQ::ItemData* self) +{ + return self->Worn.Level2; +} + +int Perl_QuestItemData_GetFocusEffect(EQ::ItemData* self) +{ + return self->Focus.Effect; +} + +int Perl_QuestItemData_GetFocusType(EQ::ItemData* self) +{ + return self->Focus.Type; +} + +int Perl_QuestItemData_GetFocusLevel(EQ::ItemData* self) +{ + return self->Focus.Level; +} + +int Perl_QuestItemData_GetFocusLevel2(EQ::ItemData* self) +{ + return self->Focus.Level2; +} + +int Perl_QuestItemData_GetScrollEffect(EQ::ItemData* self) +{ + return self->Scroll.Effect; +} + +int Perl_QuestItemData_GetScrollType(EQ::ItemData* self) +{ + return self->Scroll.Type; +} + +int Perl_QuestItemData_GetScrollLevel(EQ::ItemData* self) +{ + return self->Scroll.Level; +} + +int Perl_QuestItemData_GetScrollLevel2(EQ::ItemData* self) +{ + return self->Scroll.Level2; +} + +int Perl_QuestItemData_GetBardEffect(EQ::ItemData* self) +{ + return self->Bard.Effect; +} + +int Perl_QuestItemData_GetBardType(EQ::ItemData* self) +{ + return self->Bard.Type; +} + +int Perl_QuestItemData_GetBardLevel(EQ::ItemData* self) +{ + return self->Bard.Level; +} + +int Perl_QuestItemData_GetBardLevel2(EQ::ItemData* self) +{ + return self->Bard.Level2; +} + +int Perl_QuestItemData_GetBook(EQ::ItemData* self) +{ + return self->Book; +} + +uint32 Perl_QuestItemData_GetBookType(EQ::ItemData* self) +{ + return self->BookType; +} + +const char* Perl_QuestItemData_GetFilename(EQ::ItemData* self) +{ + return self->Filename; +} + +int Perl_QuestItemData_GetCorruption(EQ::ItemData* self) +{ + return self->SVCorruption; +} + +uint32 Perl_QuestItemData_GetPurity(EQ::ItemData* self) +{ + return self->Purity; +} + +uint32 Perl_QuestItemData_GetBackstabDamage(EQ::ItemData* self) +{ + return self->BackstabDmg; +} + +uint32 Perl_QuestItemData_GetDSMitigation(EQ::ItemData* self) +{ + return self->DSMitigation; +} + +int Perl_QuestItemData_GetHeroicSTR(EQ::ItemData* self) +{ + return self->HeroicStr; +} + +int Perl_QuestItemData_GetHeroicINT(EQ::ItemData* self) +{ + return self->HeroicInt; +} + +int Perl_QuestItemData_GetHeroicWIS(EQ::ItemData* self) +{ + return self->HeroicWis; +} + +int Perl_QuestItemData_GetHeroicAGI(EQ::ItemData* self) +{ + return self->HeroicAgi; +} + +int Perl_QuestItemData_GetHeroicDEX(EQ::ItemData* self) +{ + return self->HeroicDex; +} + +int Perl_QuestItemData_GetHeroicSTA(EQ::ItemData* self) +{ + return self->HeroicSta; +} + +int Perl_QuestItemData_GetHeroicCHA(EQ::ItemData* self) +{ + return self->HeroicCha; +} + +int Perl_QuestItemData_GetHeroicMR(EQ::ItemData* self) +{ + return self->HeroicMR; +} + +int Perl_QuestItemData_GetHeroicFR(EQ::ItemData* self) +{ + return self->HeroicFR; +} + +int Perl_QuestItemData_GetHeroicCR(EQ::ItemData* self) +{ + return self->HeroicCR; +} + +int Perl_QuestItemData_GetHeroicDR(EQ::ItemData* self) +{ + return self->HeroicDR; +} + +int Perl_QuestItemData_GetHeroicPR(EQ::ItemData* self) +{ + return self->HeroicPR; +} + +int Perl_QuestItemData_GetHeroicCorruption(EQ::ItemData* self) +{ + return self->HeroicSVCorrup; +} + +int Perl_QuestItemData_GetHealAmount(EQ::ItemData* self) +{ + return self->HealAmt; +} + +int Perl_QuestItemData_GetSpellDamage(EQ::ItemData* self) +{ + return self->SpellDmg; +} + +uint32 Perl_QuestItemData_GetLDoNSellBackRate(EQ::ItemData* self) +{ + return self->LDoNSellBackRate; +} + +uint32 Perl_QuestItemData_GetScriptFileID(EQ::ItemData* self) +{ + return self->ScriptFileID; +} + +int Perl_QuestItemData_GetExpendableArrow(EQ::ItemData* self) +{ + return self->ExpendableArrow; +} + +uint32 Perl_QuestItemData_GetClairvoyance(EQ::ItemData* self) +{ + return self->Clairvoyance; +} + +const char* Perl_QuestItemData_GetClickName(EQ::ItemData* self) +{ + return self->ClickName; +} + +const char* Perl_QuestItemData_GetProcName(EQ::ItemData* self) +{ + return self->ProcName; +} + +const char* Perl_QuestItemData_GetWornName(EQ::ItemData* self) +{ + return self->WornName; +} + +const char* Perl_QuestItemData_GetFocusName(EQ::ItemData* self) +{ + return self->FocusName; +} + +const char* Perl_QuestItemData_GetScrollName(EQ::ItemData* self) +{ + return self->ScrollName; +} + +void perl_register_questitem_data() +{ + perl::interpreter perl(PERL_GET_THX); + + auto package = perl.new_class("QuestItemData"); + package.add("GetAGI", &Perl_QuestItemData_GetAGI); + package.add("GetAC", &Perl_QuestItemData_GetAC); + package.add("GetCHA", &Perl_QuestItemData_GetCHA); + package.add("GetDEX", &Perl_QuestItemData_GetDEX); + package.add("GetINT", &Perl_QuestItemData_GetINT); + package.add("GetSTA", &Perl_QuestItemData_GetSTA); + package.add("GetSTR", &Perl_QuestItemData_GetSTR); + package.add("GetAWis", &Perl_QuestItemData_GetAWis); + package.add("GetAccuracy", &Perl_QuestItemData_GetAccuracy); + package.add("GetArtifactFlag", &Perl_QuestItemData_GetArtifactFlag); + package.add("GetAttack", &Perl_QuestItemData_GetAttack); + package.add("GetAttuneable", &Perl_QuestItemData_GetAttuneable); + package.add("GetAugmentDistiller", &Perl_QuestItemData_GetAugmentDistiller); + package.add("GetAugmentRestrict", &Perl_QuestItemData_GetAugmentRestrict); + package.add("GetAugmentSlotType", &Perl_QuestItemData_GetAugmentSlotType); + package.add("GetAugmentSlotUnk2", &Perl_QuestItemData_GetAugmentSlotUnk2); + package.add("GetAugmentSlotVisible", &Perl_QuestItemData_GetAugmentSlotVisible); + package.add("GetAugmentType", &Perl_QuestItemData_GetAugmentType); + package.add("GetAvoidance", &Perl_QuestItemData_GetAvoidance); + package.add("GetBackstabDamage", &Perl_QuestItemData_GetBackstabDamage); + package.add("GetBagSize", &Perl_QuestItemData_GetBagSize); + package.add("GetBagSlots", &Perl_QuestItemData_GetBagSlots); + package.add("GetBagType", &Perl_QuestItemData_GetBagType); + package.add("GetBagWeightReduction", &Perl_QuestItemData_GetBagWeightReduction); + package.add("GetBaneDamageAmount", &Perl_QuestItemData_GetBaneDamageAmount); + package.add("GetBaneDamageBody", &Perl_QuestItemData_GetBaneDamageBody); + package.add("GetBaneDamageRace", &Perl_QuestItemData_GetBaneDamageRace); + package.add("GetBaneDamageRaceAmount", &Perl_QuestItemData_GetBaneDamageRaceAmount); + package.add("GetBardEffect", &Perl_QuestItemData_GetBardEffect); + package.add("GetBardLevel", &Perl_QuestItemData_GetBardLevel); + package.add("GetBardLevel2", &Perl_QuestItemData_GetBardLevel2); + package.add("GetBardType", &Perl_QuestItemData_GetBardType); + package.add("GetBardSkillType", &Perl_QuestItemData_GetBardSkillType); + package.add("GetBardSkillValue", &Perl_QuestItemData_GetBardSkillValue); + package.add("GetBenefitFlag", &Perl_QuestItemData_GetBenefitFlag); + package.add("GetBook", &Perl_QuestItemData_GetBook); + package.add("GetBookType", &Perl_QuestItemData_GetBookType); + package.add("GetCR", &Perl_QuestItemData_GetCR); + package.add("GetCastTime", &Perl_QuestItemData_GetCastTime); + package.add("GetCastTime_", &Perl_QuestItemData_GetCastTime_); + package.add("GetCharmFile", &Perl_QuestItemData_GetCharmFile); + package.add("GetCharmFileID", &Perl_QuestItemData_GetCharmFileID); + package.add("GetClairvoyance", &Perl_QuestItemData_GetClairvoyance); + package.add("GetClasses", &Perl_QuestItemData_GetClasses); + package.add("GetClickName", &Perl_QuestItemData_GetClickName); + package.add("GetClickEffect", &Perl_QuestItemData_GetClickEffect); + package.add("GetClickLevel", &Perl_QuestItemData_GetClickLevel); + package.add("GetClickLevel2", &Perl_QuestItemData_GetClickLevel2); + package.add("GetClickType", &Perl_QuestItemData_GetClickType); + package.add("GetColor", &Perl_QuestItemData_GetColor); + package.add("GetCombatEffects", &Perl_QuestItemData_GetCombatEffects); + package.add("GetCorruption", &Perl_QuestItemData_GetCorruption); + package.add("GetDR", &Perl_QuestItemData_GetDR); + package.add("GetDSMitigation", &Perl_QuestItemData_GetDSMitigation); + package.add("GetDamage", &Perl_QuestItemData_GetDamage); + package.add("GetDamageShield", &Perl_QuestItemData_GetDamageShield); + package.add("GetDeity", &Perl_QuestItemData_GetDeity); + package.add("GetDelay", &Perl_QuestItemData_GetDelay); + package.add("GetDOTShielding", &Perl_QuestItemData_GetDOTShielding); + package.add("GetElementalDamageAmount", &Perl_QuestItemData_GetElementalDamageAmount); + package.add("GetElementalDamageType", &Perl_QuestItemData_GetElementalDamageType); + package.add("GetEliteMaterial", &Perl_QuestItemData_GetEliteMaterial); + package.add("GetEndurance", &Perl_QuestItemData_GetEndurance); + package.add("GetEnduranceRegen", &Perl_QuestItemData_GetEnduranceRegen); + package.add("GetExpendableArrow", &Perl_QuestItemData_GetExpendableArrow); + package.add("GetExtraDamageAmount", &Perl_QuestItemData_GetExtraDamageAmount); + package.add("GetExtraDamageSkill", &Perl_QuestItemData_GetExtraDamageSkill); + package.add("GetFR", &Perl_QuestItemData_GetFR); + package.add("GetFVNoDrop", &Perl_QuestItemData_GetFVNoDrop); + package.add("GetFactionAmount1", &Perl_QuestItemData_GetFactionAmount1); + package.add("GetFactionAmount2", &Perl_QuestItemData_GetFactionAmount2); + package.add("GetFactionAmount3", &Perl_QuestItemData_GetFactionAmount3); + package.add("GetFactionAmount4", &Perl_QuestItemData_GetFactionAmount4); + package.add("GetFactionModifier1", &Perl_QuestItemData_GetFactionModifier1); + package.add("GetFactionModifier2", &Perl_QuestItemData_GetFactionModifier2); + package.add("GetFactionModifier3", &Perl_QuestItemData_GetFactionModifier3); + package.add("GetFactionModifier4", &Perl_QuestItemData_GetFactionModifier4); + package.add("GetFavor", &Perl_QuestItemData_GetFavor); + package.add("GetFilename", &Perl_QuestItemData_GetFilename); + package.add("GetFocusEffect", &Perl_QuestItemData_GetFocusEffect); + package.add("GetFocusName", &Perl_QuestItemData_GetFocusName); + package.add("GetFocusLevel", &Perl_QuestItemData_GetFocusLevel); + package.add("GetFocusLevel2", &Perl_QuestItemData_GetFocusLevel2); + package.add("GetFocusType", &Perl_QuestItemData_GetFocusType); + package.add("GetFulfilment", &Perl_QuestItemData_GetFulfilment); + package.add("GetGuildFavor", &Perl_QuestItemData_GetGuildFavor); + package.add("GetHP", &Perl_QuestItemData_GetHP); + package.add("GetHaste", &Perl_QuestItemData_GetHaste); + package.add("GetHealAmount", &Perl_QuestItemData_GetHealAmount); + package.add("GetHeroicAGI", &Perl_QuestItemData_GetHeroicAGI); + package.add("GetHeroicCR", &Perl_QuestItemData_GetHeroicCR); + package.add("GetHeroicCHA", &Perl_QuestItemData_GetHeroicCHA); + package.add("GetHeroicCorruption", &Perl_QuestItemData_GetHeroicCorruption); + package.add("GetHeroicDR", &Perl_QuestItemData_GetHeroicDR); + package.add("GetHeroicDEX", &Perl_QuestItemData_GetHeroicDEX); + package.add("GetHeroicFR", &Perl_QuestItemData_GetHeroicFR); + package.add("GetHeroicINT", &Perl_QuestItemData_GetHeroicINT); + package.add("GetHeroicMR", &Perl_QuestItemData_GetHeroicMR); + package.add("GetHeroicPR", &Perl_QuestItemData_GetHeroicPR); + package.add("GetHeroicSTA", &Perl_QuestItemData_GetHeroicSTA); + package.add("GetHeroicSTR", &Perl_QuestItemData_GetHeroicSTR); + package.add("GetHeroicWIS", &Perl_QuestItemData_GetHeroicWIS); + package.add("GetID", &Perl_QuestItemData_GetID); + package.add("GetIDFile", &Perl_QuestItemData_GetIDFile); + package.add("GetIcon", &Perl_QuestItemData_GetIcon); + package.add("GetItemClass", &Perl_QuestItemData_GetItemClass); + package.add("GetItemType", &Perl_QuestItemData_GetItemType); + package.add("GetLDoNPrice", &Perl_QuestItemData_GetLDoNPrice); + package.add("GetLDoNSellBackRate", &Perl_QuestItemData_GetLDoNSellBackRate); + package.add("GetLDoNSold", &Perl_QuestItemData_GetLDoNSold); + package.add("GetLDoNTheme", &Perl_QuestItemData_GetLDoNTheme); + package.add("GetLight", &Perl_QuestItemData_GetLight); + package.add("GetLore", &Perl_QuestItemData_GetLore); + package.add("GetLoreFlag", &Perl_QuestItemData_GetLoreFlag); + package.add("GetLoreGroup", &Perl_QuestItemData_GetLoreGroup); + package.add("GetMR", &Perl_QuestItemData_GetMR); + package.add("GetMagic", &Perl_QuestItemData_GetMagic); + package.add("GetMana", &Perl_QuestItemData_GetMana); + package.add("GetManaRegen", &Perl_QuestItemData_GetManaRegen); + package.add("GetMaterial", &Perl_QuestItemData_GetMaterial); + package.add("GetMaximumCharges", &Perl_QuestItemData_GetMaximumCharges); + package.add("GetMinimumStatus", &Perl_QuestItemData_GetMinimumStatus); + package.add("GetName", &Perl_QuestItemData_GetName); + package.add("GetNoDrop", &Perl_QuestItemData_GetNoDrop); + package.add("GetNoPet", &Perl_QuestItemData_GetNoPet); + package.add("GetNoRent", &Perl_QuestItemData_GetNoRent); + package.add("GetNoTransfer", &Perl_QuestItemData_GetNoTransfer); + package.add("GetPR", &Perl_QuestItemData_GetPR); + package.add("GetPendingLoreFlag", &Perl_QuestItemData_GetPendingLoreFlag); + package.add("GetPointType", &Perl_QuestItemData_GetPointType); + package.add("GetPotionBelt", &Perl_QuestItemData_GetPotionBelt); + package.add("GetPotionBeltSlots", &Perl_QuestItemData_GetPotionBeltSlots); + package.add("GetPrice", &Perl_QuestItemData_GetPrice); + package.add("GetProcEffect", &Perl_QuestItemData_GetProcEffect); + package.add("GetProcName", &Perl_QuestItemData_GetProcName); + package.add("GetProcRate", &Perl_QuestItemData_GetProcRate); + package.add("GetProcLevel", &Perl_QuestItemData_GetProcLevel); + package.add("GetProcLevel2", &Perl_QuestItemData_GetProcLevel2); + package.add("GetProcType", &Perl_QuestItemData_GetProcType); + package.add("GetPurity", &Perl_QuestItemData_GetPurity); + package.add("GetQuestItemFlag", &Perl_QuestItemData_GetQuestItemFlag); + package.add("GetRaces", &Perl_QuestItemData_GetRaces); + package.add("GetRange", &Perl_QuestItemData_GetRange); + package.add("GetRecLevel", &Perl_QuestItemData_GetRecLevel); + package.add("GetRecSkill", &Perl_QuestItemData_GetRecSkill); + package.add("GetRecastDelay", &Perl_QuestItemData_GetRecastDelay); + package.add("GetRecastType", &Perl_QuestItemData_GetRecastType); + package.add("GetRegen", &Perl_QuestItemData_GetRegen); + package.add("GetReqLevel", &Perl_QuestItemData_GetReqLevel); + package.add("GetScriptFileID", &Perl_QuestItemData_GetScriptFileID); + package.add("GetScrollEffect", &Perl_QuestItemData_GetScrollEffect); + package.add("GetScrollName", &Perl_QuestItemData_GetScrollName); + package.add("GetScrollLevel", &Perl_QuestItemData_GetScrollLevel); + package.add("GetScrollLevel2", &Perl_QuestItemData_GetScrollLevel2); + package.add("GetScrollType", &Perl_QuestItemData_GetScrollType); + package.add("GetSellRate", &Perl_QuestItemData_GetSellRate); + package.add("GetShielding", &Perl_QuestItemData_GetShielding); + package.add("GetSize", &Perl_QuestItemData_GetSize); + package.add("GetSkillModifierType", &Perl_QuestItemData_GetSkillModifierType); + package.add("GetSkillModifierValue", &Perl_QuestItemData_GetSkillModifierValue); + package.add("GetSlots", &Perl_QuestItemData_GetSlots); + package.add("GetSpellDamage", &Perl_QuestItemData_GetSpellDamage); + package.add("GetSpellShield", &Perl_QuestItemData_GetSpellShield); + package.add("GetStackSize", &Perl_QuestItemData_GetStackSize); + package.add("GetStackable", &Perl_QuestItemData_GetStackable); + package.add("GetStrikeThrough", &Perl_QuestItemData_GetStrikeThrough); + package.add("GetStunResist", &Perl_QuestItemData_GetStunResist); + package.add("GetSummonedFlag", &Perl_QuestItemData_GetSummonedFlag); + package.add("GetTradeskills", &Perl_QuestItemData_GetTradeskills); + package.add("GetWeight", &Perl_QuestItemData_GetWeight); + package.add("GetWornName", &Perl_QuestItemData_GetWornName); + package.add("GetWornEffect", &Perl_QuestItemData_GetWornEffect); + package.add("GetWornLevel", &Perl_QuestItemData_GetWornLevel); + package.add("GetWornLevel2", &Perl_QuestItemData_GetWornLevel2); + package.add("GetWornType", &Perl_QuestItemData_GetWornType); +} + +#endif //EMBPERL_XS_CLASSES diff --git a/zone/perl_spawn.cpp b/zone/perl_spawn.cpp new file mode 100644 index 000000000..95c38aed1 --- /dev/null +++ b/zone/perl_spawn.cpp @@ -0,0 +1,171 @@ +#include "../common/features.h" + +#ifdef EMBPERL_XS_CLASSES +#include "../common/global_define.h" +#include "embperl.h" +#include "spawn2.h" + +void Perl_Spawn_Depop(Spawn2* self) +{ + self->Depop(); +} + +void Perl_Spawn_Disable(Spawn2* self) +{ + return self->Disable(); +} + +void Perl_Spawn_Enable(Spawn2* self) +{ + return self->Enable(); +} + +void Perl_Spawn_ForceDespawn(Spawn2* self) +{ + self->ForceDespawn(); +} + +uint32 Perl_Spawn_GetCurrentNPCID(Spawn2* self) +{ + return self->CurrentNPCID(); +} + +float Perl_Spawn_GetHeading(Spawn2* self) +{ + return self->GetHeading(); +} + +uint32 Perl_Spawn_GetID(Spawn2* self) +{ + return self->GetID(); +} + +uint32 Perl_Spawn_GetKillCount(Spawn2* self) +{ + return self->GetKillCount(); +} + +uint32 Perl_Spawn_GetRespawnTimer(Spawn2* self) +{ + return self->RespawnTimer(); +} + +uint32 Perl_Spawn_GetSpawnCondition(Spawn2* self) +{ + return self->GetSpawnCondition(); +} + +uint32 Perl_Spawn_GetSpawnGroupID(Spawn2* self) +{ + return self->SpawnGroupID(); +} + +uint32 Perl_Spawn_GetVariance(Spawn2* self) +{ + return self->GetVariance(); +} + +float Perl_Spawn_GetX(Spawn2* self) +{ + return self->GetX(); +} + +float Perl_Spawn_GetY(Spawn2* self) +{ + return self->GetY(); +} + +float Perl_Spawn_GetZ(Spawn2* self) +{ + return self->GetZ(); +} + +bool Perl_Spawn_IsEnabled(Spawn2* self) +{ + return self->Enabled(); +} + +bool Perl_Spawn_IsNPCPointerValid(Spawn2* self) +{ + return self->NPCPointerValid(); +} + +void Perl_Spawn_LoadGrid(Spawn2* self) +{ + self->LoadGrid(); +} + +void Perl_Spawn_Repop(Spawn2* self) +{ + self->Repop(); +} + +void Perl_Spawn_Repop(Spawn2* self, uint32 delay) +{ + self->Repop(delay); +} + +void Perl_Spawn_Reset(Spawn2* self) +{ + self->Reset(); +} + +void Perl_Spawn_SetCurrentNPCID(Spawn2* self, uint32 npc_id) +{ + self->SetCurrentNPCID(npc_id); +} + +void Perl_Spawn_SetNPCPointer(Spawn2* self, NPC* n) +{ + self->SetNPCPointer(n); +} + +void Perl_Spawn_SetRespawnTimer(Spawn2* self, uint32 new_respawn_time) +{ + self->SetRespawnTimer(new_respawn_time); +} + +void Perl_Spawn_SetTimer(Spawn2* self, uint32 duration) +{ + self->SetTimer(duration); +} + +void Perl_Spawn_SetVariance(Spawn2* self, uint32 new_variance) +{ + self->SetVariance(new_variance); +} + +void perl_register_spawn() +{ + perl::interpreter perl(PERL_GET_THX); + + auto package = perl.new_class("Spawn"); + package.add("Depop", (void(*)(Spawn2*))&Perl_Spawn_Depop); + package.add("Disable", (void(*)(Spawn2*))&Perl_Spawn_Disable); + package.add("Enable", (void(*)(Spawn2*))&Perl_Spawn_Enable); + package.add("ForceDespawn", (void(*)(Spawn2*))&Perl_Spawn_ForceDespawn); + package.add("GetCurrentNPCID", (uint32(*)(Spawn2*))&Perl_Spawn_GetCurrentNPCID); + package.add("GetHeading", (float(*)(Spawn2*))&Perl_Spawn_GetHeading); + package.add("GetID", (uint32(*)(Spawn2*))&Perl_Spawn_GetID); + package.add("GetKillCount", (uint32(*)(Spawn2*))&Perl_Spawn_GetKillCount); + package.add("GetRespawnTimer", (uint32(*)(Spawn2*))&Perl_Spawn_GetRespawnTimer); + package.add("GetSpawnCondition", (uint32(*)(Spawn2*))&Perl_Spawn_GetSpawnCondition); + package.add("GetSpawnGroupID", (uint32(*)(Spawn2*))&Perl_Spawn_GetSpawnGroupID); + package.add("GetVariance", (uint32(*)(Spawn2*))&Perl_Spawn_GetVariance); + package.add("GetX", (float(*)(Spawn2*))&Perl_Spawn_GetX); + package.add("GetY", (float(*)(Spawn2*))&Perl_Spawn_GetY); + package.add("GetZ", (float(*)(Spawn2*))&Perl_Spawn_GetZ); + package.add("IsEnabled", (bool(*)(Spawn2*))&Perl_Spawn_IsEnabled); + package.add("IsNPCPointerValid", (bool(*)(Spawn2*))&Perl_Spawn_IsNPCPointerValid); + package.add("LoadGrid", (void(*)(Spawn2*))&Perl_Spawn_LoadGrid); + package.add("Repop", (void(*)(Spawn2*))&Perl_Spawn_Repop); + package.add("Repop", (void(*)(Spawn2*, uint32))&Perl_Spawn_Repop); + package.add("Reset", (void(*)(Spawn2*))&Perl_Spawn_Reset); + package.add("SetCurrentNPCID", (void(*)(Spawn2*, uint32))&Perl_Spawn_SetCurrentNPCID); + package.add("SetNPCPointer", (void(*)(Spawn2*, NPC*))&Perl_Spawn_SetNPCPointer); + package.add("SetRespawnTimer", (void(*)(Spawn2*, uint32))&Perl_Spawn_SetRespawnTimer); + package.add("SetTimer", (void(*)(Spawn2*, uint32))&Perl_Spawn_SetTimer); + package.add("SetVariance", (void(*)(Spawn2*, uint32))&Perl_Spawn_SetVariance); +} + +#endif //EMBPERL_XS_CLASSES diff --git a/zone/perl_stat_bonuses.cpp b/zone/perl_stat_bonuses.cpp new file mode 100644 index 000000000..398abf487 --- /dev/null +++ b/zone/perl_stat_bonuses.cpp @@ -0,0 +1,1551 @@ +#include "../common/features.h" +#include "common.h" + +#ifdef EMBPERL_XS_CLASSES + +#include "embperl.h" +#include "../common/data_verification.h" + +int32 Perl_StatBonuses_GetAC(StatBonuses* self) +{ + return self->AC; +} + +int64 Perl_StatBonuses_GetHP(StatBonuses* self) +{ + return self->HP; +} + +int64 Perl_StatBonuses_GetHPRegen(StatBonuses* self) +{ + return self->HPRegen; +} + +int64 Perl_StatBonuses_GetMaxHP(StatBonuses* self) +{ + return self->MaxHP; +} + +int64 Perl_StatBonuses_GetManaRegen(StatBonuses* self) +{ + return self->ManaRegen; +} + +int64 Perl_StatBonuses_GetEnduranceRegen(StatBonuses* self) +{ + return self->EnduranceRegen; +} + +int64 Perl_StatBonuses_GetMana(StatBonuses* self) +{ + return self->Mana; +} + +int64 Perl_StatBonuses_GetEndurance(StatBonuses* self) +{ + return self->Endurance; +} + +int32 Perl_StatBonuses_GetATK(StatBonuses* self) +{ + return self->ATK; +} + +int32 Perl_StatBonuses_GetSTR(StatBonuses* self) +{ + return self->STR; +} + +int32 Perl_StatBonuses_GetSTRCapModifier(StatBonuses* self) +{ + return self->STRCapMod; +} + +int32 Perl_StatBonuses_GetHeroicSTR(StatBonuses* self) +{ + return self->HeroicSTR; +} + +int32 Perl_StatBonuses_GetSTA(StatBonuses* self) +{ + return self->STA; +} + +int32 Perl_StatBonuses_GetSTACapModifier(StatBonuses* self) +{ + return self->STACapMod; +} + +int32 Perl_StatBonuses_GetHeroicSTA(StatBonuses* self) +{ + return self->HeroicSTA; +} + +int32 Perl_StatBonuses_GetDEX(StatBonuses* self) +{ + return self->DEX; +} + +int32 Perl_StatBonuses_GetDEXCapModifier(StatBonuses* self) +{ + return self->DEXCapMod; +} + +int32 Perl_StatBonuses_GetHeroicDEX(StatBonuses* self) +{ + return self->HeroicDEX; +} + +int32 Perl_StatBonuses_GetAGI(StatBonuses* self) +{ + return self->AGI; +} + +int32 Perl_StatBonuses_GetAGICapModifier(StatBonuses* self) +{ + return self->AGICapMod; +} + +int32 Perl_StatBonuses_GetHeroicAGI(StatBonuses* self) +{ + return self->HeroicAGI; +} + +int32 Perl_StatBonuses_GetINT(StatBonuses* self) +{ + return self->INT; +} + +int32 Perl_StatBonuses_GetINTCapModifier(StatBonuses* self) +{ + return self->INTCapMod; +} + +int32 Perl_StatBonuses_GetHeroicINT(StatBonuses* self) +{ + return self->HeroicINT; +} + +int32 Perl_StatBonuses_GetWIS(StatBonuses* self) +{ + return self->WIS; +} + +int32 Perl_StatBonuses_GetWISCapModifier(StatBonuses* self) +{ + return self->WISCapMod; +} + +int32 Perl_StatBonuses_GetHeroicWIS(StatBonuses* self) +{ + return self->HeroicWIS; +} + +int32 Perl_StatBonuses_GetCHA(StatBonuses* self) +{ + return self->CHA; +} + +int32 Perl_StatBonuses_GetCHACapModifier(StatBonuses* self) +{ + return self->CHACapMod; +} + +int32 Perl_StatBonuses_GetHeroicCHA(StatBonuses* self) +{ + return self->HeroicCHA; +} + +int32 Perl_StatBonuses_GetMR(StatBonuses* self) +{ + return self->MR; +} + +int32 Perl_StatBonuses_GetMRCapModifier(StatBonuses* self) +{ + return self->MRCapMod; +} + +int32 Perl_StatBonuses_GetHeroicMR(StatBonuses* self) +{ + return self->HeroicMR; +} + +int32 Perl_StatBonuses_GetFR(StatBonuses* self) +{ + return self->FR; +} + +int32 Perl_StatBonuses_GetFRCapModifier(StatBonuses* self) +{ + return self->FRCapMod; +} + +int32 Perl_StatBonuses_GetHeroicFR(StatBonuses* self) +{ + return self->HeroicFR; +} + +int32 Perl_StatBonuses_GetCR(StatBonuses* self) +{ + return self->CR; +} + +int32 Perl_StatBonuses_GetCRCapModifier(StatBonuses* self) +{ + return self->CRCapMod; +} + +int32 Perl_StatBonuses_GetHeroicCR(StatBonuses* self) +{ + return self->HeroicCR; +} + +int32 Perl_StatBonuses_GetPR(StatBonuses* self) +{ + return self->PR; +} + +int32 Perl_StatBonuses_GetPRCapModifier(StatBonuses* self) +{ + return self->PRCapMod; +} + +int32 Perl_StatBonuses_GetHeroicPR(StatBonuses* self) +{ + return self->HeroicPR; +} + +int32 Perl_StatBonuses_GetDR(StatBonuses* self) +{ + return self->DR; +} + +int32 Perl_StatBonuses_GetDRCapModifier(StatBonuses* self) +{ + return self->DRCapMod; +} + +int32 Perl_StatBonuses_GetHeroicDR(StatBonuses* self) +{ + return self->HeroicDR; +} + +int32 Perl_StatBonuses_GetCorruption(StatBonuses* self) +{ + return self->Corrup; +} + +int32 Perl_StatBonuses_GetCorruptionCapModifier(StatBonuses* self) +{ + return self->CorrupCapMod; +} + +int32 Perl_StatBonuses_GetHeroicCorrup(StatBonuses* self) +{ + return self->HeroicCorrup; +} + +uint16 Perl_StatBonuses_GetDamageShieldSpellID(StatBonuses* self) +{ + return self->DamageShieldSpellID; +} + +int Perl_StatBonuses_GetDamageShield(StatBonuses* self) +{ + return self->DamageShield; +} + +int Perl_StatBonuses_GetDamageShieldType(StatBonuses* self) +{ + return self->DamageShieldType; +} + +int Perl_StatBonuses_GetSpellDamageShield(StatBonuses* self) +{ + return self->SpellDamageShield; +} + +int Perl_StatBonuses_GetSpellShield(StatBonuses* self) +{ + return self->SpellShield; +} + +int Perl_StatBonuses_GetReverseDamageShield(StatBonuses* self) +{ + return self->ReverseDamageShield; +} + +uint16 Perl_StatBonuses_GetReverseDamageShieldSpellID(StatBonuses* self) +{ + return self->ReverseDamageShieldSpellID; +} + +int Perl_StatBonuses_GetReverseDamageShieldType(StatBonuses* self) +{ + return self->ReverseDamageShieldType; +} + +int Perl_StatBonuses_GetMovementSpeed(StatBonuses* self) +{ + return self->movementspeed; +} + +int32 Perl_StatBonuses_GetHaste(StatBonuses* self) +{ + return self->haste; +} + +int32 Perl_StatBonuses_GetHasteType2(StatBonuses* self) +{ + return self->hastetype2; +} + +int32 Perl_StatBonuses_GetHasteType3(StatBonuses* self) +{ + return self->hastetype3; +} + +int32 Perl_StatBonuses_GetInhibitMelee(StatBonuses* self) +{ + return self->inhibitmelee; +} + +float Perl_StatBonuses_GetAggroRange(StatBonuses* self) +{ + return self->AggroRange; +} + +float Perl_StatBonuses_GetAssistRange(StatBonuses* self) +{ + return self->AssistRange; +} + +int32 Perl_StatBonuses_GetSkillModifier(StatBonuses* self, int slot) +{ + return self->skillmod[slot]; +} + +int32 Perl_StatBonuses_GetSkillModifierMax(StatBonuses* self, int slot) +{ + return self->skillmodmax[slot]; +} + +int Perl_StatBonuses_GetEffectiveCastingLevel(StatBonuses* self) +{ + return self->effective_casting_level; +} + +int Perl_StatBonuses_GetAdjustedCastingSkill(StatBonuses* self) +{ + return self->adjusted_casting_skill; +} + +int Perl_StatBonuses_GetReflectChance(StatBonuses* self) +{ + return self->reflect[SBIndex::REFLECT_CHANCE]; +} + +uint32 Perl_StatBonuses_GetSingingModifier(StatBonuses* self) +{ + return self->singingMod; +} + +uint32 Perl_StatBonuses_GetAmplification(StatBonuses* self) +{ + return self->Amplification; +} + +uint32 Perl_StatBonuses_GetBrassModifier(StatBonuses* self) +{ + return self->brassMod; +} + +uint32 Perl_StatBonuses_GetPercussionModifier(StatBonuses* self) +{ + return self->percussionMod; +} + +uint32 Perl_StatBonuses_GetWindModifier(StatBonuses* self) +{ + return self->windMod; +} + +uint32 Perl_StatBonuses_GetStringedModifier(StatBonuses* self) +{ + return self->stringedMod; +} + +uint32 Perl_StatBonuses_GetSongModifierCap(StatBonuses* self) +{ + return self->songModCap; +} + +int32 Perl_StatBonuses_GetHateModifier(StatBonuses* self) +{ + return self->hatemod; +} + +int64 Perl_StatBonuses_GetEnduranceReduction(StatBonuses* self) +{ + return self->EnduranceReduction; +} + +int32 Perl_StatBonuses_GetStrikeThrough(StatBonuses* self) +{ + return self->StrikeThrough; +} + +int32 Perl_StatBonuses_GetMeleeMitigation(StatBonuses* self) +{ + return self->MeleeMitigation; +} + +int32 Perl_StatBonuses_GetMeleeMitigationEffect(StatBonuses* self) +{ + return self->MeleeMitigationEffect; +} + +int32 Perl_StatBonuses_GetCriticalHitChance(StatBonuses* self, int slot) +{ + return self->CriticalHitChance[slot]; +} + +int32 Perl_StatBonuses_GetCriticalSpellChance(StatBonuses* self) +{ + return self->CriticalSpellChance; +} + +int32 Perl_StatBonuses_GetSpellCriticalDamageIncrease(StatBonuses* self) +{ + return self->SpellCritDmgIncrease; +} + +int32 Perl_StatBonuses_GetSpellCriticalDamageIncreaseNoStack(StatBonuses* self) +{ + return self->SpellCritDmgIncNoStack; +} + +int32 Perl_StatBonuses_GetDOTCriticalDamageIncrease(StatBonuses* self) +{ + return self->DotCritDmgIncrease; +} + +int32 Perl_StatBonuses_GetCriticalHealChance(StatBonuses* self) +{ + return self->CriticalHealChance; +} + +int32 Perl_StatBonuses_GetCriticalHealOverTime(StatBonuses* self) +{ + return self->CriticalHealOverTime; +} + +int32 Perl_StatBonuses_GetCriticalDOTChance(StatBonuses* self) +{ + return self->CriticalDoTChance; +} + +int32 Perl_StatBonuses_GetCripplingBlowChance(StatBonuses* self) +{ + return self->CrippBlowChance; +} + +int32 Perl_StatBonuses_GetAvoidMeleeChance(StatBonuses* self) +{ + return self->AvoidMeleeChance; +} + +int32 Perl_StatBonuses_GetAvoidMeleeChanceEffect(StatBonuses* self) +{ + return self->AvoidMeleeChanceEffect; +} + +int32 Perl_StatBonuses_GetRiposteChance(StatBonuses* self) +{ + return self->RiposteChance; +} + +int32 Perl_StatBonuses_GetDodgeChance(StatBonuses* self) +{ + return self->DodgeChance; +} + +int32 Perl_StatBonuses_GetParryChance(StatBonuses* self) +{ + return self->ParryChance; +} + +int32 Perl_StatBonuses_GetDualWieldChance(StatBonuses* self) +{ + return self->DualWieldChance; +} + +int32 Perl_StatBonuses_GetDoubleAttackChance(StatBonuses* self) +{ + return self->DoubleAttackChance; +} + +int32 Perl_StatBonuses_GetTripleAttackChance(StatBonuses* self) +{ + return self->TripleAttackChance; +} + +int32 Perl_StatBonuses_GetDoubleRangedAttack(StatBonuses* self) +{ + return self->DoubleRangedAttack; +} + +int32 Perl_StatBonuses_GetResistSpellChance(StatBonuses* self) +{ + return self->ResistSpellChance; +} + +int32 Perl_StatBonuses_GetResistFearChance(StatBonuses* self) +{ + return self->ResistFearChance; +} + +bool Perl_StatBonuses_GetFearless(StatBonuses* self) +{ + return self->Fearless; +} + +bool Perl_StatBonuses_GetIsFeared(StatBonuses* self) +{ + return self->IsFeared; +} + +bool Perl_StatBonuses_GetIsBlind(StatBonuses* self) +{ + return self->IsBlind; +} + +int32 Perl_StatBonuses_GetStunResist(StatBonuses* self) +{ + return self->StunResist; +} + +int32 Perl_StatBonuses_GetMeleeSkillCheck(StatBonuses* self) +{ + return self->MeleeSkillCheck; +} + +uint8 Perl_StatBonuses_GetMeleeSkillCheckSkill(StatBonuses* self) +{ + return self->MeleeSkillCheckSkill; +} + +int32 Perl_StatBonuses_GetHitChance(StatBonuses* self) +{ + return self->HitChance; +} + +int32 Perl_StatBonuses_GetHitChanceEffect(StatBonuses* self, int slot) +{ + return self->HitChanceEffect[slot]; +} + +int32 Perl_StatBonuses_GetDamageModifier(StatBonuses* self, int slot) +{ + return self->DamageModifier[slot]; +} + +int32 Perl_StatBonuses_GetDamageModifier2(StatBonuses* self, int slot) +{ + return self->DamageModifier2[slot]; +} + +int32 Perl_StatBonuses_GetMinimumDamageModifier(StatBonuses* self, int slot) +{ + return self->MinDamageModifier[slot]; +} + +int32 Perl_StatBonuses_GetProcChance(StatBonuses* self) +{ + return self->ProcChance; +} + +int32 Perl_StatBonuses_GetProcChanceSPA(StatBonuses* self) +{ + return self->ProcChanceSPA; +} + +int32 Perl_StatBonuses_GetExtraAttackChance(StatBonuses* self) +{ + return self->ExtraAttackChance[0]; +} + +int32 Perl_StatBonuses_GetDOTShielding(StatBonuses* self) +{ + return self->DoTShielding; +} + +int32 Perl_StatBonuses_GetFlurryChance(StatBonuses* self) +{ + return self->FlurryChance; +} + +int32 Perl_StatBonuses_GetHundredHands(StatBonuses* self) +{ + return self->HundredHands; +} + +int32 Perl_StatBonuses_GetMeleeLifetap(StatBonuses* self) +{ + return self->MeleeLifetap; +} + +int32 Perl_StatBonuses_GetVampirism(StatBonuses* self) +{ + return self->Vampirism; +} + +int32 Perl_StatBonuses_GetHealRate(StatBonuses* self) +{ + return self->HealRate; +} + +int32 Perl_StatBonuses_GetMaxHPChange(StatBonuses* self) +{ + return self->MaxHPChange; +} + +int32 Perl_StatBonuses_GetHealAmt(StatBonuses* self) +{ + return self->HealAmt; +} + +int32 Perl_StatBonuses_GetSpellDamage(StatBonuses* self) +{ + return self->SpellDmg; +} + +int32 Perl_StatBonuses_GetClairvoyance(StatBonuses* self) +{ + return self->Clairvoyance; +} + +int32 Perl_StatBonuses_GetDSMitigation(StatBonuses* self) +{ + return self->DSMitigation; +} + +int32 Perl_StatBonuses_GetDSMitigationOffHand(StatBonuses* self) +{ + return self->DSMitigationOffHand; +} + +int32 Perl_StatBonuses_GetTwoHandBluntBlock(StatBonuses* self) +{ + return self->TwoHandBluntBlock; +} + +uint32 Perl_StatBonuses_GetItemManaRegenCap(StatBonuses* self) +{ + return self->ItemManaRegenCap; +} + +int32 Perl_StatBonuses_GetGravityEffect(StatBonuses* self) +{ + return self->GravityEffect; +} + +bool Perl_StatBonuses_GetAntiGate(StatBonuses* self) +{ + return self->AntiGate; +} + +bool Perl_StatBonuses_GetMagicWeapon(StatBonuses* self) +{ + return self->MagicWeapon; +} + +int32 Perl_StatBonuses_GetIncreaseBlockChance(StatBonuses* self) +{ + return self->IncreaseBlockChance; +} + +uint32 Perl_StatBonuses_GetPersistentCasting(StatBonuses* self) +{ + return self->PersistantCasting; +} + +int Perl_StatBonuses_GetXPRateModifier(StatBonuses* self) +{ + return self->XPRateMod; +} + +bool Perl_StatBonuses_GetImmuneToFlee(StatBonuses* self) +{ + return self->ImmuneToFlee; +} + +uint32 Perl_StatBonuses_GetVoiceGraft(StatBonuses* self) +{ + return self->VoiceGraft; +} + +int32 Perl_StatBonuses_GetSpellProcChance(StatBonuses* self) +{ + return self->SpellProcChance; +} + +int32 Perl_StatBonuses_GetCharmBreakChance(StatBonuses* self) +{ + return self->CharmBreakChance; +} + +int32 Perl_StatBonuses_GetSongRange(StatBonuses* self) +{ + return self->SongRange; +} + +uint32 Perl_StatBonuses_GetHPToManaConvert(StatBonuses* self) +{ + return self->HPToManaConvert; +} + +bool Perl_StatBonuses_GetNegateEffects(StatBonuses* self) +{ + return self->NegateEffects; +} + +bool Perl_StatBonuses_GetTriggerMeleeThreshold(StatBonuses* self) +{ + return self->TriggerMeleeThreshold; +} + +bool Perl_StatBonuses_GetTriggerSpellThreshold(StatBonuses* self) +{ + return self->TriggerSpellThreshold; +} + +int32 Perl_StatBonuses_GetShieldBlock(StatBonuses* self) +{ + return self->ShieldBlock; +} + +int32 Perl_StatBonuses_GetBlockBehind(StatBonuses* self) +{ + return self->BlockBehind; +} + +bool Perl_StatBonuses_GetCriticalRegenDecay(StatBonuses* self) +{ + return self->CriticalRegenDecay; +} + +bool Perl_StatBonuses_GetCriticalHealDecay(StatBonuses* self) +{ + return self->CriticalHealDecay; +} + +bool Perl_StatBonuses_GetCriticalDOTDecay(StatBonuses* self) +{ + return self->CriticalDotDecay; +} + +bool Perl_StatBonuses_GetDivineAura(StatBonuses* self) +{ + return self->DivineAura; +} + +bool Perl_StatBonuses_GetDistanceRemoval(StatBonuses* self) +{ + return self->DistanceRemoval; +} + +int32 Perl_StatBonuses_GetFrenziedDevastation(StatBonuses* self) +{ + return self->FrenziedDevastation; +} + +bool Perl_StatBonuses_GetNegateIfCombat(StatBonuses* self) +{ + return self->NegateIfCombat; +} + +int8 Perl_StatBonuses_GetScreech(StatBonuses* self) +{ + return self->Screech; +} + +int32 Perl_StatBonuses_GetAlterNPCLevel(StatBonuses* self) +{ + return self->AlterNPCLevel; +} + +bool Perl_StatBonuses_GetBerserkSPA(StatBonuses* self) +{ + return self->BerserkSPA; +} + +int32 Perl_StatBonuses_GetMetabolism(StatBonuses* self) +{ + return self->Metabolism; +} + +bool Perl_StatBonuses_GetSanctuary(StatBonuses* self) +{ + return self->Sanctuary; +} + +int32 Perl_StatBonuses_GetFactionModifierPercent(StatBonuses* self) +{ + return self->FactionModPct; +} + +uint32 Perl_StatBonuses_GetPCPetFlurry(StatBonuses* self) +{ + return self->PC_Pet_Flurry; +} + +int8 Perl_StatBonuses_GetPackrat(StatBonuses* self) +{ + return self->Packrat; +} + +uint8 Perl_StatBonuses_GetBuffSlotIncrease(StatBonuses* self) +{ + return self->BuffSlotIncrease; +} + +uint32 Perl_StatBonuses_GetDelayDeath(StatBonuses* self) +{ + return self->DelayDeath; +} + +int8 Perl_StatBonuses_GetBaseMovementSpeed(StatBonuses* self) +{ + return self->BaseMovementSpeed; +} + +uint8 Perl_StatBonuses_GetIncreaseRunSpeedCap(StatBonuses* self) +{ + return self->IncreaseRunSpeedCap; +} + +int32 Perl_StatBonuses_GetDoubleSpecialAttack(StatBonuses* self) +{ + return self->DoubleSpecialAttack; +} + +uint8 Perl_StatBonuses_GetFrontalStunResist(StatBonuses* self) +{ + return self->FrontalStunResist; +} + +int32 Perl_StatBonuses_GetBindWound(StatBonuses* self) +{ + return self->BindWound; +} + +int32 Perl_StatBonuses_GetMaxBindWound(StatBonuses* self) +{ + return self->MaxBindWound; +} + +int32 Perl_StatBonuses_GetChannelChanceSpells(StatBonuses* self) +{ + return self->ChannelChanceSpells; +} + +int32 Perl_StatBonuses_GetChannelChanceItems(StatBonuses* self) +{ + return self->ChannelChanceItems; +} + +uint8 Perl_StatBonuses_GetSeeInvis(StatBonuses* self) +{ + return self->SeeInvis; +} + +uint8 Perl_StatBonuses_GetTripleBackstab(StatBonuses* self) +{ + return self->TripleBackstab; +} + +bool Perl_StatBonuses_GetFrontalBackstabMinimumDamage(StatBonuses* self) +{ + return self->FrontalBackstabMinDmg; +} + +uint8 Perl_StatBonuses_GetFrontalBackstabChance(StatBonuses* self) +{ + return self->FrontalBackstabChance; +} + +uint8 Perl_StatBonuses_GetConsumeProjectile(StatBonuses* self) +{ + return self->ConsumeProjectile; +} + +uint8 Perl_StatBonuses_GetForageAdditionalItems(StatBonuses* self) +{ + return self->ForageAdditionalItems; +} + +uint8 Perl_StatBonuses_GetSalvageChance(StatBonuses* self) +{ + return self->SalvageChance; +} + +uint32 Perl_StatBonuses_GetArcheryDamageModifier(StatBonuses* self) +{ + return self->ArcheryDamageModifier; +} + +bool Perl_StatBonuses_GetSecondaryDamageIncrease(StatBonuses* self) +{ + return self->SecondaryDmgInc; +} + +uint32 Perl_StatBonuses_GetGiveDoubleAttack(StatBonuses* self) +{ + return self->GiveDoubleAttack; +} + +int32 Perl_StatBonuses_GetPetCriticalHit(StatBonuses* self) +{ + return self->PetCriticalHit; +} + +int32 Perl_StatBonuses_GetPetAvoidance(StatBonuses* self) +{ + return self->PetAvoidance; +} + +int32 Perl_StatBonuses_GetCombatStability(StatBonuses* self) +{ + return self->CombatStability; +} + +int32 Perl_StatBonuses_GetDoubleRiposte(StatBonuses* self) +{ + return self->DoubleRiposte; +} + +int32 Perl_StatBonuses_GetAmbidexterity(StatBonuses* self) +{ + return self->Ambidexterity; +} + +int32 Perl_StatBonuses_GetPetMaxHP(StatBonuses* self) +{ + return self->PetMaxHP; +} + +int32 Perl_StatBonuses_GetPetFlurry(StatBonuses* self) +{ + return self->PetFlurry; +} + +uint8 Perl_StatBonuses_GetMasteryOfPast(StatBonuses* self) +{ + return self->MasteryofPast; +} + +bool Perl_StatBonuses_GetGivePetGroupTarget(StatBonuses* self) +{ + return self->GivePetGroupTarget; +} + +int32 Perl_StatBonuses_GetRootBreakChance(StatBonuses* self) +{ + return self->RootBreakChance; +} + +int32 Perl_StatBonuses_GetUnfailingDivinity(StatBonuses* self) +{ + return self->UnfailingDivinity; +} + +int32 Perl_StatBonuses_GetItemHPRegenCap(StatBonuses* self) +{ + return self->ItemHPRegenCap; +} + +int32 Perl_StatBonuses_GetOffhandRiposteFail(StatBonuses* self) +{ + return self->OffhandRiposteFail; +} + +int32 Perl_StatBonuses_GetItemATKCap(StatBonuses* self) +{ + return self->ItemATKCap; +} + +int32 Perl_StatBonuses_GetShieldEquipDamageModifier(StatBonuses* self) +{ + return self->ShieldEquipDmgMod; +} + +bool Perl_StatBonuses_GetTriggerOnValueAmount(StatBonuses* self) +{ + return self->TriggerOnCastRequirement; +} + +int8 Perl_StatBonuses_GetStunBashChance(StatBonuses* self) +{ + return self->StunBashChance; +} + +int8 Perl_StatBonuses_GetIncreaseChanceMemoryWipe(StatBonuses* self) +{ + return self->IncreaseChanceMemwipe; +} + +int8 Perl_StatBonuses_GetCriticalMend(StatBonuses* self) +{ + return self->CriticalMend; +} + +int32 Perl_StatBonuses_GetImprovedReclaimEnergy(StatBonuses* self) +{ + return self->ImprovedReclaimEnergy; +} + +int32 Perl_StatBonuses_GetPetMeleeMitigation(StatBonuses* self) +{ + return self->PetMeleeMitigation; +} + +bool Perl_StatBonuses_GetIllusionPersistence(StatBonuses* self) +{ + return self->IllusionPersistence; +} + +uint16 Perl_StatBonuses_GetExtraXTargets(StatBonuses* self) +{ + return self->extra_xtargets; +} + +bool Perl_StatBonuses_GetShroudOfStealth(StatBonuses* self) +{ + return self->ShroudofStealth; +} + +uint16 Perl_StatBonuses_GetReduceFallDamage(StatBonuses* self) +{ + return self->ReduceFallDamage; +} + +uint8 Perl_StatBonuses_GetTradeSkillMastery(StatBonuses* self) +{ + return self->TradeSkillMastery; +} + +int16 Perl_StatBonuses_GetNoBreakAESneak(StatBonuses* self) +{ + return self->NoBreakAESneak; +} + +int16 Perl_StatBonuses_GetFeignedCastOnChance(StatBonuses* self) +{ + return self->FeignedCastOnChance; +} + +int32 Perl_StatBonuses_GetDivineSaveChance(StatBonuses* self, int slot) +{ + return self->DivineSaveChance[slot]; +} + +uint32 Perl_StatBonuses_GetDeathSave(StatBonuses* self, int slot) +{ + return self->DeathSave[slot]; +} + +int32 Perl_StatBonuses_GetAccuracy(StatBonuses* self, int slot) +{ + return self->Accuracy[slot]; +} + +int16 Perl_StatBonuses_GetSkillDamageTaken(StatBonuses* self, int slot) +{ + return self->SkillDmgTaken[slot]; +} + +uint32 Perl_StatBonuses_GetSpellTriggers(StatBonuses* self, int slot) +{ + return self->SpellTriggers[slot]; +} + +uint32 Perl_StatBonuses_GetSpellOnKill(StatBonuses* self, int slot) +{ + return self->SpellOnKill[slot]; +} + +uint32 Perl_StatBonuses_GetSpellOnDeath(StatBonuses* self, int slot) +{ + return self->SpellOnDeath[slot]; +} + +int32 Perl_StatBonuses_GetCriticalDamageModifier(StatBonuses* self, int slot) +{ + return self->CritDmgMod[slot]; +} + +int32 Perl_StatBonuses_GetSkillReuseTime(StatBonuses* self, int slot) +{ + return self->SkillReuseTime[slot]; +} + +int32 Perl_StatBonuses_GetSkillDamageAmount(StatBonuses* self, int slot) +{ + if (!EQ::ValueWithin(slot, ALL_SKILLS, EQ::skills::HIGHEST_SKILL)) + { + return 0; + } + + return slot == ALL_SKILLS ? self->SkillDamageAmount[EQ::skills::HIGHEST_SKILL + 1] : self->SkillDamageAmount[slot]; +} + +int Perl_StatBonuses_GetHPPercentCap(StatBonuses* self, int slot) +{ + return self->HPPercCap[slot]; +} + +int Perl_StatBonuses_GetManaPercentCap(StatBonuses* self, int slot) +{ + return self->ManaPercCap[slot]; +} + +int Perl_StatBonuses_GetEndurancePercentCAp(StatBonuses* self, int slot) +{ + return self->EndPercCap[slot]; +} + +uint8 Perl_StatBonuses_GetFocusEffects(StatBonuses* self, int slot) +{ + return self->FocusEffects[slot]; +} + +int16 Perl_StatBonuses_GetFocusEffectsWorn(StatBonuses* self, int slot) +{ + return self->FocusEffectsWorn[slot]; +} + +int32 Perl_StatBonuses_GetSkillDamageAmount2(StatBonuses* self, int slot) +{ + return self->SkillDamageAmount2[slot]; +} + +uint32 Perl_StatBonuses_GetNegateAttacks(StatBonuses* self, int slot) +{ + return self->NegateAttacks[slot]; +} + +uint32 Perl_StatBonuses_GetMitigateMeleeRune(StatBonuses* self, int slot) +{ + return self->MitigateMeleeRune[slot]; +} + +uint32 Perl_StatBonuses_GetMeleeThresholdGuard(StatBonuses* self, int slot) +{ + return self->MeleeThresholdGuard[slot]; +} + +uint32 Perl_StatBonuses_GetSpellThresholdGuard(StatBonuses* self, int slot) +{ + return self->SpellThresholdGuard[slot]; +} + +uint32 Perl_StatBonuses_GetMitigateSpellRune(StatBonuses* self, int slot) +{ + return self->MitigateSpellRune[slot]; +} + +uint32 Perl_StatBonuses_GetMitigateDOTRune(StatBonuses* self, int slot) +{ + return self->MitigateDotRune[slot]; +} + +uint32 Perl_StatBonuses_GetManaAbsorbPercentDamage(StatBonuses* self, int slot) +{ + return self->ManaAbsorbPercentDamage; +} + +int32 Perl_StatBonuses_GetImprovedTaunt(StatBonuses* self, int slot) +{ + return self->ImprovedTaunt[slot]; +} + +int8 Perl_StatBonuses_GetRoot(StatBonuses* self, int slot) +{ + return self->Root[slot]; +} + +uint32 Perl_StatBonuses_GetAbsorbMagicAttack(StatBonuses* self, int slot) +{ + return self->AbsorbMagicAtt[slot]; +} + +uint32 Perl_StatBonuses_GetMeleeRune(StatBonuses* self, int slot) +{ + return self->MeleeRune[slot]; +} + +int32 Perl_StatBonuses_GetAStacker(StatBonuses* self, int slot) +{ + return self->AStacker[slot]; +} + +int32 Perl_StatBonuses_GetBStacker(StatBonuses* self, int slot) +{ + return self->BStacker[slot]; +} + +int32 Perl_StatBonuses_GetCStacker(StatBonuses* self, int slot) +{ + return self->CStacker[slot]; +} + +int32 Perl_StatBonuses_GetDStacker(StatBonuses* self, int slot) +{ + return self->DStacker[slot]; +} + +bool Perl_StatBonuses_GetLimitToSkill(StatBonuses* self, int slot) +{ + return self->LimitToSkill[slot]; +} + +uint32 Perl_StatBonuses_GetSkillProc(StatBonuses* self, int slot) +{ + return self->SkillProc[slot]; +} + +uint32 Perl_StatBonuses_GetSkillProcSuccess(StatBonuses* self, int slot) +{ + return self->SkillProcSuccess[slot]; +} + +uint32 Perl_StatBonuses_GetPCPetRampage(StatBonuses* self, int slot) +{ + return self->PC_Pet_Rampage[slot]; +} + +int32 Perl_StatBonuses_GetSkillAttackProc(StatBonuses* self, int slot) +{ + return self->SkillAttackProc[slot]; +} + +int32 Perl_StatBonuses_GetSlayUndead(StatBonuses* self, int slot) +{ + return self->SlayUndead[slot]; +} + +int32 Perl_StatBonuses_GetGiveDoubleRiposte(StatBonuses* self, int slot) +{ + return self->GiveDoubleRiposte[slot]; +} + +uint32 Perl_StatBonuses_GetRaiseSkillCap(StatBonuses* self, int slot) +{ + return self->RaiseSkillCap[slot]; +} + +int32 Perl_StatBonuses_GetSEResist(StatBonuses* self, int slot) +{ + return self->SEResist[slot]; +} + +int32 Perl_StatBonuses_GetFinishingBlow(StatBonuses* self, int slot) +{ + return self->FinishingBlow[slot]; +} + +uint32 Perl_StatBonuses_GetFinishingBlowLevel(StatBonuses* self, int slot) +{ + return self->FinishingBlowLvl[slot]; +} + +uint32 Perl_StatBonuses_GetHeadShot(StatBonuses* self, int slot) +{ + return self->HeadShot[slot]; +} + +uint8 Perl_StatBonuses_GetHeadShotLevel(StatBonuses* self, int slot) +{ + return self->HSLevel[slot]; +} + +uint32 Perl_StatBonuses_GetAssassinate(StatBonuses* self, int slot) +{ + return self->Assassinate[slot]; +} + +uint8 Perl_StatBonuses_GetAssassinateLevel(StatBonuses* self, int slot) +{ + return self->AssassinateLevel[slot]; +} + +int32 Perl_StatBonuses_GetReduceTradeskillFail(StatBonuses* self, int slot) +{ + return self->ReduceTradeskillFail[slot]; +} + +void perl_register_stat_bonuses() +{ + perl::interpreter perl(PERL_GET_THX); + + auto package = perl.new_class("StatBonuses"); + package.add("GetAbsorbMagicAttack", &Perl_StatBonuses_GetAbsorbMagicAttack); + package.add("GetAC", &Perl_StatBonuses_GetAC); + package.add("GetAccuracy", &Perl_StatBonuses_GetAccuracy); + package.add("GetAdjustedCastingSkill", &Perl_StatBonuses_GetAdjustedCastingSkill); + package.add("GetAggroRange", &Perl_StatBonuses_GetAggroRange); + package.add("GetAGI", &Perl_StatBonuses_GetAGI); + package.add("GetAGICapModifier", &Perl_StatBonuses_GetAGICapModifier); + package.add("GetAlterNPCLevel", &Perl_StatBonuses_GetAlterNPCLevel); + package.add("GetAmbidexterity", &Perl_StatBonuses_GetAmbidexterity); + package.add("GetAmplification", &Perl_StatBonuses_GetAmplification); + package.add("GetAntiGate", &Perl_StatBonuses_GetAntiGate); + package.add("GetArcheryDamageModifier", &Perl_StatBonuses_GetArcheryDamageModifier); + package.add("GetAssassinate", &Perl_StatBonuses_GetAssassinate); + package.add("GetAssassinateLevel", &Perl_StatBonuses_GetAssassinateLevel); + package.add("GetAssistRange", &Perl_StatBonuses_GetAssistRange); + package.add("GetAStacker", &Perl_StatBonuses_GetAStacker); + package.add("GetATK", &Perl_StatBonuses_GetATK); + package.add("GetAvoidMeleeChance", &Perl_StatBonuses_GetAvoidMeleeChance); + package.add("GetAvoidMeleeChanceEffect", &Perl_StatBonuses_GetAvoidMeleeChanceEffect); + package.add("GetBaseMovementSpeed", &Perl_StatBonuses_GetBaseMovementSpeed); + package.add("GetBerserkSPA", &Perl_StatBonuses_GetBerserkSPA); + package.add("GetBindWound", &Perl_StatBonuses_GetBindWound); + package.add("GetBlockBehind", &Perl_StatBonuses_GetBlockBehind); + package.add("GetBrassModifier", &Perl_StatBonuses_GetBrassModifier); + package.add("GetBStacker", &Perl_StatBonuses_GetBStacker); + package.add("GetBuffSlotIncrease", &Perl_StatBonuses_GetBuffSlotIncrease); + package.add("GetCHA", &Perl_StatBonuses_GetCHA); + package.add("GetCHACapModifier", &Perl_StatBonuses_GetCHACapModifier); + package.add("GetChannelChanceItems", &Perl_StatBonuses_GetChannelChanceItems); + package.add("GetChannelChanceSpells", &Perl_StatBonuses_GetChannelChanceSpells); + package.add("GetCharmBreakChance", &Perl_StatBonuses_GetCharmBreakChance); + package.add("GetClairvoyance", &Perl_StatBonuses_GetClairvoyance); + package.add("GetCombatStability", &Perl_StatBonuses_GetCombatStability); + package.add("GetConsumeProjectile", &Perl_StatBonuses_GetConsumeProjectile); + package.add("GetCorruption", &Perl_StatBonuses_GetCorruption); + package.add("GetCorruptionCapModifier", &Perl_StatBonuses_GetCorruptionCapModifier); + package.add("GetCR", &Perl_StatBonuses_GetCR); + package.add("GetCRCapModifier", &Perl_StatBonuses_GetCRCapModifier); + package.add("GetCripplingBlowChance", &Perl_StatBonuses_GetCripplingBlowChance); + package.add("GetCriticalDamageModifier", &Perl_StatBonuses_GetCriticalDamageModifier); + package.add("GetCriticalDOTChance", &Perl_StatBonuses_GetCriticalDOTChance); + package.add("GetCriticalDOTDecay", &Perl_StatBonuses_GetCriticalDOTDecay); + package.add("GetCriticalHealChance", &Perl_StatBonuses_GetCriticalHealChance); + package.add("GetCriticalHealDecay", &Perl_StatBonuses_GetCriticalHealDecay); + package.add("GetCriticalHealOverTime", &Perl_StatBonuses_GetCriticalHealOverTime); + package.add("GetCriticalHitChance", &Perl_StatBonuses_GetCriticalHitChance); + package.add("GetCriticalMend", &Perl_StatBonuses_GetCriticalMend); + package.add("GetCriticalRegenDecay", &Perl_StatBonuses_GetCriticalRegenDecay); + package.add("GetCriticalSpellChance", &Perl_StatBonuses_GetCriticalSpellChance); + package.add("GetCStacker", &Perl_StatBonuses_GetCStacker); + package.add("GetDamageModifier", &Perl_StatBonuses_GetDamageModifier); + package.add("GetDamageModifier2", &Perl_StatBonuses_GetDamageModifier2); + package.add("GetDamageShield", &Perl_StatBonuses_GetDamageShield); + package.add("GetDamageShieldSpellID", &Perl_StatBonuses_GetDamageShieldSpellID); + package.add("GetDamageShieldType", &Perl_StatBonuses_GetDamageShieldType); + package.add("GetDeathSave", &Perl_StatBonuses_GetDeathSave); + package.add("GetDelayDeath", &Perl_StatBonuses_GetDelayDeath); + package.add("GetDEX", &Perl_StatBonuses_GetDEX); + package.add("GetDEXCapModifier", &Perl_StatBonuses_GetDEXCapModifier); + package.add("GetDistanceRemoval", &Perl_StatBonuses_GetDistanceRemoval); + package.add("GetDivineAura", &Perl_StatBonuses_GetDivineAura); + package.add("GetDivineSaveChance", &Perl_StatBonuses_GetDivineSaveChance); + package.add("GetDodgeChance", &Perl_StatBonuses_GetDodgeChance); + package.add("GetDOTCriticalDamageIncrease", &Perl_StatBonuses_GetDOTCriticalDamageIncrease); + package.add("GetDOTShielding", &Perl_StatBonuses_GetDOTShielding); + package.add("GetDoubleAttackChance", &Perl_StatBonuses_GetDoubleAttackChance); + package.add("GetDoubleRangedAttack", &Perl_StatBonuses_GetDoubleRangedAttack); + package.add("GetDoubleRiposte", &Perl_StatBonuses_GetDoubleRiposte); + package.add("GetDoubleSpecialAttack", &Perl_StatBonuses_GetDoubleSpecialAttack); + package.add("GetDR", &Perl_StatBonuses_GetDR); + package.add("GetDRCapModifier", &Perl_StatBonuses_GetDRCapModifier); + package.add("GetDSMitigation", &Perl_StatBonuses_GetDSMitigation); + package.add("GetDSMitigationOffHand", &Perl_StatBonuses_GetDSMitigationOffHand); + package.add("GetDStacker", &Perl_StatBonuses_GetDStacker); + package.add("GetDualWieldChance", &Perl_StatBonuses_GetDualWieldChance); + package.add("GetEffectiveCastingLevel", &Perl_StatBonuses_GetEffectiveCastingLevel); + package.add("GetEndurancePercentCAp", &Perl_StatBonuses_GetEndurancePercentCAp); + package.add("GetEndurance", &Perl_StatBonuses_GetEndurance); + package.add("GetEnduranceReduction", &Perl_StatBonuses_GetEnduranceReduction); + package.add("GetEnduranceRegen", &Perl_StatBonuses_GetEnduranceRegen); + package.add("GetExtraXTargets", &Perl_StatBonuses_GetExtraXTargets); + package.add("GetExtraAttackChance", &Perl_StatBonuses_GetExtraAttackChance); + package.add("GetFactionModifierPercent", &Perl_StatBonuses_GetFactionModifierPercent); + package.add("GetFearless", &Perl_StatBonuses_GetFearless); + package.add("GetFeignedCastOnChance", &Perl_StatBonuses_GetFeignedCastOnChance); + package.add("GetFinishingBlow", &Perl_StatBonuses_GetFinishingBlow); + package.add("GetFinishingBlowLevel", &Perl_StatBonuses_GetFinishingBlowLevel); + package.add("GetFlurryChance", &Perl_StatBonuses_GetFlurryChance); + package.add("GetFocusEffects", &Perl_StatBonuses_GetFocusEffects); + package.add("GetFocusEffectsWorn", &Perl_StatBonuses_GetFocusEffectsWorn); + package.add("GetForageAdditionalItems", &Perl_StatBonuses_GetForageAdditionalItems); + package.add("GetFR", &Perl_StatBonuses_GetFR); + package.add("GetFRCapModifier", &Perl_StatBonuses_GetFRCapModifier); + package.add("GetFrenziedDevastation", &Perl_StatBonuses_GetFrenziedDevastation); + package.add("GetFrontalBackstabChance", &Perl_StatBonuses_GetFrontalBackstabChance); + package.add("GetFrontalBackstabMinimumDamage", &Perl_StatBonuses_GetFrontalBackstabMinimumDamage); + package.add("GetFrontalStunResist", &Perl_StatBonuses_GetFrontalStunResist); + package.add("GetGiveDoubleAttack", &Perl_StatBonuses_GetGiveDoubleAttack); + package.add("GetGiveDoubleRiposte", &Perl_StatBonuses_GetGiveDoubleRiposte); + package.add("GetGivePetGroupTarget", &Perl_StatBonuses_GetGivePetGroupTarget); + package.add("GetGravityEffect", &Perl_StatBonuses_GetGravityEffect); + package.add("GetHaste", &Perl_StatBonuses_GetHaste); + package.add("GetHasteType2", &Perl_StatBonuses_GetHasteType2); + package.add("GetHasteType3", &Perl_StatBonuses_GetHasteType3); + package.add("GetHateModifier", &Perl_StatBonuses_GetHateModifier); + package.add("GetHeadShot", &Perl_StatBonuses_GetHeadShot); + package.add("GetHeadShotLevel", &Perl_StatBonuses_GetHeadShotLevel); + package.add("GetHealAmt", &Perl_StatBonuses_GetHealAmt); + package.add("GetHealRate", &Perl_StatBonuses_GetHealRate); + package.add("GetHeroicAGI", &Perl_StatBonuses_GetHeroicAGI); + package.add("GetHeroicCHA", &Perl_StatBonuses_GetHeroicCHA); + package.add("GetHeroicCorrup", &Perl_StatBonuses_GetHeroicCorrup); + package.add("GetHeroicCR", &Perl_StatBonuses_GetHeroicCR); + package.add("GetHeroicDEX", &Perl_StatBonuses_GetHeroicDEX); + package.add("GetHeroicDR", &Perl_StatBonuses_GetHeroicDR); + package.add("GetHeroicFR", &Perl_StatBonuses_GetHeroicFR); + package.add("GetHeroicINT", &Perl_StatBonuses_GetHeroicINT); + package.add("GetHeroicMR", &Perl_StatBonuses_GetHeroicMR); + package.add("GetHeroicPR", &Perl_StatBonuses_GetHeroicPR); + package.add("GetHeroicSTA", &Perl_StatBonuses_GetHeroicSTA); + package.add("GetHeroicSTR", &Perl_StatBonuses_GetHeroicSTR); + package.add("GetHeroicWIS", &Perl_StatBonuses_GetHeroicWIS); + package.add("GetHitChance", &Perl_StatBonuses_GetHitChance); + package.add("GetHitChanceEffect", &Perl_StatBonuses_GetHitChanceEffect); + package.add("GetHP", &Perl_StatBonuses_GetHP); + package.add("GetHPPercentCap", &Perl_StatBonuses_GetHPPercentCap); + package.add("GetHPRegen", &Perl_StatBonuses_GetHPRegen); + package.add("GetHPToManaConvert", &Perl_StatBonuses_GetHPToManaConvert); + package.add("GetHundredHands", &Perl_StatBonuses_GetHundredHands); + package.add("GetIllusionPersistence", &Perl_StatBonuses_GetIllusionPersistence); + package.add("GetImmuneToFlee", &Perl_StatBonuses_GetImmuneToFlee); + package.add("GetImprovedReclaimEnergy", &Perl_StatBonuses_GetImprovedReclaimEnergy); + package.add("GetImprovedTaunt", &Perl_StatBonuses_GetImprovedTaunt); + package.add("GetIncreaseBlockChance", &Perl_StatBonuses_GetIncreaseBlockChance); + package.add("GetIncreaseChanceMemoryWipe", &Perl_StatBonuses_GetIncreaseChanceMemoryWipe); + package.add("GetIncreaseRunSpeedCap", &Perl_StatBonuses_GetIncreaseRunSpeedCap); + package.add("GetInhibitMelee", &Perl_StatBonuses_GetInhibitMelee); + package.add("GetINT", &Perl_StatBonuses_GetINT); + package.add("GetINTCapModifier", &Perl_StatBonuses_GetINTCapModifier); + package.add("GetIsBlind", &Perl_StatBonuses_GetIsBlind); + package.add("GetIsFeared", &Perl_StatBonuses_GetIsFeared); + package.add("GetItemATKCap", &Perl_StatBonuses_GetItemATKCap); + package.add("GetItemHPRegenCap", &Perl_StatBonuses_GetItemHPRegenCap); + package.add("GetItemManaRegenCap", &Perl_StatBonuses_GetItemManaRegenCap); + package.add("GetLimitToSkill", &Perl_StatBonuses_GetLimitToSkill); + package.add("GetMagicWeapon", &Perl_StatBonuses_GetMagicWeapon); + package.add("GetMana", &Perl_StatBonuses_GetMana); + package.add("GetManaAbsorbPercentDamage", &Perl_StatBonuses_GetManaAbsorbPercentDamage); + package.add("GetManaPercentCap", &Perl_StatBonuses_GetManaPercentCap); + package.add("GetManaRegen", &Perl_StatBonuses_GetManaRegen); + package.add("GetMasteryOfPast", &Perl_StatBonuses_GetMasteryOfPast); + package.add("GetMaxBindWound", &Perl_StatBonuses_GetMaxBindWound); + package.add("GetMaxHP", &Perl_StatBonuses_GetMaxHP); + package.add("GetMaxHPChange", &Perl_StatBonuses_GetMaxHPChange); + package.add("GetMeleeLifetap", &Perl_StatBonuses_GetMeleeLifetap); + package.add("GetMeleeMitigation", &Perl_StatBonuses_GetMeleeMitigation); + package.add("GetMeleeMitigationEffect", &Perl_StatBonuses_GetMeleeMitigationEffect); + package.add("GetMeleeRune", &Perl_StatBonuses_GetMeleeRune); + package.add("GetMeleeSkillCheck", &Perl_StatBonuses_GetMeleeSkillCheck); + package.add("GetMeleeSkillCheckSkill", &Perl_StatBonuses_GetMeleeSkillCheckSkill); + package.add("GetMeleeThresholdGuard", &Perl_StatBonuses_GetMeleeThresholdGuard); + package.add("GetMetabolism", &Perl_StatBonuses_GetMetabolism); + package.add("GetMinimumDamageModifier", &Perl_StatBonuses_GetMinimumDamageModifier); + package.add("GetMitigateDOTRune", &Perl_StatBonuses_GetMitigateDOTRune); + package.add("GetMitigateMeleeRune", &Perl_StatBonuses_GetMitigateMeleeRune); + package.add("GetMitigateSpellRune", &Perl_StatBonuses_GetMitigateSpellRune); + package.add("GetMovementSpeed", &Perl_StatBonuses_GetMovementSpeed); + package.add("GetMR", &Perl_StatBonuses_GetMR); + package.add("GetMRCapModifier", &Perl_StatBonuses_GetMRCapModifier); + package.add("GetNegateAttacks", &Perl_StatBonuses_GetNegateAttacks); + package.add("GetNegateEffects", &Perl_StatBonuses_GetNegateEffects); + package.add("GetNegateIfCombat", &Perl_StatBonuses_GetNegateIfCombat); + package.add("GetNoBreakAESneak", &Perl_StatBonuses_GetNoBreakAESneak); + package.add("GetOffhandRiposteFail", &Perl_StatBonuses_GetOffhandRiposteFail); + package.add("GetPackrat", &Perl_StatBonuses_GetPackrat); + package.add("GetParryChance", &Perl_StatBonuses_GetParryChance); + package.add("GetPCPetFlurry", &Perl_StatBonuses_GetPCPetFlurry); + package.add("GetPCPetRampage", &Perl_StatBonuses_GetPCPetRampage); + package.add("GetPercussionModifier", &Perl_StatBonuses_GetPercussionModifier); + package.add("GetPersistentCasting", &Perl_StatBonuses_GetPersistentCasting); + package.add("GetPetAvoidance", &Perl_StatBonuses_GetPetAvoidance); + package.add("GetPetCriticalHit", &Perl_StatBonuses_GetPetCriticalHit); + package.add("GetPetFlurry", &Perl_StatBonuses_GetPetFlurry); + package.add("GetPetMaxHP", &Perl_StatBonuses_GetPetMaxHP); + package.add("GetPetMeleeMitigation", &Perl_StatBonuses_GetPetMeleeMitigation); + package.add("GetPR", &Perl_StatBonuses_GetPR); + package.add("GetPRCapModifier", &Perl_StatBonuses_GetPRCapModifier); + package.add("GetProcChance", &Perl_StatBonuses_GetProcChance); + package.add("GetProcChanceSPA", &Perl_StatBonuses_GetProcChanceSPA); + package.add("GetRaiseSkillCap", &Perl_StatBonuses_GetRaiseSkillCap); + package.add("GetReduceFallDamage", &Perl_StatBonuses_GetReduceFallDamage); + package.add("GetReduceTradeskillFail", &Perl_StatBonuses_GetReduceTradeskillFail); + package.add("GetReflectChance", &Perl_StatBonuses_GetReflectChance); + package.add("GetResistFearChance", &Perl_StatBonuses_GetResistFearChance); + package.add("GetResistSpellChance", &Perl_StatBonuses_GetResistSpellChance); + package.add("GetReverseDamageShield", &Perl_StatBonuses_GetReverseDamageShield); + package.add("GetReverseDamageShieldSpellID", &Perl_StatBonuses_GetReverseDamageShieldSpellID); + package.add("GetReverseDamageShieldType", &Perl_StatBonuses_GetReverseDamageShieldType); + package.add("GetRiposteChance", &Perl_StatBonuses_GetRiposteChance); + package.add("GetRoot", &Perl_StatBonuses_GetRoot); + package.add("GetRootBreakChance", &Perl_StatBonuses_GetRootBreakChance); + package.add("GetSalvageChance", &Perl_StatBonuses_GetSalvageChance); + package.add("GetSanctuary", &Perl_StatBonuses_GetSanctuary); + package.add("GetScreech", &Perl_StatBonuses_GetScreech); + package.add("GetSecondaryDamageIncrease", &Perl_StatBonuses_GetSecondaryDamageIncrease); + package.add("GetSeeInvis", &Perl_StatBonuses_GetSeeInvis); + package.add("GetSEResist", &Perl_StatBonuses_GetSEResist); + package.add("GetShieldBlock", &Perl_StatBonuses_GetShieldBlock); + package.add("GetShieldEquipDamageModifier", &Perl_StatBonuses_GetShieldEquipDamageModifier); + package.add("GetShroudOfStealth", &Perl_StatBonuses_GetShroudOfStealth); + package.add("GetSingingModifier", &Perl_StatBonuses_GetSingingModifier); + package.add("GetSkillAttackProc", &Perl_StatBonuses_GetSkillAttackProc); + package.add("GetSkillDamageAmount", &Perl_StatBonuses_GetSkillDamageAmount); + package.add("GetSkillDamageAmount2", &Perl_StatBonuses_GetSkillDamageAmount2); + package.add("GetSkillDamageTaken", &Perl_StatBonuses_GetSkillDamageTaken); + package.add("GetSkillModifier", &Perl_StatBonuses_GetSkillModifier); + package.add("GetSkillModifierMax", &Perl_StatBonuses_GetSkillModifierMax); + package.add("GetSkillProc", &Perl_StatBonuses_GetSkillProc); + package.add("GetSkillProcSuccess", &Perl_StatBonuses_GetSkillProcSuccess); + package.add("GetSkillReuseTime", &Perl_StatBonuses_GetSkillReuseTime); + package.add("GetSlayUndead", &Perl_StatBonuses_GetSlayUndead); + package.add("GetSongModifierCap", &Perl_StatBonuses_GetSongModifierCap); + package.add("GetSongRange", &Perl_StatBonuses_GetSongRange); + package.add("GetSpellCriticalDamageIncreaseNoStack", &Perl_StatBonuses_GetSpellCriticalDamageIncreaseNoStack); + package.add("GetSpellCriticalDamageIncrease", &Perl_StatBonuses_GetSpellCriticalDamageIncrease); + package.add("GetSpellDamageShield", &Perl_StatBonuses_GetSpellDamageShield); + package.add("GetSpellDamage", &Perl_StatBonuses_GetSpellDamage); + package.add("GetSpellOnDeath", &Perl_StatBonuses_GetSpellOnDeath); + package.add("GetSpellOnKill", &Perl_StatBonuses_GetSpellOnKill); + package.add("GetSpellProcChance", &Perl_StatBonuses_GetSpellProcChance); + package.add("GetSpellShield", &Perl_StatBonuses_GetSpellShield); + package.add("GetSpellThresholdGuard", &Perl_StatBonuses_GetSpellThresholdGuard); + package.add("GetSpellTriggers", &Perl_StatBonuses_GetSpellTriggers); + package.add("GetSTA", &Perl_StatBonuses_GetSTA); + package.add("GetSTACapModifier", &Perl_StatBonuses_GetSTACapModifier); + package.add("GetSTR", &Perl_StatBonuses_GetSTR); + package.add("GetSTRCapModifier", &Perl_StatBonuses_GetSTRCapModifier); + package.add("GetStrikeThrough", &Perl_StatBonuses_GetStrikeThrough); + package.add("GetStringedModifier", &Perl_StatBonuses_GetStringedModifier); + package.add("GetStunBashChance", &Perl_StatBonuses_GetStunBashChance); + package.add("GetStunResist", &Perl_StatBonuses_GetStunResist); + package.add("GetTradeSkillMastery", &Perl_StatBonuses_GetTradeSkillMastery); + package.add("GetTriggerMeleeThreshold", &Perl_StatBonuses_GetTriggerMeleeThreshold); + package.add("GetTriggerOnValueAmount", &Perl_StatBonuses_GetTriggerOnValueAmount); + package.add("GetTriggerSpellThreshold", &Perl_StatBonuses_GetTriggerSpellThreshold); + package.add("GetTripleAttackChance", &Perl_StatBonuses_GetTripleAttackChance); + package.add("GetTripleBackstab", &Perl_StatBonuses_GetTripleBackstab); + package.add("GetTwoHandBluntBlock", &Perl_StatBonuses_GetTwoHandBluntBlock); + package.add("GetUnfailingDivinity", &Perl_StatBonuses_GetUnfailingDivinity); + package.add("GetVampirism", &Perl_StatBonuses_GetVampirism); + package.add("GetVoiceGraft", &Perl_StatBonuses_GetVoiceGraft); + package.add("GetWindModifier", &Perl_StatBonuses_GetWindModifier); + package.add("GetWIS", &Perl_StatBonuses_GetWIS); + package.add("GetWISCapModifier", &Perl_StatBonuses_GetWISCapModifier); + package.add("GetXPRateModifier", &Perl_StatBonuses_GetXPRateModifier); +} + +#endif //EMBPERL_XS_CLASSES diff --git a/zone/questmgr.cpp b/zone/questmgr.cpp index 719154a90..eb841555d 100644 --- a/zone/questmgr.cpp +++ b/zone/questmgr.cpp @@ -1018,8 +1018,8 @@ bool QuestManager::isdisctome(uint32 item_id) { const std::string item_name = item->Name; if ( - strcmp(item_name.substr(0, 5).c_str(), "Tome ") && - strcmp(item_name.substr(0, 7).c_str(), "Skill: ") + !Strings::BeginsWith(item_name, "Tome of ") && + !Strings::BeginsWith(item_name, "Skill: ") ) { return false; } @@ -3881,7 +3881,7 @@ std::string QuestManager::getgendername(uint32 gender_id) { } std::string QuestManager::getdeityname(uint32 deity_id) { - return EQ::deity::DeityName(static_cast(deity_id)); + return EQ::deity::GetDeityName(static_cast(deity_id)); } std::string QuestManager::getinventoryslotname(int16 slot_id) { diff --git a/zone/spell_effects.cpp b/zone/spell_effects.cpp index 3940139a6..c53b45e92 100644 --- a/zone/spell_effects.cpp +++ b/zone/spell_effects.cpp @@ -788,9 +788,13 @@ bool Mob::SpellEffect(Mob* caster, uint16 spell_id, float partial, int level_ove SetPetOrder(SPO_Follow); SetAppearance(eaStanding); // Client has saved previous pet sit/stand - make all new pets - // stand on charm. + // stand and follow on charm. if (caster->IsClient()) { - caster->CastToClient()->SetPetCommandState(PET_BUTTON_SIT,0); + Client *cpet = caster->CastToClient(); + cpet->SetPetCommandState(PET_BUTTON_SIT,0); + cpet->SetPetCommandState(PET_BUTTON_FOLLOW, 1); + cpet->SetPetCommandState(PET_BUTTON_GUARD, 0); + cpet->SetPetCommandState(PET_BUTTON_STOP, 0); } SetPetType(petCharmed); diff --git a/zone/tradeskills.cpp b/zone/tradeskills.cpp index 2383d841e..e654f4828 100644 --- a/zone/tradeskills.cpp +++ b/zone/tradeskills.cpp @@ -1050,6 +1050,11 @@ bool Client::TradeskillExecute(DBTradeskillRecipe_Struct *spec) { // above critical still stands. // Mastery modifier is: 10%/25%/50% for rank one/two/three chance = 95.0f + (float(user_skill - spec->trivial) / 40.0f); + + if (RuleB(Skills, TrivialTradeskillCombinesNoFail)) { + chance = 100; + } + MessageString(Chat::Emote, TRADESKILL_TRIVIAL); } else if(chance < 5) { // Minimum chance is always 5 diff --git a/zone/trap.cpp b/zone/trap.cpp index 0c447a2d2..cb2fe2363 100644 --- a/zone/trap.cpp +++ b/zone/trap.cpp @@ -360,17 +360,17 @@ void EntityList::UpdateAllTraps(bool respawn, bool repopnow) Log(Logs::General, Logs::Traps, "All traps updated."); } -void EntityList::GetTrapInfo(Client* client) +void EntityList::GetTrapInfo(Client* c) { - uint32 trap_count = 0; + uint32 trap_count = 0; uint32 trap_number = 1; for (const auto& trap : trap_list) { auto t = trap.second; if (t->IsTrap()) { - bool is_set = (t->chkarea_timer.Enabled() && !t->reset_timer.Enabled()); + const bool is_set = (t->chkarea_timer.Enabled() && !t->reset_timer.Enabled()); - client->Message( + c->Message( Chat::White, fmt::format( "Trap {} | ID: {} Active: {} Coordinates: {:.2f}, {:.2f}, {:.2f}", @@ -383,7 +383,7 @@ void EntityList::GetTrapInfo(Client* client) ).c_str() ); - client->Message( + c->Message( Chat::White, fmt::format( "Trap {} | Times Triggered: {} Group: {}", @@ -394,7 +394,7 @@ void EntityList::GetTrapInfo(Client* client) ); if (!t->message.empty()) { - client->Message( + c->Message( Chat::White, fmt::format( "Trap {} | Message: {}", @@ -410,14 +410,14 @@ void EntityList::GetTrapInfo(Client* client) } if (!trap_count) { - client->Message(Chat::White, "No traps were found in this zone."); + c->Message(Chat::White, "No traps were found."); return; } - client->Message( + c->Message( Chat::White, fmt::format( - "{} trap{} found.", + "{} Trap{} found.", trap_count, trap_count != 1 ? "s" : "" ).c_str() diff --git a/zone/waypoints.cpp b/zone/waypoints.cpp index 56e69d017..6eb96cbd2 100644 --- a/zone/waypoints.cpp +++ b/zone/waypoints.cpp @@ -592,7 +592,19 @@ void NPC::NextGuardPosition() { } float Mob::CalculateDistance(float x, float y, float z) { - return (float)sqrtf(((m_Position.x - x)*(m_Position.x - x)) + ((m_Position.y - y)*(m_Position.y - y)) + ((m_Position.z - z)*(m_Position.z - z))); + return sqrtf( + ((m_Position.x - x) * (m_Position.x - x)) + + ((m_Position.y - y) * (m_Position.y - y)) + + ((m_Position.z - z) * (m_Position.z - z)) + ); +} + +float Mob::CalculateDistance(Mob* mob) { + return sqrtf( + ((m_Position.x - mob->GetX()) * (m_Position.x - mob->GetX())) + + ((m_Position.y - mob->GetX()) * (m_Position.y - mob->GetY())) + + ((m_Position.z - mob->GetX()) * (m_Position.z - mob->GetZ())) + ); } void Mob::WalkTo(float x, float y, float z) diff --git a/zone/zoning.cpp b/zone/zoning.cpp index 1f9375ef1..6c59d14ff 100644 --- a/zone/zoning.cpp +++ b/zone/zoning.cpp @@ -1023,8 +1023,8 @@ void Client::SendZoneFlagInfo(Client *to) const { to->Message( Chat::White, fmt::format( - "{} {} no Zone Flags.", - to == this ? "You" : GetName(), + "{} {} no zone flags.", + to->GetTargetDescription(const_cast(CastToMob()), TargetDescriptionType::UCYou), to == this ? "have" : "has" ).c_str() ); @@ -1034,32 +1034,29 @@ void Client::SendZoneFlagInfo(Client *to) const { to->Message( Chat::White, fmt::format( - "{} {} the following Zone Flags:", - to == this ? "You" : GetName(), + "{} {} the following zone flags:", + to->GetTargetDescription(const_cast(CastToMob()), TargetDescriptionType::UCYou), to == this ? "have" : "has" ).c_str() ); - int flag_count = 0; - for (const auto& zone_id : zone_flags) { - int flag_number = (flag_count + 1); - const char* zone_short_name = ZoneName(zone_id, true); - if (strncmp(zone_short_name, "UNKNOWN", strlen(zone_short_name)) != 0) { - std::string zone_long_name = ZoneLongName(zone_id); - std::string flag_name = "ERROR"; + uint32 flag_count = 0; - auto z = GetZone(zone_id); - if (z) { - flag_name = z->flag_needed; - } + for (const auto& zone_id : zone_flags) { + const uint32 flag_number = (flag_count + 1); + + const auto& z = GetZone(zone_id); + + if (z) { + const std::string& flag_name = z->flag_needed; to->Message( Chat::White, fmt::format( - "Flag {} | Zone: {} ({}) ID: {}", + "Flag {} | Zone: {} ({}) ID: {}{}", flag_number, - zone_long_name, - zone_short_name, + z->long_name, + z->short_name, zone_id, ( !flag_name.empty() ? @@ -1078,10 +1075,10 @@ void Client::SendZoneFlagInfo(Client *to) const { to->Message( Chat::White, fmt::format( - "{} {} {} Zone Flags.", - to == this ? "You" : GetName(), - to == this ? "have" : "has", - flag_count + "{} Zone flag{} found for {}.", + flag_count, + flag_count != 1 ? "s" : "", + to->GetTargetDescription(const_cast(CastToMob())) ).c_str() ); }