Fix trock entrances when intensity >= 3
Keysanity menu countdowns Standard rain state Multi-entrance dungeon bosses This dungeon/universl key drops skip pose More rupee candidates to remove for retro
This commit is contained in:
@@ -1499,6 +1499,10 @@ class Portal(object):
|
||||
self.deadEnd = False
|
||||
self.light_world = False
|
||||
|
||||
def change_boss_exit(self, exit_idx):
|
||||
self.default = False
|
||||
self.boss_exit_idx = exit_idx
|
||||
|
||||
def change_door(self, new_door):
|
||||
if new_door != self.door:
|
||||
self.default = False
|
||||
|
||||
@@ -369,6 +369,9 @@ def choose_portals(world, player):
|
||||
sanc = world.get_portal('Sanctuary', player)
|
||||
sanc.destination = True
|
||||
clean_up_portal_assignment(portal_assignment, dungeon, sanc, master_door_list, outstanding_portals)
|
||||
for target_region, possible_portals in info.required_passage.items():
|
||||
info.required_passage[target_region] = [x for x in possible_portals if x != sanc.name]
|
||||
info.required_passage = {x: y for x, y in info.required_passage.items() if len(y) > 0}
|
||||
for target_region, possible_portals in info.required_passage.items():
|
||||
candidates = find_portal_candidates(master_door_list, dungeon, need_passage=True, crossed=cross_flag,
|
||||
bk_shuffle=bk_shuffle)
|
||||
@@ -596,6 +599,8 @@ def create_dungeon_entrances(world, player):
|
||||
filtered_choices = [x for x in choices if any(y not in world.inaccessible_regions[player] for y in originating[key][x].keys())]
|
||||
else:
|
||||
filtered_choices = dest_choices
|
||||
if len(filtered_choices) == 0:
|
||||
raise Exception('No valid destinations')
|
||||
choice = random.choice(filtered_choices)
|
||||
r_name = portal.door.entrance.parent_region.name
|
||||
split_map[key][choice].append(r_name)
|
||||
@@ -650,6 +655,8 @@ def within_dungeon(world, player):
|
||||
target = portal.door.entrance.parent_region
|
||||
connect_simple_door(world, 'Sanctuary Mirror Route', target, player)
|
||||
|
||||
refine_boss_exits(world, player)
|
||||
|
||||
|
||||
def handle_split_dungeons(dungeon_builders, recombinant_builders, entrances_map, builder_info):
|
||||
dungeon_entrances, split_dungeon_entrances, world, player = builder_info
|
||||
@@ -943,6 +950,7 @@ def cross_dungeon(world, player):
|
||||
palette_assignment(world, player)
|
||||
|
||||
refine_hints(dungeon_builders)
|
||||
refine_boss_exits(world, player)
|
||||
|
||||
|
||||
def assign_cross_keys(dungeon_builders, world, player):
|
||||
@@ -1138,6 +1146,44 @@ def refine_hints(dungeon_builders):
|
||||
location.hint_text = dungeon_hints[name]
|
||||
|
||||
|
||||
def refine_boss_exits(world, player):
|
||||
for d_name, d_boss in {'Desert Palace': 'Desert Boss',
|
||||
'Skull Woods': 'Skull Boss',
|
||||
'Turtle Rock': 'TR Boss'}.items():
|
||||
possible_portals = []
|
||||
current_boss = None
|
||||
for portal_name in dungeon_portals[d_name]:
|
||||
portal = world.get_portal(portal_name, player)
|
||||
if not portal.destination:
|
||||
possible_portals.append(portal)
|
||||
if portal.boss_exit_idx > -1:
|
||||
current_boss = portal
|
||||
if len(possible_portals) == 1:
|
||||
if possible_portals[0] != current_boss:
|
||||
possible_portals[0].change_boss_exit(current_boss.boss_exit_idx)
|
||||
current_boss.change_boss_exit(-1)
|
||||
else:
|
||||
reachable_portals = []
|
||||
for portal in possible_portals:
|
||||
start_area = portal.door.entrance.parent_region
|
||||
state = ExplorationState(dungeon=d_name)
|
||||
state.visit_region(start_area)
|
||||
state.add_all_doors_check_unattached(start_area, world, player)
|
||||
explore_state_not_inaccessible(state, world, player)
|
||||
if state.visited_at_all(world.get_region(d_boss, player)):
|
||||
reachable_portals.append(portal)
|
||||
if len(reachable_portals) == 0:
|
||||
reachable_portals = possible_portals
|
||||
unreachable = world.inaccessible_regions[player]
|
||||
filtered = [x for x in reachable_portals if x.door.entrance.connected_region.name not in unreachable]
|
||||
if 0 < len(filtered) < len(reachable_portals):
|
||||
reachable_portals = filtered
|
||||
chosen_one = random.choice(reachable_portals) if len(reachable_portals) > 1 else reachable_portals[0]
|
||||
if chosen_one != current_boss:
|
||||
chosen_one.change_boss_exit(current_boss.boss_exit_idx)
|
||||
current_boss.change_boss_exit(-1)
|
||||
|
||||
|
||||
def convert_to_sectors(region_names, world, player):
|
||||
region_list = convert_regions(region_names, world, player)
|
||||
sectors = []
|
||||
@@ -1806,6 +1852,15 @@ def explore_state(state, world, player):
|
||||
state.add_all_doors_check_unattached(connect_region, world, player)
|
||||
|
||||
|
||||
def explore_state_not_inaccessible(state, world, player):
|
||||
while len(state.avail_doors) > 0:
|
||||
door = state.next_avail_door().door
|
||||
connect_region = world.get_entrance(door.name, player).connected_region
|
||||
if state.can_traverse(door) and not state.visited(connect_region) and connect_region.type == RegionType.Dungeon:
|
||||
state.visit_region(connect_region)
|
||||
state.add_all_doors_check_unattached(connect_region, world, player)
|
||||
|
||||
|
||||
def check_if_regions_visited(state, check_paths):
|
||||
valid = False
|
||||
breaking_region = None
|
||||
|
||||
@@ -1,34 +1,78 @@
|
||||
# New Features
|
||||
|
||||
* Lobby shuffle added as Intensity level 3
|
||||
* Can now be found in the spoiler
|
||||
* Palette changes:
|
||||
* Certain doors/transition no longer have an effect on the palette choice (dead ends mostly or just bridges)
|
||||
* Sanctuary palette back to the adjacent rooms to Sanctuary (sanctuary stays the dungeon color for now)
|
||||
* Sewer palette comes back for part of Hyrule Castle for areas "near" the sewer dropdown
|
||||
* Known issues:
|
||||
* Palettes aren't perfect
|
||||
May add a way to turn off palette "fixing"
|
||||
* Some ugly colors
|
||||
* Invisible floors can be see in many palettes
|
||||
* --keydropshuffle added (coming to the GUI soon). This add 33 new locations to the game where keys are found under pots
|
||||
## Lobby shuffle added as Intensity level 3
|
||||
|
||||
* Standard notes:
|
||||
* The sanctuary is vanilla, and will be missing the exit door until Zelda is rescued
|
||||
* In entrance shuffle the hyrule castle left and right exit door will be missing until Zelda is rescued. This
|
||||
replaces the rails that used to block those lobby exits
|
||||
* In non-entrance shuffle, Agahnims tower can be in logic if you have cape and/or Master sword, but you are never
|
||||
required to beat Agahnim 1 until Zelda is rescued.
|
||||
* Open notes:
|
||||
* The Sanctuary is limited to be in a LW dungeon unless you have ER Crossed or higher enabled
|
||||
* Mirroring from the Sanctuary to the new "Sanctuary" lobby is now in logic, as is exiting there.
|
||||
* In ER crossed or higher, if the Sanctuary is in the Dark World, Link starts as Bunny there until the Moon Pearl
|
||||
is found. Nothing inside that dungeon is in logic until the Moon Pearl is found. (Unless it is a multi-entrance
|
||||
dungeon that you can access from some LW entrance)
|
||||
* Lobby list is found in the spoiler
|
||||
* Exits for Multi-entrance dungeons after beating bosses now makes more sense. Generally you'll exit from a entrance
|
||||
from which the boss can logically be reached. If there are multiple, ones that do not lead to regions only accessible
|
||||
by connector are preferred. The exit is randomly chosen if there's no obvious preference. However, In certain poor
|
||||
cases like Skull Woods in ER, sometimes an exit is chosen not because you can reach the boss from there, but to
|
||||
prevent a potential forced S&Q.
|
||||
* Palette changes:
|
||||
* Certain doors/transition no longer have an effect on the palette choice (dead ends mostly or just bridges)
|
||||
* Sanctuary palette used on the adjacent rooms to Sanctuary (Sanctuary stays the dungeon color for now)
|
||||
* Sewer palette comes back for part of Hyrule Castle for areas "near" the sewer dropdown
|
||||
* There is a setting to keep original palettes (--standardize_palettes original)
|
||||
* Known issues:
|
||||
* Palettes aren't perfect
|
||||
* Some ugly colors
|
||||
* Invisible floors can be see in many palettes
|
||||
|
||||
## Key Drop Shuffle
|
||||
|
||||
--keydropshuffle added. This add 33 new locations to the game where keys are found under pots
|
||||
and where enemies drop keys. This includes 32 small key location and the ball and chain guard who normally drop the HC
|
||||
Big Key.
|
||||
* Overall location count updated
|
||||
* Setting mentioned in spoiler
|
||||
* Known issue:
|
||||
* GT Big Key count needs to be updated
|
||||
* --mixed_travel setting added
|
||||
* Due to Hammerjump, Hovering in PoD Arena, and the Mire Big Key Chest bomb jump two sections of a supertile that are
|
||||
|
||||
* Overall location count updated
|
||||
* Setting mentioned in spoiler
|
||||
* Minor change: if a key is Universal or for that dungeon, then if will use the old mechanics of picking up the key without
|
||||
an entire pose and should be obtainable with the hookshot or boomerang as before
|
||||
|
||||
## --mixed_travel setting
|
||||
* Due to Hammerjump, Hovering in PoD Arena, and the Mire Big Key Chest bomb jump two sections of a supertile that are
|
||||
otherwise unconnected logically can be reach using these glitches. To prevent the player from unintentionally
|
||||
* prevent: Rails are added the 3 spots to prevent this tricks. This setting is recommend for those learning
|
||||
crossed dungeon mode to learn what is dangerous and what is not. No logic seeds ignore this setting.
|
||||
* allow: The rooms are left alone and it is up to the discretion of the player whether to use these tricks or not.
|
||||
* force: The two disjointed sections are forced to be in the same dungeon but never logically required to complete that game.
|
||||
* prevent: Rails are added the 3 spots to prevent this tricks. This setting is recommend for those learning
|
||||
crossed dungeon mode to learn what is dangerous and what is not. No logic seeds ignore this setting.
|
||||
* allow: The rooms are left alone and it is up to the discretion of the player whether to use these tricks or not.
|
||||
* force: The two disjointed sections are forced to be in the same dungeon but never logically required to complete that game.
|
||||
|
||||
## Keysanity menu redesign
|
||||
|
||||
Redesign of Keysanity Menu complete for crossed dungeon and moved out of experimental.
|
||||
* First screen about Big Keys and Small Keys
|
||||
* 1st Column: The map is required for information about the Big Key
|
||||
* If you don't have the map, it'll be blank until you obtain the Big Key
|
||||
* If have the map:
|
||||
* 0 indicates there is no Big Key for that dungeon
|
||||
* A red symbol indicates the Ball N Chain guard has the big key for that dungeon (does not apply in
|
||||
--keydropshuffle)
|
||||
* Blank if there a big key but you haven't found it yet
|
||||
* 2nd Column displays the current number of keys for that dungeon. Suppressed in retro (always blank)
|
||||
* 3rd Column only display if you have the map. It shows the number of keys left to collect for that dungeon. If
|
||||
--keydropshuffle is off, this does not count key drops. If on, it does.
|
||||
* (Note: the key columns can display up to 36 using the letters A-Z after 9)
|
||||
* Second screen about Maps / Compass
|
||||
* 1st Column: indicate if you have foudn the map of not for that dungeon
|
||||
* 2nd and 3rd Column: You must have the compass to see these columns. A two-digit display that show you how
|
||||
many chests are left in the dungeon. If -keydropshuffle is off, this does not count key drop. If on, it does.
|
||||
|
||||
### Experimental features
|
||||
|
||||
* Redesign of Keysanity Menu for Crossed Dungeon - soon to move out of experimental
|
||||
* Only the random bomb doors and the item counter are currently experimental
|
||||
* Item counter is suppressed in Triforce Hunt
|
||||
|
||||
#### Temporary debug features
|
||||
|
||||
@@ -37,12 +81,12 @@ otherwise unconnected logically can be reach using these glitches. To prevent th
|
||||
# Bug Fixes
|
||||
|
||||
* 2.0.12u
|
||||
* Option to keep original palettes in crossed dungeon mode
|
||||
* If sanc if in a DW dungeon because of crossed+ ER, then you start in bunny form
|
||||
* Mirroring from sanc to the portal is now in logic
|
||||
* Another fix for animated tiles (fairy fountains)
|
||||
* GT Big Key stat fixed on credits
|
||||
* Todo: Standard logic fixes for lobbies
|
||||
* Any denomination of rupee 20 or below can be removed to make room for Crossed Dungeon's extra dungeon items. This
|
||||
helps retro generate more often.
|
||||
* Fix for TR Lobbies in intensity 3 and ER shuffles that was causing a hardlock
|
||||
* Standard ER logic revised for lobby shuffle and rain state considerations.
|
||||
* 2.0.11u
|
||||
* Fix output path setting in settings.json
|
||||
* Fix trock entrances when intensity <= 2
|
||||
|
||||
39
Rom.py
39
Rom.py
@@ -26,7 +26,7 @@ from EntranceShuffle import door_addresses, exit_ids
|
||||
|
||||
|
||||
JAP10HASH = '03a63945398191337e896e5771f77173'
|
||||
RANDOMIZERBASEHASH = 'f6be3fdaac906a2217e7ee328e27b95b'
|
||||
RANDOMIZERBASEHASH = '87fb1ec80d48487a84eac3a0a9bf9e04'
|
||||
|
||||
|
||||
class JsonRom(object):
|
||||
@@ -648,16 +648,17 @@ def patch_rom(world, rom, player, team, enemized):
|
||||
for name, layout in world.key_layout[player].items():
|
||||
offset = compass_data[name][4]//2
|
||||
if world.retro[player]:
|
||||
rom.write_byte(0x13f02a+offset, layout.max_chests + layout.max_drops)
|
||||
rom.write_byte(0x13f030+offset, layout.max_chests + layout.max_drops)
|
||||
else:
|
||||
rom.write_byte(0x13f01c+offset, layout.max_chests + layout.max_drops) # not currently used
|
||||
rom.write_byte(0x13f02a+offset, layout.max_chests)
|
||||
rom.write_byte(0x13f020+offset, layout.max_chests + layout.max_drops) # not currently used
|
||||
rom.write_byte(0x13f030+offset, layout.max_chests)
|
||||
builder = world.dungeon_layouts[player][name]
|
||||
rom.write_byte(0x13f070+offset, builder.location_cnt % 10)
|
||||
rom.write_byte(0x13f07e+offset, builder.location_cnt // 10)
|
||||
rom.write_byte(0x13f080+offset, builder.location_cnt % 10)
|
||||
rom.write_byte(0x13f090+offset, builder.location_cnt // 10)
|
||||
rom.write_byte(0x13f0a0+offset, builder.location_cnt)
|
||||
bk_status = 1 if builder.bk_required else 0
|
||||
bk_status = 2 if builder.bk_provided else bk_status
|
||||
rom.write_byte(0x13f038+offset*2, bk_status)
|
||||
rom.write_byte(0x13f040+offset*2, bk_status)
|
||||
if player in world.sanc_portal.keys():
|
||||
rom.write_byte(0x159a6, world.sanc_portal[player].ent_offset)
|
||||
sanc_region = world.sanc_portal[player].door.entrance.parent_region
|
||||
@@ -1282,7 +1283,21 @@ def patch_rom(world, rom, player, team, enemized):
|
||||
rom.write_byte(0x18005F, world.crystals_needed_for_ganon[player])
|
||||
|
||||
# block HC upstairs doors in rain state in standard mode
|
||||
rom.write_byte(0x18008A, 0x01 if world.mode[player] == "standard" and world.shuffle[player] != 'vanilla' else 0x00)
|
||||
prevent_rain = world.mode[player] == "standard" and world.shuffle[player] != 'vanilla'
|
||||
rom.write_byte(0x18008A, 0x01 if prevent_rain else 0x00)
|
||||
# block sanc door in rain state and the dungeon is not vanilla
|
||||
rom.write_byte(0x13f0fa, 0x01 if world.mode[player] == "standard" and world.doorShuffle[player] != 'vanilla' else 0x00)
|
||||
|
||||
if prevent_rain:
|
||||
portals = [world.get_portal('Hyrule Castle East', player), world.get_portal('Hyrule Castle West', player)]
|
||||
for idx, portal in enumerate(portals):
|
||||
x = idx*2
|
||||
room_idx = portal.door.roomIndex
|
||||
room = world.get_room(room_idx, player)
|
||||
rom.write_byte(0x13f0f0+x, room_idx & 0xff)
|
||||
rom.write_byte(0x13f0f1+x, (room_idx >> 8) & 0xff)
|
||||
rom.write_byte(0x13f0f6+x, room.position(portal.door).value)
|
||||
rom.write_byte(0x13f0f7+x, room.kind(portal.door).value)
|
||||
|
||||
rom.write_byte(0x18016A, 0x10 | ((0x01 if world.keyshuffle[player] else 0x00)
|
||||
| (0x02 if world.compassshuffle[player] else 0x00)
|
||||
@@ -1415,9 +1430,11 @@ def patch_rom(world, rom, player, team, enemized):
|
||||
|
||||
# fix trock doors for reverse entrances
|
||||
if world.fix_trock_doors[player]:
|
||||
# do this unconditionally
|
||||
world.get_room(0x23, player).change(0, DoorKind.CaveEntrance)
|
||||
world.get_room(0xd5, player).change(0, DoorKind.CaveEntrance)
|
||||
if world.get_door('TR Lazy Eyes SE', player).entranceFlag:
|
||||
world.get_room(0x23, player).change(0, DoorKind.CaveEntrance)
|
||||
if world.get_door('TR Eye Bridge SW', player).entranceFlag:
|
||||
world.get_room(0xd5, player).change(0, DoorKind.CaveEntrance)
|
||||
# do this unconditionally - gets overwritten by RoomData in doorShufflemodes
|
||||
rom.write_byte(0xFED31, 0x0E) # preopen bombable exit
|
||||
rom.write_byte(0xFEE41, 0x0E) # preopen bombable exit
|
||||
|
||||
|
||||
@@ -263,6 +263,9 @@ class Room(object):
|
||||
self.modified = False
|
||||
self.palette = None
|
||||
|
||||
def position(self, door):
|
||||
return self.doorList[door.doorListPos][0]
|
||||
|
||||
def kind(self, door):
|
||||
return self.doorList[door.doorListPos][1]
|
||||
|
||||
|
||||
11
Rules.py
11
Rules.py
@@ -832,10 +832,13 @@ def standard_rules(world, player):
|
||||
set_rule(world.get_entrance('Sanctuary S&Q', player), lambda state: state.can_reach('Sanctuary', 'Region', player))
|
||||
# these are because of rails
|
||||
if world.shuffle[player] != 'vanilla':
|
||||
# todo:
|
||||
set_rule(world.get_entrance('Hyrule Castle Exit (East)', player), lambda state: state.has('Zelda Delivered', player))
|
||||
set_rule(world.get_entrance('Hyrule Castle Exit (West)', player), lambda state: state.has('Zelda Delivered', player))
|
||||
set_rule(world.get_entrance('Sanctuary Exit', player), lambda state: state.has('Zelda Delivered', player))
|
||||
# where ever these happen to be
|
||||
for portal_name in ['Hyrule Castle East', 'Hyrule Castle West']:
|
||||
entrance = world.get_portal(portal_name, player).door.entrance
|
||||
set_rule(entrance, lambda state: state.has('Zelda Delivered', player))
|
||||
set_rule(world.get_entrance('Sanctuary Exit', player), lambda state: state.has('Zelda Delivered', player))
|
||||
# zelda should be saved before agahnim is in play
|
||||
set_rule(world.get_location('Agahnim 1', player), lambda state: state.has('Zelda Delivered', player))
|
||||
|
||||
# too restrictive for crossed?
|
||||
def uncle_item_rule(item):
|
||||
|
||||
@@ -562,23 +562,26 @@ db $01, $02, $03, $04, $05, $06, $0a, $14
|
||||
; HC HC EP DP AT SP PD MM SW IP TH TT TR GT
|
||||
org $27f000
|
||||
CompassBossIndicator:
|
||||
dw $0000, $0000, $0000, $0000, $0000, $0000, $0000, $0000, $0000, $0000, $0000, $0000, $0000, $0000
|
||||
TotalKeys: ;27f01c
|
||||
db $04, $04, $02, $04, $04, $06, $06, $06, $05, $06, $01, $03, $06, $08
|
||||
ChestKeys: ;27f02a
|
||||
db $01, $01, $00, $01, $02, $01, $06, $03, $03, $02, $01, $01, $04, $04
|
||||
BigKeyStatus: ;27f038 (status 2 indicate BnC guard)
|
||||
dw $0002, $0002, $0001, $0001, $0000, $0001, $0001, $0001, $0001, $0001, $0001, $0001, $0001, $0001
|
||||
DungeonReminderTable: ;27f054
|
||||
dw $2D50, $2D50, $2D51, $2D52, $2D54, $2D56, $2D55, $2D5A, $2D57, $2D59, $2D53, $2D58, $2D5B, $2D5C
|
||||
TotalLocationsLow: ;27f070
|
||||
db $08, $08, $06, $06, $02, $00, $04, $08, $08, $08, $06, $08, $02, $07
|
||||
TotalLocationsHigh: ;27f07e
|
||||
db $00, $00, $00, $00, $00, $01, $01, $00, $00, $00, $00, $00, $01, $02
|
||||
;27F08C
|
||||
dw $0000, $0000, $0000, $0000, $0000, $0000, $0000, $0000, $0000, $0000, $0000, $0000, $0000, $0000, $0000, $0000
|
||||
TotalKeys: ;27f020
|
||||
db $04, $04, $02, $04, $04, $06, $06, $06, $05, $06, $01, $03, $06, $08, $00, $00
|
||||
ChestKeys: ;27f030
|
||||
db $01, $01, $00, $01, $02, $01, $06, $03, $03, $02, $01, $01, $04, $04, $00, $00
|
||||
BigKeyStatus: ;27f040 (status 2 indicate BnC guard)
|
||||
dw $0002, $0002, $0001, $0001, $0000, $0001, $0001, $0001, $0001, $0001, $0001, $0001, $0001, $0001, $0000, $0000
|
||||
DungeonReminderTable: ;27f060
|
||||
dw $2D50, $2D50, $2D51, $2D52, $2D54, $2D56, $2D55, $2D5A, $2D57, $2D59, $2D53, $2D58, $2D5B, $2D5C, $0000, $0000
|
||||
TotalLocationsLow: ;27f080
|
||||
db $08, $08, $06, $06, $02, $00, $04, $08, $08, $08, $06, $08, $02, $07, $00, $00
|
||||
TotalLocationsHigh: ;27f090
|
||||
db $00, $00, $00, $00, $00, $01, $01, $00, $00, $00, $00, $00, $01, $02, $00, $00
|
||||
org $27f0a0
|
||||
TotalLocations:
|
||||
db $08, $08, $06, $06, $02, $0a, $0e, $08, $08, $08, $06, $08, $0c, $1b, $00, $00
|
||||
; no more room here
|
||||
|
||||
; Vert 0,6,0 Horz 2,0,8
|
||||
org $27f090
|
||||
org $27f0b0
|
||||
CoordIndex: ; Horizontal 1st
|
||||
db 2, 0 ; Coordinate Index $20-$23
|
||||
OppCoordIndex:
|
||||
@@ -598,7 +601,16 @@ dw $007f, $0077 ; Left/Top camera bounds when at edge or layout frozen
|
||||
dw $0007, $000b ; Left/Top camera bounds when not frozen + appropriate low byte $22/$20 (preadj. by #$78/#$6c)
|
||||
dw $00ff, $010b ; Right/Bot camera bounds when not frozen + appropriate low byte $20/$22
|
||||
dw $017f, $0187 ; Right/Bot camera bound when at edge or layout frozen
|
||||
;27f0ae next free byte
|
||||
;27f0ce next free byte
|
||||
|
||||
org $27f0f0
|
||||
RemoveRainDoorsRoom:
|
||||
dw $0060, $0062, $ffff ; ffff indicates end of list
|
||||
RainDoorMatch: ; org $27f0f6 and f8 for now
|
||||
dw $0081, $0061 ; not xba'd
|
||||
BlockSanctuaryDoorInRain: ;27f0fa
|
||||
dw $0000
|
||||
|
||||
|
||||
org $27f100
|
||||
TilesetTable:
|
||||
|
||||
@@ -156,6 +156,9 @@ JSL RetrieveBunnyState : NOP
|
||||
org $02d9ce ; <- Bank02.asm : Dungeon_LoadEntrance 10829 (STA $A0 : STA $048E)
|
||||
JSL CheckDarkWorldSanc : NOP
|
||||
|
||||
org $01891e ; <- Bank 01.asm : 991 Dungeon_LoadType2Object (LDA $00 : XBA : AND.w #$00FF)
|
||||
JSL RainPrevention : NOP #2
|
||||
|
||||
; These two, if enabled together, have implications for vanilla BK doors in IP/Hera/Mire
|
||||
; IPBJ is common enough to consider not doing this. Mire is not a concern for vanilla - maybe glitched modes
|
||||
; Hera BK door back can be seen with Pot clipping - likely useful for no logic seeds
|
||||
|
||||
@@ -95,12 +95,18 @@ DrHudDungeonItemsAdditions:
|
||||
+ stx $00
|
||||
txa : lsr : tax
|
||||
lda.w #$24f5 : sta $1644, y
|
||||
lda.l $7ef37c, x : beq +
|
||||
lda.l GenericKeys : bne +
|
||||
lda.l $7ef37c, x : and #$00FF : beq +
|
||||
jsr ConvertToDisplay2 : sta $1644, y
|
||||
+ iny #2 : lda.w #$24f5 : sta $1644, y
|
||||
phx : ldx $00
|
||||
lda $7ef368 : and.l $0098c0, x : beq + ; must have map
|
||||
plx : lda.l ChestKeys, x : jsr ConvertToDisplay2 : sta $1644, y ; small key totals
|
||||
plx : sep #$30 : lda.l ChestKeys, x : sta $02
|
||||
lda.l GenericKeys : bne +++
|
||||
lda $02 : !sub $7ef4e0, x : sta $02
|
||||
+++ lda $02
|
||||
rep #$30
|
||||
jsr ConvertToDisplay2 : sta $1644, y ; small key totals
|
||||
bra .skipStack
|
||||
+ plx
|
||||
.skipStack iny #2
|
||||
@@ -131,15 +137,18 @@ DrHudDungeonItemsAdditions:
|
||||
+ lda $7ef364 : and.l $0098c0, x : beq + ; must have compass
|
||||
phx ; total chest counts
|
||||
txa : lsr : tax
|
||||
lda.l TotalLocationsHigh, x : jsr ConvertToDisplay2 : sta $1644, y : iny #2
|
||||
lda.l TotalLocationsLow, x : jsr ConvertToDisplay2 : sta $1644, y
|
||||
sep #$30
|
||||
lda.l TotalLocations, x : !sub $7EF4BF, x : JSR HudHexToDec2DigitCopy
|
||||
rep #$30
|
||||
lda $06 : jsr ConvertToDisplay2 : sta $1644, y : iny #2
|
||||
lda $07 : jsr ConvertToDisplay2 : sta $1644, y
|
||||
plx
|
||||
bra .skipBlanks
|
||||
+ lda.w #$24f5 : sta $1644, y : iny #2 : sta $1644, y
|
||||
.skipBlanks iny #2
|
||||
cpx #$001a : beq +
|
||||
lda.w #$24f5 : sta $1644, y ; blank out spot
|
||||
+ inx #2 : cpx #$001b : bcc -
|
||||
+ inx #2 : cpx #$001b : !bge ++ : brl -
|
||||
++
|
||||
plp : ply : plx : rtl
|
||||
}
|
||||
@@ -203,4 +212,27 @@ HudHexToDec4DigitCopy:
|
||||
DEC : BNE -
|
||||
+
|
||||
STY $07 ; Store 1s digit
|
||||
RTS
|
||||
|
||||
;================================================================================
|
||||
; 8-bit registers
|
||||
; in: A(b) - Byte to Convert
|
||||
; out: $06 - $07 (high - low)
|
||||
;================================================================================
|
||||
HudHexToDec2DigitCopy: ; modified
|
||||
PHY
|
||||
LDY.b #$00
|
||||
-
|
||||
CMP.b #10 : !BLT +
|
||||
INY
|
||||
SBC.b #10 : BRA -
|
||||
+
|
||||
STY $06 : LDY #$00 ; Store 10s digit and reset Y
|
||||
CMP.b #1 : !BLT +
|
||||
-
|
||||
INY
|
||||
DEC : BNE -
|
||||
+
|
||||
STY $07 ; Store 1s digit
|
||||
PLY
|
||||
RTS
|
||||
@@ -127,7 +127,7 @@ KeyGet:
|
||||
phx
|
||||
lda $040c : lsr : tax
|
||||
lda $00 : cmp KeyTable, x : bne +
|
||||
- plx : pla : rtl
|
||||
- JSL.l FullInventoryExternal : jsl CountChestKeyLong : plx : pla : rtl
|
||||
+ cmp #$af : beq - ; universal key
|
||||
cmp #$24 : beq - ; small key for this dungeon
|
||||
plx
|
||||
|
||||
@@ -121,3 +121,22 @@ RetrieveBunnyState:
|
||||
LDA $5F : BEQ +
|
||||
STA $5D
|
||||
+ RTL
|
||||
|
||||
RainPrevention:
|
||||
LDA $00 : XBA : AND #$00FF ; what we wrote over
|
||||
PHA
|
||||
LDA $7EF3C5 : AND #$00FF : CMP #$0002 : !BGE .done ; only in rain states (0 or 1)
|
||||
LDA.l $7EF3C6 : AND #$0004 : BNE .done ; zelda's been rescued
|
||||
LDA.l BlockSanctuaryDoorInRain : BEQ .done ;flagged
|
||||
LDA $A0 : CMP #$0012 : BNE + ;we're in the sanctuary
|
||||
LDA.l $7EF3CC : AND #$00FF : CMP #$0001 : BEQ .done ; zelda is following
|
||||
LDA $00 : CMP #$02A1 : BNE .done
|
||||
PLA : LDA #$0008 : RTL
|
||||
+ LDA.l BlockCastleDoorsInRain : BEQ .done ;flagged
|
||||
LDX #$FFFE
|
||||
- INX #2 : LDA.l RemoveRainDoorsRoom, X : CMP #$FFFF : BEQ .done
|
||||
CMP $A0 : BNE -
|
||||
LDA.l RainDoorMatch, X : CMP $00 : BNE -
|
||||
PLA : LDA #$0008 : RTL
|
||||
.done PLA : RTL
|
||||
|
||||
|
||||
Binary file not shown.
Reference in New Issue
Block a user