KDL3: Fix invalid animal placements and fill error (#3152)
This commit is contained in:
parent
8b8df9fa33
commit
6f7c2fa25f
|
@ -1,8 +1,8 @@
|
||||||
import orjson
|
import orjson
|
||||||
import os
|
import os
|
||||||
import typing
|
|
||||||
from pkgutil import get_data
|
from pkgutil import get_data
|
||||||
|
|
||||||
|
from typing import TYPE_CHECKING, List, Dict, Optional, Union
|
||||||
from BaseClasses import Region
|
from BaseClasses import Region
|
||||||
from worlds.generic.Rules import add_item_rule
|
from worlds.generic.Rules import add_item_rule
|
||||||
from .Locations import KDL3Location
|
from .Locations import KDL3Location
|
||||||
|
@ -10,7 +10,7 @@ from .Names import LocationName
|
||||||
from .Options import BossShuffle
|
from .Options import BossShuffle
|
||||||
from .Room import KDL3Room
|
from .Room import KDL3Room
|
||||||
|
|
||||||
if typing.TYPE_CHECKING:
|
if TYPE_CHECKING:
|
||||||
from . import KDL3World
|
from . import KDL3World
|
||||||
|
|
||||||
default_levels = {
|
default_levels = {
|
||||||
|
@ -39,22 +39,24 @@ first_world_limit = {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
def generate_valid_level(world: "KDL3World", level, stage, possible_stages, placed_stages):
|
def generate_valid_level(world: "KDL3World", level: int, stage: int,
|
||||||
|
possible_stages: List[int], placed_stages: List[int]):
|
||||||
new_stage = world.random.choice(possible_stages)
|
new_stage = world.random.choice(possible_stages)
|
||||||
if level == 1:
|
if level == 1:
|
||||||
if stage == 0 and new_stage in first_stage_blacklist:
|
if stage == 0 and new_stage in first_stage_blacklist:
|
||||||
return generate_valid_level(world, level, stage, possible_stages, placed_stages)
|
return generate_valid_level(world, level, stage, possible_stages, placed_stages)
|
||||||
elif not (world.multiworld.players > 1 or world.options.consumables or world.options.starsanity) and \
|
elif (not (world.multiworld.players > 1 or world.options.consumables or world.options.starsanity) and
|
||||||
new_stage in first_world_limit and \
|
new_stage in first_world_limit and
|
||||||
sum(p_stage in first_world_limit for p_stage in placed_stages) >= 2:
|
sum(p_stage in first_world_limit for p_stage in placed_stages)
|
||||||
|
>= (2 if world.options.open_world else 1)):
|
||||||
return generate_valid_level(world, level, stage, possible_stages, placed_stages)
|
return generate_valid_level(world, level, stage, possible_stages, placed_stages)
|
||||||
return new_stage
|
return new_stage
|
||||||
|
|
||||||
|
|
||||||
def generate_rooms(world: "KDL3World", level_regions: typing.Dict[int, Region]):
|
def generate_rooms(world: "KDL3World", level_regions: Dict[int, Region]):
|
||||||
level_names = {LocationName.level_names[level]: level for level in LocationName.level_names}
|
level_names = {LocationName.level_names[level]: level for level in LocationName.level_names}
|
||||||
room_data = orjson.loads(get_data(__name__, os.path.join("data", "Rooms.json")))
|
room_data = orjson.loads(get_data(__name__, os.path.join("data", "Rooms.json")))
|
||||||
rooms: typing.Dict[str, KDL3Room] = dict()
|
rooms: Dict[str, KDL3Room] = dict()
|
||||||
for room_entry in room_data:
|
for room_entry in room_data:
|
||||||
room = KDL3Room(room_entry["name"], world.player, world.multiworld, None, room_entry["level"],
|
room = KDL3Room(room_entry["name"], world.player, world.multiworld, None, room_entry["level"],
|
||||||
room_entry["stage"], room_entry["room"], room_entry["pointer"], room_entry["music"],
|
room_entry["stage"], room_entry["room"], room_entry["pointer"], room_entry["music"],
|
||||||
|
@ -75,7 +77,7 @@ def generate_rooms(world: "KDL3World", level_regions: typing.Dict[int, Region]):
|
||||||
world.rooms = list(rooms.values())
|
world.rooms = list(rooms.values())
|
||||||
world.multiworld.regions.extend(world.rooms)
|
world.multiworld.regions.extend(world.rooms)
|
||||||
|
|
||||||
first_rooms: typing.Dict[int, KDL3Room] = dict()
|
first_rooms: Dict[int, KDL3Room] = dict()
|
||||||
for name, room in rooms.items():
|
for name, room in rooms.items():
|
||||||
if room.room == 0:
|
if room.room == 0:
|
||||||
if room.stage == 7:
|
if room.stage == 7:
|
||||||
|
@ -118,7 +120,7 @@ def generate_rooms(world: "KDL3World", level_regions: typing.Dict[int, Region]):
|
||||||
|
|
||||||
|
|
||||||
def generate_valid_levels(world: "KDL3World", enforce_world: bool, enforce_pattern: bool) -> dict:
|
def generate_valid_levels(world: "KDL3World", enforce_world: bool, enforce_pattern: bool) -> dict:
|
||||||
levels: typing.Dict[int, typing.List[typing.Optional[int]]] = {
|
levels: Dict[int, List[Optional[int]]] = {
|
||||||
1: [None] * 7,
|
1: [None] * 7,
|
||||||
2: [None] * 7,
|
2: [None] * 7,
|
||||||
3: [None] * 7,
|
3: [None] * 7,
|
||||||
|
@ -158,7 +160,7 @@ def generate_valid_levels(world: "KDL3World", enforce_world: bool, enforce_patte
|
||||||
raise Exception(f"Failed to find valid stage for {level}-{stage}. Remaining Stages:{possible_stages}")
|
raise Exception(f"Failed to find valid stage for {level}-{stage}. Remaining Stages:{possible_stages}")
|
||||||
|
|
||||||
# now handle bosses
|
# now handle bosses
|
||||||
boss_shuffle: typing.Union[int, str] = world.options.boss_shuffle.value
|
boss_shuffle: Union[int, str] = world.options.boss_shuffle.value
|
||||||
plando_bosses = []
|
plando_bosses = []
|
||||||
if isinstance(boss_shuffle, str):
|
if isinstance(boss_shuffle, str):
|
||||||
# boss plando
|
# boss plando
|
||||||
|
|
|
@ -203,11 +203,13 @@ class KDL3World(World):
|
||||||
animal_pool.append("Coo Spawn")
|
animal_pool.append("Coo Spawn")
|
||||||
else:
|
else:
|
||||||
animal_pool.append("Kine Spawn")
|
animal_pool.append("Kine Spawn")
|
||||||
|
# Weird fill hack, this forces ChuChu to be the last animal friend placed
|
||||||
|
# If Kine is ever the last animal friend placed, he will cause fill errors on closed world
|
||||||
|
animal_pool.sort()
|
||||||
locations = [self.multiworld.get_location(spawn, self.player) for spawn in spawns]
|
locations = [self.multiworld.get_location(spawn, self.player) for spawn in spawns]
|
||||||
items = [self.create_item(animal) for animal in animal_pool]
|
items = [self.create_item(animal) for animal in animal_pool]
|
||||||
allstate = self.multiworld.get_all_state(False)
|
allstate = self.multiworld.get_all_state(False)
|
||||||
self.random.shuffle(locations)
|
self.random.shuffle(locations)
|
||||||
self.random.shuffle(items)
|
|
||||||
fill_restrictive(self.multiworld, allstate, locations, items, True, True)
|
fill_restrictive(self.multiworld, allstate, locations, items, True, True)
|
||||||
else:
|
else:
|
||||||
animal_friends = animal_friend_spawns.copy()
|
animal_friends = animal_friend_spawns.copy()
|
||||||
|
|
Loading…
Reference in New Issue