Merge branch 'DoorDevUnstable' into KeyLogicAttempt1

This commit is contained in:
aerinon
2021-07-06 13:46:14 -07:00
9 changed files with 55 additions and 24 deletions

View File

@@ -2625,7 +2625,7 @@ access_mode = {"items": 0, "locations": 1, "none": 2}
# byte 6: BSMC BBEE (big, small, maps, compass, bosses, enemies) # byte 6: BSMC BBEE (big, small, maps, compass, bosses, enemies)
boss_mode = {"none": 0, "simple": 1, "full": 2, "random": 3, "chaos": 3} boss_mode = {"none": 0, "simple": 1, "full": 2, "random": 3, "chaos": 3}
enemy_mode = {"none": 0, "shuffled": 1, "random": 2, "chaos": 2} enemy_mode = {"none": 0, "shuffled": 1, "random": 2, "chaos": 2, "legacy": 3}
# byte 7: HHHD DP?? (enemy_health, enemy_dmg, potshuffle, ?) # byte 7: HHHD DP?? (enemy_health, enemy_dmg, potshuffle, ?)
e_health = {"default": 0, "easy": 1, "normal": 2, "hard": 3, "expert": 4} e_health = {"default": 0, "easy": 1, "normal": 2, "hard": 3, "expert": 4}

22
Fill.py
View File

@@ -3,7 +3,7 @@ import logging
from BaseClasses import CollectionState from BaseClasses import CollectionState
from Items import ItemFactory from Items import ItemFactory
from Regions import shop_to_location_table from Regions import shop_to_location_table, retro_shops
class FillError(RuntimeError): class FillError(RuntimeError):
@@ -494,6 +494,10 @@ def balance_multiworld_progression(world):
new_location = replacement_locations.pop() new_location = replacement_locations.pop()
new_location.item, old_location.item = old_location.item, new_location.item new_location.item, old_location.item = old_location.item, new_location.item
if world.shopsanity[new_location.player]:
check_shop_swap(new_location)
if world.shopsanity[old_location.player]:
check_shop_swap(old_location)
new_location.event, old_location.event = True, False new_location.event, old_location.event = True, False
state.collect(new_location.item, True, new_location) state.collect(new_location.item, True, new_location)
replaced_items = True replaced_items = True
@@ -514,6 +518,18 @@ def balance_multiworld_progression(world):
raise RuntimeError('Not all required items reachable. Something went terribly wrong here.') raise RuntimeError('Not all required items reachable. Something went terribly wrong here.')
def check_shop_swap(l):
if l.parent_region.name in shop_to_location_table:
if l.name in shop_to_location_table[l.parent_region.name]:
idx = shop_to_location_table[l.parent_region.name].index(l.name)
inv_slot = l.parent_region.shop.inventory[idx]
inv_slot['item'] = l.item.name
elif l.parent_region in retro_shops:
idx = retro_shops[l.parent_region.name].index(l.name)
inv_slot = l.parent_region.shop.inventory[idx]
inv_slot['item'] = l.item.name
def balance_money_progression(world): def balance_money_progression(world):
logger = logging.getLogger('') logger = logging.getLogger('')
state = CollectionState(world) state = CollectionState(world)
@@ -555,7 +571,6 @@ def balance_money_progression(world):
for player in range(1, world.players+1): for player in range(1, world.players+1):
logger.debug(f'Money balance for P{player}: Needed: {total_price[player]} Available: {available_money[player]}') logger.debug(f'Money balance for P{player}: Needed: {total_price[player]} Available: {available_money[player]}')
def get_sphere_locations(sphere_state, locations): def get_sphere_locations(sphere_state, locations):
sphere_state.sweep_for_events(key_only=True, locations=locations) sphere_state.sweep_for_events(key_only=True, locations=locations)
return [loc for loc in locations if sphere_state.can_reach(loc) and sphere_state.not_flooding_a_key(sphere_state.world, loc)] return [loc for loc in locations if sphere_state.can_reach(loc) and sphere_state.not_flooding_a_key(sphere_state.world, loc)]
@@ -670,6 +685,7 @@ def balance_money_progression(world):
logger.debug(f'Upgrading {best_target.item.name} @ {best_target.name} for 300 Rupees') logger.debug(f'Upgrading {best_target.item.name} @ {best_target.name} for 300 Rupees')
best_target.item = ItemFactory('Rupees (300)', best_target.item.player) best_target.item = ItemFactory('Rupees (300)', best_target.item.player)
best_target.item.location = best_target best_target.item.location = best_target
check_shop_swap(best_target.item.location)
else: else:
old_item = best_target.item old_item = best_target.item
logger.debug(f'Swapping {best_target.item.name} @ {best_target.name} for {best_swap.item.name} @ {best_swap.name}') logger.debug(f'Swapping {best_target.item.name} @ {best_target.name} for {best_swap.item.name} @ {best_swap.name}')
@@ -677,6 +693,8 @@ def balance_money_progression(world):
best_target.item.location = best_target best_target.item.location = best_target
best_swap.item = old_item best_swap.item = old_item
best_swap.item.location = best_swap best_swap.item.location = best_swap
check_shop_swap(best_target.item.location)
check_shop_swap(best_swap.item.location)
increase = best_value - old_value increase = best_value - old_value
difference -= increase difference -= increase
wallet[target_player] += increase wallet[target_player] += increase

