Completionist fixes
This commit is contained in:
@@ -470,7 +470,10 @@ class World(object):
|
||||
if self.has_beaten_game(state):
|
||||
return True
|
||||
|
||||
prog_locations = [location for location in self.get_locations() if location.item is not None and (location.item.advancement or location.event) and location not in state.locations_checked]
|
||||
prog_locations = [location for location in self.get_locations() if location.item is not None
|
||||
and (location.item.advancement or location.event
|
||||
or self.goal[location.player] == 'completionist')
|
||||
and location not in state.locations_checked]
|
||||
|
||||
while prog_locations:
|
||||
sphere = []
|
||||
@@ -1038,8 +1041,10 @@ class CollectionState(object):
|
||||
return self.prog_items[item, player]
|
||||
|
||||
def everything(self, player):
|
||||
all_locations = self.world.get_filled_locations(player)
|
||||
all_locations.remove(self.world.get_location('Ganon', player))
|
||||
return (len([x for x in self.locations_checked if x.player == player])
|
||||
>= len(self.world.get_filled_locations(player)))
|
||||
>= len(all_locations))
|
||||
|
||||
def has_crystals(self, count, player):
|
||||
crystals = ['Crystal 1', 'Crystal 2', 'Crystal 3', 'Crystal 4', 'Crystal 5', 'Crystal 6', 'Crystal 7']
|
||||
|
||||
@@ -6,7 +6,7 @@ from enum import unique, Flag
|
||||
from typing import DefaultDict, Dict, List
|
||||
from itertools import chain
|
||||
|
||||
from BaseClasses import RegionType, Region, Door, DoorType, Direction, Sector, CrystalBarrier, DungeonInfo, dungeon_keys
|
||||
from BaseClasses import RegionType, Region, Door, DoorType, Sector, CrystalBarrier, DungeonInfo, dungeon_keys
|
||||
from BaseClasses import PotFlags, LocationType, Direction
|
||||
from Doors import reset_portals
|
||||
from Dungeons import dungeon_regions, region_starts, standard_starts, split_region_starts
|
||||
@@ -15,12 +15,12 @@ from Items import ItemFactory
|
||||
from RoomData import DoorKind, PairedDoor, reset_rooms
|
||||
from source.dungeon.DungeonStitcher import GenerationException, generate_dungeon
|
||||
from source.dungeon.DungeonStitcher import ExplorationState as ExplorationState2
|
||||
from DungeonGenerator import ExplorationState, convert_regions, pre_validate, determine_required_paths, drop_entrances
|
||||
from DungeonGenerator import ExplorationState, convert_regions, determine_required_paths, drop_entrances
|
||||
from DungeonGenerator import create_dungeon_builders, split_dungeon_builder, simple_dungeon_builder, default_dungeon_entrances
|
||||
from DungeonGenerator import dungeon_portals, dungeon_drops, connect_doors, count_reserved_locations
|
||||
from DungeonGenerator import valid_region_to_explore
|
||||
from KeyDoorShuffle import analyze_dungeon, build_key_layout, validate_key_layout, determine_prize_lock
|
||||
from KeyDoorShuffle import validate_bk_layout, check_bk_special
|
||||
from KeyDoorShuffle import validate_bk_layout
|
||||
from Utils import ncr, kth_combination
|
||||
|
||||
|
||||
|
||||
@@ -12,7 +12,7 @@ from typing import List
|
||||
from BaseClasses import DoorType, Direction, CrystalBarrier, RegionType, Polarity, PolSlot, flooded_keys, Sector
|
||||
from BaseClasses import Hook, hook_from_door, Door
|
||||
from Regions import dungeon_events, flooded_keys_reverse
|
||||
from Dungeons import dungeon_regions, split_region_starts
|
||||
from Dungeons import split_region_starts
|
||||
from RoomData import DoorKind
|
||||
|
||||
from source.dungeon.DungeonStitcher import generate_dungeon_find_proposal
|
||||
|
||||
5
Main.py
5
Main.py
@@ -617,7 +617,8 @@ def create_playthrough(world):
|
||||
world = copy_world(world)
|
||||
|
||||
# get locations containing progress items
|
||||
prog_locations = [location for location in world.get_filled_locations() if location.item.advancement]
|
||||
prog_locations = [location for location in world.get_filled_locations() if location.item.advancement
|
||||
or world.goal[location.player] == 'completionist']
|
||||
optional_locations = ['Trench 1 Switch', 'Trench 2 Switch', 'Ice Block Drop', 'Skull Star Tile']
|
||||
state_cache = [None]
|
||||
collection_spheres = []
|
||||
@@ -654,6 +655,8 @@ def create_playthrough(world):
|
||||
for num, sphere in reversed(list(enumerate(collection_spheres))):
|
||||
to_delete = set()
|
||||
for location in sphere:
|
||||
if world.goal[location.player] == 'completionist':
|
||||
continue # every location for that player is required
|
||||
# we remove the item at location and check if game is still beatable
|
||||
logging.getLogger('').debug('Checking if %s (Player %d) is required to beat the game.', location.item.name, location.item.player)
|
||||
old_item = location.item
|
||||
|
||||
6
Rom.py
6
Rom.py
@@ -15,7 +15,7 @@ try:
|
||||
except ImportError:
|
||||
raise Exception('Could not load BPS module')
|
||||
|
||||
from BaseClasses import ShopType, Region, Location, Door, DoorType, RegionType, LocationType, Item
|
||||
from BaseClasses import ShopType, Region, Location, Door, DoorType, RegionType, LocationType
|
||||
from DoorShuffle import compass_data, DROptions, boss_indicator, dungeon_portals
|
||||
from Dungeons import dungeon_music_addresses, dungeon_table
|
||||
from Regions import location_table, shop_to_location_table, retro_shops
|
||||
@@ -37,7 +37,7 @@ from source.dungeon.RoomList import Room0127
|
||||
|
||||
|
||||
JAP10HASH = '03a63945398191337e896e5771f77173'
|
||||
RANDOMIZERBASEHASH = 'fb7f9a0d501ba9ecd0a31066f9a0a973'
|
||||
RANDOMIZERBASEHASH = '54cfc4c5e85c80fb2958cb458d36ad14'
|
||||
|
||||
|
||||
class JsonRom(object):
|
||||
@@ -1344,7 +1344,7 @@ def patch_rom(world, rom, player, team, enemized, is_mystery=False):
|
||||
elif world.goal[player] in ['ganonhunt']:
|
||||
rom.write_byte(0x18003E, 0x05) # make ganon invincible until all triforce pieces collected
|
||||
elif world.goal[player] in ['completionist']:
|
||||
rom.write_byte(0x18003E, 0x09) # make ganon invincible until everything is collected
|
||||
rom.write_byte(0x18003E, 0x0a) # make ganon invincible until everything is collected
|
||||
else:
|
||||
rom.write_byte(0x18003E, 0x03) # make ganon invincible until all crystals and aga 2 are collected
|
||||
|
||||
|
||||
3
Rules.py
3
Rules.py
@@ -2075,7 +2075,8 @@ def add_key_logic_rules(world, player):
|
||||
for chest in d_logic.bk_chests:
|
||||
big_chest = world.get_location(chest.name, player)
|
||||
add_rule(big_chest, create_rule(d_logic.bk_name, player))
|
||||
if len(d_logic.bk_doors) == 0 and len(d_logic.bk_chests) <= 1:
|
||||
if (len(d_logic.bk_doors) == 0 and len(d_logic.bk_chests) <= 1
|
||||
and world.accessibility[player] != 'locations'):
|
||||
set_always_allow(big_chest, allow_big_key_in_big_chest(d_logic.bk_name, player))
|
||||
if world.keyshuffle[player] == 'universal':
|
||||
for d_name, layout in world.key_layout[player].items():
|
||||
|
||||
Binary file not shown.
@@ -1,5 +1,7 @@
|
||||
import os
|
||||
import sys
|
||||
sys.path.append(os.path.join(os.path.dirname(__file__), '..', '..'))
|
||||
import RaceRandom as random
|
||||
import logging
|
||||
import time
|
||||
|
||||
from collections import Counter, defaultdict
|
||||
@@ -106,7 +108,7 @@ def test_loop(tests, entrance_set, exit_set, ctr, shuffle_mode, main_mode, links
|
||||
# seed = 635441530
|
||||
random.seed(seed)
|
||||
world = World(1, {1: shuffle_mode}, {1: 'vanilla'}, {1: 'noglitches'}, {1: main_mode}, {}, {}, {},
|
||||
{}, {}, {}, {}, {}, True, {}, {}, [], {})
|
||||
{}, {}, {}, {}, {}, True, {}, [], {})
|
||||
world.customizer = False
|
||||
world.shufflelinks = {1: links}
|
||||
if world.mode[1] != 'inverted':
|
||||
|
||||
Reference in New Issue
Block a user