diff --git a/common/emu_constants.cpp b/common/emu_constants.cpp index be54d8d61..0dd705cde 100644 --- a/common/emu_constants.cpp +++ b/common/emu_constants.cpp @@ -628,3 +628,13 @@ std::string EQ::constants::GetConsiderColorName(uint32 consider_color) const auto& c = EQ::constants::GetConsiderColorMap().find(consider_color); return c != EQ::constants::GetConsiderColorMap().end() ? c->second : std::string(); } + +std::string ComparisonType::GetName(uint8 type) +{ + return IsValid(type) ? comparison_types[type] : "UNKNOWN COMPARISON TYPE"; +} + +bool ComparisonType::IsValid(uint8 type) +{ + return comparison_types.find(type) != comparison_types.end(); +} diff --git a/common/emu_constants.h b/common/emu_constants.h index 5fda27252..bdfb5ccb7 100644 --- a/common/emu_constants.h +++ b/common/emu_constants.h @@ -26,6 +26,35 @@ #include +namespace ComparisonType { + constexpr uint8 Equal = 0; + constexpr uint8 NotEqual = 1; + constexpr uint8 GreaterOrEqual = 2; + constexpr uint8 LesserOrEqual = 3; + constexpr uint8 Greater = 4; + constexpr uint8 Lesser = 5; + constexpr uint8 Any = 6; + constexpr uint8 NotAny = 7; + constexpr uint8 Between = 8; + constexpr uint8 NotBetween = 9; + + std::string GetName(uint8 type); + bool IsValid(uint8 type); +} + +static std::map comparison_types = { + { ComparisonType::Equal, "Equal" }, + { ComparisonType::NotEqual, "Not Equal" }, + { ComparisonType::GreaterOrEqual, "Greater or Equal" }, + { ComparisonType::LesserOrEqual, "Lesser or Equal" }, + { ComparisonType::Greater, "Greater" }, + { ComparisonType::Lesser, "Lesser" }, + { ComparisonType::Any, "Any" }, + { ComparisonType::NotAny, "Not Any" }, + { ComparisonType::Between, "Between" }, + { ComparisonType::NotBetween, "Not Between" }, +}; + // local definitions are the result of using hybrid-client or server-only values and methods namespace EQ @@ -554,19 +583,6 @@ enum ReloadWorld : uint8 { ForceRepop }; -enum BucketComparison : uint8 { - BucketEqualTo = 0, - BucketNotEqualTo, - BucketGreaterThanOrEqualTo, - BucketLesserThanOrEqualTo, - BucketGreaterThan, - BucketLesserThan, - BucketIsAny, - BucketIsNotAny, - BucketIsBetween, - BucketIsNotBetween -}; - enum class EntityFilterType { All, Bots, diff --git a/common/repositories/command_subsettings_repository.h b/common/repositories/command_subsettings_repository.h index 1cef68224..6e8458991 100644 --- a/common/repositories/command_subsettings_repository.h +++ b/common/repositories/command_subsettings_repository.h @@ -52,6 +52,7 @@ public: {.parent_command = "find", .sub_command = "bug_category", .access_level = AccountStatus::QuestTroupe, .top_level_aliases = "findbugcategory"}, {.parent_command = "find", .sub_command = "character", .access_level = AccountStatus::QuestTroupe, .top_level_aliases = "findcharacter"}, {.parent_command = "find", .sub_command = "class", .access_level = AccountStatus::QuestTroupe, .top_level_aliases = "findclass"}, + {.parent_command = "find", .sub_command = "comparison_type", .access_level = AccountStatus::QuestTroupe, .top_level_aliases = "findcomparisontype"}, {.parent_command = "find", .sub_command = "currency", .access_level = AccountStatus::QuestTroupe, .top_level_aliases = "findcurrency"}, {.parent_command = "find", .sub_command = "deity", .access_level = AccountStatus::QuestTroupe, .top_level_aliases = "finddeity"}, {.parent_command = "find", .sub_command = "emote", .access_level = AccountStatus::QuestTroupe, .top_level_aliases = "findemote"}, diff --git a/zone/gm_commands/find.cpp b/zone/gm_commands/find.cpp index 88d786e8f..d21c6bad6 100644 --- a/zone/gm_commands/find.cpp +++ b/zone/gm_commands/find.cpp @@ -3,6 +3,7 @@ #include "find/bug_category.cpp" #include "find/character.cpp" #include "find/class.cpp" +#include "find/comparison_type.cpp" #include "find/currency.cpp" #include "find/deity.cpp" #include "find/emote.cpp" @@ -35,6 +36,7 @@ void command_find(Client *c, const Seperator *sep) Cmd{.cmd = "bug_category", .u = "bug_category [Search Criteria]", .fn = FindBugCategory, .a = {"#findbugcategory"}}, Cmd{.cmd = "character", .u = "character [Search Criteria]", .fn = FindCharacter, .a = {"#findcharacter"}}, Cmd{.cmd = "class", .u = "class [Search Criteria]", .fn = FindClass, .a = {"#findclass"}}, + Cmd{.cmd = "comparison_type", .u = "comparison_type [Search Criteria]", .fn = FindComparisonType, .a = {"#findcomparisontype"}}, 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"}}, diff --git a/zone/gm_commands/find/comparison_type.cpp b/zone/gm_commands/find/comparison_type.cpp new file mode 100644 index 000000000..52a9dea6e --- /dev/null +++ b/zone/gm_commands/find/comparison_type.cpp @@ -0,0 +1,63 @@ +#include "../../client.h" + +void FindComparisonType(Client *c, const Seperator *sep) +{ + if (sep->IsNumber(2)) { + const uint8 type = static_cast(Strings::ToUnsignedInt(sep->arg[2])); + const std::string& type_name = ComparisonType::GetName(type); + if (Strings::EqualFold(type_name, "UNKNOWN COMPARISON TYPE")) { + c->Message( + Chat::White, + fmt::format( + "Comparison Type {} does not exist.", + type + ).c_str() + ); + + return; + } + + c->Message( + Chat::White, + fmt::format( + "Comparison Type {} | {}", + type, + type_name + ).c_str() + ); + + return; + } + + const std::string& search_criteria = Strings::ToLower(sep->argplus[2]); + + uint32 found_count = 0; + + for (const auto& e : comparison_types) { + const std::string& type_name_lower = Strings::ToLower(e.second); + if (!Strings::Contains(type_name_lower, search_criteria)) { + continue; + } + + c->Message( + Chat::White, + fmt::format( + "Comparison Type {} | {}", + e.first, + e.second + ).c_str() + ); + + found_count++; + } + + c->Message( + Chat::White, + fmt::format( + "{} Comparison Type{} found matching '{}'.", + found_count, + found_count != 1 ? "s" : "", + sep->argplus[2] + ).c_str() + ); +} diff --git a/zone/zone.cpp b/zone/zone.cpp index b94c34813..88edb4757 100644 --- a/zone/zone.cpp +++ b/zone/zone.cpp @@ -2987,179 +2987,69 @@ std::string Zone::GetAAName(int aa_id) return std::string(); } -bool Zone::CompareDataBucket(uint8 bucket_comparison, const std::string& bucket_value, const std::string& player_value) +bool Zone::CompareDataBucket(uint8 comparison_type, const std::string& bucket, const std::string& value) { - std::vector bucket_checks; - bool found = false; - bool passes = false; - - switch (bucket_comparison) { - case BucketComparison::BucketEqualTo: - { - if (player_value != bucket_value) { - break; - } - - passes = true; - break; - } - case BucketComparison::BucketNotEqualTo: - { - if (player_value == bucket_value) { - break; - } - - passes = true; - break; - } - case BucketComparison::BucketGreaterThanOrEqualTo: - { - if (!Strings::IsNumber(player_value) || !Strings::IsNumber(bucket_value)) { - break; - } - - if (Strings::ToBigInt(player_value) < Strings::ToBigInt(bucket_value)) { - break; - } - - passes = true; - break; - } - case BucketComparison::BucketLesserThanOrEqualTo: - { - if (!Strings::IsNumber(player_value) || !Strings::IsNumber(bucket_value)) { - break; - } - - if (Strings::ToBigInt(player_value) > Strings::ToBigInt(bucket_value)) { - break; - } - - passes = true; - break; - } - case BucketComparison::BucketGreaterThan: - { - if (!Strings::IsNumber(player_value) || !Strings::IsNumber(bucket_value)) { - break; - } - - if (Strings::ToBigInt(player_value) <= Strings::ToBigInt(bucket_value)) { - break; - } - - passes = true; - break; - } - case BucketComparison::BucketLesserThan: - { - if (!Strings::IsNumber(player_value) || !Strings::IsNumber(bucket_value)) { - break; - } - - if (Strings::ToBigInt(player_value) >= Strings::ToBigInt(bucket_value)) { - break; - } - - passes = true; - - break; - } - case BucketComparison::BucketIsAny: - { - bucket_checks = Strings::Split(bucket_value, "|"); - if (bucket_checks.empty()) { - break; - } - - if (std::find(bucket_checks.begin(), bucket_checks.end(), player_value) != bucket_checks.end()) { - found = true; - } - - if (!found) { - break; - } - - passes = true; - break; - } - case BucketComparison::BucketIsNotAny: - { - bucket_checks = Strings::Split(bucket_value, "|"); - if (bucket_checks.empty()) { - break; - } - - if (std::find(bucket_checks.begin(), bucket_checks.end(), player_value) != bucket_checks.end()) { - found = true; - } - - if (found) { - break; - } - - passes = true; - break; - } - case BucketComparison::BucketIsBetween: - { - bucket_checks = Strings::Split(bucket_value, "|"); - if (bucket_checks.empty()) { - break; - } - - if ( - !Strings::IsNumber(player_value) || - !Strings::IsNumber(bucket_checks[0]) || - !Strings::IsNumber(bucket_checks[1]) - ) { - break; - } - - if ( - !EQ::ValueWithin( - Strings::ToBigInt(player_value), - Strings::ToBigInt(bucket_checks[0]), - Strings::ToBigInt(bucket_checks[1]) - ) - ) { - break; - } - - passes = true; - break; - } - case BucketComparison::BucketIsNotBetween: - { - bucket_checks = Strings::Split(bucket_value, "|"); - if (bucket_checks.empty()) { - break; - } - - if ( - !Strings::IsNumber(player_value) || - !Strings::IsNumber(bucket_checks[0]) || - !Strings::IsNumber(bucket_checks[1]) - ) { - break; - } - - if ( - EQ::ValueWithin( - Strings::ToBigInt(player_value), - Strings::ToBigInt(bucket_checks[0]), - Strings::ToBigInt(bucket_checks[1]) - ) - ) { - break; - } - - passes = true; - break; - } + if (!ComparisonType::IsValid(comparison_type)) { + return false; } - return passes; + if (EQ::ValueWithin(comparison_type, ComparisonType::Equal, ComparisonType::NotEqual)) { + const bool is_equal = value == bucket; + + return comparison_type == ComparisonType::Equal ? is_equal : !is_equal; + } else if (EQ::ValueWithin(comparison_type, ComparisonType::GreaterOrEqual, ComparisonType::LesserOrEqual)) { + if (!Strings::IsNumber(value) || !Strings::IsNumber(bucket)) { + return false; + } + + const int64 p = Strings::ToBigInt(value); + const int64 b = Strings::ToBigInt(bucket); + + const bool is_greater_or_equal = p >= b; + const bool is_lesser_or_equal = p <= b; + + return comparison_type == ComparisonType::GreaterOrEqual ? is_greater_or_equal : is_lesser_or_equal; + } else if (EQ::ValueWithin(comparison_type, ComparisonType::Greater, ComparisonType::Lesser)) { + if (!Strings::IsNumber(value) || !Strings::IsNumber(bucket)) { + return false; + } + + const bool is_greater = Strings::ToBigInt(value) > Strings::ToBigInt(bucket); + + return comparison_type == ComparisonType::Greater ? is_greater : !is_greater; + } else if (EQ::ValueWithin(comparison_type, ComparisonType::Any, ComparisonType::NotAny)) { + const auto& values = Strings::Split(bucket, "|"); + if (values.empty()) { + return false; + } + + const bool is_any = std::find(values.begin(), values.end(), value) != values.end(); + + return comparison_type == ComparisonType::Any ? is_any : !is_any; + } else if (EQ::ValueWithin(comparison_type, ComparisonType::Between, ComparisonType::NotBetween)) { + if (!Strings::IsNumber(value)) { + return false; + } + + const auto& values = Strings::Split(bucket, "|"); + if (values.empty()) { + return false; + } + + if (!Strings::IsNumber(values[0]) || !Strings::IsNumber(values[1])) { + return false; + } + + const bool is_between = EQ::ValueWithin( + Strings::ToBigInt(value), + Strings::ToBigInt(values[0]), + Strings::ToBigInt(values[1]) + ); + + return comparison_type == ComparisonType::Between ? is_between : !is_between; + } + + return false; } void Zone::ReloadContentFlags() diff --git a/zone/zone.h b/zone/zone.h index 544cf8a1a..f1675cc22 100755 --- a/zone/zone.h +++ b/zone/zone.h @@ -334,7 +334,7 @@ public: bool IsQuestHotReloadQueued() const; void SetQuestHotReloadQueued(bool in_quest_hot_reload_queued); - bool CompareDataBucket(uint8 bucket_comparison, const std::string& bucket_value, const std::string& player_value); + bool CompareDataBucket(uint8 comparison_type, const std::string& bucket, const std::string& value); WaterMap *watermap; ZonePoint *GetClosestZonePoint(const glm::vec3 &location, uint32 to, Client *client, float max_distance = 40000.0f);