View File

@@ -253,12 +253,10 @@ def main(args, seed=None, fish=None):
or world.enemy_health[player] != 'default' or world.enemy_damage[player] != 'default' or world.enemy_health[player] != 'default' or world.enemy_damage[player] != 'default'
or sprite_random_on_hit) or sprite_random_on_hit)
if use_enemizer:
base_patch = LocalRom(args.rom) # update base2current.json
rom = JsonRom() if args.jsonout or use_enemizer else LocalRom(args.rom) rom = JsonRom() if args.jsonout or use_enemizer else LocalRom(args.rom)
if use_enemizer and (args.enemizercli or not args.jsonout): if use_enemizer and (args.enemizercli or not args.jsonout):
base_patch = LocalRom(args.rom) # update base2current.json (side effect)
if args.rom and not(os.path.isfile(args.rom)): if args.rom and not(os.path.isfile(args.rom)):
raise RuntimeError("Could not find valid base rom for enemizing at expected path %s." % args.rom) raise RuntimeError("Could not find valid base rom for enemizing at expected path %s." % args.rom)
if os.path.exists(args.enemizercli): if os.path.exists(args.enemizercli):

View File

@@ -195,15 +195,17 @@ def roll_settings(weights):
boss_choice = old_style_bosses[boss_choice] boss_choice = old_style_bosses[boss_choice]
ret.shufflebosses = boss_choice ret.shufflebosses = boss_choice
ret.shuffleenemies = {'none': 'none', enemy_choice = get_choice('enemy_shuffle')
'shuffled': 'shuffled', if enemy_choice == 'chaos':
'random': 'chaos' enemy_choice = 'random'
}[get_choice('enemy_shuffle')] ret.shuffleenemies = enemy_choice
ret.enemy_damage = {'default': 'default', old_style_damage = {'none': 'default',
'shuffled': 'shuffled', 'chaos': 'random'}
'random': 'chaos' damage_choice = get_choice('enemy_damage')
}[get_choice('enemy_damage')] if damage_choice in old_style_damage:
damage_choice = old_style_damage[damage_choice]
ret.enemy_damage = damage_choice
ret.enemy_health = get_choice('enemy_health') ret.enemy_health = get_choice('enemy_health')

View File

@@ -17,6 +17,13 @@ Thanks to qadan, cheuer, & compiling
* 0.4.0.8 * 0.4.0.8
* Ganon jokes added for when silvers aren't available * Ganon jokes added for when silvers aren't available
* Some text updated (Blind jokes, uncle text) * Some text updated (Blind jokes, uncle text)
* Fixed some enemizer Mystery settings
* Added a setting that's random enemy shuffle without Unkillable Thieves possible
* Fixed shop spoiler when money balancing/multiworld balancing
* Fixed a problem with insanity
* Fixed an issue with the credit stats specific to DR (e.g. collection rate total)
* More helpful error message when bps is missing?
* Minor generation issues involving enemizer and the link sprite
* 0.4.0.7 * 0.4.0.7
* Reduce flashing option added * Reduce flashing option added
* Sprite author credit added * Sprite author credit added

19
Rom.py
View File

