forked from mirror/Archipelago
Some checks failed
Analyze modified files / flake8 (push) Failing after 2m28s
Build / build-win (push) Has been cancelled
Build / build-ubuntu2204 (push) Has been cancelled
ctest / Test C++ ubuntu-latest (push) Has been cancelled
ctest / Test C++ windows-latest (push) Has been cancelled
Analyze modified files / mypy (push) Has been cancelled
Build and Publish Docker Images / Push Docker image to Docker Hub (push) Successful in 5m4s
Native Code Static Analysis / scan-build (push) Failing after 5m2s
type check / pyright (push) Successful in 1m7s
unittests / Test Python 3.11.2 ubuntu-latest (push) Failing after 16m23s
unittests / Test Python 3.12 ubuntu-latest (push) Failing after 28m19s
unittests / Test Python 3.13 ubuntu-latest (push) Failing after 14m49s
unittests / Test hosting with 3.13 on ubuntu-latest (push) Successful in 5m0s
unittests / Test Python 3.13 macos-latest (push) Has been cancelled
unittests / Test Python 3.11 windows-latest (push) Has been cancelled
unittests / Test Python 3.13 windows-latest (push) Has been cancelled
171 lines
7.3 KiB
Python
171 lines
7.3 KiB
Python
from typing import List
|
|
|
|
from BaseClasses import Tutorial, MultiWorld
|
|
from worlds.AutoWorld import WebWorld, World
|
|
from .Items import KHRECOMItem, KHRECOMItemData, get_items_by_category, item_table, item_name_groups
|
|
from .Locations import location_table, location_name_groups
|
|
from .Options import KHRECOMOptions, khrecom_option_groups
|
|
from .Regions import create_regions
|
|
from .Rules import set_rules
|
|
from .Presets import khrecom_option_presets
|
|
from worlds.LauncherComponents import Component, components, Type, launch_subprocess
|
|
|
|
|
|
|
|
def launch_client():
|
|
from .Client import launch
|
|
launch_subprocess(launch, name="KHRECOM Client")
|
|
|
|
|
|
components.append(Component("KHRECOM Client", "KHRECOMClient", func=launch_client, component_type=Type.CLIENT))
|
|
|
|
class KHRECOMWeb(WebWorld):
|
|
theme = "ocean"
|
|
tutorials = [Tutorial(
|
|
"Multiworld Setup Guide",
|
|
"A guide to setting up the Kingdom Hearts RE Chain of Memories Randomizer software on your computer. This guide covers single-player, "
|
|
"multiworld, and related software.",
|
|
"English",
|
|
"khrecom_en.md",
|
|
"khrecom/en",
|
|
["Gicu"]
|
|
)]
|
|
option_groups = khrecom_option_groups
|
|
options_presets = khrecom_option_presets
|
|
|
|
class KHRECOMWorld(World):
|
|
"""
|
|
Kingdom Hearts RE Chain of Memories is an action card RPG following
|
|
Sora on his journey through Castle Oblivion to find Riku and Kairi.
|
|
"""
|
|
game = "Kingdom Hearts RE Chain of Memories"
|
|
options_dataclass = KHRECOMOptions
|
|
options: KHRECOMOptions
|
|
topology_present = True
|
|
data_version = 4
|
|
web = KHRECOMWeb()
|
|
world_order = []
|
|
|
|
item_name_to_id = {name: data.code for name, data in item_table.items()}
|
|
location_name_to_id = {name: data.code for name, data in location_table.items()}
|
|
item_name_groups = item_name_groups
|
|
location_name_groups = location_name_groups
|
|
|
|
def create_items(self):
|
|
self.place_predetermined_items()
|
|
# Handle starting worlds
|
|
starting_worlds = []
|
|
if self.options.starting_worlds > 0:
|
|
possible_starting_worlds = [
|
|
"World Card Wonderland",
|
|
"World Card Olympus Coliseum",
|
|
"World Card Agrabah",
|
|
"World Card Monstro",
|
|
"World Card Atlantica",
|
|
"World Card Halloween Town",
|
|
"World Card Neverland",
|
|
"World Card Hollow Bastion",
|
|
"World Card 100 Acre Wood",
|
|
"World Card Twilight Town",
|
|
"World Card Destiny Islands"]
|
|
starting_worlds = self.random.sample(possible_starting_worlds, min(self.options.starting_worlds.value, len(possible_starting_worlds)))
|
|
for starting_world in starting_worlds:
|
|
self.multiworld.push_precollected(self.create_item(starting_world))
|
|
if self.options.starting_cure:
|
|
self.multiworld.push_precollected(self.create_item("Card Set Cure"))
|
|
|
|
item_pool: List[KHRECOMItem] = []
|
|
total_locations = len(self.multiworld.get_unfilled_locations(self.player))
|
|
sleights_added = 0
|
|
enemy_cards_added = 0
|
|
shuffled_item_list = list(item_table.items())
|
|
self.random.shuffle(shuffled_item_list)
|
|
for name, data in shuffled_item_list:
|
|
# Ignore filler, it will be added in a later stage.
|
|
if data.category not in ["World Unlocks", "Gold Map Cards", "Friend Cards", "Enemy Cards", "Sleights"]:
|
|
continue
|
|
elif data.category == "Enemy Cards" and enemy_cards_added < self.options.enemy_card_amount and name not in ["Enemy Card " + card_name for card_name in self.options.exclude_enemy_cards.value]:
|
|
enemy_cards_added = enemy_cards_added + 1
|
|
item_pool.append(self.create_item(name))
|
|
elif data.category == "Sleights" and sleights_added < self.options.sleight_amount and name not in ["Sleight " + sleight_name for sleight_name in self.options.exclude_sleights.value]:
|
|
sleights_added = sleights_added + 1
|
|
item_pool.append(self.create_item(name))
|
|
elif data.category not in ["Sleights", "Enemy Cards"] and name not in starting_worlds and name != "Friend Card Pluto":
|
|
item_pool.append(self.create_item(name))
|
|
|
|
# Fill any empty locations with filler items.
|
|
while len(item_pool) < total_locations:
|
|
item_pool.append(self.create_item(self.get_filler_item_name()))
|
|
|
|
self.multiworld.itempool += item_pool
|
|
|
|
def place_predetermined_items(self) -> None:
|
|
self.get_location("12F Exit Hall Larxene II (Enemy Cards Larxene)").place_locked_item(self.create_item("Friend Card Pluto"))
|
|
self.get_location("Final Marluxia").place_locked_item(self.create_item("Victory"))
|
|
|
|
def get_filler_item_name(self) -> str:
|
|
fillers = {}
|
|
exclude = []
|
|
for card in self.options.exclude_cards.value:
|
|
exclude.append("Card Set " + card)
|
|
fillers.update(get_items_by_category("Sets", exclude))
|
|
return self.random.choices([filler for filler in fillers.keys()], k=1)[0]
|
|
|
|
def create_item(self, name: str) -> KHRECOMItem:
|
|
data = item_table[name]
|
|
return KHRECOMItem(name, data.classification, data.code, self.player)
|
|
|
|
def set_rules(self):
|
|
set_rules(self)
|
|
|
|
def create_regions(self):
|
|
create_regions(self.multiworld, self.player, self.options)
|
|
|
|
def fill_slot_data(self) -> dict:
|
|
self.decide_world_order()
|
|
world_order_string = ""
|
|
for world_id in self.world_order:
|
|
world_order_string = world_order_string + str(world_id) + ","
|
|
world_order_string = world_order_string[:-1]
|
|
|
|
set_values = [
|
|
self.options.value_0_on,
|
|
self.options.value_1_on,
|
|
self.options.value_2_on,
|
|
self.options.value_3_on,
|
|
self.options.value_4_on,
|
|
self.options.value_5_on,
|
|
self.options.value_6_on,
|
|
self.options.value_7_on,
|
|
self.options.value_8_on,
|
|
self.options.value_9_on,
|
|
self.options.value_0_p_on,
|
|
self.options.value_1_p_on,
|
|
self.options.value_2_p_on,
|
|
self.options.value_3_p_on,
|
|
self.options.value_4_p_on,
|
|
self.options.value_5_p_on,
|
|
self.options.value_6_p_on,
|
|
self.options.value_7_p_on,
|
|
self.options.value_8_p_on,
|
|
self.options.value_9_p_on]
|
|
set_data = []
|
|
set_data_string = ""
|
|
for i in range(20):
|
|
set_data.append([])
|
|
for set_index, set_value in enumerate(set_values):
|
|
if set_value == i + 1:
|
|
set_data[i].append(set_index)
|
|
set_data_string = set_data_string + ','.join(map(str, set_data[i])) + "\n"
|
|
slot_data = {"xpmult": int(self.options.exp_multiplier)
|
|
,"worldorder": world_order_string
|
|
,"attackpower": int(self.options.attack_power)
|
|
,"setdata": set_data_string}
|
|
return slot_data
|
|
|
|
def decide_world_order(self):
|
|
if len(self.world_order) == 0:
|
|
possible_world_assignments = [2,3,4,5,6,7,8,9,10]
|
|
self.random.shuffle(possible_world_assignments)
|
|
self.world_order = possible_world_assignments
|