From c9da387ede51f207825b63d9f13036a7b661d4b3 Mon Sep 17 00:00:00 2001 From: Star Rauchenberger Date: Thu, 7 Aug 2025 16:05:15 -0400 Subject: Started apworld vcpkg's libprotobuf is older than what PIP has, but neither are completely up to date either. Ugh. Doors have a room now because that's where the location will go. --- apworld/__init__.py | 38 ++++++++++++++++++++++++++++++++++++++ apworld/locations.py | 5 +++++ apworld/options.py | 8 ++++++++ apworld/player_logic.py | 24 ++++++++++++++++++++++++ apworld/regions.py | 28 ++++++++++++++++++++++++++++ apworld/requirements.txt | 1 + apworld/static_logic.py | 9 +++++++++ 7 files changed, 113 insertions(+) create mode 100644 apworld/__init__.py create mode 100644 apworld/locations.py create mode 100644 apworld/options.py create mode 100644 apworld/player_logic.py create mode 100644 apworld/regions.py create mode 100644 apworld/requirements.txt create mode 100644 apworld/static_logic.py (limited to 'apworld') diff --git a/apworld/__init__.py b/apworld/__init__.py new file mode 100644 index 0000000..013910e --- /dev/null +++ b/apworld/__init__.py @@ -0,0 +1,38 @@ +""" +Archipelago init file for Lingo 2 +""" +from worlds.AutoWorld import WebWorld, World +from .options import Lingo2Options +from .player_logic import Lingo2PlayerLogic +from .regions import create_regions +from .static_logic import Lingo2StaticLogic + + +class Lingo2WebWorld(WebWorld): + rich_text_options_doc = True + theme = "grass" + + +class Lingo2World(World): + """ + Lingo 2 is a first person indie puzzle game where you solve word puzzles in a labyrinthe world. Compared to its + predecessor, Lingo 2 has new mechanics, more areas, and a unique progression system where you have to unlock letters + before using them in puzzle solutions. + """ + game = "Lingo 2" + web = Lingo2WebWorld() + + options_dataclass = Lingo2Options + options: Lingo2Options + + item_name_to_id = {} + location_name_to_id = {} + + static_logic = Lingo2StaticLogic() + player_logic: Lingo2PlayerLogic + + def generate_early(self): + self.player_logic = Lingo2PlayerLogic(self) + + def create_regions(self): + create_regions(self) diff --git a/apworld/locations.py b/apworld/locations.py new file mode 100644 index 0000000..818be39 --- /dev/null +++ b/apworld/locations.py @@ -0,0 +1,5 @@ +from BaseClasses import Location + + +class Lingo2Location(Location): + game: str = "Lingo 2" \ No newline at end of file diff --git a/apworld/options.py b/apworld/options.py new file mode 100644 index 0000000..f33f5af --- /dev/null +++ b/apworld/options.py @@ -0,0 +1,8 @@ +from dataclasses import dataclass + +from Options import PerGameCommonOptions + + +@dataclass +class Lingo2Options(PerGameCommonOptions): + pass diff --git a/apworld/player_logic.py b/apworld/player_logic.py new file mode 100644 index 0000000..f54573f --- /dev/null +++ b/apworld/player_logic.py @@ -0,0 +1,24 @@ +from typing import TYPE_CHECKING, NamedTuple + +if TYPE_CHECKING: + from . import Lingo2World + + +class PlayerLocation(NamedTuple): + name: str + code: int | None + + +class Lingo2PlayerLogic: + locations_by_room: dict[int, list[PlayerLocation]] + + def __init__(self, world: "Lingo2World"): + self.locations_by_room = {} + + code = 1 + for door in world.static_logic.objects.doors: + if not door.HasField("room_id"): + continue + + self.locations_by_room.setdefault(door.room_id, []).append(PlayerLocation(door.name, code)) + code += 1 diff --git a/apworld/regions.py b/apworld/regions.py new file mode 100644 index 0000000..24c2281 --- /dev/null +++ b/apworld/regions.py @@ -0,0 +1,28 @@ +from typing import TYPE_CHECKING + +from BaseClasses import Region +from .locations import Lingo2Location + +if TYPE_CHECKING: + from . import Lingo2World + + +def create_region(room, world: "Lingo2World") -> Region: + new_region = Region(room.name, world.player, world.multiworld) + + for location in world.player_logic.locations_by_room.get(room.id, {}): + new_location = Lingo2Location(world.player, location.name, location.code, new_region) + new_region.locations.append(new_location) + + return new_region + + +def create_regions(world: "Lingo2World"): + regions = { + "Menu": Region("Menu", world.player, world.multiworld) + } + + for room in world.static_logic.objects.rooms: + regions[room.name] = create_region(room, world) + + world.multiworld.regions += regions.values() diff --git a/apworld/requirements.txt b/apworld/requirements.txt new file mode 100644 index 0000000..b701d11 --- /dev/null +++ b/apworld/requirements.txt @@ -0,0 +1 @@ +protobuf>=5.29.3 \ No newline at end of file diff --git a/apworld/static_logic.py b/apworld/static_logic.py new file mode 100644 index 0000000..6c38f1f --- /dev/null +++ b/apworld/static_logic.py @@ -0,0 +1,9 @@ +from .generated import data_pb2 as data_pb2 +import pkgutil + +class Lingo2StaticLogic: + def __init__(self): + file = pkgutil.get_data(__name__, "generated/data.binpb") + + self.objects = data_pb2.AllObjects() + self.objects.ParseFromString(bytearray(file)) -- cgit 1.4.1