about summary refs log tree commit diff stats
path: root/apworld/rules.py
blob: 5e20de5edec23fc2d1b7acaa01fba26ebdb4277a (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
from collections.abc import Callable
from typing import TYPE_CHECKING

from BaseClasses import CollectionState
from .player_logic import AccessRequirements

if TYPE_CHECKING:
    from . import Lingo2World


def lingo2_can_satisfy_requirements(state: CollectionState, reqs: AccessRequirements, world: "Lingo2World") -> bool:
    if not all(state.has(item, world.player) for item in reqs.items):
        return False

    if not all(state.has(item, world.player, amount) for item, amount in reqs.progressives.items()):
        return False

    if not all(state.can_reach_region(region_name, world.player) for region_name in reqs.rooms):
        return False

    # TODO: symbols

    for letter_key, letter_level in reqs.letters.items():
        if not state.has(letter_key, world.player, letter_level):
            return False

    if len(reqs.or_logic) > 0:
        if not all(any(lingo2_can_satisfy_requirements(state, sub_reqs, world) for sub_reqs in subjunction)
                   for subjunction in reqs.or_logic):
            return False

    return True

def make_location_lambda(reqs: AccessRequirements, world: "Lingo2World") -> Callable[[CollectionState], bool]:
    return lambda state: lingo2_can_satisfy_requirements(state, reqs, world)
an><variant> namespace com::fourisland::lingo2_archipelago { namespace { struct Heading { std::string type; std::string id; std::string path; std::string resource_type; std::string name; std::string parent; GodotInstanceType instance_type; }; Heading ParseTscnHeading(absl::string_view line) { std::string original_line(line); Heading heading; if (line[0] != '[') { std::ostringstream errormsg; errormsg << "Heading must start with [." << std::endl << "Bad heading: " << original_line; throw std::invalid_argument(errormsg.str()); } line.remove_prefix(1); int divider = line.find_first_of(" ]"); if (divider == std::string_view::npos) { std::ostringstream errormsg; errormsg << "Malformatted heading: " << line << std::endl << "Original line: " << original_line; throw std::invalid_argument(errormsg.str()); } heading.type = std::string(line.substr(0, divider)); line.remove_prefix(divider + 1); while (!line.empty()) { divider = line.find_first_of("="); if (divider == std::string_view::npos) { std::ostringstream errormsg; errormsg << "Malformatted heading: " << line << std::endl << "Original line: " << original_line; throw std::invalid_argument(errormsg.str()); } std::string key(line.substr(0, divider)); line.remove_prefix(divider + 1); if (line[0] == '"') { line.remove_prefix(1); divider = line.find_first_of("\""); if (divider == std::string_view::npos) { std::ostringstream errormsg; errormsg << "Malformatted heading: " << line << std::endl << "Original line: " << original_line; throw std::invalid_argument(errormsg.str()); } std::string strval(line.substr(0, divider)); line.remove_prefix(divider + 2); if (key == "name") { heading.name = strval; } else if (key == "parent") { heading.parent = strval; } else if (key == "path") { heading.path = strval; } else if (key == "type") { heading.resource_type = strval; } else if (key == "id") { heading.id = strval; } } else if (line[0] == 'S' || line[0] == 'E') { GodotInstanceType rrval; char internal = line[0]; line.remove_prefix(13); // SubResource(" divider = line.find_first_of("\""); if (divider == std::string_view::npos) { std::ostringstream errormsg; errormsg << "Malformatted heading: " << line << std::endl << "Original line: " << original_line; throw std::invalid_argument(errormsg.str()); } std::string refid = std::string(line.substr(0, divider)); line.remove_prefix(divider + 3); GodotInstanceType instance_type; if (internal == 'E') { instance_type = GodotExtResourceRef{.id = refid}; } else { // SubResource is not supported right now. } if (key == "instance") { heading.instance_type = instance_type; } else { // Other keys aren't supported right now. } } else { divider = line.find_first_of(" ]"); if (divider == std::string_view::npos) { std::ostringstream errormsg; errormsg << "Malformatted heading: " << line << std::endl << "Original line: " << original_line; throw std::invalid_argument(errormsg.str()); } int numval = std::atoi(line.substr(0, divider).data()); line.remove_prefix(divider + 1); // keyvals_[key] = numval; } } return heading; } } // namespace std::string GodotNode::GetPath() const { if (parent.empty() || parent == ".") { return name; } else { return parent + "/" + name; } } GodotScene ReadGodotSceneFromFile(const std::string& path) { std::map<std::string, GodotExtResource> ext_resources; std::vector<GodotNode> nodes; std::ifstream input(path); std::string line; bool section_started = false; Heading cur_heading; std::ostringstream cur_value; bool value_started = false; auto handle_end_of_section = [&]() { section_started = false; value_started = false; if (cur_heading.type == "sub_resource") { // sub_resources_[std::get<int>(cur_heading.GetKeyval("id"))] = // {cur_heading, cur_value.str(), ""}; } else { // other_.emplace_back(cur_heading, cur_value.str()); } cur_value = {}; }; while (std::getline(input, line)) { if (section_started && (line.empty() || line[0] == '[')) { handle_end_of_section(); } if (!line.empty() && line[0] == '[') { Heading heading = ParseTscnHeading(line); if (heading.type == "gd_scene") { // file_descriptor_ = heading; } else if (heading.type == "ext_resource") { GodotExtResource ext_resource; ext_resource.path = heading.path; ext_resource.type = heading.resource_type; ext_resources[heading.id] = ext_resource; } else if (heading.type == "node") { if (heading.parent != "") { nodes.push_back(GodotNode{.name = heading.name, .parent = heading.parent, .instance_type = heading.instance_type}); } } else { cur_heading = heading; section_started = true; } } else if (!line.empty()) { if (value_started) { cur_value << std::endl; } else { value_started = true; } cur_value << line; } } if (section_started) { handle_end_of_section(); } return GodotScene(std::move(ext_resources), std::move(nodes)); } } // namespace com::fourisland::lingo2_archipelago