@@ -9,8 +9,11 @@ import random
import struct import struct
import sys import sys
import subprocess import subprocess
import bps.apply try:
import bps.io import bps.apply
import bps.io
except ImportError:
raise Exception('Could not load BPS module')
from BaseClasses import CollectionState, ShopType, Region, Location, Door, DoorType, RegionType, PotItem from BaseClasses import CollectionState, ShopType, Region, Location, Door, DoorType, RegionType, PotItem
from DoorShuffle import compass_data, DROptions, boss_indicator from DoorShuffle import compass_data, DROptions, boss_indicator
@@ -201,7 +204,7 @@ def patch_enemizer(world, player, rom, baserom_path, enemizercli, random_sprite_
options = { options = {
'RandomizeEnemies': world.enemy_shuffle[player] != 'none', 'RandomizeEnemies': world.enemy_shuffle[player] != 'none',
'RandomizeEnemiesType': 3, 'RandomizeEnemiesType': 3,
'RandomizeBushEnemyChance': world.enemy_shuffle[player] == 'random', 'RandomizeBushEnemyChance': world.enemy_shuffle[player] in ['random', 'legacy'],
'RandomizeEnemyHealthRange': world.enemy_health[player] != 'default', 'RandomizeEnemyHealthRange': world.enemy_health[player] != 'default',
'RandomizeEnemyHealthType': {'default': 0, 'easy': 0, 'normal': 1, 'hard': 2, 'expert': 3}[world.enemy_health[player]], 'RandomizeEnemyHealthType': {'default': 0, 'easy': 0, 'normal': 1, 'hard': 2, 'expert': 3}[world.enemy_health[player]],
'OHKO': False, 'OHKO': False,
@@ -247,9 +250,9 @@ def patch_enemizer(world, player, rom, baserom_path, enemizercli, random_sprite_
'SwordGraphics': "sword_gfx/normal.gfx", 'SwordGraphics': "sword_gfx/normal.gfx",
'BeeMizer': False, 'BeeMizer': False,
'BeesLevel': 0, 'BeesLevel': 0,
'RandomizeTileTrapPattern': world.enemy_shuffle[player] == 'random', 'RandomizeTileTrapPattern': world.enemy_shuffle[player] in ['random', 'legacy'],
'RandomizeTileTrapFloorTile': False, 'RandomizeTileTrapFloorTile': False,
'AllowKillableThief': bool(random.randint(0, 1)) if world.enemy_shuffle[player] == 'random' else world.enemy_shuffle[player] != 'none', 'AllowKillableThief': bool(random.randint(0, 1)) if world.enemy_shuffle[player] == 'legacy' else world.enemy_shuffle[player] != 'none',
'RandomizeSpriteOnHit': random_sprite_on_hit, 'RandomizeSpriteOnHit': random_sprite_on_hit,
'DebugMode': False, 'DebugMode': False,
'DebugForceEnemy': False, 'DebugForceEnemy': False,
@@ -806,7 +809,7 @@ def patch_rom(world, rom, player, team, enemized, is_mystery=False):
write_int16(rom, 0x187010, credits_total) # dynamic credits write_int16(rom, 0x187010, credits_total) # dynamic credits
if credits_total != 216: if credits_total != 216:
# collection rate address: # collection rate address:
cr_address = 0x2391BE cr_address = 0x2391FA
cr_pc = cr_address - 0x120000 # convert to pc cr_pc = cr_address - 0x120000 # convert to pc
mid_top, mid_bot = credits_digit((credits_total // 10) % 10) mid_top, mid_bot = credits_digit((credits_total // 10) % 10)
last_top, last_bot = credits_digit(credits_total % 10) last_top, last_bot = credits_digit(credits_total % 10)
@@ -825,7 +828,7 @@ def patch_rom(world, rom, player, team, enemized, is_mystery=False):
total += count_locations_exclude_logic(region.locations, gt_logic) total += count_locations_exclude_logic(region.locations, gt_logic)
# rom.write_byte(0x187012, total) # dynamic credits # rom.write_byte(0x187012, total) # dynamic credits
# gt big key address: # gt big key address:
gtbk_address = 0x2390E0 gtbk_address = 0x23911C
gtbk_pc = gtbk_address - 0x120000 # convert to pc gtbk_pc = gtbk_address - 0x120000 # convert to pc
mid_top, mid_bot = credits_digit(total // 10) mid_top, mid_bot = credits_digit(total // 10)
last_top, last_bot = credits_digit(total % 10) last_top, last_bot = credits_digit(total % 10)
@@ -1640,7 +1643,7 @@ def hud_format_text(text):
def apply_rom_settings(rom, beep, color, quickswap, fastmenu, disable_music, sprite, def apply_rom_settings(rom, beep, color, quickswap, fastmenu, disable_music, sprite,
ow_palettes, uw_palettes, reduce_flashing): ow_palettes, uw_palettes, reduce_flashing):
if not os.path.exists("data/sprites/official/001.link.1.zspr"): if not os.path.exists("data/sprites/official/001.link.1.zspr") and rom.orig_buffer:
dump_zspr(rom.orig_buffer[0x80000:0x87000], rom.orig_buffer[0xdd308:0xdd380], dump_zspr(rom.orig_buffer[0x80000:0x87000], rom.orig_buffer[0xdd308:0xdd380],
rom.orig_buffer[0xdedf5:0xdedf9], "data/sprites/official/001.link.1.zspr", "Nintendo", "Link") rom.orig_buffer[0xdedf5:0xdedf9], "data/sprites/official/001.link.1.zspr", "Nintendo", "Link")

View File

@@ -340,7 +340,8 @@
"choices": [ "choices": [
"none", "none",
"shuffled", "shuffled",
"random" "random",
"legacy"
] ]
}, },
"enemy_health": { "enemy_health": {

View File

@@ -87,6 +87,7 @@
"randomizer.enemizer.enemyshuffle.none": "None", "randomizer.enemizer.enemyshuffle.none": "None",
"randomizer.enemizer.enemyshuffle.shuffled": "Shuffled", "randomizer.enemizer.enemyshuffle.shuffled": "Shuffled",
"randomizer.enemizer.enemyshuffle.random": "Random", "randomizer.enemizer.enemyshuffle.random": "Random",
"randomizer.enemizer.enemyshuffle.legacy": "Random (including Thieves)",
"randomizer.enemizer.bossshuffle": "Boss Shuffle", "randomizer.enemizer.bossshuffle": "Boss Shuffle",
"randomizer.enemizer.bossshuffle.none": "None", "randomizer.enemizer.bossshuffle.none": "None",

View File

@@ -5,7 +5,8 @@
"options": [ "options": [
"none", "none",
"shuffled", "shuffled",
"random" "random",
"legacy"
] ]
}, },
"bossshuffle": { "bossshuffle": {