Skip to content

Commit

Permalink
Merge branch 'main' into zgi
Browse files Browse the repository at this point in the history
  • Loading branch information
nbrochu authored Jan 14, 2024
2 parents b359e66 + 01fb44c commit d1727d0
Show file tree
Hide file tree
Showing 55 changed files with 4,535 additions and 267 deletions.
18 changes: 18 additions & 0 deletions .run/Archipelago Unittests.run.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
<component name="ProjectRunConfigurationManager">
<configuration default="false" name="Archipelago Unittests" type="tests" factoryName="Unittests">
<module name="Archipelago" />
<option name="INTERPRETER_OPTIONS" value="" />
<option name="PARENT_ENVS" value="true" />
<option name="SDK_HOME" value="" />
<option name="WORKING_DIRECTORY" value="$PROJECT_DIR$" />
<option name="IS_MODULE_SDK" value="true" />
<option name="ADD_CONTENT_ROOTS" value="true" />
<option name="ADD_SOURCE_ROOTS" value="true" />
<EXTENSION ID="PythonCoverageRunConfigurationExtension" runner="coverage.py" />
<option name="_new_pattern" value="&quot;&quot;" />
<option name="_new_additionalArguments" value="&quot;&quot;" />
<option name="_new_target" value="&quot;$PROJECT_DIR$/test&quot;" />
<option name="_new_targetType" value="&quot;PATH&quot;" />
<method v="2" />
</configuration>
</component>
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@ Currently, the following games are supported:
* Heretic
* Landstalker: The Treasures of King Nole
* Final Fantasy Mystic Quest
* TUNIC
* Zork Grand Inquisitor

