Bringing in Unstable2 changes
This commit is contained in:
@@ -148,7 +148,9 @@ class World(object):
|
||||
region.world = self
|
||||
self._region_cache[region.player][region.name] = region
|
||||
for exit in region.exits:
|
||||
self._entrance_cache[(exit.name, exit.player)] = exit
|
||||
self._entrance_cache[exit.name, exit.player] = exit
|
||||
for r_location in region.locations:
|
||||
self._location_cache[r_location.name, r_location.player] = r_location
|
||||
|
||||
def initialize_doors(self, doors):
|
||||
for door in doors:
|
||||
|
||||
@@ -2418,7 +2418,7 @@ interior_doors = [
|
||||
('Skull Pull Switch S', 'Skull Big Chest N'),
|
||||
('Skull Left Drop ES', 'Skull Compass Room WS'),
|
||||
('Skull 2 East Lobby NW', 'Skull Big Key SW'),
|
||||
('Skull Big Key WN', 'Skull Lone Pot EN'),
|
||||
('Skull Big Key EN', 'Skull Lone Pot WN'),
|
||||
('Skull Small Hall WS', 'Skull 2 West Lobby ES'),
|
||||
('Skull 2 West Lobby NW', 'Skull X Room SW'),
|
||||
('Skull 3 Lobby EN', 'Skull East Bridge WN'),
|
||||
|
||||
5
Doors.py
5
Doors.py
@@ -541,8 +541,8 @@ def create_doors(world, player):
|
||||
create_door(player, 'Skull 2 East Lobby WS', Nrml).dir(We, 0x57, Bot, High).pos(4),
|
||||
create_door(player, 'Skull 2 East Lobby NW', Intr).dir(No, 0x57, Left, High).pos(1),
|
||||
create_door(player, 'Skull Big Key SW', Intr).dir(So, 0x57, Left, High).pos(1),
|
||||
create_door(player, 'Skull Big Key WN', Intr).dir(We, 0x57, Top, High).pos(0),
|
||||
create_door(player, 'Skull Lone Pot EN', Intr).dir(Ea, 0x57, Top, High).pos(0),
|
||||
create_door(player, 'Skull Big Key EN', Intr).dir(Ea, 0x57, Top, High).pos(0),
|
||||
create_door(player, 'Skull Lone Pot WN', Intr).dir(We, 0x57, Top, High).pos(0),
|
||||
create_door(player, 'Skull Small Hall ES', Nrml).dir(Ea, 0x56, Bot, High).pos(3),
|
||||
create_door(player, 'Skull Small Hall WS', Intr).dir(We, 0x56, Bot, High).pos(2),
|
||||
create_door(player, 'Skull 2 West Lobby S', Nrml).dir(So, 0x56, Left, High).pos(1).portal(Z, 0x00),
|
||||
@@ -1304,7 +1304,6 @@ def create_doors(world, player):
|
||||
world.get_door('GT Petting Zoo SE', player).dead_end()
|
||||
world.get_door('GT DMs Room SW', player).dead_end()
|
||||
world.get_door("GT Bob\'s Room SE", player).passage = False
|
||||
world.get_door('PoD Mimics 2 SW', player).bk_shuffle_req = True
|
||||
world.get_door('Desert Tiles 2 SE', player).bk_shuffle_req = True # key-drop note (todo)
|
||||
world.get_door('Swamp Lobby S', player).standard_restricted = True # key-drop note (todo)
|
||||
|
||||
|
||||
@@ -579,7 +579,7 @@ def progressive_ctr(new_counter, last_counter):
|
||||
def unique_child_door(child, key_counter):
|
||||
if child in key_counter.child_doors or child.dest in key_counter.child_doors:
|
||||
return False
|
||||
if child in key_counter.open_doors or child.dest in key_counter.child_doors:
|
||||
if child in key_counter.open_doors or child.dest in key_counter.open_doors:
|
||||
return False
|
||||
if child.bigKey and key_counter.big_key_opened:
|
||||
return False
|
||||
@@ -589,7 +589,7 @@ def unique_child_door(child, key_counter):
|
||||
def unique_child_door_2(child, key_counter):
|
||||
if child in key_counter.child_doors or child.dest in key_counter.child_doors:
|
||||
return False
|
||||
if child in key_counter.open_doors or child.dest in key_counter.child_doors:
|
||||
if child in key_counter.open_doors or child.dest in key_counter.open_doors:
|
||||
return False
|
||||
return True
|
||||
|
||||
@@ -1463,7 +1463,10 @@ def create_odd_key_counter(door, parent_counter, key_layout, world, player):
|
||||
next_counter = find_next_counter(door, parent_counter, key_layout)
|
||||
odd_counter.free_locations = dict_difference(next_counter.free_locations, parent_counter.free_locations)
|
||||
odd_counter.key_only_locations = dict_difference(next_counter.key_only_locations, parent_counter.key_only_locations)
|
||||
odd_counter.child_doors = dict_difference(next_counter.child_doors, parent_counter.child_doors)
|
||||
odd_counter.child_doors = {}
|
||||
for d in next_counter.child_doors:
|
||||
if d not in parent_counter.child_doors and (d.type == DoorType.SpiralStairs or d.dest not in parent_counter.child_doors):
|
||||
odd_counter.child_doors[d] = None
|
||||
odd_counter.other_locations = dict_difference(next_counter.other_locations, parent_counter.other_locations)
|
||||
odd_counter.important_locations = dict_difference(next_counter.important_locations, parent_counter.important_locations)
|
||||
for loc in odd_counter.other_locations:
|
||||
|
||||
3
Main.py
3
Main.py
@@ -401,12 +401,13 @@ def copy_world(world):
|
||||
copied_shop.inventory = copy.copy(shop.inventory)
|
||||
|
||||
# connect copied world
|
||||
copied_locations = {(loc.name, loc.player): loc for loc in ret.get_locations()} # caches all locations
|
||||
for region in world.regions:
|
||||
copied_region = ret.get_region(region.name, region.player)
|
||||
copied_region.is_light_world = region.is_light_world
|
||||
copied_region.is_dark_world = region.is_dark_world
|
||||
copied_region.dungeon = region.dungeon
|
||||
copied_region.locations = [ret.get_location(location.name, location.player) for location in region.locations]
|
||||
copied_region.locations = [copied_locations[(location.name, location.player)] for location in region.locations]
|
||||
for entrance in region.entrances:
|
||||
ret.get_entrance(entrance.name, entrance.player).connect(copied_region)
|
||||
|
||||
|
||||
@@ -122,15 +122,32 @@ Added to CLI only now.
|
||||
The Mystery.py file has been updated for those who like to use that for generating games. Supports keydropshuffle,
|
||||
shopsanity, and other settings that have been included.
|
||||
|
||||
## Experimental Item Counter
|
||||
|
||||
New item counter modified to show total
|
||||
|
||||
# Bug Fixes
|
||||
|
||||
* 0.3.1.1-u
|
||||
* 0.3.1.0-u
|
||||
* Shopsanity introduced
|
||||
* Minor fix to Standard generation
|
||||
* 0.3.0.4-u
|
||||
* QoL fixes from Mike
|
||||
* Allow PoD Mimics 2 as a lobby in non-keysanity seeds (Thanks @Catobat)
|
||||
* Fix for double-counting Hera key in keydropshuffle
|
||||
* 0.3.0.3-u
|
||||
* Disallowed Swamp Lobby in Hyrule Castle in Standard mode
|
||||
* Prevent defeating Aga 1 before Zelda is delivered to the Sanctuary. (He can't take damage)
|
||||
* Fix for Ice Jelly room when going backward and enemizer is on
|
||||
* Fix for inverted - don't start as a bunny in Dark Sanctuary
|
||||
* Fix for non-ER Inverted with Lobby shuffle. Aga Tower's exit works properly now.
|
||||
* Minor fix to Standard generation
|
||||
* Fix for In-Room Stairs with Trap Doors
|
||||
* Key logic fix
|
||||
* Fix for door gen re-start
|
||||
* More lenient keys in DR+Retro
|
||||
* Fix for shufflepots option
|
||||
* 0.3.0.2-u
|
||||
* Introduced in-room staircases/ladders
|
||||
* 0.3.0.1-u
|
||||
* Problem with lobbies on re-rolls corrected
|
||||
* Potential playthrough problem addressed
|
||||
|
||||
@@ -473,8 +473,8 @@ def create_dungeon_regions(world, player):
|
||||
create_dungeon_region(player, 'Skull Compass Room', 'Skull Woods', ['Skull Woods - Compass Chest'], ['Skull Compass Room NE', 'Skull Compass Room ES', 'Skull Compass Room WS']),
|
||||
create_dungeon_region(player, 'Skull Left Drop', 'Skull Woods', None, ['Skull Left Drop ES']),
|
||||
create_dungeon_region(player, 'Skull 2 East Lobby', 'Skull Woods', None, ['Skull 2 East Lobby NW', 'Skull 2 East Lobby WS', 'Skull 2 East Lobby SW']),
|
||||
create_dungeon_region(player, 'Skull Big Key', 'Skull Woods', ['Skull Woods - Big Key Chest'], ['Skull Big Key SW', 'Skull Big Key WN']),
|
||||
create_dungeon_region(player, 'Skull Lone Pot', 'Skull Woods', None, ['Skull Lone Pot EN']),
|
||||
create_dungeon_region(player, 'Skull Big Key', 'Skull Woods', ['Skull Woods - Big Key Chest'], ['Skull Big Key SW', 'Skull Big Key EN']),
|
||||
create_dungeon_region(player, 'Skull Lone Pot', 'Skull Woods', None, ['Skull Lone Pot WN']),
|
||||
create_dungeon_region(player, 'Skull Small Hall', 'Skull Woods', None, ['Skull Small Hall ES', 'Skull Small Hall WS']),
|
||||
create_dungeon_region(player, 'Skull Back Drop', 'Skull Woods', None, ['Skull Back Drop Star Path', ]),
|
||||
create_dungeon_region(player, 'Skull 2 West Lobby', 'Skull Woods', ['Skull Woods - West Lobby Pot Key'], ['Skull 2 West Lobby ES', 'Skull 2 West Lobby NW', 'Skull 2 West Lobby S']),
|
||||
|
||||
4
Rom.py
4
Rom.py
@@ -27,7 +27,7 @@ from EntranceShuffle import door_addresses, exit_ids
|
||||
|
||||
|
||||
JAP10HASH = '03a63945398191337e896e5771f77173'
|
||||
RANDOMIZERBASEHASH = '6a4096235f682b7e4e1a65f274c7037b'
|
||||
RANDOMIZERBASEHASH = '0a34dc667a29125f09b10aeb1e06b83c'
|
||||
|
||||
|
||||
class JsonRom(object):
|
||||
@@ -942,8 +942,6 @@ def patch_rom(world, rom, player, team, enemized, is_mystery=False):
|
||||
|
||||
if difficulty.progressive_bow_limit < 2 and world.swords == 'swordless':
|
||||
rom.write_bytes(0x180098, [2, overflow_replacement])
|
||||
rom.write_byte(0x180181, 0x01) # Make silver arrows work only on ganon
|
||||
rom.write_byte(0x180182, 0x00) # Don't auto equip silvers on pickup
|
||||
|
||||
# set up game internal RNG seed
|
||||
for i in range(1024):
|
||||
|
||||
@@ -200,3 +200,14 @@ $bc - TT 188 idx 1
|
||||
; called by 10CE2, (Dungeon_SpiralStaircase_3)
|
||||
;122f0
|
||||
|
||||
|
||||
Link's position after screen transition and auto-walk (from $02C034):
|
||||
|
||||
0C 20 30 38 48 ; down
|
||||
D4 D8 C0 C0 A8 ; up
|
||||
0C 18 28 30 40 ; right
|
||||
E4 D8 C8 C0 B0 ; left
|
||||
|
||||
Effectively indexed by $0418*#$05+$4E.
|
||||
Row ($0418) is the direction and column ($4E) determines how far to auto-walk (depends on tile attribute at edge of screen).
|
||||
From left to right: edge, inside high door, outside high door, inside low door and outside low door.
|
||||
|
||||
@@ -170,10 +170,10 @@ InroomStairsWarp: {
|
||||
; should be the same as lda $0462 : and #$04 : lsr #2 : eor #$01 : sta $07
|
||||
lda $01 : and #$80 : beq .notEdge
|
||||
lda $07 : sta $03 : beq +
|
||||
lda $01 : jsr LoadSouthMidpoint : sta $22 : lda #$e0
|
||||
lda $01 : jsr LoadSouthMidpoint : sta $22 : lda #$f4
|
||||
bra ++
|
||||
+
|
||||
lda $01 : jsr LoadNorthMidpoint : sta $22 : lda #$1b
|
||||
lda $01 : jsr LoadNorthMidpoint : sta $22 : dec $21 : lda #$f7
|
||||
++
|
||||
sta $20
|
||||
lda $01 : and #$20 : beq +
|
||||
@@ -185,26 +185,36 @@ InroomStairsWarp: {
|
||||
brl .layer
|
||||
.notEdge
|
||||
lda $01 : and #$03 : cmp #$03 : bne .normal
|
||||
txa : and #$06 : sta $07
|
||||
lda $01 : and #$30 : lsr #3 : tay
|
||||
lda.w InroomStairsX,y : sta $22
|
||||
lda.w InroomStairsX+1,y : sta $02
|
||||
lda.w InroomStairsY+1,y : sta $03
|
||||
lda.w InroomStairsY,y
|
||||
ldy $07 : beq +
|
||||
!add #$07
|
||||
+
|
||||
sta $20
|
||||
cpy $07 : beq .vanillaTransition
|
||||
lda.w InroomStairsX,y : sta $22
|
||||
lda.w InroomStairsY,y
|
||||
ldy $07 : beq +
|
||||
!add #$07
|
||||
+
|
||||
sta $20
|
||||
inc $07
|
||||
bra ++
|
||||
.vanillaTransition
|
||||
lda #$c0 : sta $07 ; leave camera
|
||||
++
|
||||
%StonewallCheck($1b)
|
||||
inc $07
|
||||
lda $01 : and #$04 : lsr #2
|
||||
bra .layer
|
||||
.normal
|
||||
lda $01 : sta $fe ; trap door
|
||||
lda $07 : sta $03 : beq +
|
||||
ldy $a0 : cpy #$51 : beq .specialFix ; throne room
|
||||
cpy #$02 : beq .specialFix ; sewers pull switch
|
||||
cpy #$71 : beq .specialFix ; castle armory
|
||||
lda #$e0
|
||||
ldy $a0 : cpy #$51 : bne ++ ; special fix for throne room
|
||||
!sub #$18
|
||||
bra ++
|
||||
bra ++
|
||||
.specialFix
|
||||
lda #$c8
|
||||
bra ++
|
||||
+
|
||||
%StonewallCheck($43)
|
||||
lda #$1b
|
||||
@@ -235,12 +245,15 @@ InroomStairsWarp: {
|
||||
ldy #$01 : jsr ShiftQuadSimple
|
||||
.skipYQuad
|
||||
|
||||
lda $07 : bmi .skipCamera
|
||||
ldy #$00 : jsr SetCamera ; horizontal camera
|
||||
ldy #$01 : sty $07 : jsr SetCamera ; vertical camera
|
||||
lda $20 : cmp #$e0 : bcc +
|
||||
lda $e8 : bne +
|
||||
lda #$10 : sta $e8 ; adjust vertical camera at bottom
|
||||
+
|
||||
.skipCamera
|
||||
|
||||
jsr StairCleanup
|
||||
ply : plx : plb ; pull the stuff we pushed
|
||||
rts
|
||||
|
||||
Binary file not shown.
@@ -43,7 +43,7 @@ class SpriteSelector(object):
|
||||
|
||||
# Open SpriteSomething directory for Link sprites
|
||||
def open_spritesomething_listing(_evt):
|
||||
webbrowser.open("https://artheau.github.io/SpriteSomething/resources/app/snes/zelda3/link/sprites.html")
|
||||
webbrowser.open("https://miketrethewey.github.io/SpriteSomething-collections/snes/zelda3/link/")
|
||||
|
||||
official_frametitle = Frame(self.window)
|
||||
official_title_text = Label(official_frametitle, text="Official Sprites")
|
||||
|
||||
@@ -1,8 +1,11 @@
|
||||
from tkinter import ttk, filedialog, StringVar, Button, Entry, Frame, Label, E, W, LEFT, X
|
||||
from tkinter import ttk, filedialog, StringVar, Button, Entry, Frame, Label, E, W, LEFT, X, Text, Tk, INSERT
|
||||
import source.classes.diags as diagnostics
|
||||
import source.gui.widgets as widgets
|
||||
import json
|
||||
import os
|
||||
from functools import partial
|
||||
from source.classes.Empty import Empty
|
||||
from Main import __version__
|
||||
|
||||
def generation_page(parent,settings):
|
||||
# Generation Setup
|
||||
@@ -76,4 +79,45 @@ def generation_page(parent,settings):
|
||||
# frame: pack
|
||||
self.widgets[widget].pieces["frame"].pack(fill=X)
|
||||
|
||||
## Run Diagnostics
|
||||
# This one's more-complicated, build it and stuff it
|
||||
# widget ID
|
||||
widget = "diags"
|
||||
|
||||
# Empty object
|
||||
self.widgets[widget] = Empty()
|
||||
# pieces
|
||||
self.widgets[widget].pieces = {}
|
||||
|
||||
# frame
|
||||
self.frames["diags"] = Frame(self)
|
||||
self.frames["diags"].pack()
|
||||
self.widgets[widget].pieces["frame"] = Frame(self.frames["diags"])
|
||||
|
||||
|
||||
def diags():
|
||||
# Debugging purposes
|
||||
dims = {
|
||||
"window": {
|
||||
"width": 800,
|
||||
"height": 500
|
||||
},
|
||||
"textarea.characters": {
|
||||
"width": 120,
|
||||
"height": 50
|
||||
}
|
||||
}
|
||||
diag = Tk()
|
||||
diag.title("Door Shuffle " + __version__)
|
||||
diag.geometry(str(dims["window"]["width"]) + 'x' + str(dims["window"]["height"]))
|
||||
text = Text(diag, width=dims["textarea.characters"]["width"], height=dims["textarea.characters"]["height"])
|
||||
text.pack()
|
||||
text.insert(INSERT,"\n".join(diagnostics.output(__version__)))
|
||||
# dialog button
|
||||
self.widgets[widget].pieces["button"] = Button(self.widgets[widget].pieces["frame"], text='Run Diagnostics', command=partial(diags))
|
||||
|
||||
# button: pack
|
||||
self.widgets[widget].pieces["button"].pack(side=LEFT)
|
||||
# frame: pack
|
||||
self.widgets[widget].pieces["frame"].pack(fill=X)
|
||||
return self,settings
|
||||
|
||||
Reference in New Issue
Block a user