diff --git a/doc/PACKS.md b/doc/PACKS.md index 0554d39b..5e2a8f81 100644 --- a/doc/PACKS.md +++ b/doc/PACKS.md @@ -416,6 +416,8 @@ Rule-goups inside `{` `}` are a different set of rules to mark the section as "c Individual rules can be specified as json array instead of string, which allows to use `,` inside names or arguments. Only available in PopTracker, since 0.19.1. +Rules can be specified as a single string, which is equivalent to `[[string]]`. Only available in PopTracker, since 0.25.6. + **Parent:** With `"parent"`, the location's parent can be overwritten. Since PopTracker v0.19.2. This is useful to put a location from `dungeons.json` into a location from `overworld.json`, diff --git a/schema/packs/locations.json b/schema/packs/locations.json index 91f4e9b8..ba55047d 100644 --- a/schema/packs/locations.json +++ b/schema/packs/locations.json @@ -43,15 +43,23 @@ "rule3,rule4", "{checkrule1, checkrule2}" ], - "type": "array", "anyOf": [ { - "description": "Access rules for the section. Section will be marked reachable (green) if all rules are matched. Rules inside [] are optional (i.e. glitches work around this rule; marked as yellow). If rules in {} are matched, the section will be marked as checkable (blue). Children will always inherit rules from parents. Each entry will be OR-ed together, comma sperated rules will be AND-ed.", - "$ref": "#/$defs/rules_string" + "type": "array", + "anyOf": [ + { + "description": "Access rules for the section. Section will be marked reachable (green) if all rules are matched. Rules inside [] are optional (i.e. glitches work around this rule; marked as yellow). If rules in {} are matched, the section will be marked as checkable (blue). Children will always inherit rules from parents. Each entry will be OR-ed together, comma sperated rules will be AND-ed.", + "$ref": "#/$defs/rules_string" + }, + { + "description": "Access rules for the section. Section will be marked reachable (green) if all rules are matched. Rules inside [] are optional (i.e. glitches work around this rule; marked as yellow). If rules in {} are matched, the section will be marked as checkable (blue). Children will always inherit rules from parents. 2-Dimensional array of rules, first dimenstion will be OR-ed together, second will be AND-ed.", + "$ref": "#/$defs/rules_array" + } + ] }, { - "description": "Access rules for the section. Section will be marked reachable (green) if all rules are matched. Rules inside [] are optional (i.e. glitches work around this rule; marked as yellow). If rules in {} are matched, the section will be marked as checkable (blue). Children will always inherit rules from parents. 2-Dimensional array of rules, first dimenstion will be OR-ed together, second will be AND-ed.", - "$ref": "#/$defs/rules_array" + "type": "string", + "description": "Single code/access rule for the section. \"code\" behaves the same as [[\"code\"]]. See array of string and array of array of string for complex rules in json." } ] }, @@ -60,15 +68,23 @@ "rule1,rule2", "rule3,rule4" ], - "type": "array", "anyOf": [ { - "description": "Visibility rules for the section. Section will only be visible if rules are matched. Children will always inherit rules from parents. Each entry will be OR-ed together, comma sperated rules will be AND-ed.", - "$ref": "#/$defs/rules_string" + "type": "array", + "anyOf": [ + { + "description": "Visibility rules for the section. Section will only be visible if rules are matched. Children will always inherit rules from parents. Each entry will be OR-ed together, comma sperated rules will be AND-ed.", + "$ref": "#/$defs/rules_string" + }, + { + "description": "Visibility rules for the section. Section will only be visible if rules are matched. Children will always inherit rules from parents. 2-Dimensional array of rules, first dimenstion will be OR-ed together, second will be AND-ed.", + "$ref": "#/$defs/rules_array" + } + ] }, { - "description": "Visibility rules for the section. Section will only be visible if rules are matched. Children will always inherit rules from parents. 2-Dimensional array of rules, first dimenstion will be OR-ed together, second will be AND-ed.", - "$ref": "#/$defs/rules_array" + "type": "string", + "description": "Single code/visibility rule for the section. \"code\" behaves the same as [[\"code\"]]. See array of string and array of array of string for complex rules in json." } ] }, @@ -152,15 +168,23 @@ "rule3,rule4", "{checkrule1, checkrule2}" ], - "type": "array", "anyOf": [ { - "description": "Access rules for the location. Location will be marked reachable (green) if all rules are matched. Rules inside [] are optional (i.e. glitches work around this rule; marked as yellow). If rules in {} are matched, the location will be marked as checkable (blue). Children/sections will always inherit rules from parents. Each entry will be OR-ed together, comma sperated rules will be AND-ed.", - "$ref": "#/$defs/rules_string" + "type": "array", + "anyOf": [ + { + "description": "Access rules for the location. Location will be marked reachable (green) if all rules are matched. Rules inside [] are optional (i.e. glitches work around this rule; marked as yellow). If rules in {} are matched, the location will be marked as checkable (blue). Children/sections will always inherit rules from parents. Each entry will be OR-ed together, comma sperated rules will be AND-ed.", + "$ref": "#/$defs/rules_string" + }, + { + "description": "Access rules for the location. Location will be marked reachable (green) if all rules are matched. Rules inside [] are optional (i.e. glitches work around this rule; marked as yellow). If rules in {} are matched, the location will be marked as checkable (blue). Children/sections will always inherit rules from parents. 2-Dimensional array of rules, first dimenstion will be OR-ed together, second will be AND-ed.", + "$ref": "#/$defs/rules_array" + } + ] }, { - "description": "Access rules for the location. Location will be marked reachable (green) if all rules are matched. Rules inside [] are optional (i.e. glitches work around this rule; marked as yellow). If rules in {} are matched, the location will be marked as checkable (blue). Children/sections will always inherit rules from parents. 2-Dimensional array of rules, first dimenstion will be OR-ed together, second will be AND-ed.", - "$ref": "#/$defs/rules_array" + "type": "string", + "description": "Single code/access rule for the location. \"code\" behaves the same as [[\"code\"]]. See array of string and array of array of string for complex rules in json." } ] }, @@ -169,15 +193,23 @@ "rule1,rule2", "rule3,rule4" ], - "type": "array", "anyOf": [ { - "description": "Visibility rules for the location. Location will only be visible if rules are matched. Children/sections will always inherit rules from parents. Each entry will be OR-ed together, comma sperated rules will be AND-ed.", - "$ref": "#/$defs/rules_string" + "type": "array", + "anyOf": [ + { + "description": "Visibility rules for the location. Location will only be visible if rules are matched. Children/sections will always inherit rules from parents. Each entry will be OR-ed together, comma sperated rules will be AND-ed.", + "$ref": "#/$defs/rules_string" + }, + { + "description": "Visibility rules for the location. Location will only be visible if rules are matched. Children/sections will always inherit rules from parents. 2-Dimensional array of rules, first dimenstion will be OR-ed together, second will be AND-ed.", + "$ref": "#/$defs/rules_array" + } + ] }, { - "description": "Visibility rules for the location. Location will only be visible if rules are matched. Children/sections will always inherit rules from parents. 2-Dimensional array of rules, first dimenstion will be OR-ed together, second will be AND-ed.", - "$ref": "#/$defs/rules_array" + "type": "string", + "description": "Single code/visibility rule for the location. \"code\" behaves the same as [[\"code\"]]. See array of string and array of array of string for complex rules in json." } ] }, @@ -255,15 +287,23 @@ "rule1,rule2", "rule3,rule4" ], - "type": "array", "anyOf": [ { - "description": "Additional visibility rules for individual map location.", - "$ref": "#/$defs/rules_string" + "type": "array", + "anyOf": [ + { + "description": "Additional visibility rules for individual map location.", + "$ref": "#/$defs/rules_string" + }, + { + "description": "Additional visibility rules for individual map location.", + "$ref": "#/$defs/rules_array" + } + ] }, { - "description": "Additional visibility rules for individual map location.", - "$ref": "#/$defs/rules_array" + "type": "string", + "description": "Single additional visibility code/rule for individual map location." } ] }, @@ -272,15 +312,23 @@ "rule1,rule2", "rule3,rule4" ], - "type": "array", "anyOf": [ { - "description": "Additional rules that force-hide the map location if true.", - "$ref": "#/$defs/rules_string" + "type": "array", + "anyOf": [ + { + "description": "Additional rules that force-hide the map location if true.", + "$ref": "#/$defs/rules_string" + }, + { + "description": "Additional rules that force-hide the map location if true.", + "$ref": "#/$defs/rules_array" + } + ] }, { - "description": "Additional rules that force-hide the map location if true.", - "$ref": "#/$defs/rules_array" + "type": "string", + "description": "Single additional code/rule that force-hides the map location if true." } ] } diff --git a/schema/packs/strict/locations.json b/schema/packs/strict/locations.json index 13693701..998c27a1 100644 --- a/schema/packs/strict/locations.json +++ b/schema/packs/strict/locations.json @@ -42,15 +42,23 @@ "rule3,rule4", "{checkrule1, checkrule2}" ], - "type": "array", "anyOf": [ { - "description": "Access rules for the section. Section will be marked reachable (green) if all rules are matched. Rules inside [] are optional (i.e. glitches work around this rule; marked as yellow). If rules in {} are matched, the section will be marked as checkable (blue). Children will always inherit rules from parents. Each entry will be OR-ed together, comma sperated rules will be AND-ed.", - "$ref": "#/$defs/rules_string" + "type": "array", + "anyOf": [ + { + "description": "Access rules for the section. Section will be marked reachable (green) if all rules are matched. Rules inside [] are optional (i.e. glitches work around this rule; marked as yellow). If rules in {} are matched, the section will be marked as checkable (blue). Children will always inherit rules from parents. Each entry will be OR-ed together, comma sperated rules will be AND-ed.", + "$ref": "#/$defs/rules_string" + }, + { + "description": "Access rules for the section. Section will be marked reachable (green) if all rules are matched. Rules inside [] are optional (i.e. glitches work around this rule; marked as yellow). If rules in {} are matched, the section will be marked as checkable (blue). Children will always inherit rules from parents. 2-Dimensional array of rules, first dimenstion will be OR-ed together, second will be AND-ed.", + "$ref": "#/$defs/rules_array" + } + ] }, { - "description": "Access rules for the section. Section will be marked reachable (green) if all rules are matched. Rules inside [] are optional (i.e. glitches work around this rule; marked as yellow). If rules in {} are matched, the section will be marked as checkable (blue). Children will always inherit rules from parents. 2-Dimensional array of rules, first dimenstion will be OR-ed together, second will be AND-ed.", - "$ref": "#/$defs/rules_array" + "type": "string", + "description": "Single code/access rule for the section. \"code\" behaves the same as [[\"code\"]]. See array of string and array of array of string for complex rules in json." } ] }, @@ -59,15 +67,23 @@ "rule1,rule2", "rule3,rule4" ], - "type": "array", "anyOf": [ { - "description": "Visibility rules for the section. Section will only be visible if rules are matched. Children will always inherit rules from parents. Each entry will be OR-ed together, comma sperated rules will be AND-ed.", - "$ref": "#/$defs/rules_string" + "type": "array", + "anyOf": [ + { + "description": "Visibility rules for the section. Section will only be visible if rules are matched. Children will always inherit rules from parents. Each entry will be OR-ed together, comma sperated rules will be AND-ed.", + "$ref": "#/$defs/rules_string" + }, + { + "description": "Visibility rules for the section. Section will only be visible if rules are matched. Children will always inherit rules from parents. 2-Dimensional array of rules, first dimenstion will be OR-ed together, second will be AND-ed.", + "$ref": "#/$defs/rules_array" + } + ] }, { - "description": "Visibility rules for the section. Section will only be visible if rules are matched. Children will always inherit rules from parents. 2-Dimensional array of rules, first dimenstion will be OR-ed together, second will be AND-ed.", - "$ref": "#/$defs/rules_array" + "type": "string", + "description": "Single code/visibility rule for the section. \"code\" behaves the same as [[\"code\"]]. See array of string and array of array of string for complex rules in json." } ] }, @@ -134,15 +150,23 @@ "rule3,rule4", "{checkrule1, checkrule2}" ], - "type": "array", "anyOf": [ { - "description": "Access rules for the location. Location will be marked reachable (green) if all rules are matched. Rules inside [] are optional (i.e. glitches work around this rule; marked as yellow). If rules in {} are matched, the location will be marked as checkable (blue). Children/sections will always inherit rules from parents. Each entry will be OR-ed together, comma sperated rules will be AND-ed.", - "$ref": "#/$defs/rules_string" + "type": "array", + "anyOf": [ + { + "description": "Access rules for the location. Location will be marked reachable (green) if all rules are matched. Rules inside [] are optional (i.e. glitches work around this rule; marked as yellow). If rules in {} are matched, the location will be marked as checkable (blue). Children/sections will always inherit rules from parents. Each entry will be OR-ed together, comma sperated rules will be AND-ed.", + "$ref": "#/$defs/rules_string" + }, + { + "description": "Access rules for the location. Location will be marked reachable (green) if all rules are matched. Rules inside [] are optional (i.e. glitches work around this rule; marked as yellow). If rules in {} are matched, the location will be marked as checkable (blue). Children/sections will always inherit rules from parents. 2-Dimensional array of rules, first dimenstion will be OR-ed together, second will be AND-ed.", + "$ref": "#/$defs/rules_array" + } + ] }, { - "description": "Access rules for the location. Location will be marked reachable (green) if all rules are matched. Rules inside [] are optional (i.e. glitches work around this rule; marked as yellow). If rules in {} are matched, the location will be marked as checkable (blue). Children/sections will always inherit rules from parents. 2-Dimensional array of rules, first dimenstion will be OR-ed together, second will be AND-ed.", - "$ref": "#/$defs/rules_array" + "type": "string", + "description": "Single code/access rule for the location. \"code\" behaves the same as [[\"code\"]]. See array of string and array of array of string for complex rules in json." } ] }, @@ -151,15 +175,23 @@ "rule1,rule2", "rule3,rule4" ], - "type": "array", "anyOf": [ { - "description": "Visibility rules for the location. Location will only be visible if rules are matched. Children/sections will always inherit rules from parents. Each entry will be OR-ed together, comma sperated rules will be AND-ed.", - "$ref": "#/$defs/rules_string" + "type": "array", + "anyOf": [ + { + "description": "Visibility rules for the location. Location will only be visible if rules are matched. Children/sections will always inherit rules from parents. Each entry will be OR-ed together, comma sperated rules will be AND-ed.", + "$ref": "#/$defs/rules_string" + }, + { + "description": "Visibility rules for the location. Location will only be visible if rules are matched. Children/sections will always inherit rules from parents. 2-Dimensional array of rules, first dimenstion will be OR-ed together, second will be AND-ed.", + "$ref": "#/$defs/rules_array" + } + ] }, { - "description": "Visibility rules for the location. Location will only be visible if rules are matched. Children/sections will always inherit rules from parents. 2-Dimensional array of rules, first dimenstion will be OR-ed together, second will be AND-ed.", - "$ref": "#/$defs/rules_array" + "type": "string", + "description": "Single code/visibility rule for the location. \"code\" behaves the same as [[\"code\"]]. See array of string and array of array of string for complex rules in json." } ] }, @@ -205,15 +237,23 @@ "rule1,rule2", "rule3,rule4" ], - "type": "array", "anyOf": [ { - "description": "Additional visibility rules for individual map location.", - "$ref": "#/$defs/rules_string" + "type": "array", + "anyOf": [ + { + "description": "Additional visibility rules for individual map location.", + "$ref": "#/$defs/rules_string" + }, + { + "description": "Additional visibility rules for individual map location.", + "$ref": "#/$defs/rules_array" + } + ] }, { - "description": "Additional visibility rules for individual map location.", - "$ref": "#/$defs/rules_array" + "type": "string", + "description": "Single additional visibility code/rule for individual map location." } ] }, @@ -222,15 +262,23 @@ "rule1,rule2", "rule3,rule4" ], - "type": "array", "anyOf": [ { - "description": "Additional rules that force-hide the map location if true.", - "$ref": "#/$defs/rules_string" + "type": "array", + "anyOf": [ + { + "description": "Additional rules that force-hide the map location if true.", + "$ref": "#/$defs/rules_string" + }, + { + "description": "Additional rules that force-hide the map location if true.", + "$ref": "#/$defs/rules_array" + } + ] }, { - "description": "Additional rules that force-hide the map location if true.", - "$ref": "#/$defs/rules_array" + "type": "string", + "description": "Single additional code/rule that force-hides the map location if true." } ] } diff --git a/src/core/location.cpp b/src/core/location.cpp index 23dc5099..5542b34f 100644 --- a/src/core/location.cpp +++ b/src/core/location.cpp @@ -179,6 +179,16 @@ std::list Location::FromJSON(json& j, const std::list& paren accessRules.push_back(newRule); } } + } else if (j["access_rules"].is_string() && !j["access_rules"].empty()) { + // single string access rule, same as [["code"]] + const std::string& newTest = j["access_rules"]; + for (auto oldRule : parentAccessRules) { + oldRule.push_back(newTest); + accessRules.push_back(oldRule); + } + if (parentAccessRules.empty()) { + accessRules.push_back({newTest}); + } } else { accessRules = parentAccessRules; // TODO: avoid copy if (!j["access_rules"].is_null()) { @@ -203,6 +213,16 @@ std::list Location::FromJSON(json& j, const std::list& paren visibilityRules.push_back(newRule); } } + } else if (j["visibility_rules"].is_string() && !j["visibility_rules"].empty()) { + // single string visibility rule, same as [["code"]] + const std::string& newTest = j["visibility_rules"]; + for (auto oldRule : parentVisibilityRules) { + oldRule.push_back(newTest); + visibilityRules.push_back(oldRule); + } + if (parentVisibilityRules.empty()) { + visibilityRules.push_back({newTest}); + } } else { visibilityRules = parentVisibilityRules; // TODO: avoid copy if (!j["visibility_rules"].is_null()) { @@ -280,20 +300,36 @@ Location::MapLocation Location::MapLocation::FromJSON(json& j) maploc._size = to_int(j["size"],-1); maploc._borderThickness = to_int(j["border_thickness"],-1); - for (const auto& v : j["restrict_visibility_rules"]) { - // outer array is logical Or, inner array (or string) is logical And - std::list newRule; - if (!parseRule(v, newRule, "MapLocation", "restrict visibility", maploc._mapName)) - continue; - maploc._visibilityRules.push_back(newRule); + if (j["restrict_visibility_rules"].is_array()) { + for (const auto& v : j["restrict_visibility_rules"]) { + // outer array is logical Or, inner array (or string) is logical And + std::list newRule; + if (!parseRule(v, newRule, "MapLocation", "restrict visibility", maploc._mapName)) + continue; + maploc._visibilityRules.push_back(newRule); + } + } else if (j["restrict_visibility_rules"].is_string()) { + const std::string& newTest = j["restrict_visibility_rules"]; + maploc._visibilityRules.push_back({newTest}); + } else if (!j["restrict_visibility_rules"].is_null()) { + fprintf(stderr, "MapLocation: invalid restrict_visibility_rules for \"%s\"\n", + sanitize_print(maploc._mapName).c_str()); } - for (const auto& v : j["force_invisibility_rules"]) { - // outer array is logical Or, inner array (or string) is logical And - std::list newRule; - if (!parseRule(v, newRule, "MapLocation", "force invisibility", maploc._mapName)) - continue; - maploc._invisibilityRules.push_back(newRule); + if (j["force_invisibility_rules"].is_array()) { + for (const auto& v : j["force_invisibility_rules"]) { + // outer array is logical Or, inner array (or string) is logical And + std::list newRule; + if (!parseRule(v, newRule, "MapLocation", "force invisibility", maploc._mapName)) + continue; + maploc._invisibilityRules.push_back(newRule); + } + } else if (j["force_invisibility_rules"].is_string()) { + const std::string& newTest = j["force_invisibility_rules"]; + maploc._invisibilityRules.push_back({newTest}); + } else if (!j["force_invisibility_rules"].is_null()) { + fprintf(stderr, "MapLocation: invalid force_invisibility_rules for \"%s\"\n", + sanitize_print(maploc._mapName).c_str()); } return maploc; @@ -334,6 +370,16 @@ LocationSection LocationSection::FromJSON(json& j, const std::string parentId, c sec._accessRules.push_back(newRule); } } + } else if (j["access_rules"].is_string() && !j["access_rules"].empty()) { + // single string access rule, same as [["code"]] + const std::string& newTest = j["access_rules"]; + for (auto oldRule : parentAccessRules) { + oldRule.push_back(newTest); + sec._accessRules.push_back(oldRule); + } + if (parentAccessRules.empty()) { + sec._accessRules.push_back({newTest}); + } } else { sec._accessRules = parentAccessRules; if (!j["access_rules"].is_null()) { @@ -358,6 +404,16 @@ LocationSection LocationSection::FromJSON(json& j, const std::string parentId, c sec._visibilityRules.push_back(newRule); } } + } else if (j["visibility_rules"].is_string() && !j["visibility_rules"].empty()) { + // single string visibility rule, same as [["code"]] + const std::string& newTest = j["visibility_rules"]; + for (auto oldRule : parentVisibilityRules) { + oldRule.push_back(newTest); + sec._visibilityRules.push_back(oldRule); + } + if (parentVisibilityRules.empty()) { + sec._visibilityRules.push_back({newTest}); + } } else { sec._visibilityRules = parentVisibilityRules; if (!j["visibility_rules"].is_null()) {