Merge DoorDev fixes

This commit is contained in:
aerinon
2020-03-03 12:49:59 -07:00
7 changed files with 24 additions and 33 deletions

View File

@@ -197,8 +197,7 @@ def connect_simple_door(world, exit_name, region_name, player):
d.dest = region
def connect_door_only(world, exit_name, region_name, player):
region = world.get_region(region_name, player)
def connect_door_only(world, exit_name, region, player):
d = world.check_for_door(exit_name, player)
if d is not None:
d.dest = region
@@ -1352,8 +1351,8 @@ def add_inaccessible_doors(world, player):
# todo: ignore standard mode hyrule castle ledge?
for inaccessible_region in world.inaccessible_regions[player]:
region = world.get_region(inaccessible_region, player)
for exit in region.exits:
create_door(world, player, exit.name, region.name)
for ext in region.exits:
create_door(world, player, ext.name, region.name)
def create_door(world, player, entName, region_name):
@@ -1459,6 +1458,7 @@ def check_for_pinball_fix(state, bad_region, world, player):
@unique
class DROptions(Flag):
NoOptions = 0x00
Eternal_Mini_Bosses = 0x01 # If on, GT minibosses marked as defeated when they try to spawn a heart
Town_Portal = 0x02 # If on, Players will start with mirror scroll
Open_Desert_Wall = 0x80 # If on, pre opens the desert wall, no fire required

View File

@@ -177,6 +177,7 @@ def get_custom_array_key(item):
key = label_switcher.get(key)
return key
def generate_itempool(world, player):
if (world.difficulty[player] not in ['normal', 'hard', 'expert'] or world.goal[player] not in ['ganon', 'pedestal', 'dungeons', 'triforcehunt', 'crystals']
or world.mode[player] not in ['open', 'standard', 'inverted'] or world.timer not in ['none', 'display', 'timed', 'timed-ohko', 'ohko', 'timed-countdown'] or world.progressive not in ['on', 'off', 'random']):
@@ -194,7 +195,7 @@ def generate_itempool(world, player):
region = world.get_region('Light World',player)
loc = Location(player, "Murahdahla", parent=region)
loc.access_rule = lambda state: state.item_count(get_custom_array_key('Triforce Piece'), player) + state.item_count(get_custom_array_key('Power Star'), player) > state.world.treasure_hunt_count[player]
loc.access_rule = lambda state: state.item_count('Triforce Piece', player) + state.item_count('Power Star', player) > state.world.treasure_hunt_count[player]
region.locations.append(loc)
world.dynamic_locations.append(loc)
@@ -253,7 +254,6 @@ def generate_itempool(world, player):
world.get_location('Zelda Drop Off', player).event = True
world.get_location('Zelda Drop Off', player).locked = True
# set up item pool
if world.custom:
(pool, placed_items, precollected_items, clock_mode, treasure_hunt_count, treasure_hunt_icon, lamps_needed_for_dark_rooms) = make_custom_item_pool(world.progressive, world.shuffle[player], world.difficulty[player], world.timer, world.goal[player], world.mode[player], world.swords[player], world.retro[player], world.customitemarray)
@@ -407,6 +407,7 @@ def set_up_take_anys(world, player):
world.initialize_regions()
def create_dynamic_shop_locations(world, player):
for shop in world.shops:
if shop.region.player == player:

View File

@@ -705,7 +705,7 @@ def unique_doors(doors):
def count_unique_sm_doors(doors):
unique_d_set = set()
for d in doors:
if d not in unique_d_set and d.dest not in unique_d_set and not d.bigKey:
if d not in unique_d_set and (d.dest not in unique_d_set or d.type == DoorType.SpiralStairs) and not d.bigKey:
unique_d_set.add(d)
return len(unique_d_set)
@@ -718,7 +718,8 @@ def count_unique_small_doors(key_counter, proposal):
if door in proposal and door not in counted:
cnt += 1
counted.add(door)
counted.add(door.dest)
if door.type != DoorType.SpiralStairs:
counted.add(door.dest)
return cnt
@@ -1069,15 +1070,6 @@ def invalid_self_locking_key(state, prev_state, prev_avail, world, player):
return prev_avail - 1 == 0
# does not allow dest doors
def count_unique_sm_doors(doors):
unique_d_set = set()
for d in doors:
if d not in unique_d_set and d.dest not in unique_d_set and not d.bigKey:
unique_d_set.add(d)
return len(unique_d_set)
def enough_small_locations(state, avail_small_loc):
unique_d_set = set()
for exp_door in state.small_doors:

