about summary refs log tree commit diff stats
path: root/apworld/tracker.py
blob: 721e9b357e71916f88878e9713b9966dfb28aec3 (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
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
from BaseClasses import MultiWorld, CollectionState, ItemClassification
from NetUtils import NetworkItem
from . import Lingo2World, Lingo2Item
from .regions import connect_ports_from_ut
from .options import Lingo2Options

PLAYER_NUM = 1


class Tracker:
    multiworld: MultiWorld

    collected_items: dict[int, int]
    checked_locations: set[int]
    accessible_locations: set[int]

    state: CollectionState

    def __init__(self):
        self.collected_items = {}
        self.checked_locations = set()
        self.accessible_locations = set()

    def setup_slot(self, slot_data):
        self.multiworld = MultiWorld(players=PLAYER_NUM)
        world = Lingo2World(self.multiworld, PLAYER_NUM)
        self.multiworld.worlds[1] = world
        world.options = Lingo2Options(**{k: t(slot_data.get(k, t.default))
                                         for k, t in Lingo2Options.type_hints.items()})

        world.generate_early()
        world.create_regions()

        if world.options.shuffle_worldports:
            port_pairings = {int(fp): int(tp) for fp, tp in slot_data["port_pairings"].items()}
            connect_ports_from_ut(port_pairings, world)

        self.state = CollectionState(self.multiworld)

    def set_checked_locations(self, checked_locations: set[int]):
        self.checked_locations = checked_locations.copy()

    def set_collected_items(self, network_items: list[NetworkItem]):
        self.collected_items = {}

        for item in network_items:
            self.collected_items[item.item] = self.collected_items.get(item.item, 0) + 1

        self.refresh_state()

    def refresh_state(self):
        self.state = CollectionState(self.multiworld)

        for item_id, item_amount in self.collected_items.items():
            for i in range(item_amount):
                self.state.collect(Lingo2Item(Lingo2World.static_logic.item_id_to_name.get(item_id),
                                              ItemClassification.progression, item_id, PLAYER_NUM), prevent_sweep=True)

        self.state.sweep_for_advancements()

        self.accessible_locations = set()

        for region in self.state.reachable_regions[PLAYER_NUM]:
            for location in region.locations:
                if location.address not in self.checked_locations and location.access_rule(self.state):
                    if location.address is not None:
                        self.accessible_locations.add(location.address)