-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.
This commit is contained in:
@@ -1214,6 +1214,7 @@ class Door(object):
|
|||||||
self.passage = True
|
self.passage = True
|
||||||
self.dungeonLink = None
|
self.dungeonLink = None
|
||||||
self.bk_shuffle_req = False
|
self.bk_shuffle_req = False
|
||||||
|
self.standard_restrict = False # flag if portal is not allowed in HC in standard
|
||||||
# self.incognitoPos = -1
|
# self.incognitoPos = -1
|
||||||
# self.sectorLink = False
|
# self.sectorLink = False
|
||||||
|
|
||||||
|
|||||||
@@ -357,6 +357,7 @@ def choose_portals(world, player):
|
|||||||
if world.doorShuffle[player] in ['basic', 'crossed']:
|
if world.doorShuffle[player] in ['basic', 'crossed']:
|
||||||
cross_flag = world.doorShuffle[player] == 'crossed'
|
cross_flag = world.doorShuffle[player] == 'crossed'
|
||||||
bk_shuffle = world.bigkeyshuffle[player]
|
bk_shuffle = world.bigkeyshuffle[player]
|
||||||
|
std_flag = world.mode[player] == 'standard'
|
||||||
# roast incognito doors
|
# roast incognito doors
|
||||||
world.get_room(0x60, player).delete(5)
|
world.get_room(0x60, player).delete(5)
|
||||||
world.get_room(0x60, player).change(2, DoorKind.DungeonEntrance)
|
world.get_room(0x60, player).change(2, DoorKind.DungeonEntrance)
|
||||||
@@ -369,13 +370,14 @@ def choose_portals(world, player):
|
|||||||
region_map = defaultdict(list)
|
region_map = defaultdict(list)
|
||||||
reachable_portals = []
|
reachable_portals = []
|
||||||
inaccessible_portals = []
|
inaccessible_portals = []
|
||||||
|
hc_flag = std_flag and dungeon == 'Hyrule Castle'
|
||||||
for portal in portal_list:
|
for portal in portal_list:
|
||||||
placeholder = world.get_region(portal + ' Portal', player)
|
placeholder = world.get_region(portal + ' Portal', player)
|
||||||
portal_region = placeholder.exits[0].connected_region
|
portal_region = placeholder.exits[0].connected_region
|
||||||
name = portal_region.name
|
name = portal_region.name
|
||||||
if portal_region.type == RegionType.LightWorld:
|
if portal_region.type == RegionType.LightWorld:
|
||||||
world.get_portal(portal, player).light_world = True
|
world.get_portal(portal, player).light_world = True
|
||||||
if name in world.inaccessible_regions[player]:
|
if name in world.inaccessible_regions[player] or (hc_flag and portal != 'Hyrule Castle South'):
|
||||||
name_key = 'Desert Ledge' if name == 'Desert Palace Entrance (North) Spot' else name
|
name_key = 'Desert Ledge' if name == 'Desert Palace Entrance (North) Spot' else name
|
||||||
region_map[name_key].append(portal)
|
region_map[name_key].append(portal)
|
||||||
inaccessible_portals.append(portal)
|
inaccessible_portals.append(portal)
|
||||||
@@ -397,7 +399,8 @@ def choose_portals(world, player):
|
|||||||
portal_assignment = defaultdict(list)
|
portal_assignment = defaultdict(list)
|
||||||
for dungeon, info in info_map.items():
|
for dungeon, info in info_map.items():
|
||||||
outstanding_portals = list(dungeon_portals[dungeon])
|
outstanding_portals = list(dungeon_portals[dungeon])
|
||||||
if dungeon == 'Hyrule Castle' and world.mode[player] == 'standard':
|
hc_flag = std_flag and dungeon == 'Hyrule Castle'
|
||||||
|
if hc_flag:
|
||||||
sanc = world.get_portal('Sanctuary', player)
|
sanc = world.get_portal('Sanctuary', player)
|
||||||
sanc.destination = True
|
sanc.destination = True
|
||||||
clean_up_portal_assignment(portal_assignment, dungeon, sanc, master_door_list, outstanding_portals)
|
clean_up_portal_assignment(portal_assignment, dungeon, sanc, master_door_list, outstanding_portals)
|
||||||
@@ -425,7 +428,7 @@ def choose_portals(world, player):
|
|||||||
the_rest = info.total - len(portal_assignment[dungeon])
|
the_rest = info.total - len(portal_assignment[dungeon])
|
||||||
for i in range(0, the_rest):
|
for i in range(0, the_rest):
|
||||||
candidates = find_portal_candidates(master_door_list, dungeon, crossed=cross_flag,
|
candidates = find_portal_candidates(master_door_list, dungeon, crossed=cross_flag,
|
||||||
bk_shuffle=bk_shuffle)
|
bk_shuffle=bk_shuffle, standard=hc_flag)
|
||||||
choice, portal = assign_portal(candidates, outstanding_portals, world, player)
|
choice, portal = assign_portal(candidates, outstanding_portals, world, player)
|
||||||
clean_up_portal_assignment(portal_assignment, dungeon, portal, master_door_list, outstanding_portals)
|
clean_up_portal_assignment(portal_assignment, dungeon, portal, master_door_list, outstanding_portals)
|
||||||
|
|
||||||
@@ -536,23 +539,20 @@ def disconnect_portal(portal, world, player):
|
|||||||
chosen_door.entranceFlag = False
|
chosen_door.entranceFlag = False
|
||||||
|
|
||||||
|
|
||||||
def find_portal_candidates(door_list, dungeon, need_passage=False, dead_end_allowed=False, crossed=False, bk_shuffle=False):
|
def find_portal_candidates(door_list, dungeon, need_passage=False, dead_end_allowed=False, crossed=False,
|
||||||
filter_list = [x for x in door_list if bk_shuffle or not x.bk_shuffle_req]
|
bk_shuffle=False, standard=False):
|
||||||
if need_passage:
|
ret = [x for x in door_list if bk_shuffle or not x.bk_shuffle_req]
|
||||||
if crossed:
|
if crossed:
|
||||||
return [x for x in filter_list if x.passage and (x.dungeonLink is None or x.entrance.parent_region.dungeon.name == dungeon)]
|
ret = [x for x in ret if not x.dungeonLink or x.entrance.parent_region.dungeon.name == dungeon]
|
||||||
else:
|
|
||||||
return [x for x in filter_list if x.passage and x.entrance.parent_region.dungeon.name == dungeon]
|
|
||||||
elif dead_end_allowed:
|
|
||||||
if crossed:
|
|
||||||
return [x for x in filter_list if x.dungeonLink is None or x.entrance.parent_region.dungeon.name == dungeon]
|
|
||||||
else:
|
|
||||||
return [x for x in filter_list if x.entrance.parent_region.dungeon.name == dungeon]
|
|
||||||
else:
|
else:
|
||||||
if crossed:
|
ret = [x for x in ret if x.entrance.parent_region.dungeon.name == dungeon]
|
||||||
return [x for x in filter_list if (not x.dungeonLink or x.entrance.parent_region.dungeon.name == dungeon) and not x.deadEnd]
|
if need_passage:
|
||||||
else:
|
ret = [x for x in ret if x.passage]
|
||||||
return [x for x in filter_list if x.entrance.parent_region.dungeon.name == dungeon and not x.deadEnd]
|
if not dead_end_allowed:
|
||||||
|
ret = [x for x in ret if not x.deadEnd]
|
||||||
|
if standard:
|
||||||
|
ret = [x for x in ret if not x.standard_restrict]
|
||||||
|
return ret
|
||||||
|
|
||||||
|
|
||||||
def assign_portal(candidates, possible_portals, world, player):
|
def assign_portal(candidates, possible_portals, world, player):
|
||||||
|
|||||||
1
Doors.py
1
Doors.py
@@ -1306,6 +1306,7 @@ def create_doors(world, player):
|
|||||||
world.get_door("GT Bob\'s Room SE", player).passage = False
|
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('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('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)
|
||||||
|
|
||||||
# can't unlink from boss right now
|
# can't unlink from boss right now
|
||||||
world.get_door('Hera Lobby S', player).dungeonLink = 'Tower of Hera'
|
world.get_door('Hera Lobby S', player).dungeonLink = 'Tower of Hera'
|
||||||
|
|||||||
@@ -9,6 +9,12 @@ Big thanks to Catobat for doing all the hard work.
|
|||||||
|
|
||||||
# Bug Fixes
|
# Bug Fixes
|
||||||
|
|
||||||
|
* 0.3.0.2-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.
|
||||||
* 0.3.0.1-u
|
* 0.3.0.1-u
|
||||||
* Problem with lobbies on re-rolls corrected
|
* Problem with lobbies on re-rolls corrected
|
||||||
* Potential playthrough problem addressed
|
* Potential playthrough problem addressed
|
||||||
|
|||||||
11
Rom.py
11
Rom.py
@@ -711,6 +711,12 @@ def patch_rom(world, rom, player, team, enemized):
|
|||||||
if dr_flags & DROptions.Town_Portal and world.mode[player] == 'inverted':
|
if dr_flags & DROptions.Town_Portal and world.mode[player] == 'inverted':
|
||||||
rom.write_byte(0x138006, 1)
|
rom.write_byte(0x138006, 1)
|
||||||
|
|
||||||
|
# swap in non-ER Lobby Shuffle Inverted - but only then
|
||||||
|
if world.mode[player] == 'inverted' and world.intensity[player] >= 3 and world.doorShuffle[player] != 'vanilla' and world.shuffle[player] == 'vanilla':
|
||||||
|
aga_portal = world.get_portal('Agahnims Tower', player)
|
||||||
|
gt_portal = world.get_portal('Ganons Tower', player)
|
||||||
|
aga_portal.exit_offset, gt_portal.exit_offset = gt_portal.exit_offset, aga_portal.exit_offset
|
||||||
|
|
||||||
for portal in world.dungeon_portals[player]:
|
for portal in world.dungeon_portals[player]:
|
||||||
if not portal.default:
|
if not portal.default:
|
||||||
offset = portal.ent_offset
|
offset = portal.ent_offset
|
||||||
@@ -2093,8 +2099,9 @@ def set_inverted_mode(world, player, rom):
|
|||||||
if world.shuffle[player] == 'vanilla':
|
if world.shuffle[player] == 'vanilla':
|
||||||
rom.write_byte(0xDBB73 + 0x23, 0x37) # switch AT and GT
|
rom.write_byte(0xDBB73 + 0x23, 0x37) # switch AT and GT
|
||||||
rom.write_byte(0xDBB73 + 0x36, 0x24)
|
rom.write_byte(0xDBB73 + 0x36, 0x24)
|
||||||
write_int16(rom, 0x15AEE + 2*0x38, 0x00E0)
|
if world.doorShuffle[player] == 'vanilla' or world.intensity[player] < 3:
|
||||||
write_int16(rom, 0x15AEE + 2*0x25, 0x000C)
|
write_int16(rom, 0x15AEE + 2*0x38, 0x00E0)
|
||||||
|
write_int16(rom, 0x15AEE + 2*0x25, 0x000C)
|
||||||
if world.shuffle[player] in ['vanilla', 'dungeonssimple', 'dungeonsfull']:
|
if world.shuffle[player] in ['vanilla', 'dungeonssimple', 'dungeonsfull']:
|
||||||
rom.write_byte(0x15B8C, 0x6C)
|
rom.write_byte(0x15B8C, 0x6C)
|
||||||
rom.write_byte(0xDBB73 + 0x00, 0x53) # switch bomb shop and links house
|
rom.write_byte(0xDBB73 + 0x00, 0x53) # switch bomb shop and links house
|
||||||
|
|||||||
@@ -252,6 +252,7 @@ def create_rooms(world, player):
|
|||||||
world.get_room(0x77, player).swap(0, 1) # fixes Hera Lobby Key Stairs - entrance now at pos 0
|
world.get_room(0x77, player).swap(0, 1) # fixes Hera Lobby Key Stairs - entrance now at pos 0
|
||||||
if world.enemy_shuffle[player] != 'none':
|
if world.enemy_shuffle[player] != 'none':
|
||||||
world.get_room(0xc0, player).change(0, DoorKind.Normal) # fix this kill room if enemizer is on
|
world.get_room(0xc0, player).change(0, DoorKind.Normal) # fix this kill room if enemizer is on
|
||||||
|
world.get_room(0x0e, player).change(1, DoorKind.TrapTriggerable) # fix this kill room if enemizer is on
|
||||||
|
|
||||||
|
|
||||||
def reset_rooms(world, player):
|
def reset_rooms(world, player):
|
||||||
@@ -369,7 +370,7 @@ class DoorKind(Enum):
|
|||||||
IncognitoEntrance = 0x12
|
IncognitoEntrance = 0x12
|
||||||
DungeonChanger = 0x14
|
DungeonChanger = 0x14
|
||||||
ToggleFlag = 0x16
|
ToggleFlag = 0x16
|
||||||
Trap = 0x18
|
Trap = 0x18 # both sides trapped
|
||||||
UnknownD6 = 0x1A
|
UnknownD6 = 0x1A
|
||||||
SmallKey = 0x1C
|
SmallKey = 0x1C
|
||||||
BigKey = 0x1E
|
BigKey = 0x1E
|
||||||
@@ -382,8 +383,8 @@ class DoorKind(Enum):
|
|||||||
Bombable = 0x2E
|
Bombable = 0x2E
|
||||||
BlastWall = 0x30
|
BlastWall = 0x30
|
||||||
Hidden = 0x32
|
Hidden = 0x32
|
||||||
TrapTriggerable = 0x36
|
TrapTriggerable = 0x36 # right side trap or south side trap
|
||||||
Trap2 = 0x38
|
Trap2 = 0x38 # left side trap or north side trap
|
||||||
NormalLow2 = 0x40
|
NormalLow2 = 0x40
|
||||||
TrapTriggerableLow = 0x44
|
TrapTriggerableLow = 0x44
|
||||||
Warp = 0x46
|
Warp = 0x46
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
CheckDarkWorldSanc:
|
CheckDarkWorldSanc:
|
||||||
STA $A0 : STA $048E ; what we wrote over
|
STA $A0 : STA $048E ; what we wrote over
|
||||||
|
LDA.l InvertedMode : BNE +
|
||||||
LDA.l SancDarkWorldFlag : BEQ +
|
LDA.l SancDarkWorldFlag : BEQ +
|
||||||
SEP #$30
|
SEP #$30
|
||||||
LDA $A0 : CMP #$12 : BNE ++
|
LDA $A0 : CMP #$12 : BNE ++
|
||||||
|
|||||||
@@ -170,6 +170,9 @@ JSL CheckDarkWorldSanc : NOP
|
|||||||
org $01891e ; <- Bank 01.asm : 991 Dungeon_LoadType2Object (LDA $00 : XBA : AND.w #$00FF)
|
org $01891e ; <- Bank 01.asm : 991 Dungeon_LoadType2Object (LDA $00 : XBA : AND.w #$00FF)
|
||||||
JSL RainPrevention : NOP #2
|
JSL RainPrevention : NOP #2
|
||||||
|
|
||||||
|
org $1edabf ; <- sprite_energy_ball.asm : 86-7 Sprite_EnergyBall (LDA.b #$10 : LDX.b #$00)
|
||||||
|
JSL StandardAgaDmg
|
||||||
|
|
||||||
; These two, if enabled together, have implications for vanilla BK doors in IP/Hera/Mire
|
; 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
|
; 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
|
; Hera BK door back can be seen with Pot clipping - likely useful for no logic seeds
|
||||||
|
|||||||
@@ -142,3 +142,10 @@ RainPrevention:
|
|||||||
PLA : LDA #$0008 : RTL
|
PLA : LDA #$0008 : RTL
|
||||||
.done PLA : RTL
|
.done PLA : RTL
|
||||||
|
|
||||||
|
; A should be how much dmg to do to Aga when leaving this function
|
||||||
|
StandardAgaDmg:
|
||||||
|
LDX.b #$00 ; part of what we wrote over
|
||||||
|
LDA.l $7EF3C6 : AND #$04 : BEQ + ; zelda's not been rescued
|
||||||
|
LDA.b #$10 ; hurt him!
|
||||||
|
+ RTL ; A is zero if the AND results in zero and then Agahnim's invincible!
|
||||||
|
|
||||||
|
|||||||
Binary file not shown.
Reference in New Issue
Block a user