mirror of
https://github.com/ArchipelagoMW/Archipelago.git
synced 2026-03-18 13:33:48 -07:00
Compare commits
9 Commits
autoworld_
...
allow_coll
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
5ce892cbb8 | ||
|
|
bc7389fbaa | ||
|
|
9cb5a7fc3a | ||
|
|
e433246f0c | ||
|
|
3a190a8fb2 | ||
|
|
4b7033fce7 | ||
|
|
37499b40a1 | ||
|
|
4311e8dbe2 | ||
|
|
d961022bff |
4
.github/workflows/build.yml
vendored
4
.github/workflows/build.yml
vendored
@@ -5,12 +5,12 @@ name: Build
|
||||
on:
|
||||
push:
|
||||
paths:
|
||||
- '.github/workflows/build.yaml'
|
||||
- '.github/workflows/build.yml'
|
||||
- 'setup.py'
|
||||
- 'requirements.txt'
|
||||
pull_request:
|
||||
paths:
|
||||
- '.github/workflows/build.yaml'
|
||||
- '.github/workflows/build.yml'
|
||||
- 'setup.py'
|
||||
- 'requirements.txt'
|
||||
workflow_dispatch:
|
||||
|
||||
14
.github/workflows/codeql-analysis.yml
vendored
14
.github/workflows/codeql-analysis.yml
vendored
@@ -14,9 +14,17 @@ name: "CodeQL"
|
||||
on:
|
||||
push:
|
||||
branches: [ main ]
|
||||
paths:
|
||||
- '**.py'
|
||||
- '**.js'
|
||||
- '.github/workflows/codeql-analysis.yml'
|
||||
pull_request:
|
||||
# The branches below must be a subset of the branches above
|
||||
branches: [ main ]
|
||||
paths:
|
||||
- '**.py'
|
||||
- '**.js'
|
||||
- '.github/workflows/codeql-analysis.yml'
|
||||
schedule:
|
||||
- cron: '44 8 * * 1'
|
||||
|
||||
@@ -39,7 +47,7 @@ jobs:
|
||||
|
||||
# Initializes the CodeQL tools for scanning.
|
||||
- name: Initialize CodeQL
|
||||
uses: github/codeql-action/init@v1
|
||||
uses: github/codeql-action/init@v2
|
||||
with:
|
||||
languages: ${{ matrix.language }}
|
||||
# If you wish to specify custom queries, you can do so here or in a config file.
|
||||
@@ -50,7 +58,7 @@ jobs:
|
||||
# Autobuild attempts to build any compiled languages (C/C++, C#, or Java).
|
||||
# If this step fails, then you should remove it and run the build manually (see below)
|
||||
- name: Autobuild
|
||||
uses: github/codeql-action/autobuild@v1
|
||||
uses: github/codeql-action/autobuild@v2
|
||||
|
||||
# ℹ️ Command-line programs to run using the OS shell.
|
||||
# 📚 https://git.io/JvXDl
|
||||
@@ -64,4 +72,4 @@ jobs:
|
||||
# make release
|
||||
|
||||
- name: Perform CodeQL Analysis
|
||||
uses: github/codeql-action/analyze@v1
|
||||
uses: github/codeql-action/analyze@v2
|
||||
|
||||
8
.github/workflows/lint.yml
vendored
8
.github/workflows/lint.yml
vendored
@@ -3,7 +3,13 @@
|
||||
|
||||
name: lint
|
||||
|
||||
on: [push, pull_request]
|
||||
on:
|
||||
push:
|
||||
paths:
|
||||
- '**.py'
|
||||
pull_request:
|
||||
paths:
|
||||
- '**.py'
|
||||
|
||||
jobs:
|
||||
build:
|
||||
|
||||
26
.github/workflows/unittests.yml
vendored
26
.github/workflows/unittests.yml
vendored
@@ -5,17 +5,23 @@ name: unittests
|
||||
|
||||
on:
|
||||
push:
|
||||
paths-ignore:
|
||||
- 'docs/**'
|
||||
- 'setup.py'
|
||||
- '*.iss'
|
||||
- '.gitignore'
|
||||
paths:
|
||||
- '**'
|
||||
- '!docs/**'
|
||||
- '!setup.py'
|
||||
- '!*.iss'
|
||||
- '!.gitignore'
|
||||
- '!.github/workflows/**'
|
||||
- '.github/workflows/unittests.yml'
|
||||
pull_request:
|
||||
paths-ignore:
|
||||
- 'docs/**'
|
||||
- 'setup.py'
|
||||
- '*.iss'
|
||||
- '.gitignore'
|
||||
paths:
|
||||
- '**'
|
||||
- '!docs/**'
|
||||
- '!setup.py'
|
||||
- '!*.iss'
|
||||
- '!.gitignore'
|
||||
- '!.github/workflows/**'
|
||||
- '.github/workflows/unittests.yml'
|
||||
|
||||
jobs:
|
||||
build:
|
||||
|
||||
@@ -67,6 +67,7 @@ class MultiWorld():
|
||||
local_early_items: Dict[int, Dict[str, int]]
|
||||
local_items: Dict[int, Options.LocalItems]
|
||||
non_local_items: Dict[int, Options.NonLocalItems]
|
||||
allow_collect: Dict[int, Options.AllowCollect]
|
||||
progression_balancing: Dict[int, Options.ProgressionBalancing]
|
||||
completion_condition: Dict[int, Callable[[CollectionState], bool]]
|
||||
indirect_connections: Dict[Region, Set[Entrance]]
|
||||
|
||||
2
Main.py
2
Main.py
@@ -316,7 +316,7 @@ def main(args, seed=None, baked_server_options: Optional[Dict[str, object]] = No
|
||||
client_versions[slot] = player_world.required_client_version
|
||||
games[slot] = world.game[slot]
|
||||
slot_info[slot] = NetUtils.NetworkSlot(names[0][slot - 1], world.game[slot],
|
||||
world.player_types[slot])
|
||||
world.player_types[slot], bool(world.allow_collect[slot].value))
|
||||
for slot, group in world.groups.items():
|
||||
games[slot] = world.game[slot]
|
||||
slot_info[slot] = NetUtils.NetworkSlot(group["name"], world.game[slot], world.player_types[slot],
|
||||
|
||||
@@ -222,6 +222,7 @@ class Context:
|
||||
self.save_dirty = False
|
||||
self.tags = ['AP']
|
||||
self.games: typing.Dict[int, str] = {}
|
||||
self.allow_collect: typing.Dict[int, bool] = {}
|
||||
self.minimum_client_versions: typing.Dict[int, Utils.Version] = {}
|
||||
self.seed_name = ""
|
||||
self.groups = {}
|
||||
@@ -391,6 +392,9 @@ class Context:
|
||||
self.games = {slot: slot_info.game for slot, slot_info in self.slot_info.items()}
|
||||
self.groups = {slot: slot_info.group_members for slot, slot_info in self.slot_info.items()
|
||||
if slot_info.type == SlotType.group}
|
||||
# TODO: around 0.4.2 or so, remove the if/else backwards compatibility check.
|
||||
self.allow_collect = {slot: slot_info.allow_collect if type(slot_info.allow_collect) is bool else True
|
||||
for slot, slot_info in self.slot_info.items()}
|
||||
|
||||
self.clients = {0: {}}
|
||||
slot_info: NetworkSlot
|
||||
@@ -885,6 +889,8 @@ def collect_player(ctx: Context, team: int, slot: int, is_group: bool = False):
|
||||
"""register any locations that are in the multidata, pointing towards this player"""
|
||||
all_locations = collections.defaultdict(set)
|
||||
for source_slot, location_data in ctx.locations.items():
|
||||
if not ctx.allow_collect[source_slot]:
|
||||
continue
|
||||
for location_id, values in location_data.items():
|
||||
if values[1] == slot:
|
||||
all_locations[source_slot].add(location_id)
|
||||
|
||||
@@ -71,6 +71,7 @@ class NetworkSlot(typing.NamedTuple):
|
||||
name: str
|
||||
game: str
|
||||
type: SlotType
|
||||
allow_collect: bool = True
|
||||
group_members: typing.Union[typing.List[int], typing.Tuple] = () # only populated if type == group
|
||||
|
||||
|
||||
|
||||
10
Options.py
10
Options.py
@@ -875,9 +875,17 @@ class ProgressionBalancing(SpecialRange):
|
||||
}
|
||||
|
||||
|
||||
class AllowCollect(DefaultOnToggle):
|
||||
"""Controls whether items are collected from the slot when a player does a !collect or not.
|
||||
The impact for the collecting player is that the collector might not get all of their items, until
|
||||
the player(s) that has disallowed collection actually completes or releases their location checks."""
|
||||
display_name = "Allow Collect"
|
||||
|
||||
|
||||
common_options = {
|
||||
"progression_balancing": ProgressionBalancing,
|
||||
"accessibility": Accessibility
|
||||
"accessibility": Accessibility,
|
||||
"allow_collect": AllowCollect
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -13,26 +13,10 @@ if TYPE_CHECKING:
|
||||
from BaseClasses import MultiWorld, Item, Location, Tutorial
|
||||
|
||||
|
||||
class WorldVersionIncompatible(Exception):
|
||||
pass
|
||||
|
||||
|
||||
class AutoWorldRegister(type):
|
||||
world_types: Dict[str, Type[World]] = {}
|
||||
|
||||
def __new__(mcs, name: str, bases: Tuple[type, ...], dct: Dict[str, Any]) -> AutoWorldRegister:
|
||||
if dct.get("required_archipelago_version", None):
|
||||
from Utils import version_tuple
|
||||
if dct["required_archipelago_version"] > version_tuple:
|
||||
raise WorldVersionIncompatible(
|
||||
f"World {name} for game {dct.get('game', None)} "
|
||||
f"requires Archipelago {dct['required_archipelago_version']}, but this is {version_tuple}")
|
||||
if dct.get("highest_archipelago_version", None):
|
||||
from Utils import version_tuple
|
||||
if version_tuple > dct["highest_archipelago_version"]:
|
||||
raise WorldVersionIncompatible(
|
||||
f"World {name} for {dct.get('game', None)} "
|
||||
f"supports Archipelago up to {dct['highest_archipelago_version']}, but this is {version_tuple}")
|
||||
if "web" in dct:
|
||||
assert isinstance(dct["web"], WebWorld), "WebWorld has to be instantiated."
|
||||
# filter out any events
|
||||
@@ -185,14 +169,6 @@ class World(metaclass=AutoWorldRegister):
|
||||
required_server_version: Tuple[int, int, int] = (0, 2, 4)
|
||||
"""update this if the resulting multidata breaks forward-compatibility of the server"""
|
||||
|
||||
required_archipelago_version: ClassVar[Optional[Tuple[int, int, int]]] = None
|
||||
"""Optional. Enter the minimum required Archipelago version that can use this world.
|
||||
Typically for version checking when distributing as apworld."""
|
||||
|
||||
highest_archipelago_version: ClassVar[Optional[Tuple[int, int, int]]] = None
|
||||
"""Optional. Enter the highest Archipelago version that can use this world.
|
||||
Typically for version checking when distributing as apworld."""
|
||||
|
||||
hint_blacklist: ClassVar[FrozenSet[str]] = frozenset()
|
||||
"""any names that should not be hintable"""
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
# The Messenger
|
||||
|
||||
## Quick Links
|
||||
- [Setup](../../../../games/The%20Messenger/setup/en)
|
||||
- [Setup](../../../../tutorial/The%20Messenger/setup/en)
|
||||
- [Settings Page](../../../../games/The%20Messenger/player-settings)
|
||||
- [Courier Github](https://github.com/Brokemia/Courier)
|
||||
- [The Messenger Randomizer Github](https://github.com/minous27/TheMessengerRandomizerMod)
|
||||
@@ -48,25 +48,23 @@ for it. The groups you can use for The Messenger are:
|
||||
## Other changes
|
||||
|
||||
* The player can return to the Tower of Time HQ at any point by selecting the button from the options menu
|
||||
* This can cause issues if used at specific times. Current known:
|
||||
* During Boss fights
|
||||
* After Courage Note collection (Corrupted Future chase)
|
||||
* This is currently an expected action in logic. If you do need to teleport during this chase sequence, it
|
||||
is recommended to quit to title and reload the save
|
||||
* This can cause issues if used at specific times. Current known:
|
||||
* During Boss fights
|
||||
* After Courage Note collection (Corrupted Future chase)
|
||||
* This is currently an expected action in logic. If you do need to teleport during this chase sequence, it
|
||||
is recommended to quit to title and reload the save
|
||||
* After reaching ninja village a teleport option is added to the menu to reach it quickly
|
||||
* Toggle Windmill Shuriken button is added to option menu once the item is received
|
||||
|
||||
## Currently known issues
|
||||
* Necro cutscene will sometimes not play correctly, but will still reward the item
|
||||
* Ruxxtin Coffin cutscene will sometimes not play correctly, but will still reward the item
|
||||
* If you receive the Fairy Bottle while in Quillshroom Marsh, The Decurse Queen cutscene will not play
|
||||
* If you receive the Fairy Bottle while in Quillshroom Marsh, The Decurse Queen cutscene will not play. You can exit
|
||||
to Searing Crags and re-enter to get it to play correctly.
|
||||
* If you defeat Barma'thazël, the cutscene afterward will not play correctly since that is what normally transitions
|
||||
you to 2nd quest. The game will not kill you if you fall here, so you can teleport to HQ at any point after defeating him.
|
||||
you to 2nd quest. The game will not kill you if you fall here, so you can teleport to HQ at any point after defeating him.
|
||||
* Sometimes upon teleporting back to HQ, Ninja will run left and enter a different portal than the one entered by the
|
||||
player.
|
||||
* If playing the game in non-english, sometimes the text entry menus will say "What is your name?" in local language
|
||||
instead of the correct text. This can be fixed by going into the game options and selecting your language in the menu.
|
||||
It does not need to be changed to something else and back.
|
||||
player.
|
||||
* Text entry menus don't accept controller input
|
||||
|
||||
## What do I do if I have a problem?
|
||||
|
||||
@@ -1,31 +1,29 @@
|
||||
# The Messenger Randomizer Setup Guide
|
||||
|
||||
## Quick Links
|
||||
- [Main Page](../../../../games/The%20Messenger/info/en)
|
||||
- [Game Info](../../../../games/The%20Messenger/info/en)
|
||||
- [Settings Page](../../../../games/The%20Messenger/player-settings)
|
||||
- [Courier Github](https://github.com/Brokemia/Courier)
|
||||
- [The Messenger Randomizer Github](https://github.com/minous27/TheMessengerRandomizerMod)
|
||||
- [Jacksonbird8237's Item Tracker](https://github.com/Jacksonbird8237/TheMessengerItemTracker)
|
||||
- [PopTracker Pack](https://github.com/alwaysintreble/TheMessengerTrackPack)
|
||||
|
||||
## Required Software
|
||||
|
||||
- [The Messenger](https://store.steampowered.com/app/764790/The_Messenger/)
|
||||
- Only Steam version is currently supported.
|
||||
- [Courier Mod Loader](https://github.com/Brokemia/Courier/releases)
|
||||
- [The Messenger Randomizer Mod](https://github.com/minous27/TheMessengerRandomizerMod/releases)
|
||||
|
||||
## Installation
|
||||
|
||||
1. Download and install Courier Mod Loader using the instructions on the release page
|
||||
* [Latest release is currently 0.7.1](https://github.com/Brokemia/Courier/releases)
|
||||
2. Download and install the randomizer mod
|
||||
* Download the latest `TheMessengerRandomizer.zip`
|
||||
* Extract the zip file to `TheMessenger/Mods/` of your game's install location
|
||||
* Optionally, Backup your save game
|
||||
1. Download the latest TheMessengerRandomizer.zip from the [The Messenger Randomizer Mod releases page](https://github.com/minous27/TheMessengerRandomizerMod/releases)
|
||||
2. Extract the zip file to `TheMessenger/Mods/` of your game's install location
|
||||
3. Optionally, Backup your save game
|
||||
* On Windows
|
||||
1. Press `Windows Key + R` to open run
|
||||
2. Type `%appdata%` to access AppData
|
||||
3. Navigate to `AppData/locallow/SabotageStudios/The Messenger`
|
||||
4. Rename `SaveGame.txt` to any name of your choice
|
||||
* On Linux
|
||||
1. Navigate to `steamapps/compatdata/764790/pfx/drive_c/users/steamuser/AppData/LocalLow/Sabotage Studio/The Messenger`
|
||||
2. Rename `SaveGame.txt` to any name of your choice
|
||||
|
||||
## Joining a MultiWorld Game
|
||||
|
||||
@@ -33,12 +31,12 @@
|
||||
2. Navigate to `Options > Third Party Mod Options`
|
||||
3. Select `Reset Randomizer File Slots`
|
||||
* This will set up all of your save slots with new randomizer save files. You can have up to 3 randomizer files at a
|
||||
time, but must do this step again to start new runs afterwards.
|
||||
time, but must do this step again to start new runs afterwards.
|
||||
4. Enter connection info using the relevant option buttons
|
||||
* **The game is limited to alphanumerical characters and `-` so when entering the host name replace `.` with ` ` and
|
||||
ensure that your player name when generating a settings file follows these constrictions**
|
||||
ensure that your player name when generating a settings file follows these constrictions**
|
||||
* This defaults to `archipelago.gg` and does not need to be manually changed if connecting to a game hosted on the
|
||||
website.
|
||||
website.
|
||||
5. Select the `Connect to Archipelago` button
|
||||
6. Navigate to save file selection
|
||||
7. Select a new valid randomizer save
|
||||
|
||||
@@ -287,8 +287,12 @@ class PokemonRedBlueWorld(World):
|
||||
else:
|
||||
break
|
||||
|
||||
if self.multiworld.old_man[self.player].value == 1:
|
||||
if self.multiworld.old_man[self.player] == "early_parcel":
|
||||
self.multiworld.local_early_items[self.player]["Oak's Parcel"] = 1
|
||||
if self.multiworld.dexsanity[self.player]:
|
||||
for location in [self.multiworld.get_location(f"Pokedex - {mon}", self.player)
|
||||
for mon in poke_data.pokemon_data.keys()]:
|
||||
add_item_rule(location, lambda item: item.name != "Oak's Parcel" or item.player != self.player)
|
||||
|
||||
if not self.multiworld.badgesanity[self.player].value:
|
||||
self.multiworld.non_local_items[self.player].value -= self.item_name_groups["Badges"]
|
||||
|
||||
@@ -753,8 +753,9 @@ location_data = [
|
||||
LocationData("Celadon Game Corner", "Hidden Item at End of Horizontal Machine Row (Coin Case)", "20 Coins", rom_addresses["Hidden_Item_Game_Corner_10"], Hidden(63), inclusion=hidden_items),
|
||||
LocationData("Celadon Game Corner", "Hidden Item in Front of Horizontal Machine Row (Coin Case)", "100 Coins", rom_addresses["Hidden_Item_Game_Corner_11"], Hidden(64), inclusion=hidden_items),
|
||||
|
||||
*[LocationData("Pokedex", mon, None, rom_addresses["Dexsanity_Items"] + i, DexSanityFlag(i),
|
||||
type="Item", inclusion=dexsanity) for (mon, i) in zip(pokemon_data.keys(), range(0, 152))],
|
||||
*[LocationData("Pokedex", mon, ball, rom_addresses["Dexsanity_Items"] + i, DexSanityFlag(i), type="Item",
|
||||
inclusion=dexsanity) for (mon, i, ball) in zip(pokemon_data.keys(), range(0, 152),
|
||||
["Poke Ball", "Great Ball", "Ultra Ball"]* 51)],
|
||||
|
||||
LocationData("Indigo Plateau", "Become Champion", "Become Champion", event=True),
|
||||
LocationData("Pokemon Tower 7F", "Fuji Saved", "Fuji Saved", event=True),
|
||||
|
||||
Binary file not shown.
Reference in New Issue
Block a user