Lots of bugfixes - see notes

This commit is contained in:
aerinon
2020-11-09 13:54:03 -07:00
parent cdf5f23b75
commit 6162fddf47
11 changed files with 129 additions and 24 deletions

View File

@@ -476,7 +476,7 @@ class CollectionState(object):
new_crystal_state = crystal_state
for exit in new_region.exits:
door = exit.door
if door is not None and door.crystal == CrystalBarrier.Either:
if door is not None and door.crystal == CrystalBarrier.Either and door.entrance.can_reach(self):
new_crystal_state = CrystalBarrier.Either
break
if new_region in rrp:
@@ -487,7 +487,7 @@ class CollectionState(object):
for exit in new_region.exits:
door = exit.door
if door is not None and not door.blocked:
door_crystal_state = new_crystal_state & (door.crystal or CrystalBarrier.Either)
door_crystal_state = door.crystal if door.crystal else new_crystal_state
bc[exit] = door_crystal_state
queue.append((exit, door_crystal_state))
elif door is None:
@@ -1906,7 +1906,8 @@ class Spoiler(object):
'enemy_damage': self.world.enemy_damage,
'players': self.world.players,
'teams': self.world.teams,
'experimental' : self.world.experimental
'experimental': self.world.experimental,
'keydropshuffle': self.world.keydropshuffle,
}
def to_json(self):
@@ -1967,6 +1968,7 @@ class Spoiler(object):
outfile.write('Enemy damage: %s\n' % self.metadata['enemy_damage'][player])
outfile.write('Hints: %s\n' % ('Yes' if self.metadata['hints'][player] else 'No'))
outfile.write('Experimental: %s\n' % ('Yes' if self.metadata['experimental'][player] else 'No'))
outfile.write('Key Drops shuffled: %s\n' % ('Yes' if self.metadata['keydropshuffle'][player] else 'No'))
if self.doors:
outfile.write('\n\nDoors:\n\n')
outfile.write('\n'.join(

View File

@@ -41,6 +41,8 @@ def link_doors(world, player):
for entrance, ext in straight_staircases:
connect_two_way(world, entrance, ext, player)
connect_custom(world, player)
find_inaccessible_regions(world, player)
if world.intensity[player] >= 3 and world.doorShuffle[player] in ['basic', 'crossed']:
@@ -197,6 +199,12 @@ def convert_key_doors(k_doors, world, player):
return result
def connect_custom(world, player):
if hasattr(world, 'custom_doors') and world.custom_doors[player]:
for entrance, ext in world.custom_doors[player]:
connect_two_way(world, entrance, ext, player)
def connect_simple_door(world, exit_name, region_name, player):
region = world.get_region(region_name, player)
world.get_entrance(exit_name, player).connect(region)

View File

@@ -564,6 +564,8 @@ def determine_paths_for_dungeon(world, player, all_regions, name):
paths.append(('Hyrule Dungeon Cellblock', 'Sanctuary'))
if world.doorShuffle[player] in ['basic'] and name == 'Thieves Town':
paths.append('Thieves Attic Window')
elif 'Thieves Attic Window' in all_r_names:
paths.append('Thieves Attic Window')
for boss in boss_path_checks:
if boss in all_r_names:
paths.append(boss)
@@ -1260,6 +1262,9 @@ def create_dungeon_builders(all_sectors, connections_tuple, world, player,
sector = find_sector(r_name, all_sectors)
reverse_d_map[sector] = key
complete_dungeons = {x: y for x, y in dungeon_map.items() if sum(len(sector.outstanding_doors) for sector in y.sectors) <= 0}
[dungeon_map.pop(key) for key in complete_dungeons.keys()]
# categorize sectors
identify_destination_sectors(accessible_sectors, reverse_d_map, dungeon_map, connections,
dungeon_entrances, split_dungeon_entrances)
@@ -1315,6 +1320,7 @@ def create_dungeon_builders(all_sectors, connections_tuple, world, player,
assign_polarized_sectors(dungeon_map, polarized_sectors, global_pole, builder_info)
# the rest
assign_the_rest(dungeon_map, neutral_sectors, global_pole, builder_info)
dungeon_map.update(complete_dungeons)
finished = True
except NeutralizingException:
pass

View File

@@ -6,7 +6,7 @@ from BaseClasses import Region, RegionType, Shop, ShopType, Location
from Bosses import place_bosses
from Dungeons import get_dungeon_item_pool
from EntranceShuffle import connect_entrance
from Fill import FillError, fill_restrictive
from Fill import FillError, fill_restrictive, fast_fill
from Items import ItemFactory
import source.classes.constants as CONST
@@ -738,3 +738,21 @@ def test():
if __name__ == '__main__':
test()
def fill_specific_items(world):
keypool = [item for item in world.itempool if item.smallkey]
cage = world.get_location('Tower of Hera - Basement Cage', 1)
c_dungeon = cage.parent_region.dungeon
key_item = next(x for x in keypool if c_dungeon.name in x.name or (c_dungeon.name == 'Hyrule Castle' and 'Escape' in x.name))
world.itempool.remove(key_item)
all_state = world.get_all_state(True)
fill_restrictive(world, all_state, [cage], [key_item])
# somaria = next(item for item in world.itempool if item.name == 'Cane of Somaria')
# shooter = world.get_location('Palace of Darkness - Shooter Room', 1)
# world.itempool.remove(somaria)
# all_state = world.get_all_state(True)
# fill_restrictive(world, all_state, [shooter], [somaria])

View File

@@ -21,10 +21,10 @@ from RoomData import create_rooms
from Rules import set_rules
from Dungeons import create_dungeons, fill_dungeons, fill_dungeons_restrictive
from Fill import distribute_items_cutoff, distribute_items_staleness, distribute_items_restrictive, flood_items, balance_multiworld_progression
from ItemList import generate_itempool, difficulties, fill_prizes
from ItemList import generate_itempool, difficulties, fill_prizes, fill_specific_items
from Utils import output_path, parse_player_names
__version__ = '0.2.0.7-u'
__version__ = '0.2.0.8-u'
class EnemizerError(RuntimeError):
pass
@@ -139,6 +139,9 @@ def main(args, seed=None, fish=None):
fill_prizes(world)
# used for debugging
# fill_specific_items(world)
logger.info(world.fish.translate("cli","cli","placing.dungeon.items"))
shuffled_locations = None

View File

@@ -3,14 +3,19 @@
* Lobby shuffle added as Intensity level 3
* Can now be found in the spoiler
* Known issues:
* If a dungeon is vanilla in ER and Sanc is in that dungeon and the dungeon has an entrance that needs to let link out: is broken.
* e.g. PoD, GT, TR
* Some TR lobbies that need a bomb aren't pre-opened.
* Palettes aren't perfect - may add Sanctuary and Sewer palette back. May add a way to turn off palette "fixing"
* Certain hints in ER due to lobby changes
* Some ugly colors
* Invisible floors can be see in many palettes
* Animated tiles aren't loaded correctly in lobbies
* If a wallmaster grabs you and the lobby is dark, the lamp doesn't turn on
* --keydropshuffle added (coming to the GUI soon). 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.
* Multiworld untested - May need changes to MultiClient/MultiServer to recognize new locations
* Overall location count updated
* Setting mentioned in spoiler
* GT Big Key count / total location 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
@@ -30,14 +35,24 @@ otherwise unconnected logically can be reach using these glitches. To prevent th
# Bug Fixes
* Fixed a situation where logic did not account properly for Big Key doors in standard Hyrule Castle
* Fixed a problem ER shuffle generation that did not account for lobbies moving around
* Fixed a problem with camera unlock (GT Mimics and Mire Minibridge)
* Fixed a problem with bad-pseudo layer at PoD map Balcony (unable to hit switch with Bomb)
* Fixed a problem with the Ganon hint when hints are turned off
* 2.0.8-u
* Player sprite disappears after picking up a key drop in keydropshuffle
* Sewers and Hyrule Castle compass problems
* Double count of the Hera Basement Cage item (both overall and compass)
* Unnecessary/inconsistent rug cutoff
* TR Crystal Maze thought you get through backwards without Somaria
* Ensure Thieves Attic Window area can always be reached
* Fixed where HC big key was not counted
* Prior fixes
* Fixed a situation where logic did not account properly for Big Key doors in standard Hyrule Castle
* Fixed a problem ER shuffle generation that did not account for lobbies moving around
* Fixed a problem with camera unlock (GT Mimics and Mire Minibridge)
* Fixed a problem with bad-pseudo layer at PoD map Balcony (unable to hit switch with Bomb)
* Fixed a problem with the Ganon hint when hints are turned off
# Known Issues
(I'm planning to fix theese in this Unstable iteration hopefully)
* Backward TR Crystal Maze locking Somaria
* Multiworld = /missing command not working
* Potenial keylocks in multi-entrance dungeons
* Incorrect vanilla keylogic for Mire
* ER - Potential for Skull Woods West to be completely inaccessible in non-beatable logic

24
Rom.py
View File

@@ -24,7 +24,7 @@ from EntranceShuffle import door_addresses, exit_ids
JAP10HASH = '03a63945398191337e896e5771f77173'
RANDOMIZERBASEHASH = '78947c3825898cac3ab57cbe44b50390'
RANDOMIZERBASEHASH = 'fb2886fc00a7736369ce6ba90b526bc9'
class JsonRom(object):
@@ -709,8 +709,21 @@ def patch_rom(world, rom, player, team, enemized):
write_custom_shops(rom, world, player)
def credits_digit(num):
# top: $54 is 1, 55 2, etc , so 57=4, 5C=9
# bot: $7A is 1, 7B is 2, etc so 7D=4, 82=9 (zero unknown...)
return 0x53+num, 0x79+num
if world.keydropshuffle[player]:
rom.write_byte(0x140000, 1)
mid_top, mid_bot = credits_digit(4)
last_top, last_bot = credits_digit(9)
# top half
rom.write_byte(0x118C53, mid_top)
rom.write_byte(0x118C54, last_top)
# bottom half
rom.write_byte(0x118C71, mid_bot)
rom.write_byte(0x118C72, last_bot)
# patch medallion requirements
if world.required_medallions[player][0] == 'Bombos':
@@ -765,7 +778,7 @@ def patch_rom(world, rom, player, team, enemized):
TRIFORCE_PIECE = ItemFactory('Triforce Piece', player).code
GREEN_CLOCK = ItemFactory('Green Clock', player).code
rom.write_byte(0x18004F, 0x01) # Byrna Invulnerability: on
rom.write_byte(0x18004F, 0x01) # Byrna Invulnerability: on
# handle difficulty_adjustments
if world.difficulty_adjustments[player] == 'hard':
@@ -2210,11 +2223,18 @@ def patch_shuffled_dark_sanc(world, rom, player):
def update_compasses(rom, world, player):
layouts = world.dungeon_layouts[player]
provided_dungeon = False
for name, builder in layouts.items():
dungeon_id = compass_data[name][4]
rom.write_byte(0x187000 + dungeon_id//2, builder.location_cnt)
if builder.bk_provided:
if provided_dungeon:
logging.getLogger('').warning('Multiple dungeons have forced BKs! Compass code might need updating?')
rom.write_byte(0x186FFF, dungeon_id)
provided_dungeon = True
if not provided_dungeon:
rom.write_byte(0x186FFF, 0xff)
InconvenientDungeonEntrances = {'Turtle Rock': 'Turtle Rock Main',

View File

@@ -139,6 +139,14 @@ org $019dbd ; <- Bank01.asm : 4465 of Object_Draw8xN (LDA $9B52, Y : STA $7E2000
jsl CutoffEntranceRug : bra .nextTile : nop
.nextTile
;maybe set 02e2 to 0
org $0799de ; <- Bank07.asm : 4088 (LDA.b #$15 : STA $5D)
JSL StoreTempBunnyState
;
org $08c450 ; <- ancilla_receive_item.asm : 146-148 (STY $5D : STZ $02D8)
JSL RetrieveBunnyState : NOP
; 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

View File

@@ -116,10 +116,12 @@ KeyGet:
lda $7ef36f ; what we wrote over
pha
lda.l ShuffleKeyDrops : bne +
pla : rtl
+
ldy $0e80, x
phy
- pla : rtl
+ ldy $0e80, x
lda $a0 : cmp #$87 : bne +
jsr ShouldKeyBeCountedForDungeon : bcc -
jsl CountChestKeyLong : bra -
+ phy
jsr KeyGetPlayer : sta !MULTIWORLD_ITEM_PLAYER_ID
jsl.l $0791b3 ; Player_HaltDashAttackLong
jsl.l Link_ReceiveItem
@@ -136,6 +138,16 @@ KeyGet:
pla : dec : rtl
}
; Input Y - the item type
ShouldKeyBeCountedForDungeon:
{
phx
lda $040c : lsr : tax
tya : cmp KeyTable, x : bne +
- plx : sec : rts
+ cmp #$24 : beq -
plx : clc : rts
}
BigKeyGet:
{

View File

@@ -88,6 +88,7 @@ SuctionOverworldFix:
CutoffRooms:
db $bc, $a2, $1a, $49, $14, $8c, $9f, $c2
db $66, $5d, $a8
; Don't forget CutoffRoomCount!!!
CutoffEntranceRug:
pha : phx
@@ -96,7 +97,7 @@ CutoffEntranceRug:
cmp #$000C : bne .norm
+ lda $a0 : sep #$20 : ldx #$0000
- cmp.l CutoffRooms, x : beq .check
inx : cpx #$0009 : !blt - ; CutoffRoom Count is here!
inx : cpx #$000B : !blt - ; CutoffRoomCount is here!
rep #$20
.norm plx : pla : lda $9B52, y : sta $7E2000, x ; what we wrote over
rtl
@@ -108,3 +109,15 @@ rtl
bra .norm
.skip plx : pla : rtl
StoreTempBunnyState:
LDA $5D : CMP #$1C : BNE +
STA $5F
+ LDA #$15 : STA $5D ; what we wrote over
RTL
RetrieveBunnyState:
STY $5D : STZ $02D8 ; what we wrote over
LDA $5F : BEQ +
STA $5D
+ RTL

Binary file not shown.