diff options
| author | Star Rauchenberger <fefferburbia@gmail.com> | 2025-08-07 16:05:15 -0400 |
|---|---|---|
| committer | Star Rauchenberger <fefferburbia@gmail.com> | 2025-08-07 16:05:15 -0400 |
| commit | c9da387ede51f207825b63d9f13036a7b661d4b3 (patch) | |
| tree | 08425dbc57c92ac72fef43c32ecbd5805f18f1f8 /apworld | |
| parent | 3c26cedd030c464e3b8a5576a98c19eb45134658 (diff) | |
| download | lingo2-archipelago-c9da387ede51f207825b63d9f13036a7b661d4b3.tar.gz lingo2-archipelago-c9da387ede51f207825b63d9f13036a7b661d4b3.tar.bz2 lingo2-archipelago-c9da387ede51f207825b63d9f13036a7b661d4b3.zip | |
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.
Diffstat (limited to 'apworld')
| -rw-r--r-- | apworld/__init__.py | 38 | ||||
| -rw-r--r-- | apworld/locations.py | 5 | ||||
| -rw-r--r-- | apworld/options.py | 8 | ||||
| -rw-r--r-- | apworld/player_logic.py | 24 | ||||
| -rw-r--r-- | apworld/regions.py | 28 | ||||
| -rw-r--r-- | apworld/requirements.txt | 1 | ||||
| -rw-r--r-- | apworld/static_logic.py | 9 |
7 files changed, 113 insertions, 0 deletions
| 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 @@ | |||
| 1 | """ | ||
| 2 | Archipelago init file for Lingo 2 | ||
| 3 | """ | ||
| 4 | from worlds.AutoWorld import WebWorld, World | ||
| 5 | from .options import Lingo2Options | ||
| 6 | from .player_logic import Lingo2PlayerLogic | ||
| 7 | from .regions import create_regions | ||
| 8 | from .static_logic import Lingo2StaticLogic | ||
| 9 | |||
| 10 | |||
| 11 | class Lingo2WebWorld(WebWorld): | ||
| 12 | rich_text_options_doc = True | ||
| 13 | theme = "grass" | ||
| 14 | |||
| 15 | |||
| 16 | class Lingo2World(World): | ||
| 17 | """ | ||
| 18 | Lingo 2 is a first person indie puzzle game where you solve word puzzles in a labyrinthe world. Compared to its | ||
| 19 | predecessor, Lingo 2 has new mechanics, more areas, and a unique progression system where you have to unlock letters | ||
| 20 | before using them in puzzle solutions. | ||
| 21 | """ | ||
| 22 | game = "Lingo 2" | ||
| 23 | web = Lingo2WebWorld() | ||
| 24 | |||
| 25 | options_dataclass = Lingo2Options | ||
| 26 | options: Lingo2Options | ||
| 27 | |||
| 28 | item_name_to_id = {} | ||
| 29 | location_name_to_id = {} | ||
| 30 | |||
| 31 | static_logic = Lingo2StaticLogic() | ||
| 32 | player_logic: Lingo2PlayerLogic | ||
| 33 | |||
| 34 | def generate_early(self): | ||
| 35 | self.player_logic = Lingo2PlayerLogic(self) | ||
| 36 | |||
| 37 | def create_regions(self): | ||
| 38 | 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 @@ | |||
| 1 | from BaseClasses import Location | ||
| 2 | |||
| 3 | |||
| 4 | class Lingo2Location(Location): | ||
| 5 | 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 @@ | |||
| 1 | from dataclasses import dataclass | ||
| 2 | |||
| 3 | from Options import PerGameCommonOptions | ||
| 4 | |||
| 5 | |||
| 6 | @dataclass | ||
| 7 | class Lingo2Options(PerGameCommonOptions): | ||
| 8 | 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 @@ | |||
| 1 | from typing import TYPE_CHECKING, NamedTuple | ||
| 2 | |||
| 3 | if TYPE_CHECKING: | ||
| 4 | from . import Lingo2World | ||
| 5 | |||
| 6 | |||
| 7 | class PlayerLocation(NamedTuple): | ||
| 8 | name: str | ||
| 9 | code: int | None | ||
| 10 | |||
| 11 | |||
| 12 | class Lingo2PlayerLogic: | ||
| 13 | locations_by_room: dict[int, list[PlayerLocation]] | ||
| 14 | |||
| 15 | def __init__(self, world: "Lingo2World"): | ||
| 16 | self.locations_by_room = {} | ||
| 17 | |||
| 18 | code = 1 | ||
| 19 | for door in world.static_logic.objects.doors: | ||
| 20 | if not door.HasField("room_id"): | ||
| 21 | continue | ||
| 22 | |||
| 23 | self.locations_by_room.setdefault(door.room_id, []).append(PlayerLocation(door.name, code)) | ||
| 24 | 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 @@ | |||
| 1 | from typing import TYPE_CHECKING | ||
| 2 | |||
| 3 | from BaseClasses import Region | ||
| 4 | from .locations import Lingo2Location | ||
| 5 | |||
| 6 | if TYPE_CHECKING: | ||
| 7 | from . import Lingo2World | ||
| 8 | |||
| 9 | |||
| 10 | def create_region(room, world: "Lingo2World") -> Region: | ||
| 11 | new_region = Region(room.name, world.player, world.multiworld) | ||
| 12 | |||
| 13 | for location in world.player_logic.locations_by_room.get(room.id, {}): | ||
| 14 | new_location = Lingo2Location(world.player, location.name, location.code, new_region) | ||
| 15 | new_region.locations.append(new_location) | ||
| 16 | |||
| 17 | return new_region | ||
| 18 | |||
| 19 | |||
| 20 | def create_regions(world: "Lingo2World"): | ||
| 21 | regions = { | ||
| 22 | "Menu": Region("Menu", world.player, world.multiworld) | ||
| 23 | } | ||
| 24 | |||
| 25 | for room in world.static_logic.objects.rooms: | ||
| 26 | regions[room.name] = create_region(room, world) | ||
| 27 | |||
| 28 | 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 @@ | |||
| 1 | from .generated import data_pb2 as data_pb2 | ||
| 2 | import pkgutil | ||
| 3 | |||
| 4 | class Lingo2StaticLogic: | ||
| 5 | def __init__(self): | ||
| 6 | file = pkgutil.get_data(__name__, "generated/data.binpb") | ||
| 7 | |||
| 8 | self.objects = data_pb2.AllObjects() | ||
| 9 | self.objects.ParseFromString(bytearray(file)) | ||
