Merge branch 'OverworldShuffleDev' into OverworldShuffle
This commit is contained in:
+2
-1
@@ -26,9 +26,10 @@ class World(object):
|
|||||||
self.teams = 1
|
self.teams = 1
|
||||||
self.owShuffle = owShuffle.copy()
|
self.owShuffle = owShuffle.copy()
|
||||||
self.owTerrain = {}
|
self.owTerrain = {}
|
||||||
self.owCrossed = owCrossed.copy()
|
|
||||||
self.owKeepSimilar = {}
|
self.owKeepSimilar = {}
|
||||||
self.owMixed = owMixed.copy()
|
self.owMixed = owMixed.copy()
|
||||||
|
self.owCrossed = owCrossed.copy()
|
||||||
|
self.owCrossed = self.owCrossed if self.owCrossed != 'polar' or self.owMixed else 'none'
|
||||||
self.owWhirlpoolShuffle = {}
|
self.owWhirlpoolShuffle = {}
|
||||||
self.owFluteShuffle = {}
|
self.owFluteShuffle = {}
|
||||||
self.shuffle = shuffle.copy()
|
self.shuffle = shuffle.copy()
|
||||||
|
|||||||
@@ -1,5 +1,13 @@
|
|||||||
# Changelog
|
# 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
|
## 0.3.0.3
|
||||||
- Fixed issue with new Cold Fairy Statue location not dropping correct item
|
- Fixed issue with new Cold Fairy Statue location not dropping correct item
|
||||||
- Fixed issue with Multiworld due to new Cold Fairy Statue location
|
- Fixed issue with Multiworld due to new Cold Fairy Statue location
|
||||||
|
|||||||
+16
-1
@@ -323,6 +323,11 @@ def connect_simple_door(world, exit_name, region_name, player):
|
|||||||
d.dest = region
|
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):
|
def connect_door_only(world, exit_name, region, player):
|
||||||
d = world.check_for_door(exit_name, player)
|
d = world.check_for_door(exit_name, player)
|
||||||
if d is not None:
|
if d is not None:
|
||||||
@@ -355,6 +360,12 @@ def connect_two_way(world, entrancename, exitname, player):
|
|||||||
x.dest = y
|
x.dest = y
|
||||||
if y is not None:
|
if y is not None:
|
||||||
y.dest = x
|
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):
|
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)
|
y = world.check_for_door(exitname, player)
|
||||||
if x is not None:
|
if x is not None:
|
||||||
x.dest = y
|
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):
|
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',
|
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():
|
for dungeon, doors in custom_dict.items():
|
||||||
all_custom[dungeon].extend(doors)
|
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)
|
used_doors = shuffle_trap_doors(door_type_pools, paths, start_regions_map, all_custom, world, player)
|
||||||
# big keys
|
# big keys
|
||||||
used_doors = shuffle_big_key_doors(door_type_pools, used_doors, start_regions_map, all_custom, world, player)
|
used_doors = shuffle_big_key_doors(door_type_pools, used_doors, start_regions_map, all_custom, world, player)
|
||||||
|
|||||||
+1
-1
@@ -2740,7 +2740,7 @@ ow_prize_table = {'Links House': (0x8b1, 0xb2d),
|
|||||||
'Lost Woods Gamble': (0x240, 0x080),
|
'Lost Woods Gamble': (0x240, 0x080),
|
||||||
'Fortune Teller (Light)': (0x2c0, 0x4c0),
|
'Fortune Teller (Light)': (0x2c0, 0x4c0),
|
||||||
'Snitch Lady (East)': (0x310, 0x7a0),
|
'Snitch Lady (East)': (0x310, 0x7a0),
|
||||||
'Snitch Lady (West)': (0x800, 0x7a0),
|
'Snitch Lady (West)': (0x080, 0x7a0),
|
||||||
'Bush Covered House': (0x2e0, 0x880),
|
'Bush Covered House': (0x2e0, 0x880),
|
||||||
'Tavern (Front)': (0x270, 0x980),
|
'Tavern (Front)': (0x270, 0x980),
|
||||||
'Light World Bomb Hut': (0x070, 0x980),
|
'Light World Bomb Hut': (0x070, 0x980),
|
||||||
|
|||||||
@@ -670,9 +670,10 @@ def sell_potions(world, player):
|
|||||||
for potion in ['Green Potion', 'Blue Potion', 'Red Potion']:
|
for potion in ['Green Potion', 'Blue Potion', 'Red Potion']:
|
||||||
location = random.choice(filter_locations(ItemFactory(potion, player), locations, world, potion=True))
|
location = random.choice(filter_locations(ItemFactory(potion, player), locations, world, potion=True))
|
||||||
locations.remove(location)
|
locations.remove(location)
|
||||||
p_item = next(item for item in world.itempool if item.name == potion and item.player == player)
|
p_item = next((item for item in world.itempool if item.name == potion and item.player == player), None)
|
||||||
world.push_item(location, p_item, collect=False)
|
if p_item:
|
||||||
world.itempool.remove(p_item)
|
world.push_item(location, p_item, collect=False)
|
||||||
|
world.itempool.remove(p_item)
|
||||||
|
|
||||||
|
|
||||||
def sell_keys(world, player):
|
def sell_keys(world, player):
|
||||||
|
|||||||
+12
-7
@@ -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):
|
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:
|
if prev_state is None or state.used_smalls == prev_state.used_smalls:
|
||||||
return False
|
return False
|
||||||
new_bk_doors = set(state.big_doors).difference(set(prev_state.big_doors))
|
if state.found_forced_bk() and not prev_state.found_forced_bk():
|
||||||
state_copy = state.copy()
|
return False
|
||||||
while len(new_bk_doors) > 0:
|
if state.big_key_opened:
|
||||||
for door in new_bk_doors:
|
new_bk_doors = set(state.big_doors).difference(set(prev_state.big_doors))
|
||||||
open_a_door(door.door, state_copy, key_layout.flat_prop, world, player)
|
state_copy = state.copy()
|
||||||
new_bk_doors = set(state_copy.big_doors).difference(set(prev_state.big_doors))
|
while len(new_bk_doors) > 0:
|
||||||
expand_key_state(state_copy, key_layout.flat_prop, world, player)
|
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))
|
new_locations = set(state_copy.found_locations).difference(set(prev_state.found_locations))
|
||||||
important_found = False
|
important_found = False
|
||||||
for loc in new_locations:
|
for loc in new_locations:
|
||||||
|
|||||||
@@ -36,7 +36,9 @@ from source.overworld.EntranceShuffle2 import link_entrances_new
|
|||||||
from source.tools.BPS import create_bps_from_data
|
from source.tools.BPS import create_bps_from_data
|
||||||
from source.classes.CustomSettings import CustomSettings
|
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
|
from source.classes.BabelFish import BabelFish
|
||||||
|
|
||||||
@@ -265,6 +267,7 @@ def main(args, seed=None, fish=None):
|
|||||||
set_rules(world, player)
|
set_rules(world, player)
|
||||||
|
|
||||||
district_item_pool_config(world)
|
district_item_pool_config(world)
|
||||||
|
fill_specific_items(world)
|
||||||
for player in range(1, world.players + 1):
|
for player in range(1, world.players + 1):
|
||||||
if world.shopsanity[player]:
|
if world.shopsanity[player]:
|
||||||
sell_potions(world, player)
|
sell_potions(world, player)
|
||||||
@@ -277,8 +280,6 @@ def main(args, seed=None, fish=None):
|
|||||||
if args.print_custom_yaml:
|
if args.print_custom_yaml:
|
||||||
world.settings.record_item_pool(world)
|
world.settings.record_item_pool(world)
|
||||||
dungeon_tracking(world)
|
dungeon_tracking(world)
|
||||||
fill_specific_items(world)
|
|
||||||
|
|
||||||
logger.info(world.fish.translate("cli", "cli", "placing.dungeon.prizes"))
|
logger.info(world.fish.translate("cli", "cli", "placing.dungeon.prizes"))
|
||||||
|
|
||||||
fill_prizes(world)
|
fill_prizes(world)
|
||||||
|
|||||||
+7
-1
@@ -46,6 +46,9 @@ class Context:
|
|||||||
self.lookup_name_to_id = {}
|
self.lookup_name_to_id = {}
|
||||||
self.lookup_id_to_name = {}
|
self.lookup_id_to_name = {}
|
||||||
|
|
||||||
|
self.disable_client_forfeit = False
|
||||||
|
|
||||||
|
|
||||||
async def send_msgs(websocket, msgs):
|
async def send_msgs(websocket, msgs):
|
||||||
if not websocket or not websocket.open or websocket.closed:
|
if not websocket or not websocket.open or websocket.closed:
|
||||||
return
|
return
|
||||||
@@ -281,7 +284,10 @@ async def process_client_cmd(ctx : Context, client : Client, cmd, args):
|
|||||||
if args.startswith('!players'):
|
if args.startswith('!players'):
|
||||||
notify_all(ctx, get_connected_players_string(ctx))
|
notify_all(ctx, get_connected_players_string(ctx))
|
||||||
if args.startswith('!forfeit'):
|
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'):
|
if args.startswith('!countdown'):
|
||||||
try:
|
try:
|
||||||
timer = int(args.split()[1])
|
timer = int(args.split()[1])
|
||||||
|
|||||||
+2
-2
@@ -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, '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, '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 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 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 NC', 0x32, No, Ld, 0x18) .coordInfo(0x04e8, 0x180c),
|
||||||
create_owedge(player, 'Flute Boy Approach EC', 0x32, Ea, Ld, 0x1a) .coordInfo(0x0d04, 0x05c0),
|
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 SW', 0x37, So, Wr, 0x1e) .coordInfo(0x0e80, 0x1002),
|
||||||
create_owedge(player, 'Ice Cave SE', 0x37, So, Ld, 0x1f) .coordInfo(0x0f50, 0x101c),
|
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 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 EC', 0x3a, Ea, Ld, 0x20) .coordInfo(0x0f18, 0x0640),
|
||||||
create_owedge(player, 'Desert Pass ES', 0x3a, Ea, Ld, 0x21) .coordInfo(0x0fcb, 0x08c0),
|
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),
|
create_owedge(player, 'Dam NC', 0x3b, No, Ld, 0x1e) .coordInfo(0x0728, 0x1816),
|
||||||
|
|||||||
+1
-1
@@ -7,7 +7,7 @@ from OWEdges import OWTileRegions, OWEdgeGroups, OWEdgeGroupsTerrain, OWExitType
|
|||||||
from OverworldGlitchRules import create_owg_connections
|
from OverworldGlitchRules import create_owg_connections
|
||||||
from Utils import bidict
|
from Utils import bidict
|
||||||
|
|
||||||
version_number = '0.3.0.3'
|
version_number = '0.3.0.4'
|
||||||
# branch indicator is intentionally different across branches
|
# branch indicator is intentionally different across branches
|
||||||
version_branch = ''
|
version_branch = ''
|
||||||
|
|
||||||
|
|||||||
@@ -108,6 +108,17 @@ These are now independent of retro mode and have three options: None, Random, an
|
|||||||
* Bonk Fairy (Dark)
|
* Bonk Fairy (Dark)
|
||||||
|
|
||||||
# Bug Fixes and Notes
|
# 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
|
* 1.2.0.12u
|
||||||
* Fix for mirror portal in inverted
|
* Fix for mirror portal in inverted
|
||||||
* Yet another fix for blocked door in Standard ER
|
* Yet another fix for blocked door in Standard ER
|
||||||
|
|||||||
@@ -38,7 +38,7 @@ from source.dungeon.RoomList import Room0127
|
|||||||
|
|
||||||
|
|
||||||
JAP10HASH = '03a63945398191337e896e5771f77173'
|
JAP10HASH = '03a63945398191337e896e5771f77173'
|
||||||
RANDOMIZERBASEHASH = 'c27bdd316ea8312214643e0a4ea32c10'
|
RANDOMIZERBASEHASH = '0a3d1d4bbec659013be5ed876c2658bd'
|
||||||
|
|
||||||
|
|
||||||
class JsonRom(object):
|
class JsonRom(object):
|
||||||
@@ -1710,12 +1710,16 @@ def patch_rom(world, rom, player, team, enemized, is_mystery=False):
|
|||||||
# set rom name
|
# set rom name
|
||||||
# 21 bytes
|
# 21 bytes
|
||||||
from Main import __version__
|
from Main import __version__
|
||||||
|
from OverworldShuffle import __version__ as ORVersion
|
||||||
seedstring = f'{world.seed:09}' if isinstance(world.seed, int) else world.seed
|
seedstring = f'{world.seed:09}' if isinstance(world.seed, int) else world.seed
|
||||||
# todo: change to DR when Enemizer is okay with DR
|
# 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 = 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.name.extend([0] * (21 - len(rom.name)))
|
||||||
rom.write_bytes(0x7FC0, 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
|
# set player names
|
||||||
for p in range(1, min(world.players, 255) + 1):
|
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]))
|
rom.write_bytes(0x195FFC + ((p - 1) * 32), hud_format_text(world.player_names[p][team]))
|
||||||
|
|||||||
@@ -113,7 +113,7 @@ Triforce_texts = [
|
|||||||
" Cool seed,\n\n right?",
|
" Cool seed,\n\n right?",
|
||||||
"\n We did it!",
|
"\n We did it!",
|
||||||
" Spam those\n emotes in\n wilds chat",
|
" Spam those\n emotes in\n wilds chat",
|
||||||
"\n O M G",
|
"\n O M G",
|
||||||
" Hello. Will you\n you be my friend?",
|
" Hello. Will you\n you be my friend?",
|
||||||
" Beetorp\n was\n here!",
|
" Beetorp\n was\n here!",
|
||||||
" The Wind Fish\n will wake soon.\n Hoot!",
|
" The Wind Fish\n will wake soon.\n Hoot!",
|
||||||
@@ -1309,6 +1309,7 @@ class GoldCreditMapper(CharTextMapper):
|
|||||||
|
|
||||||
class GreenCreditMapper(CharTextMapper):
|
class GreenCreditMapper(CharTextMapper):
|
||||||
char_map = {' ': 0x9F,
|
char_map = {' ': 0x9F,
|
||||||
|
'.': 0x52,
|
||||||
'·': 0x52}
|
'·': 0x52}
|
||||||
alpha_offset = -0x29
|
alpha_offset = -0x29
|
||||||
alpha_lower_offset = -0x29
|
alpha_lower_offset = -0x29
|
||||||
|
|||||||
+112
-27
@@ -11,9 +11,11 @@ OWMode:
|
|||||||
dw 0
|
dw 0
|
||||||
OWFlags:
|
OWFlags:
|
||||||
dw 0
|
dw 0
|
||||||
org $aa8010
|
|
||||||
OWReserved:
|
OWReserved:
|
||||||
dw 0
|
dw 0
|
||||||
|
org $aa8010
|
||||||
|
OWVersionInfo:
|
||||||
|
dw $0000, $0000, $0000, $0000, $0000, $0000, $0000, $0000
|
||||||
|
|
||||||
;Hooks
|
;Hooks
|
||||||
org $02a929
|
org $02a929
|
||||||
@@ -45,6 +47,10 @@ Overworld_LoadSpecialOverworld_RoomId:
|
|||||||
org $04E8B4
|
org $04E8B4
|
||||||
Overworld_LoadSpecialOverworld:
|
Overworld_LoadSpecialOverworld:
|
||||||
|
|
||||||
|
org $02A9DA
|
||||||
|
JSL OWSkipPalettes
|
||||||
|
BCC OverworldHandleTransitions_change_palettes : NOP #4
|
||||||
|
|
||||||
org $07982A
|
org $07982A
|
||||||
Link_ResetSwimmingState:
|
Link_ResetSwimmingState:
|
||||||
|
|
||||||
@@ -238,6 +244,19 @@ OWWhirlpoolEnd:
|
|||||||
RTL
|
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:
|
OWMirrorSpriteOnMap:
|
||||||
{
|
{
|
||||||
lda.w $1ac0,x : bit.b #$f0 : beq .continue
|
lda.w $1ac0,x : bit.b #$f0 : beq .continue
|
||||||
@@ -421,7 +440,7 @@ OWBonkGoodBeeDrop:
|
|||||||
JMP .spawn_item
|
JMP .spawn_item
|
||||||
+
|
+
|
||||||
|
|
||||||
.determine_type ; S = Collected, FlagBitmask, X (row + 2)
|
.determine_type ; S = Collected
|
||||||
LDA.l OWBonkPrizeTable[42].loot ; A = item id
|
LDA.l OWBonkPrizeTable[42].loot ; A = item id
|
||||||
CMP.b #$B0 : BNE +
|
CMP.b #$B0 : BNE +
|
||||||
LDA.b #$79 : JMP .sprite_transform ; transform to bees
|
LDA.b #$79 : JMP .sprite_transform ; transform to bees
|
||||||
@@ -465,33 +484,34 @@ OWBonkGoodBeeDrop:
|
|||||||
JSL.l OWBonkSpritePrep
|
JSL.l OWBonkSpritePrep
|
||||||
|
|
||||||
.mark_collected ; S = Collected
|
.mark_collected ; S = Collected
|
||||||
PLA : BNE .return
|
PLA : BNE +
|
||||||
LDA.l RoomDataWRAM[$0120].high : ORA.b #$02 : STA.l RoomDataWRAM[$0120].high
|
LDA.l RoomDataWRAM[$0120].high : ORA.b #$02 : STA.l RoomDataWRAM[$0120].high
|
||||||
|
|
||||||
REP #$20
|
REP #$20
|
||||||
LDA.l TotalItemCounter : INC : STA.l TotalItemCounter
|
LDA.l TotalItemCounter : INC : STA.l TotalItemCounter
|
||||||
SEP #$20
|
SEP #$20
|
||||||
BRA .return
|
+ BRA .return
|
||||||
|
|
||||||
; spawn itemget item
|
; spawn itemget item
|
||||||
.spawn_item ; A = item id ; Y = bonk sprite slot ; S = Collected
|
.spawn_item ; A = item id ; Y = bonk sprite slot ; S = Collected
|
||||||
PLX : BEQ + : LDA.b #$00 : STA.w $0DD0,Y : BRA .return
|
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
|
LDA.b #$EB : STA.l $7FFE00
|
||||||
JSL Sprite_SpawnDynamically+15 ; +15 to skip finding a new slot, use existing sprite
|
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
|
; 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 #$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 #$FF : STA.w $0B58,Y ; stun timer
|
||||||
LDA.b #$30 : STA.w $0F10,Y ; aux delay timer 4 ?? dunno what that means
|
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
|
; sets OW event bitmask flag, uses free RAM
|
||||||
LDA.l OWBonkPrizeTable[42].flag : STA.w $0ED0,Y
|
LDA.l OWBonkPrizeTable[42].flag : STA.w $0ED0,Y
|
||||||
@@ -597,9 +617,7 @@ OWBonkDrops:
|
|||||||
; spawn itemget item
|
; spawn itemget item
|
||||||
.spawn_item ; A = item id ; Y = tree sprite slot ; S = Collected, FlagBitmask, X (row + 2)
|
.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)
|
PLX : BEQ + : LDA.b #$00 : STA.w $0DD0,Y : JMP .return ; S = FlagBitmask, X (row + 2)
|
||||||
+ LDA 2,S : TAX : INX : INX
|
+ LDA 2,S : TAX : INX
|
||||||
LDA.w OWBonkPrizeData,X : STA.l !MULTIWORLD_SPRITEITEM_PLAYER_ID
|
|
||||||
DEX
|
|
||||||
|
|
||||||
LDA.b #$01 : STA !REDRAW
|
LDA.b #$01 : STA !REDRAW
|
||||||
|
|
||||||
@@ -610,7 +628,7 @@ OWBonkDrops:
|
|||||||
LDA.b #$00 : STA.w $0D40,Y
|
LDA.b #$00 : STA.w $0D40,Y
|
||||||
LDA.b #$0A : STA.w $0D50,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 #$FF : STA.w $0B58,Y ; stun timer
|
||||||
LDA.b #$30 : STA.w $0F10,Y ; aux delay timer 4 ?? dunno what that means
|
LDA.b #$30 : STA.w $0F10,Y ; aux delay timer 4 ?? dunno what that means
|
||||||
|
|
||||||
@@ -648,6 +666,7 @@ OWBonkSpritePrep:
|
|||||||
org $aa9000
|
org $aa9000
|
||||||
OWDetectEdgeTransition:
|
OWDetectEdgeTransition:
|
||||||
{
|
{
|
||||||
|
JSL OWDestroyItemSprites
|
||||||
STZ.w $06FC
|
STZ.w $06FC
|
||||||
LDA.l OWMode : ORA.l OWMode+1 : BEQ .vanilla
|
LDA.l OWMode : ORA.l OWMode+1 : BEQ .vanilla
|
||||||
JSR OWShuffle
|
JSR OWShuffle
|
||||||
@@ -926,7 +945,11 @@ OWNewDestination:
|
|||||||
; crossed OW shuffle and terrain
|
; crossed OW shuffle and terrain
|
||||||
ldx $05 : ldy $08 : jsr OWWorldTerrainUpdate
|
ldx $05 : ldy $08 : jsr OWWorldTerrainUpdate
|
||||||
|
|
||||||
lda $05 : sta $8a
|
ldx $8a : lda $05 : sta $8a : stx $05 ; $05 is prev screen id, $8a is dest screen
|
||||||
|
|
||||||
|
jsr OWGfxUpdate
|
||||||
|
|
||||||
|
lda $8a
|
||||||
rep #$30 : rts
|
rep #$30 : rts
|
||||||
}
|
}
|
||||||
OWLoadSpecialArea:
|
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
|
lda #$38 : sta $012f ; play sfx - #$3b is an alternative
|
||||||
|
|
||||||
; toggle bunny mode
|
; toggle bunny mode
|
||||||
lda MoonPearlEquipment : bne .nobunny
|
lda MoonPearlEquipment : beq + : jmp .nobunny
|
||||||
lda.l InvertedMode : bne .inverted
|
+ lda.l InvertedMode : bne .inverted
|
||||||
lda CurrentWorld : bra +
|
lda CurrentWorld : bra +
|
||||||
.inverted lda CurrentWorld : eor #$40
|
.inverted lda CurrentWorld : eor #$40
|
||||||
+ and #$40 : beq .nobunny
|
+ and #$40 : beq .nobunny
|
||||||
|
|
||||||
LDA.w $0703 : BEQ + ; check if forced transition
|
LDA.w $0703 : BEQ + ; check if forced transition
|
||||||
CPY.b #$03 : BEQ .end_forced_whirlpool
|
CPY.b #$03 : BEQ ++
|
||||||
LDA.b #$17 : STA.b $5D
|
LDA.b #$17 : STA.b $5D
|
||||||
LDA.b #$01 : STA.w $02E0 : STA.b $56
|
LDA.b #$01 : STA.w $02E0 : STA.b $56
|
||||||
LDA.w $0703 : BRA .end_forced_edge
|
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 #$01 : BEQ .auto ; check if going from land to water
|
||||||
CPY.b #$02 : BEQ .to_bunny_reset_swim ; bunny state if swimming to land
|
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
|
STZ.b $5D
|
||||||
PLX
|
PLX
|
||||||
BRA .to_pseudo_bunny
|
BRA .to_pseudo_bunny
|
||||||
.whirlpool
|
.whirlpool
|
||||||
PLX : RTS
|
PLX : JMP OWLoadGearPalettes
|
||||||
.to_bunny_reset_swim
|
.to_bunny_reset_swim
|
||||||
LDA.b $5D : CMP.b #$04 : BNE .to_bunny ; check if swimming
|
LDA.b $5D : CMP.b #$04 : BNE .to_bunny ; check if swimming
|
||||||
JSL Link_ResetSwimmingState
|
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
|
LDA.b #$17 : STA.b $5D
|
||||||
.to_pseudo_bunny
|
.to_pseudo_bunny
|
||||||
LDA.b #$01 : STA.w $02E0 : STA.b $56
|
LDA.b #$01 : STA.w $02E0 : STA.b $56
|
||||||
RTS
|
JMP OWLoadGearPalettes
|
||||||
|
|
||||||
.nobunny
|
.nobunny
|
||||||
lda $5d : cmp #$17 : bne + ; retain current state unless bunny
|
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
|
.return
|
||||||
RTS
|
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:
|
OWAdjustExitPosition:
|
||||||
{
|
{
|
||||||
LDA.w $06FC : CMP.b #$60 : BEQ .stone_bridge
|
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 $0ce4, $0d33, $004f, $0d0b, $3434, $0000, $0001, $001c
|
||||||
dw $0d34, $0db8, $0084, $0d76, $3434, $0000, $0000, $001d
|
dw $0d34, $0db8, $0084, $0d76, $3434, $0000, $0000, $001d
|
||||||
dw $0ea8, $0f20, $0078, $0ee4, $3a3a, $0000, $0000, $001e
|
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 $0f18, $0f18, $0000, $0f18, $3b3b, $0000, $0000, $0020
|
||||||
dw $0fc8, $0fc8, $0000, $0fc8, $3b3b, $0000, $0000, $0021
|
dw $0fc8, $0fc8, $0000, $0fc8, $3b3b, $0000, $0000, $0021
|
||||||
dw $0e28, $0fb8, $0190, $0ef0, $3c3c, $0000, $0000, $0022
|
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 $0ce4, $0d33, $004f, $0d0b, $3333, $0000, $0001, $001d
|
||||||
dw $0d34, $0db8, $0084, $0d76, $3333, $0000, $0000, $001e
|
dw $0d34, $0db8, $0084, $0d76, $3333, $0000, $0000, $001e
|
||||||
dw $0ea8, $0f20, $0078, $0ee4, $3039, $0000, $0000, $001f
|
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 $0f18, $0f18, $0000, $0f18, $3a3a, $0000, $0000, $0021
|
||||||
dw $0fc8, $0fc8, $0000, $0fc8, $3a3a, $0000, $0000, $0022
|
dw $0fc8, $0fc8, $0000, $0fc8, $3a3a, $0000, $0000, $0022
|
||||||
dw $0e28, $0fb8, $0190, $0ef0, $3b3b, $0000, $0000, $0023
|
dw $0e28, $0fb8, $0190, $0ef0, $3b3b, $0000, $0000, $0023
|
||||||
|
|||||||
Binary file not shown.
@@ -4,7 +4,15 @@ settings:
|
|||||||
1:
|
1:
|
||||||
mode: standard
|
mode: standard
|
||||||
ow_mixed: true
|
ow_mixed: true
|
||||||
|
entrances:
|
||||||
|
1:
|
||||||
|
entrances:
|
||||||
|
Sanctuary Grave: Sewer Drop
|
||||||
|
two-way:
|
||||||
|
Sanctuary: Sanctuary Exit
|
||||||
ow-tileflips:
|
ow-tileflips:
|
||||||
1:
|
1:
|
||||||
|
force_no_flip:
|
||||||
|
- 0x13
|
||||||
undefined_chance: 100
|
undefined_chance: 100
|
||||||
|
|
||||||
|
|||||||
@@ -171,6 +171,9 @@ def do_vanilla_connections(avail_pool):
|
|||||||
connect_vanilla_two_way(ent, avail_pool.default_map[ent], 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:
|
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)
|
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):
|
def do_main_shuffle(entrances, exits, avail, mode_def):
|
||||||
|
|||||||
Reference in New Issue
Block a user