For setup and instructions check out our [tutorials page](https://archipelago.gg/tutorial/).
Expand Down
4 changes: 2 additions & 2 deletions WebHostLib/api/generate.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,8 @@ def generate_api():
race = False
meta_options_source = {}
if 'file' in request.files:
file = request.files['file']
options = get_yaml_data(file)
files = request.files.getlist('file')
options = get_yaml_data(files)
if isinstance(options, Markup):
return {"text": options.striptags()}, 400
if isinstance(options, str):
Expand Down
3 changes: 3 additions & 0 deletions docs/CODEOWNERS
Original file line number Diff line number Diff line change
Expand Up @@ -164,6 +164,9 @@
# The Legend of Zelda (1)
/worlds/tloz/ @Rosalie-A @t3hf1gm3nt

# TUNIC
/worlds/tunic/ @silent-destroyer

# Undertale
/worlds/undertale/ @jonloveslegos

Expand Down
10 changes: 5 additions & 5 deletions docs/network protocol.md
Original file line number Diff line number Diff line change
Expand Up @@ -675,8 +675,8 @@ Tags are represented as a list of strings, the common Client tags follow:
### DeathLink
A special kind of Bounce packet that can be supported by any AP game. It targets the tag "DeathLink" and carries the following data:

| Name | Type | Notes |
| ---- | ---- | ---- |
| time | float | Unix Time Stamp of time of death. |
| cause | str | Optional. Text to explain the cause of death, ex. "Berserker was run over by a train." |
| source | str | Name of the player who first died. Can be a slot name, but can also be a name from within a multiplayer game. |
| Name | Type | Notes |
|--------|-------|--------------------------------------------------------------------------------------------------------------------------------------------------------|
| time | float | Unix Time Stamp of time of death. |
| cause | str | Optional. Text to explain the cause of death. When provided, or checked, this should contain the player name, ex. "Berserker was run over by a train." |
| source | str | Name of the player who first died. Can be a slot name, but can also be a name from within a multiplayer game. |
2 changes: 1 addition & 1 deletion requirements.txt
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ PyYAML>=6.0.1
jellyfish>=1.0.3
jinja2>=3.1.2
schema>=0.7.5
kivy>=2.2.1
kivy>=2.3.0
bsdiff4>=1.2.4
platformdirs>=4.0.0
certifi>=2023.11.17
Expand Down
1 change: 0 additions & 1 deletion setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,6 @@
"Ocarina of Time",
"Overcooked! 2",
"Raft",
"Secret of Evermore",
"Slay the Spire",
"Sudoku",
"Super Mario 64",
Expand Down
2 changes: 1 addition & 1 deletion test/bases.py
Original file line number Diff line number Diff line change
Expand Up @@ -285,7 +285,7 @@ def test_all_state_can_reach_everything(self):
if not (self.run_default_tests and self.constructed):
return
with self.subTest("Game", game=self.game):
excluded = self.multiworld.exclude_locations[1].value
excluded = self.multiworld.worlds[1].options.exclude_locations.value
state = self.multiworld.get_all_state(False)
for location in self.multiworld.get_locations():
if location.name not in excluded:
Expand Down
2 changes: 1 addition & 1 deletion test/general/test_reachability.py
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ def test_default_all_state_can_reach_everything(self):
unreachable_regions = self.default_settings_unreachable_regions.get(game_name, set())
with self.subTest("Game", game=game_name):
world = setup_solo_multiworld(world_type)
excluded = world.exclude_locations[1].value
excluded = world.worlds[1].options.exclude_locations.value
state = world.get_all_state(False)
for location in world.get_locations():
if location.name not in excluded:
Expand Down
20 changes: 19 additions & 1 deletion test/webhost/test_api_generate.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
import io
import unittest
import json
import yaml


class TestDocs(unittest.TestCase):
Expand All @@ -23,7 +25,7 @@ def test_correct_error_empty_request(self):
response = self.client.post("/api/generate")
self.assertIn("No options found. Expected file attachment or json weights.", response.text)

def test_generation_queued(self):
def test_generation_queued_weights(self):
options = {
"Tester1":
{
Expand All @@ -40,3 +42,19 @@ def test_generation_queued(self):
json_data = response.get_json()
self.assertTrue(json_data["text"].startswith("Generation of seed "))
self.assertTrue(json_data["text"].endswith(" started successfully."))

def test_generation_queued_file(self):
options = {
"game": "Archipelago",
"name": "Tester",
"Archipelago": {}
}
response = self.client.post(
"/api/generate",
data={
'file': (io.BytesIO(yaml.dump(options, encoding="utf-8")), "test.yaml")
},
)
json_data = response.get_json()
self.assertTrue(json_data["text"].startswith("Generation of seed "))
self.assertTrue(json_data["text"].endswith(" started successfully."))
13 changes: 11 additions & 2 deletions worlds/dlcquest/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,14 +13,23 @@


class DLCqwebworld(WebWorld):
tutorials = [Tutorial(
setup_en = Tutorial(
"Multiworld Setup Tutorial",
"A guide to setting up the Archipelago DLCQuest game on your computer.",
"English",
"setup_en.md",
"setup/en",
["axe_y"]
)]
)
setup_fr = Tutorial(
"Guide de configuration MultiWorld",
"Un guide pour configurer DLCQuest sur votre PC.",
"Français",
"setup_fr.md",
"setup/fr",
["Deoxis"]
)
tutorials = [setup_en, setup_fr]


class DLCqworld(World):
Expand Down
49 changes: 49 additions & 0 deletions worlds/dlcquest/docs/fr_DLCQuest.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
# DLC Quest

## Où se trouve la page des paramètres ?

La [page des paramètres du joueur pour ce jeu](../player-settings) contient tous les paramètres dont vous avez besoin pour configurer et exporter le fichier.


## Quel est l'effet de la randomisation sur ce jeu ?

Les DLC seront obtenus en tant que check pour le multiworld. Il existe également d'autres checks optionnels dans DLC Quest.

## Quel est le but de DLC Quest ?

DLC Quest a deux campagnes, et le joueur peut choisir celle qu'il veut jouer pour sa partie.
Il peut également choisir de faire les deux campagnes.


## Quels sont les emplacements dans DLC quest ?

Les emplacements dans DLC Quest comprennent toujours
- les achats de DLC auprès du commerçant
- Les objectifs liés aux récompenses
- Tuer des moutons dans DLC Quest
- Objectifs spécifiques de l'attribution dans Live Freemium or Die

Il existe également un certain nombres de critères de localisation qui sont optionnels et que les joueurs peuvent choisir d'inclure ou non dans leur sélection :
- Objets que votre personnage peut obtenir de différentes manières
- Swords
- Gun
- Box of Various Supplies
- Humble Indie Bindle
- Pickaxe
- Coinsanity : Pièces de monnaie, soit individuellement, soit sous forme de lots personnalisés

## Quels objets peuvent se trouver dans le monde d'un autre joueur ?

Tous les DLC du jeu sont mélangés dans le stock d'objets. Les objets liés aux contrôles optionnels décrits ci-dessus sont également dans le stock

Il y a aussi de nouveaux objets pièges, utilisés comme substituts, basés sur les désagréments du jeu vanille.
- Zombie Sheep
- Loading Screens
- Temporary Spikes

## Que se passe-t-il lorsque le joueur reçoit un objet ?

Chaque fois qu'un objet est reçu en ligne, une notification apparaît à l'écran pour en informer le joueur.
Certains objets sont accompagnés d'une animation ou d'une scène qui se déroule immédiatement après leur réception.

Les objets reçus hors ligne ne sont pas accompagnés d'une animation ou d'une scène, et sont simplement activés lors de la connexion.
55 changes: 55 additions & 0 deletions worlds/dlcquest/docs/setup_fr.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
# # Guide de configuration MultiWorld de DLCQuest

## Logiciels requis

- DLC Quest sur PC (Recommandé: [Version Steam](https://store.steampowered.com/app/230050/DLC_Quest/))
- [DLCQuestipelago](https://github.com/agilbert1412/DLCQuestipelago/releases)
- BepinEx (utilisé comme un modloader pour DLCQuest. La version du mod ci-dessus inclut BepInEx si vous choisissez la version d'installation complète)

## Logiciels optionnels
- [Archipelago] (https://github.com/ArchipelagoMW/Archipelago/releases)
- (Uniquement pour le TextClient)

## Créer un fichier de configuration (.yaml)

### Qu'est-ce qu'un fichier YAML et pourquoi en ai-je besoin ?

Voir le guide d'Archipelago sur la mise en place d'un YAML de base : [Basic Multiworld Setup Guide](/tutorial/Archipelago/setup/en)

### Où puis-je obtenir un fichier YAML ?

Vous pouvez personnaliser vos paramètres en visitant la [page des paramètres du joueur DLC Quest] (/games/DLCQuest/player-settings).

## Rejoindre une partie multi-monde

### Installer le mod

- Télécharger le [DLCQuestipelago mod release](https://github.com/agilbert1412/DLCQuestipelago/releases). Si c'est la première fois que vous installez le mod, ou si vous n'êtes pas à l'aise avec l'édition manuelle de fichiers, vous devriez choisir l'Installateur. Il se chargera de la plus grande partie du travail pour vous


- Extraire l'archive .zip à l'emplacement de votre choix


- Exécutez "DLCQuestipelagoInstaller.exe".

![image](https://i.imgur.com/2sPhMgs.png)
- Le programme d'installation devrait décrire ce qu'il fait à chaque étape, et vous demandera votre avis si nécessaire.
- Il vous permettra de choisir l'emplacement d'installation de votre jeu moddé et vous proposera un emplacement par défaut
- Il **essayera** de trouver votre jeu DLCQuest sur votre ordinateur et, en cas d'échec, vous demandera d'indiquer le chemin d'accès.
- Il vous offrira la possibilité de créer un raccourci sur le bureau pour le lanceur moddé.

### Se connecter au MultiServer

- Localisez le fichier "ArchipelagoConnectionInfo.json", qui se situe dans le même emplacement que votre installation moddée. Vous pouvez éditer ce fichier avec n'importe quel éditeur de texte, et vous devez entrer l'adresse IP du serveur, le port et votre nom de joueur dans les champs appropriés.

- Exécutez BepInEx.NET.Framework.Launcher.exe. Si vous avez opté pour un raccourci sur le bureau, vous le trouverez avec une icône et un nom plus reconnaissable.
![image](https://i.imgur.com/ZUiFrhf.png)

- Votre jeu devrait se lancer en même temps qu'une console de modloader, qui contiendra des informations de débogage importantes si vous rencontrez des problèmes.
- Le jeu devrait se connecter automatiquement, et tenter de se reconnecter si votre internet ou le serveur se déconnecte, pendant que vous jouez.

### Interagir avec le MultiWorld depuis le jeu

Vous ne pouvez pas envoyer de commandes au serveur ou discuter avec les autres joueurs depuis DLC Quest, car le jeu ne dispose pas d'un moyen approprié pour saisir du texte.
Vous pouvez suivre l'activité du serveur dans votre console BepInEx, car les messages de chat d'Archipelago y seront affichés.
Vous devrez utiliser [Archipelago Text Client] (https://github.com/ArchipelagoMW/Archipelago/releases) si vous voulez envoyer des commandes.
5 changes: 0 additions & 5 deletions worlds/ffmq/Items.py
Original file line number Diff line number Diff line change
Expand Up @@ -223,11 +223,6 @@ def yaml_item(text):
def create_items(self) -> None:
items = []
starting_weapon = self.multiworld.starting_weapon[self.player].current_key.title().replace("_", " ")
if self.multiworld.progressive_gear[self.player]:
for item_group in prog_map:
if starting_weapon in self.item_name_groups[item_group]:
starting_weapon = prog_map[item_group]
break
self.multiworld.push_precollected(self.create_item(starting_weapon))
self.multiworld.push_precollected(self.create_item("Steel Armor"))
if self.multiworld.sky_coin_mode[self.player] == "start_with":
Expand Down
2 changes: 1 addition & 1 deletion worlds/hk/ExtractedData.py

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion worlds/kh2/Options.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

from Options import Choice, Range, Toggle, ItemDict, PerGameCommonOptions, StartInventoryPool

from worlds.kh2 import default_itempool_option
from . import default_itempool_option


class SoraEXP(Range):
Expand Down
8 changes: 5 additions & 3 deletions worlds/kh2/Rules.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
from typing import Dict, Callable, TYPE_CHECKING

from BaseClasses import CollectionState
from .Items import exclusion_item_table, visit_locking_dict, DonaldAbility_Table, GoofyAbility_Table
from .Items import exclusion_item_table, visit_locking_dict, DonaldAbility_Table, GoofyAbility_Table, SupportAbility_Table
from .Locations import exclusion_table, popups_set, Goofy_Checks, Donald_Checks
from .Names import LocationName, ItemName, RegionName
from worlds.generic.Rules import add_rule, forbid_items, add_item_rule
Expand Down Expand Up @@ -224,7 +224,7 @@ def __init__(self, kh2world: KH2World) -> None:
RegionName.Pl2: lambda state: self.pl_unlocked(state, 2),

RegionName.Ag: lambda state: self.ag_unlocked(state, 1),
RegionName.Ag2: lambda state: self.ag_unlocked(state, 2) and self.kh2_has_all([ItemName.FireElement,ItemName.BlizzardElement,ItemName.ThunderElement],state),
RegionName.Ag2: lambda state: self.ag_unlocked(state, 2) and self.kh2_has_all([ItemName.FireElement, ItemName.BlizzardElement, ItemName.ThunderElement], state),

RegionName.Bc: lambda state: self.bc_unlocked(state, 1),
RegionName.Bc2: lambda state: self.bc_unlocked(state, 2),
Expand Down Expand Up @@ -266,6 +266,8 @@ def set_kh2_rules(self) -> None:
add_item_rule(location, lambda item: item.player == self.player and item.name in GoofyAbility_Table.keys())
elif location.name in Donald_Checks:
add_item_rule(location, lambda item: item.player == self.player and item.name in DonaldAbility_Table.keys())
else:
add_item_rule(location, lambda item: item.player == self.player and item.name in SupportAbility_Table.keys())

def set_kh2_goal(self):
final_xemnas_location = self.multiworld.get_location(LocationName.FinalXemnas, self.player)
Expand Down Expand Up @@ -417,7 +419,7 @@ def __init__(self, world: KH2World) -> None:
RegionName.DataLexaeus: lambda state: self.get_data_lexaeus_rules(state),
RegionName.OldPete: lambda state: self.get_old_pete_rules(),
RegionName.FuturePete: lambda state: self.get_future_pete_rules(state),
RegionName.Terra: lambda state: self.get_terra_rules(state),
RegionName.Terra: lambda state: self.get_terra_rules(state) and state.has(ItemName.ProofofConnection, self.player),
RegionName.DataMarluxia: lambda state: self.get_data_marluxia_rules(state),
RegionName.Barbosa: lambda state: self.get_barbosa_rules(state),
RegionName.GrimReaper1: lambda state: self.get_grim_reaper1_rules(),
Expand Down
4 changes: 2 additions & 2 deletions worlds/landstalker/docs/landstalker_setup_en.md
Original file line number Diff line number Diff line change
Expand Up @@ -30,8 +30,8 @@ guide: [Basic Multiworld Setup Guide](/tutorial/Archipelago/setup/en)

### Where do I get a config file?

The [Player Settings Page](../player-settings) on the website allows you to easily configure your personal settings
and export a config file from them.
The [Player Settings Page](/games/Landstalker%20-%20The%20Treasures%20of%20King%20Nole/player-settings) on the website allows
you to easily configure your personal settings

## How-to-play

Expand Down
22 changes: 17 additions & 5 deletions worlds/musedash/MuseDashCollection.py
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ class MuseDashCollections:
"Rush-Hour",
"Find this Month's Featured Playlist",
"PeroPero in the Universe",
"umpopoff"
]

album_items: Dict[str, AlbumData] = {}
Expand Down Expand Up @@ -81,11 +82,22 @@ def __init__(self) -> None:
steamer_mode = sections[3] == "True"

if song_name in self.DIFF_OVERRIDES:
# Note: These difficulties may not actually be representative of these songs.
# The game does not provide these difficulties so they have to be filled in.
diff_of_easy = 4
diff_of_hard = 7
diff_of_master = 10
# These songs use non-standard difficulty values. Which are being overriden with standard values.
# But also avoid filling any missing difficulties (i.e. 0s) with a difficulty value.
if sections[4] != '0':
diff_of_easy = 4
else:
diff_of_easy = None

if sections[5] != '0':
diff_of_hard = 7
else:
diff_of_hard = None

if sections[6] != '0':
diff_of_master = 10
else:
diff_of_master = None
else:
diff_of_easy = self.parse_song_difficulty(sections[4])
diff_of_hard = self.parse_song_difficulty(sections[5])
Expand Down
12 changes: 10 additions & 2 deletions worlds/musedash/MuseDashData.txt
Original file line number Diff line number Diff line change
Expand Up @@ -119,7 +119,7 @@ Prestige and Vestige|56-4|Give Up TREATMENT Vol.11|True|6|8|11|
Tiny Fate|56-5|Give Up TREATMENT Vol.11|False|7|9|11|
Tsuki ni Murakumo Hana ni Kaze|55-0|Touhou Mugakudan -2-|False|3|5|7|
Patchouli's - Best Hit GSK|55-1|Touhou Mugakudan -2-|False|3|5|8|
Monosugoi Space Shuttle de Koishi ga Monosugoi uta|55-2|Touhou Mugakudan -2-|False|3|5|7|
Monosugoi Space Shuttle de Koishi ga Monosugoi uta|55-2|Touhou Mugakudan -2-|False|3|5|7|11
Kakoinaki Yo wa Ichigo no Tsukikage|55-3|Touhou Mugakudan -2-|False|3|6|8|
Psychedelic Kizakura Doumei|55-4|Touhou Mugakudan -2-|False|4|7|10|
Mischievous Sensation|55-5|Touhou Mugakudan -2-|False|5|7|9|
Expand Down Expand Up @@ -501,4 +501,12 @@ slic.hertz|68-1|Gambler's Tricks|True|5|7|9|
Fuzzy-Navel|68-2|Gambler's Tricks|True|6|8|10|11
Swing Edge|68-3|Gambler's Tricks|True|4|8|10|
Twisted Escape|68-4|Gambler's Tricks|True|5|8|10|11
Swing Sweet Twee Dance|68-5|Gambler's Tricks|False|4|7|10|
Swing Sweet Twee Dance|68-5|Gambler's Tricks|False|4|7|10|
Sanyousei SAY YA!!!|43-42|MD Plus Project|False|4|6|8|
YUKEMURI TAMAONSEN II|43-43|MD Plus Project|False|3|6|9|
Samayoi no mei Amatsu|69-0|Touhou Mugakudan -3-|False|4|6|9|
INTERNET SURVIVOR|69-1|Touhou Mugakudan -3-|False|5|8|10|
Shuki*RaiRai|69-2|Touhou Mugakudan -3-|False|5|7|9|
HELLOHELL|69-3|Touhou Mugakudan -3-|False|4|7|10|
Calamity Fortune|69-4|Touhou Mugakudan -3-|True|6|8|10|11
Tsurupettan|69-5|Touhou Mugakudan -3-|True|2|5|8|
Loading

0 comments on commit d1727d0

Please sign in to comment.