Many bugfixes

* Fixed inverted generation issues with pottery option
* Moved SRAM according to SRAM standard
* Removed equitable algorithm
* Upped TFH goal limit to 254
* Cuccos should no longer cause trap door rooms to not open
* Added double click fix for install.py
* Fix for pottery item palettes near bonkable torches
* Fix for multiworld progression balancing would place Nothing or Arrow items
This commit is contained in:
aerinon
2022-02-09 14:19:10 -07:00
parent 64c19bc651
commit 49accbd2b1
15 changed files with 38 additions and 22 deletions

View File

@@ -446,15 +446,19 @@ def distribute_items_restrictive(world, gftower_trash=False, fill_locations=None
unfilled = [location.name for location in fill_locations]
if unplaced or unfilled:
logging.warning('Unplaced items: %s - Unfilled Locations: %s', unplaced, unfilled)
ensure_good_pots(world)
def ensure_good_pots(world, write_skips=False):
for loc in world.get_locations():
# convert Arrows 5 and Nothing when necessary
if (loc.item.name in {'Arrows (5)', 'Nothing'}
and (loc.type != LocationType.Pot or loc.item.player != loc.player)):
loc.item = ItemFactory(invalid_location_replacement[loc.item.name], loc.item.player)
# don't write out all pots to spoiler
if loc.type == LocationType.Pot and loc.item.name in valid_pot_items:
loc.skip = True
if write_skips:
if loc.type == LocationType.Pot and loc.item.name in valid_pot_items:
loc.skip = True
invalid_location_replacement = {'Arrows (5)': 'Arrows (10)', 'Nothing': 'Rupees (5)'}

View File

@@ -117,6 +117,7 @@ def create_inverted_regions(world, player):
'Spectacle Rock Cave Peak', 'Spectacle Rock Cave (Bottom)', 'Broken Bridge (West)', 'Death Mountain Mirror Spot']),
create_cave_region(player, 'Death Mountain Return Cave (left)', 'a connector', None, ['Death Mountain Return Cave Exit (West)', 'Death Mountain Return Cave E']),
create_cave_region(player, 'Death Mountain Return Cave (right)', 'a connector', None, ['Death Mountain Return Cave Exit (East)', 'Death Mountain Return Cave W']),
create_lw_region(player, 'Death Mountain Return Ledge', None, ['Death Mountain Return Ledge Drop', 'Death Mountain Return Cave (West)', 'Bumper Cave Ledge Mirror Spot']),
create_cave_region(player, 'Spectacle Rock Cave (Top)', 'a connector', ['Spectacle Rock Cave'], ['Spectacle Rock Cave Drop', 'Spectacle Rock Cave Exit (Top)']),
create_cave_region(player, 'Spectacle Rock Cave (Bottom)', 'a connector', None, ['Spectacle Rock Cave Exit']),
create_cave_region(player, 'Spectacle Rock Cave (Peak)', 'a connector', None, ['Spectacle Rock Cave Peak Drop', 'Spectacle Rock Cave Exit (Peak)']),

View File