View File

@@ -148,6 +148,7 @@ def roll_settings(weights):
ret.shuffle = entrance_shuffle if entrance_shuffle != 'none' else 'vanilla'
door_shuffle = get_choice('door_shuffle')
ret.door_shuffle = door_shuffle if door_shuffle != 'none' else 'vanilla'
ret.experimental = get_choice('experimental') == 'on'
goal = get_choice('goals')
ret.goal = {'ganon': 'ganon',
@@ -156,7 +157,7 @@ def roll_settings(weights):
'pedestal': 'pedestal',
'triforce-hunt': 'triforcehunt'
}[goal]
ret.openpyramid = goal == 'fast_ganon'
ret.openpyramid = goal == 'fast_ganon' if ret.shuffle in ['vanilla', 'dungeonsfull', 'dungeonssimple'] else False
ret.crystals_gt = get_choice('tower_open')

View File

@@ -36,10 +36,6 @@ Doors are shuffled between dungeons as well.
Doors are not shuffled.
### Experimental
Used for development testing. This will be removed in a future version. Use at your own risk. Might play like a plando.
## Map/Compass/Small Key/Big Key shuffle (aka Keysanity)
These settings allow dungeon specific items to be distributed anywhere in the world and not just in their native dungeon.

2
Rom.py
View File

@@ -591,7 +591,7 @@ def patch_rom(world, rom, player, team, enemized):
patch_shuffled_dark_sanc(world, rom, player)
# patch doors
dr_flags = DROptions.Eternal_Mini_Bosses if not world.experimental[player] else DROptions.Town_Portal
dr_flags = DROptions.Eternal_Mini_Bosses if world.doorShuffle[player] == 'vanilla' or not world.experimental[player] else DROptions.Town_Portal
if world.doorShuffle[player] == 'crossed':
rom.write_byte(0x139004, 2)
rom.write_byte(0x151f1, 2)

View File

@@ -1,11 +1,12 @@
from tkinter import ttk, StringVar, Entry, Frame, Label, N, E, W, LEFT, RIGHT, X, VERTICAL, Y
from tkinter import ttk, Frame, N, LEFT, VERTICAL, Y
import gui.widgets as widgets
import json
import os
import classes.constants as CONST
def custom_page(top,parent):
def custom_page(top, parent):
# Custom Item Pool
self = ttk.Frame(parent)
@@ -31,24 +32,24 @@ def custom_page(top,parent):
# Custom Item Pool option sections
self.frames = {}
create_list_frame(self,"itemList1")
create_list_frame(self, "itemList1")
create_vertical_rule(2)
create_list_frame(self,"itemList2")
create_list_frame(self, "itemList2")
create_vertical_rule(2)
create_list_frame(self,"itemList3")
create_list_frame(self, "itemList3")
create_vertical_rule(2)
create_list_frame(self,"itemList4")
create_list_frame(self, "itemList4")
create_vertical_rule(2)
create_list_frame(self,"itemList5")
create_list_frame(self, "itemList5")
with open(os.path.join("resources","app","gui","custom","overview","widgets.json")) as widgetDefns:
with open(os.path.join("resources", "app", "gui", "custom", "overview", "widgets.json")) as widgetDefns:
myDict = json.load(widgetDefns)
for framename,theseWidgets in myDict.items():
dictWidgets = widgets.make_widgets_from_dict(self, theseWidgets, self.frames[framename])
for key in dictWidgets:
self.customWidgets[key] = dictWidgets[key]
for key in CONST.CUSTOMITEMS:
self.customWidgets[key].storageVar.set(top.settings["customitemarray"][key])
for i, key in enumerate(CONST.CUSTOMITEMS):
self.customWidgets[key].storageVar.set(top.settings["customitemarray"][i])
return self