Pull in OR 0.7.0.1 #2
11
CHANGELOG.md
11
CHANGELOG.md
@@ -1,5 +1,16 @@
|
||||
# Changelog
|
||||
|
||||
# 0.6.1.11
|
||||
- Fixed bonk drops duplicate counting and potentially overwriting arbitrary values
|
||||
- Fixed boss icons on dungeon map check
|
||||
- Fixed dungeon counters to autotrack correctly
|
||||
- Key and chest counts in menu now display consistently (must have dungeon item or have visited dungeon to see the HUD)
|
||||
- Money balancing will fail in less scenarios
|
||||
- Fixed issue with Sanc pots not collecting
|
||||
- Enemizer now allows more enemies on water
|
||||
- Fix infinite pit fall issue with Old Man follower location
|
||||
- Fix bad overworld tilemap drawing on HC and Pyramid screens in OW Layout Shuffle
|
||||
|
||||
## 0.6.1.10
|
||||
- Emergency fix for bonk functionality
|
||||
|
||||
|
||||
20
Fill.py
20
Fill.py
@@ -1024,7 +1024,10 @@ def balance_money_progression(world):
|
||||
'Rupees (100)': 100, 'Rupees (300)': 300}
|
||||
rupee_rooms = {'Eastern Rupees': 90, 'Mire Key Rupees': 45, 'Mire Shooter Rupees': 90,
|
||||
'TR Rupees': 270, 'PoD Dark Basement': 270}
|
||||
acceptable_balancers = ['Bombs (3)', 'Arrows (10)', 'Bombs (10)']
|
||||
acceptable_balancers = ['Single Bomb', 'Bombs (3)', 'Bombs (10)',
|
||||
'Single Arrow', 'Arrows (5)', 'Arrows (10)',
|
||||
'Small Magic', 'Big Magic', 'Small Heart',
|
||||
'Fairy', 'Chicken', 'Nothing']
|
||||
|
||||
base_value = sum(rupee_rooms.values())
|
||||
available_money = {player: base_value for player in range(1, world.players+1)}
|
||||
@@ -1125,10 +1128,11 @@ def balance_money_progression(world):
|
||||
unchecked_locations.remove(location)
|
||||
if location.item:
|
||||
if location.item.name.startswith('Rupee'):
|
||||
wallet[location.item.player] += rupee_chart[location.item.name]
|
||||
if location.item.name != 'Rupees (300)':
|
||||
balance_locations[location.item.player].add(location)
|
||||
if interesting_item(location, location.item, world, location.item.player):
|
||||
if not (location.item.name == 'Rupee (1)' and world.algorithm != 'district'):
|
||||
wallet[location.item.player] += rupee_chart[location.item.name]
|
||||
if location.item.name != 'Rupees (300)':
|
||||
balance_locations[location.item.player].add(location)
|
||||
elif interesting_item(location, location.item, world, location.item.player):
|
||||
checked_locations.append(location)
|
||||
elif location.item.name in acceptable_balancers:
|
||||
balance_locations[location.item.player].add(location)
|
||||
@@ -1172,7 +1176,11 @@ def balance_money_progression(world):
|
||||
if len(increase_targets) == 0:
|
||||
increase_targets = [x for x in balance_locations[target_player] if (rupee_chart[x.item.name] if x.item.name in rupee_chart else 0) < best_value]
|
||||
if len(increase_targets) == 0:
|
||||
raise Exception('No early sphere swaps for rupees - money grind would be required - bailing for now')
|
||||
if state.can_farm_rupees(target_player):
|
||||
logger.warning(f'No more swap targets available. Short by {difference} rupees, but continuing (player can farm)')
|
||||
break
|
||||
else:
|
||||
raise Exception(f'No early sphere swaps for rupees - money grind would be required - bailing for now')
|
||||
best_target = min(increase_targets, key=lambda t: rupee_chart[t.item.name] if t.item.name in rupee_chart else 0)
|
||||
make_item_free = wallet[target_player] < 20
|
||||
old_value = 0 if make_item_free else (rupee_chart[best_target.item.name] if best_target.item.name in rupee_chart else 0)
|
||||
|
||||
2
Main.py
2
Main.py
@@ -40,7 +40,7 @@ from source.enemizer.DamageTables import DamageTable
|
||||
from source.enemizer.Enemizer import randomize_enemies
|
||||
from source.rom.DataTables import init_data_tables
|
||||
|
||||
version_number = '1.5.0'
|
||||
version_number = '1.5.2'
|
||||
version_branch = '-u'
|
||||
__version__ = f'{version_number}{version_branch}'
|
||||
|
||||
|
||||
@@ -8,7 +8,7 @@ from OWEdges import OWTileRegions, OWEdgeGroups, OWEdgeGroupsTerrain, OWExitType
|
||||
from OverworldGlitchRules import create_owg_connections
|
||||
from Utils import bidict
|
||||
|
||||
version_number = '0.6.1.10'
|
||||
version_number = '0.6.1.11'
|
||||
# branch indicator is intentionally different across branches
|
||||
version_branch = ''
|
||||
|
||||
|
||||
14
Rom.py
14
Rom.py
@@ -43,7 +43,7 @@ from source.enemizer.Enemizer import write_enemy_shuffle_settings
|
||||
|
||||
|
||||
JAP10HASH = '03a63945398191337e896e5771f77173'
|
||||
RANDOMIZERBASEHASH = 'f2eebfbec9c8ad638e922ed1047d1c10'
|
||||
RANDOMIZERBASEHASH = '34c9d7b09fad982dea9e7c9e3ae885ee'
|
||||
|
||||
|
||||
class JsonRom(object):
|
||||
@@ -1382,9 +1382,15 @@ def patch_rom(world, rom, player, team, is_mystery=False, rom_header=None):
|
||||
| (0x04 if world.mapshuffle[player] != 'none' else 0x00)
|
||||
| (0x08 if world.bigkeyshuffle[player] != 'none' else 0x00))) # free roaming item text boxes
|
||||
rom.write_byte(0x18003B, 0x01 if world.mapshuffle[player] not in ['none', 'nearby'] else 0x00) # maps showing crystals on overworld
|
||||
if world.keyshuffle[player] != 'universal' and (world.mapshuffle[player] not in ['none', 'nearby'] or world.doorShuffle[player] != 'vanilla'
|
||||
or world.dropshuffle[player] != 'none' or world.pottery[player] not in ['none', 'cave']):
|
||||
rom.write_byte(0x18003A, 0x01) # show key counts on map pickup
|
||||
map_hud_mode = 0x00
|
||||
if world.dungeon_counters[player] == 'on':
|
||||
map_hud_mode = 0x02 # always on
|
||||
elif world.dungeon_counters[player] == 'off':
|
||||
pass
|
||||
elif world.keyshuffle[player] != 'universal' and (world.mapshuffle[player] not in ['none', 'nearby'] or world.doorShuffle[player] != 'vanilla'
|
||||
or world.dropshuffle[player] != 'none' or world.pottery[player] not in ['none', 'cave'] or world.dungeon_counters[player] == 'pickup'):
|
||||
map_hud_mode = 0x01 # show on pickup
|
||||
rom.write_byte(0x18003A, map_hud_mode)
|
||||
|
||||
# compasses showing dungeon count
|
||||
compass_mode = 0x80 if world.compassshuffle[player] not in ['none', 'nearby'] else 0x00
|
||||
|
||||
Binary file not shown.
@@ -177,9 +177,9 @@ def init_sprite_requirements():
|
||||
SpriteRequirement(EnemySprite.Vulture).no_drop().sub_group(2, 0x12).exclude(NoFlyingRooms),
|
||||
SpriteRequirement(EnemySprite.CorrectPullSwitch).affix().sub_group(3, [0x52, 0x53]),
|
||||
SpriteRequirement(EnemySprite.WrongPullSwitch).affix().sub_group(3, [0x52, 0x53]),
|
||||
SpriteRequirement(EnemySprite.Octorok).aquaphobia().sub_group(2, [0xc, 0x18]),
|
||||
SpriteRequirement(EnemySprite.Octorok).sub_group(2, [0xc, 0x18]),
|
||||
SpriteRequirement(EnemySprite.Moldorm).exalt().sub_group(2, 0x30),
|
||||
SpriteRequirement(EnemySprite.Octorok4Way).aquaphobia().sub_group(2, 0xc),
|
||||
SpriteRequirement(EnemySprite.Octorok4Way).sub_group(2, 0xc),
|
||||
SpriteRequirement(EnemySprite.Cucco).immune().sub_group(3, [0x15, 0x50]).exclude(NoFlyingRooms),
|
||||
SpriteRequirement(EnemySprite.Buzzblob).sub_group(3, 0x11),
|
||||
SpriteRequirement(EnemySprite.Snapdragon).sub_group(0, 0x16).sub_group(2, 0x17),
|
||||
@@ -191,7 +191,7 @@ def init_sprite_requirements():
|
||||
.exclude(NoFlyingRooms).exclude({0x40}), # no anti-fairies in aga tower bridge room
|
||||
SpriteRequirement(EnemySprite.Wiseman).affix().sub_group(2, 0x4c),
|
||||
SpriteRequirement(EnemySprite.Hoarder).sub_group(3, 0x11).exclude({0x10c}),
|
||||
SpriteRequirement(EnemySprite.MiniMoldorm).aquaphobia().sub_group(1, 0x1e),
|
||||
SpriteRequirement(EnemySprite.MiniMoldorm).sub_group(1, 0x1e),
|
||||
SpriteRequirement(EnemySprite.Poe).no_drop().sub_group(3, 0x15).exclude(NoFlyingRooms),
|
||||
SpriteRequirement(EnemySprite.Smithy).affix().sub_group(1, 0x1d).sub_group(3, 0x15),
|
||||
SpriteRequirement(EnemySprite.Statue).stasis().immune().sub_group(3, [0x52, 0x53]),
|
||||
@@ -225,12 +225,12 @@ def init_sprite_requirements():
|
||||
SpriteRequirement(EnemySprite.Hoarder2).sub_group(3, 0x11).exclude({0x10c}),
|
||||
SpriteRequirement(EnemySprite.TutorialGuard).affix(),
|
||||
SpriteRequirement(EnemySprite.LightningGate).affix().sub_group(3, 0x3f),
|
||||
SpriteRequirement(EnemySprite.BlueGuard).aquaphobia().sub_group(1, [0xd, 0x49]).exclude(PitRooms),
|
||||
SpriteRequirement(EnemySprite.BlueGuard).aquaphobia().sub_group(1, [0xd, 0x49]).sub_group(2, [0x29, 0x13]),
|
||||
SpriteRequirement(EnemySprite.GreenGuard).aquaphobia().sub_group(1, 0x49).exclude(PitRooms),
|
||||
SpriteRequirement(EnemySprite.GreenGuard).aquaphobia().sub_group(1, 0x49).sub_group(2, 0x13),
|
||||
SpriteRequirement(EnemySprite.RedSpearGuard).aquaphobia().sub_group(1, [0xd, 0x49]).exclude(PitRooms),
|
||||
SpriteRequirement(EnemySprite.RedSpearGuard).aquaphobia().sub_group(1, [0xd, 0x49]).sub_group(2, [0x29, 0x13]),
|
||||
SpriteRequirement(EnemySprite.BlueGuard).sub_group(1, [0xd, 0x49]).exclude(PitRooms),
|
||||
SpriteRequirement(EnemySprite.BlueGuard).sub_group(1, [0xd, 0x49]).sub_group(2, [0x29, 0x13]),
|
||||
SpriteRequirement(EnemySprite.GreenGuard).sub_group(1, 0x49).exclude(PitRooms),
|
||||
SpriteRequirement(EnemySprite.GreenGuard).sub_group(1, 0x49).sub_group(2, 0x13),
|
||||
SpriteRequirement(EnemySprite.RedSpearGuard).sub_group(1, [0xd, 0x49]).exclude(PitRooms),
|
||||
SpriteRequirement(EnemySprite.RedSpearGuard).sub_group(1, [0xd, 0x49]).sub_group(2, [0x29, 0x13]),
|
||||
SpriteRequirement(EnemySprite.BluesainBolt).aquaphobia().sub_group(0, 0x46).sub_group(1, [0xd, 0x49]),
|
||||
SpriteRequirement(EnemySprite.UsainBolt).aquaphobia().sub_group(1, [0xd, 0x49]),
|
||||
SpriteRequirement(EnemySprite.BlueArcher).sub_group(0, 0x48).sub_group(1, 0x49),
|
||||
|
||||
@@ -141,10 +141,11 @@ class DataTables:
|
||||
bytes = sum(1+len(x)*3 for x in self.ow_enemy_table.values() if len(x) > 0)+1
|
||||
self.pointer_addresses['ow_sprites'][1] = bytes
|
||||
# ending_byte = 0x09CB3B + bytes
|
||||
max_per_state = {0: 0x40, 1: 0x90, 2: 0x90}
|
||||
max_per_state = {0: 0x40, 1: 0x90, 2: 0x81} # dropped max on state 2 to steal space for extra sprites (Murahdahla, extra tutorial guard)
|
||||
|
||||
pointer_address = snes_to_pc(self.pointer_addresses['ow_sprites'][2][0])
|
||||
data_pointer = snes_to_pc(self.pointer_addresses['ow_sprites'][0])
|
||||
self.pointer_addresses['ow_sprites'][0] = pointer_address + ((max_per_state[0] + max_per_state[1] + max_per_state[2]) * 2)
|
||||
data_pointer = self.pointer_addresses['ow_sprites'][0]
|
||||
empty_pointer = pc_to_snes(data_pointer) & 0xFFFF
|
||||
rom.write_byte(data_pointer, 0xff)
|
||||
cached_dark_world = {}
|
||||
@@ -177,6 +178,10 @@ class DataTables:
|
||||
data_pointer += len(data)
|
||||
rom.write_byte(data_pointer, 0xff)
|
||||
data_pointer += 1
|
||||
# Check if OW sprite data has overwritten the UW sprite pointer table
|
||||
max_allowed_address = snes_to_pc(0x09D62E)
|
||||
if data_pointer > max_allowed_address:
|
||||
raise Exception(f'OW sprite data will cause the UW sprite pointer table to overwrite the pots pointer table. Data end: {hex(pc_to_snes(data_pointer))}, Max allowed: $09D62E')
|
||||
|
||||
|
||||
special_health_table = {
|
||||
|
||||
@@ -147,11 +147,7 @@ def roll_settings(weights):
|
||||
ret.door_self_loops = get_choice_bool('door_self_loops')
|
||||
ret.experimental = get_choice_bool('experimental')
|
||||
ret.collection_rate = get_choice_bool('collection_rate')
|
||||
|
||||
ret.dungeon_counters = get_choice_non_bool('dungeon_counters') if 'dungeon_counters' in weights else 'default'
|
||||
if ret.dungeon_counters == 'default':
|
||||
ret.dungeon_counters = 'pickup' if ret.door_shuffle != 'vanilla' or ret.compassshuffle != 'none' else 'off'
|
||||
|
||||
ret.pseudoboots = get_choice_bool('pseudoboots')
|
||||
ret.mirrorscroll = get_choice_bool('mirrorscroll')
|
||||
ret.shopsanity = get_choice_bool('shopsanity')
|
||||
|
||||
Reference in New Issue
Block a user