@@ -964,7 +964,8 @@ def make_custom_item_pool(progressive, shuffle, difficulty, timer, goal, mode, s
pool.append(thisbottle)
if customitemarray["triforcepieces"] > 0 or customitemarray["triforcepiecesgoal"] > 0:
treasure_hunt_count = max(min(customitemarray["triforcepiecesgoal"], 99), 1) #To display, count must be between 1 and 99.
# To display, count must be between 1 and 254 - larger values are not yet supported
treasure_hunt_count = max(min(customitemarray["triforcepiecesgoal"], 254), 1)
treasure_hunt_icon = 'Triforce Piece'
# Ensure game is always possible to complete here, force sufficient pieces if the player is unwilling.
if (customitemarray["triforcepieces"] < treasure_hunt_count) and (goal == 'triforcehunt') and (customitemarray["triforce"] == 0):

View File

@@ -23,7 +23,7 @@ from DoorShuffle import link_doors, connect_portal, link_doors_prep
from RoomData import create_rooms
from Rules import set_rules
from Dungeons import create_dungeons
from Fill import distribute_items_restrictive, promote_dungeon_items, fill_dungeons_restrictive
from Fill import distribute_items_restrictive, promote_dungeon_items, fill_dungeons_restrictive, ensure_good_pots
from Fill import sell_potions, sell_keys, balance_multiworld_progression, balance_money_progression, lock_shop_locations
from ItemList import generate_itempool, difficulties, fill_prizes, customize_shops
from Utils import output_path, parse_player_names
@@ -31,7 +31,7 @@ from Utils import output_path, parse_player_names
from source.item.FillUtil import create_item_pool_config, massage_item_pool, district_item_pool_config
__version__ = '1.0.1.2-v'
__version__ = '1.0.1.3-v'
from source.classes.BabelFish import BabelFish
@@ -253,6 +253,7 @@ def main(args, seed=None, fish=None):
customize_shops(world, player)
if args.algorithm in ['balanced', 'equitable']:
balance_money_progression(world)
ensure_good_pots(world, True)
outfilebase = f'DR_{args.outputname if args.outputname else world.seed}'

View File

@@ -90,8 +90,8 @@ INGAME_MODES = {0x07, 0x09, 0x0b}
SAVEDATA_START = WRAM_START + 0xF000
SAVEDATA_SIZE = 0x500
POT_ITEMS_SRAM_START = WRAM_START + 0x016600
SPRITE_ITEMS_SRAM_START = WRAM_START + 0x016850
POT_ITEMS_SRAM_START = WRAM_START + 0x016018
SPRITE_ITEMS_SRAM_START = WRAM_START + 0x016268
ITEM_SRAM_SIZE = 0x250
RECV_PROGRESS_ADDR = SAVEDATA_START + 0x4D0 # 2 bytes

View File

@@ -45,10 +45,6 @@ The "Item Sorting" option or ```--algorithm``` has been updated with new placeme
This one stays the same as before and is recommended for the most random distribution of items.
### Equitable
This one is currently under development and may not fill correctly. It is a new method that should allow item and key logic to interact. (Vanilla key placement in PoD is theoretically possible, but isn't yet.)
### Vanilla Fill
This fill attempts to place all items in their vanilla locations when possible. Obviously shuffling entrances or the dungeon interiors will often prevent items from being placed in their vanilla location. If the vanilla fill is not possible, then other locations are tried in sequence preferring "major" locations (see below), then heart piece locations, then the rest except for GT locations which are preferred last. Note the PoD small key that is normally found in the dark maze in vanilla is move to Harmless Hellway due to the placement algorithm limitation.
@@ -95,7 +91,7 @@ In multiworld, the districts chosen apply to all players.
### CLI values:
```balanced, equitable, vanilla_fill, major_only, dungeon_only, district```
```balanced, vanilla_fill, major_only, dungeon_only, district```
## New Hints
@@ -148,6 +144,15 @@ Same as above but both small keys and bigs keys of the dungeon are not allowed o
#### Volatile
* 1.0.1.3
* Fixed inverted generation issues with pottery option
* Moved SRAM according to SRAM standard
* Removed equitable algorithm
* Upped TFH goal limit to 254
* Cuccos should no longer cause trap door rooms to not open
* Added double click fix for install.py
* Fix for pottery item palettes near bonkable torches
* Fix for multiworld progression balancing would place Nothing or Arrow items
* 1.0.1.2
* Fixed logic for pots in TR Hub and TR Dark Ride
* Fix for districting + shopsanity

View File

@@ -1057,7 +1057,11 @@ def create_pot_location(pot, pot_index, super_tile, world, player):
if (pot.item not in [PotItem.Key, PotItem.Hole]
and (pot.item != PotItem.Switch or world.potshuffle[player])):
address = pot_address(pot_index, super_tile)
parent = world.get_region(pot.room, player)
region = pot.room
if world.mode[player] == 'inverted':
if region == 'Links House':
region = 'Inverted Links House'
parent = world.get_region(region, player)
descriptor = 'Large Block' if pot.flags & PotFlags.Block else f'Pot #{pot_index+1}'
hint_text = ('under a block' if pot.flags & PotFlags.Block else 'in a pot')
modifier = parent.hint_text not in {'a storyteller', 'fairies deep in a cave', 'a spiky hint',
@@ -1073,7 +1077,7 @@ def create_pot_location(pot, pot_index, super_tile, world, player):
def pot_address(pot_index, super_tile):
return 0x7f6600 + super_tile * 2 + (pot_index << 24)
return 0x7f6018 + super_tile * 2 + (pot_index << 24)
# (type, room_id, shopkeeper, custom, locked, [items])

5
Rom.py
View File

@@ -35,7 +35,7 @@ from source.item.FillUtil import valid_pot_items
JAP10HASH = '03a63945398191337e896e5771f77173'
RANDOMIZERBASEHASH = '83bdcdbe989281b7eb36a10150314997'
RANDOMIZERBASEHASH = 'a25e589ca9359e73b0ed94cab8db107d'
class JsonRom(object):
@@ -884,6 +884,9 @@ def patch_rom(world, rom, player, team, enemized, is_mystery=False):
rom.write_byte(0x142A51, multiClientFlags)
rom.write_byte(0x142A55, ((0x1 if world.pottery[player] != 'none' else 0) # StandingItemCounterMask
| (0x2 if world.dropshuffle[player] else 0)))
if world.pottery[player] not in ['none', 'keys']:
# Cuccos should not prevent kill rooms from opening
rom.write_byte(snes_to_pc(0x0DB457), 0x40)
write_int16(rom, 0x187010, credits_total) # dynamic credits
if credits_total != 216:

Binary file not shown.

View File

@@ -116,7 +116,6 @@
"algorithm": {
"choices": [
"balanced",
"equitable",
"vanilla_fill",
"major_only",
"dungeon_only",

View File

@@ -154,8 +154,6 @@
"balanced: vt26 derivative that aims to strike a balance between",
" the overworld heavy vt25 and the dungeon heavy vt26",
" algorithm.",
"equitable: does not place dungeon items first allowing new potential",
" but mixed with the normal advancement pool",
"restricted placements: these consider all major items to be special and attempts",
"to place items from fixed to semi-random locations. For purposes of these shuffles, all",
"Y items, A items, swords (unless vanilla swords), mails, shields, heart containers and",

View File

@@ -289,7 +289,6 @@
"randomizer.item.sortingalgo": "Item Sorting",
"randomizer.item.sortingalgo.balanced": "Balanced",
"randomizer.item.sortingalgo.equitable": "Equitable",
"randomizer.item.sortingalgo.vanilla_fill": "Vanilla Fill",
"randomizer.item.sortingalgo.major_only": "Major Location Restriction",
"randomizer.item.sortingalgo.dungeon_only": "Dungeon Restriction",

View File

@@ -117,7 +117,6 @@
"default": "balanced",
"options": [
"balanced",
"equitable",
"vanilla_fill",
"major_only",
"dungeon_only",

View File

@@ -6,7 +6,9 @@ import subprocess # do stuff at the shell level
env = common.prepare_env()
pip_requirements = os.path.join(".","resources","app","meta","manifests","pip_requirements.txt")
pip_requirements = os.path.join("..","resources","app","meta","manifests","pip_requirements.txt")
if not os.path.isfile(pip_requirements):
pip_requirements = os.path.join("..","..","..","resources","app","meta","manifests","pip_requirements.txt")
def run_install(PY_VERSION,USER):
# get executables

View File

@@ -100,7 +100,7 @@ def create_district_helper(world, player):
central_lw_entrances.append('Inverted Big Bomb Shop')
central_lw_entrances.remove('Links House')
south_dw_entrances.append('Inverted Links House')
voo_north_entrances.remove('Dark Sanctuary')
voo_north_entrances.remove('Dark Sanctuary Hint')
voo_north_entrances.append('Inverted Dark Sanctuary')
voo_north_entrances.remove('Bumper Cave (Top)')
nw_lw_entrances.append('Bumper Cave (Top)')