Merge branch 'OverworldShuffleDev' into OverworldShuffle
This commit is contained in:
@@ -1,5 +1,12 @@
|
||||
# Changelog
|
||||
|
||||
## 0.3.0.2
|
||||
- \~Merged in DR v1.2.0.12~
|
||||
- Fixed some door landing issues
|
||||
- Added Cold Fairy Statue as a new Bonk Location in Bonk Drop Shuffle
|
||||
- Added Customizer support for enabling OWR Options
|
||||
- Removed `Arrows (5)` item from Item Table, replaces with `Arrows (10)`
|
||||
|
||||
## 0.3.0.1
|
||||
- \~Merged in DR v1.2.0.10~
|
||||
- Fixed some door landing issues
|
||||
|
||||
2
Fill.py
2
Fill.py
@@ -538,7 +538,7 @@ def ensure_good_pots(world, write_skips=False):
|
||||
and (loc.type != LocationType.Pot or loc.item.player != loc.player)):
|
||||
loc.item = ItemFactory(invalid_location_replacement[loc.item.name], loc.item.player)
|
||||
if (loc.item.name in {'Arrows (5)'}
|
||||
and (loc.type not in [LocationType.Pot, LocationType.Bonk] or loc.item.player != loc.player)):
|
||||
and (loc.type != LocationType.Pot or loc.item.player != loc.player)):
|
||||
loc.item = ItemFactory(invalid_location_replacement[loc.item.name], loc.item.player)
|
||||
# # can be placed here by multiworld balancing or shop balancing
|
||||
# # change it to something normal for the player it got swapped to
|
||||
|
||||
30
ItemList.py
30
ItemList.py
@@ -392,20 +392,6 @@ def generate_itempool(world, player):
|
||||
for i in range(4):
|
||||
next(adv_heart_pieces).advancement = True
|
||||
|
||||
beeweights = {'0': {None: 100},
|
||||
'1': {None: 75, 'trap': 25},
|
||||
'2': {None: 40, 'trap': 40, 'bee': 20},
|
||||
'3': {'trap': 50, 'bee': 50},
|
||||
'4': {'trap': 100}}
|
||||
def beemizer(item):
|
||||
if world.beemizer[item.player] and not item.advancement and not item.priority and not item.type:
|
||||
choice = random.choices(list(beeweights[world.beemizer[item.player]].keys()), weights=list(beeweights[world.beemizer[item.player]].values()))[0]
|
||||
return item if not choice else ItemFactory("Bee Trap", player) if choice == 'trap' else ItemFactory("Bee", player)
|
||||
return item
|
||||
|
||||
if not skip_pool_adjustments:
|
||||
world.itempool += [beemizer(item) for item in items]
|
||||
else:
|
||||
world.itempool += items
|
||||
|
||||
# shuffle medallions
|
||||
@@ -463,6 +449,20 @@ def generate_itempool(world, player):
|
||||
# modfiy based on start inventory, if any
|
||||
modify_pool_for_start_inventory(start_inventory, world, player)
|
||||
|
||||
beeweights = {'0': {None: 100},
|
||||
'1': {None: 75, 'trap': 25},
|
||||
'2': {None: 40, 'trap': 40, 'bee': 20},
|
||||
'3': {'trap': 50, 'bee': 50},
|
||||
'4': {'trap': 100}}
|
||||
def beemizer(item):
|
||||
if world.beemizer[item.player] and not item.advancement and not item.priority and not item.type:
|
||||
choice = random.choices(list(beeweights[world.beemizer[item.player]].keys()), weights=list(beeweights[world.beemizer[item.player]].values()))[0]
|
||||
return item if not choice else ItemFactory("Bee Trap", player) if choice == 'trap' else ItemFactory("Bee", player)
|
||||
return item
|
||||
|
||||
if not skip_pool_adjustments:
|
||||
world.itempool = [beemizer(item) for item in world.itempool]
|
||||
|
||||
# increase pool if not enough items
|
||||
ttl_locations = sum(1 for x in world.get_unfilled_locations(player) if '- Prize' not in x.name)
|
||||
pool_size = count_player_dungeon_item_pool(world, player)
|
||||
@@ -1104,6 +1104,8 @@ def get_pool_core(world, player, progressive, shuffle, difficulty, treasure_hunt
|
||||
pool.remove('Fighter Sword')
|
||||
pool.extend(['Rupees (50)'])
|
||||
|
||||
#TODO: Remove test placements
|
||||
#place_item('Purple Chest', 'Magic Mirror')
|
||||
if timer in ['timed', 'timed-countdown']:
|
||||
pool.extend(diff.timedother)
|
||||
clock_mode = 'stopwatch' if timer == 'timed' else 'countdown'
|
||||
|
||||
3
Items.py
3
Items.py
@@ -80,7 +80,7 @@ item_table = {'Bow': (True, False, None, 0x0B, 200, 'You have\nchosen the\narche
|
||||
'Arrow Upgrade (+10)': (False, False, None, 0x54, 100, 'Increase arrow\nstorage, low\nlow price', 'and the quiver', 'quiver-enlarging kid', 'arrow boost for sale', 'witch and more skewers', 'upgrade boy sews more again', 'arrow capacity'),
|
||||
'Arrow Upgrade (+5)': (False, False, None, 0x53, 100, 'Increase arrow\nstorage, low\nlow price', 'and the quiver', 'quiver-enlarging kid', 'arrow boost for sale', 'witch and more skewers', 'upgrade boy sews more again', 'arrow capacity'),
|
||||
'Single Bomb': (False, False, None, 0x27, 5, 'I make things\ngo BOOM! But\njust once.', 'and the explosion', 'the bomb-holding kid', 'firecracker for sale', 'blend fungus into bomb', '\'splosion boy explodes again', 'a bomb'),
|
||||
'Arrows (5)': (False, False, None, 0xB5, 15, 'This will give\nyou five shots\nwith your bow!', 'and the arrow pack', 'stick-collecting kid', 'sewing kit for sale', 'fungus for arrows', 'archer boy sews again', 'five arrows'),
|
||||
'Arrows (5)': (False, False, None, 0x5A, 15, 'This will give\nyou five shots\nwith your bow!', 'and the arrow pack', 'stick-collecting kid', 'sewing kit for sale', 'fungus for arrows', 'archer boy sews again', 'five arrows'),
|
||||
'Small Magic': (False, False, None, 0x45, 5, 'A bit of magic', 'and the bit of magic', 'bit-o-magic kid', 'magic bit for sale', 'fungus for magic', 'magic boy conjures again', 'a bit of magic'),
|
||||
'Big Magic': (False, False, None, 0xB4, 40, 'A lot of magic', 'and lots of magic', 'lot-o-magic kid', 'magic refill for sale', 'fungus for magic', 'magic boy conjures again', 'a magic refill'),
|
||||
'Chicken': (False, False, None, 0xB3, 5, 'Cucco of Legend', 'and the legendary cucco', 'chicken kid', 'fried chicken for sale', 'fungus for chicken', 'cucco boy clucks again', 'a cucco'),
|
||||
@@ -175,6 +175,7 @@ item_table = {'Bow': (True, False, None, 0x0B, 200, 'You have\nchosen the\narche
|
||||
'Green Potion': (False, False, None, 0x2F, 60, 'Refreshing green goop!', 'and the green goo', 'the liquid kid', 'potion for sale', 'free samples', 'bottle boy has green goo again', 'a green potion'),
|
||||
'Blue Potion': (False, False, None, 0x30, 160, 'Delicious blue goop!', 'and the blue goo', 'the liquid kid', 'potion for sale', 'free samples', 'bottle boy has blue goo again', 'a blue potion'),
|
||||
'Bee': (False, False, None, 0x0E, 10, 'I will sting your foes a few times', 'and the sting buddy', 'the beekeeper kid', 'insect for sale', 'shroom pollenation', 'bottle boy has mad bee again', 'a bee'),
|
||||
'Good Bee': (False, False, None, 0xB5, 10, 'I will sting your foes a lot', 'and the cold buddy', 'the beekeeper kid', 'cold insect for sale', 'shroom pollenation', 'bottle boy has cold bee again', 'a good bee'),
|
||||
'Small Heart': (False, False, None, 0x42, 10, 'Just a little\npiece of love!', 'and the heart', 'the life-giving kid', 'little love for sale', 'fungus for life', 'life boy feels some love again', 'a heart'),
|
||||
'Apples': (False, False, None, 0xB1, 30, 'Just a few pieces of fruit!', 'and the juicy fruit', 'the fruity kid', 'the fruit stand', 'expired fruit', 'bottle boy has fruit again', 'an apple hoard'),
|
||||
'Fairy': (False, False, None, 0xB2, 50, 'Just a pixie!', 'and the pixie', 'the pixie kid', 'pixie for sale', 'pixie fungus', 'bottle boy has pixie again', 'a pixie'),
|
||||
|
||||
2
Main.py
2
Main.py
@@ -36,7 +36,7 @@ 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.10u'
|
||||
__version__ = '1.2.0.12u'
|
||||
|
||||
from source.classes.BabelFish import BabelFish
|
||||
|
||||
|
||||
@@ -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.1'
|
||||
version_number = '0.3.0.2'
|
||||
# branch indicator is intentionally different across branches
|
||||
version_branch = ''
|
||||
|
||||
|
||||
@@ -108,6 +108,16 @@ These are now independent of retro mode and have three options: None, Random, an
|
||||
* Bonk Fairy (Dark)
|
||||
|
||||
# Bug Fixes and Notes
|
||||
* 1.2.0.12u
|
||||
* Fix for mirror portal in inverted
|
||||
* Yet another fix for blocked door in Standard ER
|
||||
* 1.2.0.11u
|
||||
* Fixed an issue with lower layer doors in Standard
|
||||
* Fix for doors in cave state (will no longer be vanilla)
|
||||
* Added a logic rule for th murderdactyl near bumper ledge for OHKO purposes
|
||||
* Enemizer alteration for Hovers and normal enemies in shallow water
|
||||
* Fix for beemizer including modes with an increased item pool
|
||||
* Fix for district algorithm
|
||||
* 1.2.0.10u
|
||||
* Fixed overrun issues with edge transitions
|
||||
* Better support for customized start_inventory with dungeon items
|
||||
|
||||
@@ -688,6 +688,8 @@ def create_dungeon_regions(world, player):
|
||||
create_dungeon_region(player, 'Thieves Big Chest Nook', 'Thieves\' Town', ['Thieves\' Town - Big Key Chest'], ['Thieves Big Chest Nook ES Edge']),
|
||||
create_dungeon_region(player, 'Thieves Hallway', 'Thieves\' Town', ['Thieves\' Town - Hallway Pot Key'], ['Thieves Hallway SE', 'Thieves Hallway NE', 'Thieves Hallway WN', 'Thieves Hallway WS']),
|
||||
create_dungeon_region(player, 'Thieves Boss', 'Thieves\' Town', ['Revealing Light', 'Thieves\' Town - Boss', 'Thieves\' Town - Prize'], ['Thieves Boss SE']),
|
||||
#create_dungeon_region(player, 'Thieves Boss', 'Thieves\' Town', ['Thieves\' Town - Boss', 'Thieves\' Town - Prize'], ['Revealing Light', 'Thieves Boss SE']),
|
||||
#create_dungeon_region(player, 'Thieves Revealing Light', 'Thieves\' Town', ['Revealing Light'], ['Thieves Boss Room']),
|
||||
create_dungeon_region(player, 'Thieves Pot Alcove Mid', 'Thieves\' Town', None, ['Thieves Pot Alcove Mid ES', 'Thieves Pot Alcove Mid WS']),
|
||||
create_dungeon_region(player, 'Thieves Pot Alcove Bottom', 'Thieves\' Town', None, ['Thieves Pot Alcove Bottom SW']),
|
||||
create_dungeon_region(player, 'Thieves Pot Alcove Top', 'Thieves\' Town', None, ['Thieves Pot Alcove Top NW']),
|
||||
@@ -1304,7 +1306,8 @@ bonk_prize_table = {
|
||||
'Dark Tree Line Tree 2': (0x26, 0x10, False, '', 'Dark Tree Line Area', 'in a tree'),
|
||||
'Dark Tree Line Tree 3': (0x27, 0x08, False, '', 'Dark Tree Line Area', 'in a tree'),
|
||||
'Dark Tree Line Tree 4': (0x28, 0x04, False, '', 'Dark Tree Line Area', 'in a tree'),
|
||||
'Hype Cave Statue': (0x29, 0x10, False, '', 'Hype Cave Area', 'encased in stone')
|
||||
'Hype Cave Statue': (0x29, 0x10, False, '', 'Hype Cave Area', 'encased in stone'),
|
||||
'Cold Fairy Statue': (0x2a, 0x02, False, '', 'Good Bee Cave', 'encased in stone')
|
||||
}
|
||||
|
||||
bonk_table_by_location_id = {0x2ABB00+(data[0]*6)+3: name for name, data in bonk_prize_table.items()}
|
||||
|
||||
21
Rom.py
21
Rom.py
@@ -38,7 +38,7 @@ from source.dungeon.RoomList import Room0127
|
||||
|
||||
|
||||
JAP10HASH = '03a63945398191337e896e5771f77173'
|
||||
RANDOMIZERBASEHASH = '7043e64e74b2452367de7cc146873524'
|
||||
RANDOMIZERBASEHASH = '4458a348e3040d79d0e28d572579fcb5'
|
||||
|
||||
|
||||
class JsonRom(object):
|
||||
@@ -686,7 +686,7 @@ def patch_rom(world, rom, player, team, enemized, is_mystery=False):
|
||||
flute_spots = default_flute_connections
|
||||
else:
|
||||
flute_spots = world.owflutespots[player]
|
||||
owFlags |= 0x100
|
||||
owFlags |= 0x0100
|
||||
|
||||
for o in range(0, len(flute_spots)):
|
||||
owslot = flute_spots[o]
|
||||
@@ -740,12 +740,12 @@ def patch_rom(world, rom, player, team, enemized, is_mystery=False):
|
||||
owMode = 2
|
||||
|
||||
if world.owKeepSimilar[player] and (world.owShuffle[player] != 'vanilla' or world.owCrossed[player] in ['limited', 'chaos']):
|
||||
owMode |= 0x100
|
||||
owMode |= 0x0100
|
||||
if world.owCrossed[player] != 'none' and (world.owCrossed[player] != 'polar' or world.owMixed[player]):
|
||||
owMode |= 0x200
|
||||
owMode |= 0x0200
|
||||
world.fix_fake_world[player] = True
|
||||
if world.owMixed[player]:
|
||||
owMode |= 0x400
|
||||
owMode |= 0x0400
|
||||
|
||||
# patches map data specific for OW Shuffle
|
||||
#inverted_buffer[0x03] = inverted_buffer[0x03] | 0x2 # convenient portal on WDM
|
||||
@@ -793,7 +793,7 @@ def patch_rom(world, rom, player, team, enemized, is_mystery=False):
|
||||
# for prize, address in zip(bonk_prizes, bonk_addresses):
|
||||
# rom.write_byte(address, prize)
|
||||
|
||||
owFlags |= 0x200
|
||||
owFlags |= 0x0200
|
||||
|
||||
# setting spriteID to D8, a placeholder sprite we use to inform ROM to spawn a dynamic item
|
||||
#for address in bonk_addresses:
|
||||
@@ -803,6 +803,8 @@ def patch_rom(world, rom, player, team, enemized, is_mystery=False):
|
||||
rom.write_byte(snes_to_pc(0x09AE32), 0xD8)
|
||||
rom.write_byte(snes_to_pc(0x09AE35), 0xD8)
|
||||
|
||||
rom.write_byte(snes_to_pc(0x06918E), 0x80) # skip good bee bottle check
|
||||
|
||||
write_int16(rom, 0x150002, owMode)
|
||||
write_int16(rom, 0x150004, owFlags)
|
||||
|
||||
@@ -1649,6 +1651,7 @@ def patch_rom(world, rom, player, team, enemized, is_mystery=False):
|
||||
if world.shuffle_bonk_drops[player]:
|
||||
# warning, this temporary patch might cause fairies to respawn differently?, limiting this to bonk drop mode only
|
||||
rom.write_byte(snes_to_pc(0x0DB808), 0x03) # patch fairies sprites to not permadeath like enemies
|
||||
rom.write_byte(snes_to_pc(0x1DF6D8), 0) # allows sprites to travel across water / same flag as write_enemizer_tweaks
|
||||
|
||||
# allow smith into multi-entrance caves in appropriate shuffles
|
||||
if world.shuffle[player] in ['restricted', 'full', 'lite', 'lean', 'crossed', 'insanity'] or (world.shuffle[player] == 'simple' and world.mode[player] == 'inverted'):
|
||||
@@ -1695,6 +1698,7 @@ def patch_rom(world, rom, player, team, enemized, is_mystery=False):
|
||||
raise Exception('Pot table is too big for current area')
|
||||
world.pot_contents[player].write_pot_data_to_rom(rom, colorize_pots)
|
||||
|
||||
write_enemizer_tweaks(rom, world, player)
|
||||
write_strings(rom, world, player, team)
|
||||
|
||||
# write initial sram
|
||||
@@ -1785,6 +1789,11 @@ def write_custom_shops(rom, world, player):
|
||||
rom.write_bytes(0x184900, items_data)
|
||||
|
||||
|
||||
def write_enemizer_tweaks(rom, world, player):
|
||||
if world.enemy_shuffle[player] != 'none':
|
||||
rom.write_byte(snes_to_pc(0x1DF6D8), 0) # lets enemies walk on water instead of clipping into infinity?
|
||||
rom.write_byte(snes_to_pc(0x0DB6B3), 0x82) # hovers don't need water necessarily?
|
||||
|
||||
def hud_format_text(text):
|
||||
output = bytes()
|
||||
for char in text.lower():
|
||||
|
||||
7
Rules.py
7
Rules.py
@@ -862,7 +862,9 @@ def default_rules(world, player):
|
||||
from Regions import bonk_prize_table
|
||||
for location_name, (_, _, aga_required, _, _, _) in bonk_prize_table.items():
|
||||
loc = world.get_location(location_name, player)
|
||||
if not aga_required:
|
||||
if location_name == 'Cold Fairy Statue':
|
||||
set_rule(loc, lambda state: state.can_use_bombs(player) and state.can_collect_bonkdrops(player))
|
||||
elif not aga_required:
|
||||
set_rule(loc, lambda state: state.can_collect_bonkdrops(player))
|
||||
else:
|
||||
set_rule(loc, lambda state: state.can_collect_bonkdrops(player) and state.has_beaten_aga(player))
|
||||
@@ -921,6 +923,8 @@ def default_rules(world, player):
|
||||
set_rule(world.get_entrance('Desert Pass Rocks (South)', player), lambda state: state.can_lift_rocks(player))
|
||||
set_rule(world.get_entrance('Skull Woods Bush Rock (West)', player), lambda state: state.can_lift_rocks(player))
|
||||
set_rule(world.get_entrance('Skull Woods Bush Rock (East)', player), lambda state: state.can_lift_rocks(player))
|
||||
# this more like an ohko rule - dependent on bird being present too - so enemizer could turn this off?
|
||||
set_rule(world.get_entrance('Bumper Cave Ledge Drop', player), lambda state: (state.has('Cape', player) or state.has('Cane of Byrna', player) or state.has_sword(player)))
|
||||
set_rule(world.get_entrance('Bumper Cave Entrance Rock', player), lambda state: state.can_lift_rocks(player))
|
||||
set_rule(world.get_entrance('Skull Woods Pass Rock (North)', player), lambda state: state.can_lift_heavy_rocks(player))
|
||||
set_rule(world.get_entrance('Skull Woods Pass Rock (South)', player), lambda state: state.can_lift_heavy_rocks(player))
|
||||
@@ -1157,6 +1161,7 @@ def ow_bunny_rules(world, player):
|
||||
add_bunny_rule(world.get_entrance('Skull Woods Forgotten Bush (East)', player), player)
|
||||
add_bunny_rule(world.get_entrance('Skull Woods Second Section Hole', player), player)
|
||||
add_bunny_rule(world.get_entrance('East Dark Death Mountain Bushes', player), player)
|
||||
add_bunny_rule(world.get_entrance('Bumper Cave Ledge Drop', player), player)
|
||||
add_bunny_rule(world.get_entrance('Bumper Cave Entrance Rock', player), player)
|
||||
add_bunny_rule(world.get_entrance('Skull Woods Pass Bush Row (West)', player), player)
|
||||
add_bunny_rule(world.get_entrance('Skull Woods Pass Bush Row (East)', player), player)
|
||||
|
||||
@@ -130,6 +130,7 @@ bonk_prize_lookup = {
|
||||
'Chicken': (0x0b, 0, None),
|
||||
'Bee Trap': (0x79, 6, None),
|
||||
'Apples': (0xac, 8, None),
|
||||
'Good Bee': (0xb2, 1, None),
|
||||
'Small Heart': (0xd8, 2, None),
|
||||
'Rupee (1)': (0xd9, 0, None),
|
||||
'Rupees (5)': (0xda, 3, None), # TODO: add in murahdahla tree rupee
|
||||
|
||||
146
asm/owrando.asm
146
asm/owrando.asm
@@ -157,6 +157,14 @@ and #$7f : eor #$40 : nop #2
|
||||
|
||||
org $06AD4C
|
||||
jsl.l OWBonkDrops : nop #4
|
||||
org $1EDE6F
|
||||
jsl.l OWBonkGoodBeeDrop : bra +
|
||||
GoldBee_SpawnSelf_SetProperties:
|
||||
phb : lda.b #$1E : pha : plb ; switch to bank 1E
|
||||
jsr GoldBee_SpawnSelf+12
|
||||
plb : rtl
|
||||
nop #3
|
||||
+
|
||||
|
||||
;Code
|
||||
org $aa8800
|
||||
@@ -395,6 +403,112 @@ LoadMapDarkOrMixed:
|
||||
dw $0400+$0210 ; bottom right
|
||||
}
|
||||
|
||||
OWBonkGoodBeeDrop:
|
||||
{
|
||||
LDA.l OWFlags+1 : AND.b #$02 : BNE .shuffled
|
||||
.vanilla ; what we wrote over
|
||||
STZ.w $0DD0,X
|
||||
LDA.l BottleContentsOne : ORA.l BottleContentsTwo
|
||||
ORA.l BottleContentsThree : ORA.l BottleContentsFour
|
||||
RTL
|
||||
.shuffled
|
||||
PHY : TXY
|
||||
LDA.l RoomDataWRAM[$0120].high : AND.b #$02 : PHA : BNE + ; check if collected
|
||||
LDA.b #$1B : STA $12F ; JSL Sound_SetSfx3PanLong ; seems that when you bonk, there is a pending bonk sfx, so we clear that out and replace with reveal secret sfx
|
||||
+
|
||||
LDA.l OWBonkPrizeData+(42*6+4) : BEQ + ; multiworld item
|
||||
LDA.l OWBonkPrizeData+(42*6+3)
|
||||
JMP .spawn_item
|
||||
+
|
||||
|
||||
.determine_type ; S = Collected, FlagBitmask, X (row + 2)
|
||||
LDA.l OWBonkPrizeData+(42*6+3) ; A = item id
|
||||
CMP.b #$B0 : BNE +
|
||||
LDA.b #$79 : JMP .sprite_transform ; transform to bees
|
||||
+ CMP.b #$42 : BNE +
|
||||
JSL.l Sprite_TransmuteToBomb ; transform a heart to bomb, vanilla behavior
|
||||
JMP .mark_collected
|
||||
+ CMP.b #$34 : BNE +
|
||||
LDA.b #$D9 : JMP .sprite_transform ; transform to single rupee
|
||||
+ CMP.b #$35 : BNE +
|
||||
LDA.b #$DA : JMP .sprite_transform ; transform to blue rupee
|
||||
+ CMP.b #$36 : BNE +
|
||||
LDA.b #$DB : BRA .sprite_transform ; transform to red rupee
|
||||
+ CMP.b #$27 : BNE +
|
||||
LDA.b #$DC : BRA .sprite_transform ; transform to 1 bomb
|
||||
+ CMP.b #$28 : BNE +
|
||||
LDA.b #$DD : BRA .sprite_transform ; transform to 4 bombs
|
||||
+ CMP.b #$31 : BNE +
|
||||
LDA.b #$DE : BRA .sprite_transform ; transform to 8 bombs
|
||||
+ CMP.b #$45 : BNE +
|
||||
LDA.b #$DF : BRA .sprite_transform ; transform to small magic
|
||||
+ CMP.b #$B4 : BNE +
|
||||
LDA.b #$E0 : BRA .sprite_transform ; transform to big magic
|
||||
+ CMP.b #$B5 : BNE +
|
||||
LDA.b #$79 : JSL.l OWBonkSpritePrep
|
||||
JSL.l GoldBee_SpawnSelf_SetProperties ; transform to good bee
|
||||
BRA .mark_collected
|
||||
+ CMP.b #$44 : BNE +
|
||||
LDA.b #$E2 : BRA .sprite_transform ; transform to 10 arrows
|
||||
+ CMP.b #$B1 : BNE +
|
||||
LDA.b #$AC : BRA .sprite_transform ; transform to apples
|
||||
+ CMP.b #$B2 : BNE +
|
||||
LDA.b #$E3 : BRA .sprite_transform ; transform to fairy
|
||||
+ CMP.b #$B3 : BNE .spawn_item
|
||||
INX : INX : LDA.l OWBonkPrizeData+(42*6+5)
|
||||
CLC : ADC.b #$08 : PHA
|
||||
LDA.w $0D00,Y : SEC : SBC.b 1,S : STA.w $0D00,Y
|
||||
LDA.w $0D20,Y : SBC.b #$00 : STA.w $0D20,Y : PLX
|
||||
LDA.b #$0B : SEC ; BRA .sprite_transform ; transform to chicken
|
||||
|
||||
.sprite_transform
|
||||
JSL.l OWBonkSpritePrep
|
||||
|
||||
.mark_collected ; S = Collected
|
||||
PLA : BNE .return
|
||||
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
|
||||
|
||||
; 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 OWBonkPrizeData+(42*6+4) : STA.l !MULTIWORLD_SPRITEITEM_PLAYER_ID
|
||||
|
||||
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
|
||||
|
||||
; affects the rate the item moves in the Y/X direction
|
||||
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 #$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 OW event bitmask flag, uses free RAM
|
||||
LDA.l OWBonkPrizeData+(42*6+2) : STA.w $0ED0,Y
|
||||
|
||||
; determines the initial spawn point of item
|
||||
LDA.w $0D00,Y : SEC : SBC.l OWBonkPrizeData+(42*6+5) : STA.w $0D00,Y
|
||||
LDA.w $0D20,Y : SBC #$00 : STA.w $0D20,Y
|
||||
|
||||
LDA.b #$01 : STA !REDRAW : STA !FORCE_HEART_SPAWN
|
||||
|
||||
.return
|
||||
PLY
|
||||
LDA #$08 ; makes original good bee not spawn
|
||||
RTL
|
||||
nop #20
|
||||
}
|
||||
|
||||
; Y = sprite slot index of bonk sprite
|
||||
OWBonkDrops:
|
||||
{
|
||||
@@ -439,7 +553,7 @@ OWBonkDrops:
|
||||
+ CMP.b #$34 : BNE +
|
||||
LDA.b #$D9 : CLC : JMP .sprite_transform ; transform to single rupee
|
||||
+ CMP.b #$35 : BNE +
|
||||
LDA.b #$DA : CLC : BRA .sprite_transform ; transform to blue rupee
|
||||
LDA.b #$DA : CLC : JMP .sprite_transform ; transform to blue rupee
|
||||
+ CMP.b #$36 : BNE +
|
||||
LDA.b #$DB : CLC : BRA .sprite_transform ; transform to red rupee
|
||||
+ CMP.b #$27 : BNE +
|
||||
@@ -453,7 +567,9 @@ OWBonkDrops:
|
||||
+ CMP.b #$B4 : BNE +
|
||||
LDA.b #$E0 : CLC : BRA .sprite_transform ; transform to big magic
|
||||
+ CMP.b #$B5 : BNE +
|
||||
LDA.b #$E1 : CLC : BRA .sprite_transform ; transform to 5 arrows
|
||||
LDA.b #$79 : JSL.l OWBonkSpritePrep
|
||||
JSL.l GoldBee_SpawnSelf_SetProperties ; transform to good bee
|
||||
BRA .mark_collected
|
||||
+ CMP.b #$44 : BNE +
|
||||
LDA.b #$E2 : CLC : BRA .sprite_transform ; transform to 10 arrows
|
||||
+ CMP.b #$B1 : BNE +
|
||||
@@ -468,14 +584,7 @@ OWBonkDrops:
|
||||
LDA.b #$0B : SEC ; BRA .sprite_transform ; transform to chicken
|
||||
|
||||
.sprite_transform
|
||||
STA.w $0E20,Y
|
||||
TYX : JSL.l Sprite_LoadProperties
|
||||
BEQ +
|
||||
; these are sprite properties that make it fall out of the tree to the east
|
||||
LDA #$30 : STA $0F80,Y ; amount of force (related to speed)
|
||||
LDA #$10 : STA $0D50,Y ; eastward rate of speed
|
||||
LDA #$FF : STA $0B58,Y ; expiration timer
|
||||
+
|
||||
JSL.l OWBonkSpritePrep
|
||||
|
||||
.mark_collected ; S = Collected, FlagBitmask, X (row + 2)
|
||||
PLA : BNE + ; S = FlagBitmask, X (row + 2)
|
||||
@@ -495,8 +604,7 @@ OWBonkDrops:
|
||||
|
||||
LDA.b #$01 : STA !REDRAW
|
||||
|
||||
LDA.b #$EB
|
||||
STA.l $7FFE00
|
||||
LDA.b #$EB : STA.l $7FFE00
|
||||
JSL Sprite_SpawnDynamically+15 ; +15 to skip finding a new slot, use existing sprite
|
||||
|
||||
; affects the rate the item moves in the Y/X direction
|
||||
@@ -525,6 +633,19 @@ OWBonkDrops:
|
||||
PLA : PLA : PLB : RTL
|
||||
}
|
||||
|
||||
; A = SpriteID, Y = Sprite Slot Index, X = free/overwritten
|
||||
OWBonkSpritePrep:
|
||||
{
|
||||
STA.w $0E20,Y
|
||||
TYX : JSL.l Sprite_LoadProperties
|
||||
BEQ +
|
||||
; these are sprite properties that make it fall out of the tree to the east
|
||||
LDA #$30 : STA $0F80,Y ; amount of force (related to speed)
|
||||
LDA #$10 : STA $0D50,Y ; eastward rate of speed
|
||||
LDA #$FF : STA $0B58,Y ; expiration timer
|
||||
+ RTL
|
||||
}
|
||||
|
||||
org $aa9000
|
||||
OWDetectEdgeTransition:
|
||||
{
|
||||
@@ -1539,6 +1660,7 @@ db $6e, $8c, $10, $35, $00, $10
|
||||
db $6e, $90, $08, $b0, $00, $10
|
||||
db $6e, $a4, $04, $b1, $00, $10
|
||||
db $74, $4e, $10, $b1, $00, $1c
|
||||
db $ff, $00, $02, $b5, $00, $08
|
||||
|
||||
; temporary fix - murahdahla replaces one of the bonk tree prizes
|
||||
; so we copy the sprite table here and update the pointer
|
||||
|
||||
Binary file not shown.
@@ -17,6 +17,13 @@ settings:
|
||||
shopsanity: true
|
||||
shuffle: crossed
|
||||
shufflelinks: true
|
||||
ow_shuffle: parallel
|
||||
ow_terrain: true
|
||||
ow_crossed: grouped
|
||||
ow_keepsimilar: true
|
||||
ow_mixed: true
|
||||
ow_whirlpool: true
|
||||
ow_fluteshuffle: balanced
|
||||
shufflebosses: unique
|
||||
item_pool:
|
||||
1:
|
||||
|
||||
@@ -72,7 +72,13 @@ class CustomSettings(object):
|
||||
args.mystery = True
|
||||
else:
|
||||
settings = defaultdict(lambda: None, player_setting)
|
||||
args.ow_shuffle[p] = get_setting(settings['ow_shuffle'], args.ow_shuffle[p])
|
||||
args.ow_terrain[p] = get_setting(settings['ow_terrain'], args.ow_terrain[p])
|
||||
args.ow_crossed[p] = get_setting(settings['ow_crossed'], args.ow_crossed[p])
|
||||
args.ow_keepsimilar[p] = get_setting(settings['ow_keepsimilar'], args.ow_keepsimilar[p])
|
||||
args.ow_mixed[p] = get_setting(settings['ow_mixed'], args.ow_mixed[p])
|
||||
args.ow_whirlpool[p] = get_setting(settings['ow_whirlpool'], args.ow_whirlpool[p])
|
||||
args.ow_fluteshuffle[p] = get_setting(settings['ow_fluteshuffle'], args.ow_fluteshuffle[p])
|
||||
args.shuffle[p] = get_setting(settings['shuffle'], args.shuffle[p])
|
||||
args.door_shuffle[p] = get_setting(settings['door_shuffle'], args.door_shuffle[p])
|
||||
args.logic[p] = get_setting(settings['logic'], args.logic[p])
|
||||
@@ -130,8 +136,8 @@ class CustomSettings(object):
|
||||
args.mapshuffle[p] = True
|
||||
args.compassshuffle[p] = True
|
||||
|
||||
args.shufflebosses[p] = get_setting(settings['shufflebosses'], args.shufflebosses[p])
|
||||
args.shuffleenemies[p] = get_setting(settings['shuffleenemies'], args.shuffleenemies[p])
|
||||
args.shufflebosses[p] = get_setting(settings['boss_shuffle'], args.shufflebosses[p])
|
||||
args.shuffleenemies[p] = get_setting(settings['enemy_shuffle'], args.shuffleenemies[p])
|
||||
args.enemy_health[p] = get_setting(settings['enemy_health'], args.enemy_health[p])
|
||||
args.enemy_damage[p] = get_setting(settings['enemy_damage'], args.enemy_damage[p])
|
||||
args.shufflepots[p] = get_setting(settings['shufflepots'], args.shufflepots[p])
|
||||
|
||||
@@ -426,7 +426,8 @@ def filter_locations(item_to_place, locations, world, vanilla_skip=False, potion
|
||||
return filtered if len(filtered) > 0 else locations
|
||||
if world.algorithm == 'district':
|
||||
config = world.item_pool_config
|
||||
if item_to_place == 'Placeholder' or item_to_place.name in config.item_pool[item_to_place.player]:
|
||||
if ((isinstance(item_to_place,str) and item_to_place == 'Placeholder')
|
||||
or item_to_place.name in config.item_pool[item_to_place.player]):
|
||||
restricted = config.location_groups[0].locations
|
||||
filtered = [l for l in locations if l.name in restricted and l.player in restricted[l.name]]
|
||||
return filtered if len(filtered) > 0 else locations
|
||||
@@ -820,7 +821,7 @@ trash_items = {
|
||||
'Nothing': -1,
|
||||
'Bee Trap': 0,
|
||||
'Rupee (1)': 1, 'Rupees (5)': 1, 'Small Heart': 1, 'Bee': 1, 'Arrows (5)': 1, 'Chicken': 1, 'Single Bomb': 1,
|
||||
'Rupees (20)': 2, 'Small Magic': 2,
|
||||
'Rupees (20)': 2, 'Small Magic': 2, 'Good Bee': 2,
|
||||
'Bombs (3)': 3, 'Arrows (10)': 3, 'Bombs (10)': 3, 'Apples': 3,
|
||||
'Fairy': 4, 'Big Magic': 4, 'Red Potion': 4, 'Blue Shield': 4, 'Rupees (50)': 4, 'Rupees (100)': 4,
|
||||
'Rupees (300)': 5,
|
||||
|
||||
@@ -444,10 +444,12 @@ def do_holes_and_linked_drops(entrances, exits, avail, cross_world, keep_togethe
|
||||
random.shuffle(hole_entrances)
|
||||
if not cross_world and 'Sanctuary Grave' in holes_to_shuffle:
|
||||
hc = avail.world.get_entrance('Hyrule Castle Exit (South)', avail.player)
|
||||
chosen_entrance = None
|
||||
if hc.connected_region and hc.connected_region.type == RegionType.DarkWorld:
|
||||
chosen_entrance = next(entrance for entrance in hole_entrances if entrance[0] in DW_Entrances)
|
||||
if not chosen_entrance:
|
||||
chosen_entrance = next(entrance for entrance in hole_entrances if entrance[0] in LW_Entrances)
|
||||
if chosen_entrance:
|
||||
hole_entrances.remove(chosen_entrance)
|
||||
sanc_interior = next(target for target in hole_targets if target[0] == 'Sanctuary Exit')
|
||||
hole_targets.remove(sanc_interior)
|
||||
@@ -1132,6 +1134,9 @@ def do_vanilla_connect(pool_def, avail):
|
||||
elif pool_def['condition'] == 'takeany':
|
||||
if avail.world.take_any[avail.player] == 'fixed':
|
||||
return
|
||||
elif pool_def['condition'] == 'bonk':
|
||||
if avail.world.shuffle_bonk_drops[avail.player]:
|
||||
return
|
||||
defaults = {**default_connections, **(inverted_default_connections if avail.inverted != avail.world.is_tile_swapped(0x1b, avail.player) else open_default_connections)}
|
||||
for entrance in pool_def['entrances']:
|
||||
if entrance in avail.entrances:
|
||||
@@ -1548,7 +1553,7 @@ modes = {
|
||||
'condition': '',
|
||||
'entrances': ['Dark Desert Fairy', 'Archery Game', 'Fortune Teller (Dark)', 'Dark Sanctuary Hint',
|
||||
'Dark Lake Hylia Ledge Hint', 'Dark Lake Hylia Fairy', 'Dark Lake Hylia Shop',
|
||||
'East Dark World Hint', 'Kakariko Gamble Game', 'Good Bee Cave', 'Long Fairy Cave',
|
||||
'East Dark World Hint', 'Kakariko Gamble Game', 'Long Fairy Cave',
|
||||
'Bush Covered House', 'Fortune Teller (Light)', 'Lost Woods Gamble',
|
||||
'Lake Hylia Fortune Teller', 'Lake Hylia Fairy', 'Bonk Fairy (Light)', 'Inverted Dark Sanctuary'],
|
||||
},
|
||||
@@ -1572,7 +1577,11 @@ modes = {
|
||||
'Light World Bomb Hut', '20 Rupee Cave', '50 Rupee Cave', 'Hookshot Fairy',
|
||||
'Palace of Darkness Hint', 'Dark Lake Hylia Ledge Spike Cave',
|
||||
'Dark Desert Hint']
|
||||
|
||||
},
|
||||
'fixed_bonk': {
|
||||
'special': 'vanilla',
|
||||
'condition': 'bonk',
|
||||
'entrances': ['Good Bee Cave']
|
||||
},
|
||||
'item_caves': { # shuffles shops/pottery if they weren't fixed in the last steps
|
||||
'entrances': ['Mimic Cave', 'Spike Cave', 'Mire Shed', 'Dark World Hammer Peg Cave', 'Chest Game',
|
||||
@@ -1580,7 +1589,7 @@ modes = {
|
||||
'Ice Rod Cave', 'Dam', 'Bonk Rock Cave', 'Library', 'Potion Shop', 'Mini Moldorm Cave',
|
||||
'Checkerboard Cave', 'Graveyard Cave', 'Cave 45', 'Sick Kids House', 'Blacksmiths Hut',
|
||||
'Sahasrahlas Hut', 'Aginahs Cave', 'Chicken House', 'Kings Grave', 'Blinds Hideout',
|
||||
'Waterfall of Wishing', 'Cave Shop (Dark Death Mountain)',
|
||||
'Waterfall of Wishing', 'Cave Shop (Dark Death Mountain)', 'Good Bee Cave',
|
||||
'Dark World Potion Shop', 'Dark World Lumberjack Shop', 'Dark World Shop',
|
||||
'Red Shield Shop', 'Kakariko Shop', 'Capacity Upgrade', 'Cave Shop (Lake Hylia)',
|
||||
'Lumberjack House', 'Snitch Lady (West)', 'Snitch Lady (East)', 'Tavern (Front)',
|
||||
@@ -1635,7 +1644,7 @@ modes = {
|
||||
'condition': '',
|
||||
'entrances': ['Dark Desert Fairy', 'Archery Game', 'Fortune Teller (Dark)', 'Dark Sanctuary Hint',
|
||||
'Dark Lake Hylia Ledge Hint', 'Dark Lake Hylia Fairy', 'Dark Lake Hylia Shop',
|
||||
'East Dark World Hint', 'Kakariko Gamble Game', 'Good Bee Cave', 'Long Fairy Cave',
|
||||
'East Dark World Hint', 'Kakariko Gamble Game', 'Long Fairy Cave',
|
||||
'Bush Covered House', 'Fortune Teller (Light)', 'Lost Woods Gamble',
|
||||
'Lake Hylia Fortune Teller', 'Lake Hylia Fairy', 'Bonk Fairy (Light)', 'Inverted Dark Sanctuary'],
|
||||
},
|
||||
@@ -1659,7 +1668,11 @@ modes = {
|
||||
'Light World Bomb Hut', '20 Rupee Cave', '50 Rupee Cave', 'Hookshot Fairy',
|
||||
'Palace of Darkness Hint', 'Dark Lake Hylia Ledge Spike Cave',
|
||||
'Dark Desert Hint']
|
||||
|
||||
},
|
||||
'fixed_bonk': {
|
||||
'special': 'vanilla',
|
||||
'condition': 'bonk',
|
||||
'entrances': ['Good Bee Cave']
|
||||
},
|
||||
'item_caves': { # shuffles shops/pottery if they weren't fixed in the last steps
|
||||
'entrances': ['Mimic Cave', 'Spike Cave', 'Mire Shed', 'Dark World Hammer Peg Cave', 'Chest Game',
|
||||
@@ -1667,7 +1680,7 @@ modes = {
|
||||
'Ice Rod Cave', 'Dam', 'Bonk Rock Cave', 'Library', 'Potion Shop', 'Mini Moldorm Cave',
|
||||
'Checkerboard Cave', 'Graveyard Cave', 'Cave 45', 'Sick Kids House', 'Blacksmiths Hut',
|
||||
'Sahasrahlas Hut', 'Aginahs Cave', 'Chicken House', 'Kings Grave', 'Blinds Hideout',
|
||||
'Waterfall of Wishing', 'Cave Shop (Dark Death Mountain)',
|
||||
'Waterfall of Wishing', 'Cave Shop (Dark Death Mountain)', 'Good Bee Cave',
|
||||
'Dark World Potion Shop', 'Dark World Lumberjack Shop', 'Dark World Shop',
|
||||
'Red Shield Shop', 'Kakariko Shop', 'Capacity Upgrade', 'Cave Shop (Lake Hylia)',
|
||||
'Lumberjack House', 'Snitch Lady (West)', 'Snitch Lady (East)', 'Tavern (Front)',
|
||||
|
||||
Reference in New Issue
Block a user