diff --git a/BaseClasses.py b/BaseClasses.py index 3c13c868..af864165 100644 --- a/BaseClasses.py +++ b/BaseClasses.py @@ -1028,11 +1028,12 @@ class Location: access_rule = staticmethod(lambda state: True) item_rule = staticmethod(lambda item: True) item: Optional[Item] = None + parent_region: Optional[Region] def __init__(self, player: int, name: str = '', address: int = None, parent=None): self.name: str = name self.address: Optional[int] = address - self.parent_region: Region = parent + self.parent_region = parent self.player: int = player def can_fill(self, state: CollectionState, item: Item, check_access=True) -> bool: diff --git a/WebHostLib/__init__.py b/WebHostLib/__init__.py index be7c442a..6d31ac15 100644 --- a/WebHostLib/__init__.py +++ b/WebHostLib/__init__.py @@ -112,7 +112,7 @@ def games(): worlds = {} for game, world in AutoWorldRegister.world_types.items(): if not world.hidden: - worlds[game] = world.__doc__ if world.__doc__ else "No description provided." + worlds[game] = world return render_template("supportedGames.html", worlds=worlds) diff --git a/WebHostLib/options.py b/WebHostLib/options.py index e1483442..d54b3217 100644 --- a/WebHostLib/options.py +++ b/WebHostLib/options.py @@ -132,7 +132,7 @@ def create(): with open(os.path.join(target_folder, 'player-settings', game_name + ".json"), "w") as f: json.dump(player_settings, f, indent=2, separators=(',', ': ')) - if not world.hidden: + if not world.hidden and world.web.settings_page is True: weighted_settings["baseOptions"]["game"][game_name] = 0 weighted_settings["games"][game_name] = {} weighted_settings["games"][game_name]["gameSettings"] = game_options diff --git a/WebHostLib/templates/supportedGames.html b/WebHostLib/templates/supportedGames.html index 7ed14ce0..90e16781 100644 --- a/WebHostLib/templates/supportedGames.html +++ b/WebHostLib/templates/supportedGames.html @@ -9,12 +9,17 @@ {% include 'header/grassHeader.html' %}

Currently Supported Games

- {% for game, description in worlds.items() | sort %} -

{{ game }}

+ {% for game_name, world in worlds.items() | sort %} +

{{ game_name }}

- Settings Page + {% if world.web.settings_page is string %} + Settings Page
- {{ description }} + {% elif world.web.settings_page %} + Settings Page +
+ {% endif %} + {{ world.__doc__ | default("No description provided.", true) }}

{% endfor %}
diff --git a/worlds/AutoWorld.py b/worlds/AutoWorld.py index c906c97c..5445f2cf 100644 --- a/worlds/AutoWorld.py +++ b/worlds/AutoWorld.py @@ -1,7 +1,7 @@ from __future__ import annotations import logging -from typing import Dict, Set, Tuple, List, Optional, TextIO, Any, Callable +from typing import Dict, Set, Tuple, List, Optional, TextIO, Any, Callable, Union from BaseClasses import MultiWorld, Item, CollectionState, Location from Options import Option @@ -73,6 +73,12 @@ def call_stage(world: MultiWorld, method_name: str, *args): stage_callable(world, *args) +class WebWorld: + """Webhost integration""" + # display a settings page. Can be a link to an out-of-ap settings tool too. + settings_page: Union[bool, str] = True + + class World(metaclass=AutoWorldRegister): """A World object encompasses a game's Items, Locations, Rules and additional data or functionality required. A Game should have its own subclass of World in which it defines the required data structures.""" @@ -130,6 +136,8 @@ class World(metaclass=AutoWorldRegister): # For example the "full" tech tree information option in Factorio sending_visible: bool = False + web: WebWorld = WebWorld() + def __init__(self, world: MultiWorld, player: int): self.world = world self.player = player @@ -250,3 +258,4 @@ class World(metaclass=AutoWorldRegister): # please use a prefix as all of them get clobbered together class LogicMixin(metaclass=AutoLogicRegister): pass + diff --git a/worlds/ff1/__init__.py b/worlds/ff1/__init__.py index 487259a9..7cb09fc7 100644 --- a/worlds/ff1/__init__.py +++ b/worlds/ff1/__init__.py @@ -3,7 +3,11 @@ from BaseClasses import Item, Location, MultiWorld from .Items import ItemData, FF1Items, FF1_STARTER_ITEMS, FF1_PROGRESSION_LIST, FF1_BRIDGE from .Locations import EventId, FF1Locations, generate_rule, CHAOS_TERMINATED_EVENT from .Options import ff1_options -from ..AutoWorld import World +from ..AutoWorld import World, WebWorld + + +class FF1Web(WebWorld): + settings_page = "https://finalfantasyrandomizer.com/" class FF1World(World): @@ -28,6 +32,8 @@ class FF1World(World): item_name_to_id = ff1_items.get_item_name_to_code_dict() location_name_to_id = ff1_locations.get_location_name_to_address_dict() + web = FF1Web() + def __init__(self, world: MultiWorld, player: int): super().__init__(world, player) self.locked_items = []