Merge branch 'OverworldShuffleDev' into OverworldShuffle

This commit is contained in:
codemann8
2023-03-22 17:49:43 -05:00
17 changed files with 198 additions and 49 deletions
+2 -1
View File
@@ -26,9 +26,10 @@ class World(object):
self.teams = 1
self.owShuffle = owShuffle.copy()
self.owTerrain = {}
self.owCrossed = owCrossed.copy()
self.owKeepSimilar = {}
self.owMixed = owMixed.copy()
self.owCrossed = owCrossed.copy()
self.owCrossed = self.owCrossed if self.owCrossed != 'polar' or self.owMixed else 'none'
self.owWhirlpoolShuffle = {}
self.owFluteShuffle = {}
self.shuffle = shuffle.copy()
+8
View File
@@ -1,5 +1,13 @@
# Changelog
## 0.3.0.4
- \~Merged in DR v1.2.0.14~
- Fixed issue with enemy drops on OW enemies
- Fixed issue with magically opened doors
- Inverted + Vanilla ER can now generate
- Fixed issue with Multiworld bonk items not sending to correct player
- Minor improvements to OW Palettes on screen transition
## 0.3.0.3
- Fixed issue with new Cold Fairy Statue location not dropping correct item
- Fixed issue with Multiworld due to new Cold Fairy Statue location
+16 -1
View File
@@ -323,6 +323,11 @@ def connect_simple_door(world, exit_name, region_name, player):
d.dest = region
def connect_simple_door_to_region(exit_door, region):
exit_door.entrance.connect(region)
exit_door.dest = region
def connect_door_only(world, exit_name, region, player):
d = world.check_for_door(exit_name, player)
if d is not None:
@@ -355,6 +360,12 @@ def connect_two_way(world, entrancename, exitname, player):
x.dest = y
if y is not None:
y.dest = x
if x.dependents:
for dep in x.dependents:
connect_simple_door_to_region(dep, ext.parent_region)
if y.dependents:
for dep in y.dependents:
connect_simple_door_to_region(dep, entrance.parent_region)
def connect_one_way(world, entrancename, exitname, player):
@@ -374,6 +385,9 @@ def connect_one_way(world, entrancename, exitname, player):
y = world.check_for_door(exitname, player)
if x is not None:
x.dest = y
if x.dependents:
for dep in x.dependents:
connect_simple_door_to_region(dep, ext.parent_region)
def unmark_ugly_smalls(world, player):
for d in ['Eastern Hint Tile Blocked Path SE', 'Eastern Darkness S', 'Thieves Hallway SE', 'Mire Left Bridge S',
@@ -1814,7 +1828,8 @@ def shuffle_door_types(door_type_pools, paths, world, player):
for dungeon, doors in custom_dict.items():
all_custom[dungeon].extend(doors)
world.paired_doors[player].clear()
for pd in world.paired_doors[player]:
pd.pair = False
used_doors = shuffle_trap_doors(door_type_pools, paths, start_regions_map, all_custom, world, player)
# big keys
used_doors = shuffle_big_key_doors(door_type_pools, used_doors, start_regions_map, all_custom, world, player)
+1 -1
View File
@@ -2740,7 +2740,7 @@ ow_prize_table = {'Links House': (0x8b1, 0xb2d),
'Lost Woods Gamble': (0x240, 0x080),
'Fortune Teller (Light)': (0x2c0, 0x4c0),
'Snitch Lady (East)': (0x310, 0x7a0),
'Snitch Lady (West)': (0x800, 0x7a0),
'Snitch Lady (West)': (0x080, 0x7a0),
'Bush Covered House': (0x2e0, 0x880),
'Tavern (Front)': (0x270, 0x980),
'Light World Bomb Hut': (0x070, 0x980),
+4 -3
View File
@@ -670,9 +670,10 @@ def sell_potions(world, player):
for potion in ['Green Potion', 'Blue Potion', 'Red Potion']:
location = random.choice(filter_locations(ItemFactory(potion, player), locations, world, potion=True))
locations.remove(location)
p_item = next(item for item in world.itempool if item.name == potion and item.player == player)
world.push_item(location, p_item, collect=False)
world.itempool.remove(p_item)
p_item = next((item for item in world.itempool if item.name == potion and item.player == player), None)
if p_item:
world.push_item(location, p_item, collect=False)
world.itempool.remove(p_item)
def sell_keys(world, player):
+12 -7
View File
@@ -1561,13 +1561,18 @@ def validate_key_layout_sub_loop(key_layout, state, checked_states, flat_proposa
def invalid_self_locking_key(key_layout, state, prev_state, prev_avail, world, player):
if prev_state is None or state.used_smalls == prev_state.used_smalls:
return False
new_bk_doors = set(state.big_doors).difference(set(prev_state.big_doors))
state_copy = state.copy()
while len(new_bk_doors) > 0:
for door in new_bk_doors:
open_a_door(door.door, state_copy, key_layout.flat_prop, world, player)
new_bk_doors = set(state_copy.big_doors).difference(set(prev_state.big_doors))
expand_key_state(state_copy, key_layout.flat_prop, world, player)
if state.found_forced_bk() and not prev_state.found_forced_bk():
return False
if state.big_key_opened:
new_bk_doors = set(state.big_doors).difference(set(prev_state.big_doors))
state_copy = state.copy()
while len(new_bk_doors) > 0:
for door in new_bk_doors:
open_a_door(door.door, state_copy, key_layout.flat_prop, world, player)
new_bk_doors = set(state_copy.big_doors).difference(set(prev_state.big_doors))
expand_key_state(state_copy, key_layout.flat_prop, world, player)
else:
state_copy = state
new_locations = set(state_copy.found_locations).difference(set(prev_state.found_locations))
important_found = False
for loc in new_locations:
+4 -3
View File
@@ -36,7 +36,9 @@ from source.overworld.EntranceShuffle2 import link_entrances_new
from source.tools.BPS import create_bps_from_data
from source.classes.CustomSettings import CustomSettings
__version__ = '1.2.0.12u'
version_number = '1.2.0.14'
version_branch = '-u'
__version__ = f'{version_number}{version_branch}'
from source.classes.BabelFish import BabelFish
@@ -265,6 +267,7 @@ def main(args, seed=None, fish=None):
set_rules(world, player)
district_item_pool_config(world)
fill_specific_items(world)
for player in range(1, world.players + 1):
if world.shopsanity[player]:
sell_potions(world, player)
@@ -277,8 +280,6 @@ def main(args, seed=None, fish=None):
if args.print_custom_yaml:
world.settings.record_item_pool(world)
dungeon_tracking(world)
fill_specific_items(world)
logger.info(world.fish.translate("cli", "cli", "placing.dungeon.prizes"))
fill_prizes(world)
+7 -1
View File
@@ -46,6 +46,9 @@ class Context:
self.lookup_name_to_id = {}
self.lookup_id_to_name = {}
self.disable_client_forfeit = False
async def send_msgs(websocket, msgs):
if not websocket or not websocket.open or websocket.closed:
return
@@ -281,7 +284,10 @@ async def process_client_cmd(ctx : Context, client : Client, cmd, args):
if args.startswith('!players'):
notify_all(ctx, get_connected_players_string(ctx))
if args.startswith('!forfeit'):
forfeit_player(ctx, client.team, client.slot)
if ctx.disable_client_forfeit:
notify_client(client, 'Client-initiated forfeits are disabled. Please ask the host of this game to forfeit on your behalf.')
else:
forfeit_player(ctx, client.team, client.slot)
if args.startswith('!countdown'):
try:
timer = int(args.split()[1])
+2 -2
View File
@@ -143,7 +143,7 @@ def create_owedges(world, player):
create_owedge(player, 'Tree Line WC', 0x2e, We, Wr, 0x1a) .coordInfo(0x0b3c, 0x0660),
create_owedge(player, 'Eastern Nook NE', 0x2f, No, Ld, 0x16) .coordInfo(0x0f78, 0x1820),
create_owedge(player, 'Desert EC', 0x30, Ea, Ld, 0x1e, 0x39).coordInfo(0x0ee4, 0x1480),
create_owedge(player, 'Desert ES', 0x30, Ea, Ld, 0x1f, 0x39).coordInfo(0x0f8c, 0x1980),
create_owedge(player, 'Desert ES', 0x30, Ea, Ld, 0x1f, 0x39).coordInfo(0x0f90, 0x1980),
create_owedge(player, 'Flute Boy Approach NW', 0x32, No, Ld, 0x17) .coordInfo(0x044c, 0x1800),
create_owedge(player, 'Flute Boy Approach NC', 0x32, No, Ld, 0x18) .coordInfo(0x04e8, 0x180c),
create_owedge(player, 'Flute Boy Approach EC', 0x32, Ea, Ld, 0x1a) .coordInfo(0x0d04, 0x05c0),
@@ -167,7 +167,7 @@ def create_owedges(world, player):
create_owedge(player, 'Ice Cave SW', 0x37, So, Wr, 0x1e) .coordInfo(0x0e80, 0x1002),
create_owedge(player, 'Ice Cave SE', 0x37, So, Ld, 0x1f) .coordInfo(0x0f50, 0x101c),
create_owedge(player, 'Desert Pass WC', 0x3a, We, Ld, 0x1f) .coordInfo(0x0ee4, 0x03e0),
create_owedge(player, 'Desert Pass WS', 0x3a, We, Ld, 0x20) .coordInfo(0x0f8c, 0x0860),
create_owedge(player, 'Desert Pass WS', 0x3a, We, Ld, 0x20) .coordInfo(0x0f90, 0x0860),
create_owedge(player, 'Desert Pass EC', 0x3a, Ea, Ld, 0x20) .coordInfo(0x0f18, 0x0640),
create_owedge(player, 'Desert Pass ES', 0x3a, Ea, Ld, 0x21) .coordInfo(0x0fcb, 0x08c0),
create_owedge(player, 'Dam NC', 0x3b, No, Ld, 0x1e) .coordInfo(0x0728, 0x1816),
+1 -1
View File
@@ -7,7 +7,7 @@ from OWEdges import OWTileRegions, OWEdgeGroups, OWEdgeGroupsTerrain, OWExitType
from OverworldGlitchRules import create_owg_connections
from Utils import bidict
version_number = '0.3.0.3'
version_number = '0.3.0.4'
# branch indicator is intentionally different across branches
version_branch = ''
+11
View File
@@ -108,6 +108,17 @@ These are now independent of retro mode and have three options: None, Random, an
* Bonk Fairy (Dark)
# Bug Fixes and Notes
* 1.2.0.14u
* Small fix for key logic validation (got rid of a false negative)
* Customized doors in ice cross work properly now
* 1.2.0.13u
* Allow green/blue potion refills to be customized
* OW Map showing dungeon entrance at Snitch Lady (West) fixed (instead of @ HC Courtyard)
* Standing item data is cleared on transition to overworld (enemy drops won't bleed to overworld sprites)
* Escape assist won't give you a free quiver in retro bow mode
* Fixed an issue where a door would be opened magically (due to original pairing)
* MultiServer can now disable forfeits if desired
* 1.2.0.12u
* Fix for mirror portal in inverted
* Yet another fix for blocked door in Standard ER
+5 -1
View File
@@ -38,7 +38,7 @@ from source.dungeon.RoomList import Room0127
JAP10HASH = '03a63945398191337e896e5771f77173'
RANDOMIZERBASEHASH = 'c27bdd316ea8312214643e0a4ea32c10'
RANDOMIZERBASEHASH = '0a3d1d4bbec659013be5ed876c2658bd'
class JsonRom(object):
@@ -1710,12 +1710,16 @@ def patch_rom(world, rom, player, team, enemized, is_mystery=False):
# set rom name
# 21 bytes
from Main import __version__
from OverworldShuffle import __version__ as ORVersion
seedstring = f'{world.seed:09}' if isinstance(world.seed, int) else world.seed
# todo: change to DR when Enemizer is okay with DR
rom.name = bytearray(f'ER{__version__.split("-")[0].replace(".","")[0:3]}_{team+1}_{player}_{seedstring}O\0', 'utf8')[:21]
rom.name.extend([0] * (21 - len(rom.name)))
rom.write_bytes(0x7FC0, rom.name)
rom.write_bytes(0x138010, bytearray(__version__, 'utf8'))
rom.write_bytes(0x150010, bytearray(ORVersion, 'utf8'))
# set player names
for p in range(1, min(world.players, 255) + 1):
rom.write_bytes(0x195FFC + ((p - 1) * 32), hud_format_text(world.player_names[p][team]))
+2 -1
View File
@@ -113,7 +113,7 @@ Triforce_texts = [
" Cool seed,\n\n right?",
"\n We did it!",
" Spam those\n emotes in\n wilds chat",
"\n O M G",
"\n O M G",
" Hello. Will you\n you be my friend?",
" Beetorp\n was\n here!",
" The Wind Fish\n will wake soon.\n Hoot!",
@@ -1309,6 +1309,7 @@ class GoldCreditMapper(CharTextMapper):
class GreenCreditMapper(CharTextMapper):
char_map = {' ': 0x9F,
'.': 0x52,
'·': 0x52}
alpha_offset = -0x29
alpha_lower_offset = -0x29
+112 -27
View File
@@ -11,9 +11,11 @@ OWMode:
dw 0
OWFlags:
dw 0
org $aa8010
OWReserved:
dw 0
org $aa8010
OWVersionInfo:
dw $0000, $0000, $0000, $0000, $0000, $0000, $0000, $0000
;Hooks
org $02a929
@@ -45,6 +47,10 @@ Overworld_LoadSpecialOverworld_RoomId:
org $04E8B4
Overworld_LoadSpecialOverworld:
org $02A9DA
JSL OWSkipPalettes
BCC OverworldHandleTransitions_change_palettes : NOP #4
org $07982A
Link_ResetSwimmingState:
@@ -238,6 +244,19 @@ OWWhirlpoolEnd:
RTL
}
OWDestroyItemSprites:
{
PHX : LDX.b #$0F
.nextSprite
LDA.w $0E20,X
CMP.b #$D8 : BCC .continue
CMP.b #$EC : BCS .continue
.killSprite ; need to kill sprites from D8 to EB on screen transition
STZ.w $0DD0,X
.continue
DEX : BPL .nextSprite
PLX : RTL
}
OWMirrorSpriteOnMap:
{
lda.w $1ac0,x : bit.b #$f0 : beq .continue
@@ -421,7 +440,7 @@ OWBonkGoodBeeDrop:
JMP .spawn_item
+
.determine_type ; S = Collected, FlagBitmask, X (row + 2)
.determine_type ; S = Collected
LDA.l OWBonkPrizeTable[42].loot ; A = item id
CMP.b #$B0 : BNE +
LDA.b #$79 : JMP .sprite_transform ; transform to bees
@@ -465,33 +484,34 @@ OWBonkGoodBeeDrop:
JSL.l OWBonkSpritePrep
.mark_collected ; S = Collected
PLA : BNE .return
PLA : BNE +
LDA.l RoomDataWRAM[$0120].high : ORA.b #$02 : STA.l RoomDataWRAM[$0120].high
REP #$20
LDA.l TotalItemCounter : INC : STA.l TotalItemCounter
SEP #$20
BRA .return
+ BRA .return
; spawn itemget item
.spawn_item ; A = item id ; Y = bonk sprite slot ; S = Collected
PLX : BEQ + : LDA.b #$00 : STA.w $0DD0,Y : BRA .return
+ LDA.l OWBonkPrizeTable[42].mw_player : STA.l !MULTIWORLD_SPRITEITEM_PLAYER_ID
LDA.b #$01 : STA !REDRAW
+ LDA.b #$01 : STA !REDRAW
LDA.b #$EB : STA.l $7FFE00
JSL Sprite_SpawnDynamically+15 ; +15 to skip finding a new slot, use existing sprite
TYX : STZ.w $0F20,X ; layer the sprite is on
; affects the rate the item moves in the Y/X direction
LDA.b #$00 : STA.w $0D40,Y
STZ.w $0D40,X
LDA.b #$0A : STA.w $0D50,Y
LDA.b #$20 : STA.w $0F80,Y ; amount of force (gives height to the arch)
LDA.b #$1A : STA.w $0F80,Y ; amount of force (gives height to the arch)
LDA.b #$FF : STA.w $0B58,Y ; stun timer
LDA.b #$30 : STA.w $0F10,Y ; aux delay timer 4 ?? dunno what that means
LDA.b #$00 : STA.w $0F20,Y ; layer the sprite is on
; sets the tile type that is underneath the sprite, water
LDA.b #$09 : STA.l $7FF9C2,X ; TODO: Figure out how to get the game to set this
; sets OW event bitmask flag, uses free RAM
LDA.l OWBonkPrizeTable[42].flag : STA.w $0ED0,Y
@@ -597,9 +617,7 @@ OWBonkDrops:
; spawn itemget item
.spawn_item ; A = item id ; Y = tree sprite slot ; S = Collected, FlagBitmask, X (row + 2)
PLX : BEQ + : LDA.b #$00 : STA.w $0DD0,Y : JMP .return ; S = FlagBitmask, X (row + 2)
+ LDA 2,S : TAX : INX : INX
LDA.w OWBonkPrizeData,X : STA.l !MULTIWORLD_SPRITEITEM_PLAYER_ID
DEX
+ LDA 2,S : TAX : INX
LDA.b #$01 : STA !REDRAW
@@ -610,7 +628,7 @@ OWBonkDrops:
LDA.b #$00 : STA.w $0D40,Y
LDA.b #$0A : STA.w $0D50,Y
LDA.b #$20 : STA.w $0F80,Y ; amount of force (gives height to the arch)
LDA.b #$1A : STA.w $0F80,Y ; amount of force (gives height to the arch)
LDA.b #$FF : STA.w $0B58,Y ; stun timer
LDA.b #$30 : STA.w $0F10,Y ; aux delay timer 4 ?? dunno what that means
@@ -648,6 +666,7 @@ OWBonkSpritePrep:
org $aa9000
OWDetectEdgeTransition:
{
JSL OWDestroyItemSprites
STZ.w $06FC
LDA.l OWMode : ORA.l OWMode+1 : BEQ .vanilla
JSR OWShuffle
@@ -925,8 +944,12 @@ OWNewDestination:
; crossed OW shuffle and terrain
ldx $05 : ldy $08 : jsr OWWorldTerrainUpdate
ldx $8a : lda $05 : sta $8a : stx $05 ; $05 is prev screen id, $8a is dest screen
lda $05 : sta $8a
jsr OWGfxUpdate
lda $8a
rep #$30 : rts
}
OWLoadSpecialArea:
@@ -966,17 +989,17 @@ OWWorldTerrainUpdate: ; x = owid of destination screen, y = 1 for land to water,
lda #$38 : sta $012f ; play sfx - #$3b is an alternative
; toggle bunny mode
lda MoonPearlEquipment : bne .nobunny
lda.l InvertedMode : bne .inverted
lda MoonPearlEquipment : beq + : jmp .nobunny
+ lda.l InvertedMode : bne .inverted
lda CurrentWorld : bra +
.inverted lda CurrentWorld : eor #$40
+ and #$40 : beq .nobunny
LDA.w $0703 : BEQ + ; check if forced transition
CPY.b #$03 : BEQ .end_forced_whirlpool
LDA.b #$17 : STA.b $5D
LDA.b #$01 : STA.w $02E0 : STA.b $56
LDA.w $0703 : BRA .end_forced_edge
CPY.b #$03 : BEQ ++
LDA.b #$17 : STA.b $5D
LDA.b #$01 : STA.w $02E0 : STA.b $56
LDA.w $0703 : JSR OWLoadGearPalettes : BRA .end_forced_edge
++ JSR OWLoadGearPalettes : BRA .end_forced_whirlpool
+
CPY.b #$01 : BEQ .auto ; check if going from land to water
CPY.b #$02 : BEQ .to_bunny_reset_swim ; bunny state if swimming to land
@@ -995,8 +1018,8 @@ OWWorldTerrainUpdate: ; x = owid of destination screen, y = 1 for land to water,
STZ.b $5D
PLX
BRA .to_pseudo_bunny
.whirlpool
PLX : RTS
.whirlpool
PLX : JMP OWLoadGearPalettes
.to_bunny_reset_swim
LDA.b $5D : CMP.b #$04 : BNE .to_bunny ; check if swimming
JSL Link_ResetSwimmingState
@@ -1005,7 +1028,7 @@ OWWorldTerrainUpdate: ; x = owid of destination screen, y = 1 for land to water,
LDA.b #$17 : STA.b $5D
.to_pseudo_bunny
LDA.b #$01 : STA.w $02E0 : STA.b $56
RTS
JMP OWLoadGearPalettes
.nobunny
lda $5d : cmp #$17 : bne + ; retain current state unless bunny
@@ -1054,6 +1077,68 @@ OWWorldTerrainUpdate: ; x = owid of destination screen, y = 1 for land to water,
.return
RTS
}
OWGfxUpdate:
{
REP #$20 : LDA.l OWMode : AND.w #$0207 : BEQ .is_only_mixed : SEP #$20
;;;;PLA : AND.b #$3F : BEQ .leaving_woods
LDA.b $8A : AND.b #$3F : BEQ .entering_woods
;LDA.b $05 : JSL OWSkipPalettes : BCS .skip_palettes
LDA.b $8A : JSR OWDetermineScreensPaletteSet
CPX.w $0AB3 : BEQ .skip_palettes ; check if next screen's palette is different
LDA $00 : PHA
JSL OverworldLoadScreensPaletteSet_long ; loading correct OW palette
PLA : STA $00
.leaving_woods
.entering_woods
.is_only_mixed
.skip_palettes
SEP #$20
}
OWLoadGearPalettes:
{
PHX : PHY : LDA $00 : PHA
LDA.w $02E0 : BEQ +
JSL LoadGearPalettes_bunny
BRA .return
+
JSL LoadGearPalettes_link
.return
PLA : STA $00 : PLY : PLX
RTS
}
OWDetermineScreensPaletteSet: ; A = OWID to check
{
LDX.b #$02
PHA : AND.b #$3F
CMP.b #$03 : BEQ .death_mountain
CMP.b #$05 : BEQ .death_mountain
CMP.b #$07 : BEQ .death_mountain
LDX.b #$00
.death_mountain
PLA : PHX : TAX : LDA.l OWTileWorldAssoc,X : BEQ +
PLX : INX : RTS
+ PLX : RTS
}
OWSkipPalettes:
{
STA.b $05 ; A = previous screen, also stored in $05
; only skip mosaic if OWR Layout or Crossed
PHP : REP #$20 : LDA.l OWMode : AND.w #$0207 : BEQ .vanilla : PLP
; checks to see if going to from any DM screens
;LDA.b $05 : JSR OWDetermineScreensPaletteSet : TXA : AND.b #$FE : STA $04
;LDA.b $8A : JSR OWDetermineScreensPaletteSet : TXA : AND.b #$FE
;CMP.b $04 : BNE .skip_palettes
BRA .vanilla+1
.vanilla
PLP
LDA.b $05 : AND.b #$3F : BEQ .skip_palettes ; what we
LDA.b $8A : AND.b #$BF : BNE .change_palettes ; wrote over, kinda
.skip_palettes
SEC : RTL ; mosaic transition occurs
.change_palettes
CLC : RTL
}
OWAdjustExitPosition:
{
LDA.w $06FC : CMP.b #$60 : BEQ .stone_bridge
@@ -1407,7 +1492,7 @@ dw $0c78, $0ce3, $006b, $0cad, $3434, $0000, $0000, $001b
dw $0ce4, $0d33, $004f, $0d0b, $3434, $0000, $0001, $001c
dw $0d34, $0db8, $0084, $0d76, $3434, $0000, $0000, $001d
dw $0ea8, $0f20, $0078, $0ee4, $3a3a, $0000, $0000, $001e
dw $0f70, $0fa8, $0038, $0f8c, $3a3a, $0000, $0000, $001f
dw $0f78, $0fa8, $0030, $0f90, $3a3a, $0000, $0000, $001f
dw $0f18, $0f18, $0000, $0f18, $3b3b, $0000, $0000, $0020
dw $0fc8, $0fc8, $0000, $0fc8, $3b3b, $0000, $0000, $0021
dw $0e28, $0fb8, $0190, $0ef0, $3c3c, $0000, $0000, $0022
@@ -1482,7 +1567,7 @@ dw $0c78, $0ce3, $006b, $0cad, $3333, $0000, $0000, $001c
dw $0ce4, $0d33, $004f, $0d0b, $3333, $0000, $0001, $001d
dw $0d34, $0db8, $0084, $0d76, $3333, $0000, $0000, $001e
dw $0ea8, $0f20, $0078, $0ee4, $3039, $0000, $0000, $001f
dw $0f70, $0fa8, $0038, $0f8c, $3039, $0000, $0000, $0020
dw $0f78, $0fa8, $0030, $0f90, $3039, $0000, $0000, $0020
dw $0f18, $0f18, $0000, $0f18, $3a3a, $0000, $0000, $0021
dw $0fc8, $0fc8, $0000, $0fc8, $3a3a, $0000, $0000, $0022
dw $0e28, $0fb8, $0190, $0ef0, $3b3b, $0000, $0000, $0023
Binary file not shown.
+8
View File
@@ -4,7 +4,15 @@ settings:
1:
mode: standard
ow_mixed: true
entrances:
1:
entrances:
Sanctuary Grave: Sewer Drop
two-way:
Sanctuary: Sanctuary Exit
ow-tileflips:
1:
force_no_flip:
- 0x13
undefined_chance: 100
+3
View File
@@ -171,6 +171,9 @@ def do_vanilla_connections(avail_pool):
connect_vanilla_two_way(ent, avail_pool.default_map[ent], avail_pool)
if ent in avail_pool.one_way_map and avail_pool.one_way_map[ent] in avail_pool.exits:
connect_vanilla(ent, avail_pool.one_way_map[ent], avail_pool)
if avail_pool.inverted:
ext = avail_pool.world.get_entrance('Dark Sanctuary Hint Exit', avail_pool.player)
ext.connect(avail_pool.world.get_region('Dark Chapel Area', avail_pool.player))
def do_main_shuffle(entrances, exits, avail, mode_def):