Open edges math fix (indices corrected in tables)

Spoiler lists bosses
Enemizer settings fix
Swamp flooded ladder's fix (Crossed mostly)
Spoiler encoding issue fixed
This commit is contained in:
aerinon
2020-05-20 10:51:56 -06:00
parent 337dbf311d
commit ae7ce076af
13 changed files with 62 additions and 44 deletions

View File

@@ -1664,7 +1664,7 @@ class Spoiler(object):
for index, item in enumerate(shop.inventory):
if item is None:
continue
shopdata['item_{}'.format(index)] = "{} {}".format(item['item'], item['price']) if item['price'] else item['item']
shopdata['item_{}'.format(index)] = "{} - {}".format(item['item'], item['price']) if item['price'] else item['item']
self.shops.append(shopdata)
for player in range(1, self.world.players + 1):
@@ -1810,6 +1810,12 @@ class Spoiler(object):
outfile.write('\n\nShops:\n\n')
outfile.write('\n'.join("{} [{}]\n {}".format(self.world.fish.translate("meta","locations",shop['location']), shop['type'], "\n ".join(self.world.fish.translate("meta","items",item) for item in [shop.get('item_0', None), shop.get('item_1', None), shop.get('item_2', None)] if item)) for shop in self.shops))
for player in range(1, self.world.players + 1):
if self.world.boss_shuffle[player] != 'none':
bossmap = self.bosses[player] if self.world.players > 1 else self.bosses
outfile.write(f'\n\nBosses (Player {player}):\n\n')
outfile.write('\n'.join([f'{x}: {y}' for x, y in bossmap.items()]))
# locations: Change up location names; in the instance of a location with multiple sections, it'll try to translate the room name
# items: Item names
outfile.write('\n\nPlaythrough:\n\n')

View File

@@ -160,7 +160,7 @@ def place_bosses(world, player):
all_bosses = sorted(boss_table.keys()) #s orted to be deterministic on older pythons
placeable_bosses = [boss for boss in all_bosses if boss not in ['Agahnim', 'Agahnim2', 'Ganon']]
if world.boss_shuffle[player] in ["basic", "normal"]:
if world.boss_shuffle[player] in ["simple", "full"]:
# temporary hack for swordless kholdstare:
if world.swords[player] == 'swordless':
world.get_dungeon('Ice Palace', player).boss = BossFactory('Kholdstare', player)
@@ -189,7 +189,7 @@ def place_bosses(world, player):
loc_text = loc + ' (' + level + ')'
logging.getLogger('').debug('Placing boss %s at %s', boss, loc_text)
world.get_dungeon(loc, player).bosses[level] = BossFactory(boss, player)
elif world.boss_shuffle[player] == "chaos": #all bosses chosen at random
elif world.boss_shuffle[player] == "random": #all bosses chosen at random
for [loc, level] in boss_locations:
loc_text = loc + (' ('+level+')' if level else '')
try:

View File

@@ -24,7 +24,7 @@ from Fill import distribute_items_cutoff, distribute_items_staleness, distribute
from ItemList import generate_itempool, difficulties, fill_prizes
from Utils import output_path, parse_player_names
__version__ = '0.1.0.2-u'
__version__ = '0.1.0.3-u'
class EnemizerError(RuntimeError):
pass

View File

@@ -1,5 +1,7 @@
# New Features
* Spoiler lists bosses (multiworld compatible)
### Experimental features
* Open "Edge" transitions can now be linked with normal doors
@@ -11,6 +13,9 @@
* Fix for Animated Tiles in crossed dungeon
* Stonewall hardlock no longer reachable from certain drops (Sewer Drop, some Skull Woods drops) that were previously possible
* No logic uses less key door logic
* Spoiler log encoding
* Enemizer settings made consistent with website
* Swamp flooded ladders in the basement now requires Flippers
##### In Progress

10
Rom.py
View File

@@ -22,7 +22,7 @@ from EntranceShuffle import door_addresses, exit_ids
JAP10HASH = '03a63945398191337e896e5771f77173'
RANDOMIZERBASEHASH = 'a793b94179f7a4afcfd958bac3a79b47'
RANDOMIZERBASEHASH = 'bd07845238de1ce060530a996378f867'
class JsonRom(object):
@@ -172,14 +172,14 @@ def patch_enemizer(world, player, rom, baserom_path, enemizercli, shufflepots, r
options = {
'RandomizeEnemies': world.enemy_shuffle[player] != 'none',
'RandomizeEnemiesType': 3,
'RandomizeBushEnemyChance': world.enemy_shuffle[player] == 'chaos',
'RandomizeBushEnemyChance': world.enemy_shuffle[player] == 'random',
'RandomizeEnemyHealthRange': world.enemy_health[player] != 'default',
'RandomizeEnemyHealthType': {'default': 0, 'easy': 0, 'normal': 1, 'hard': 2, 'expert': 3}[world.enemy_health[player]],
'OHKO': False,
'RandomizeEnemyDamage': world.enemy_damage[player] != 'default',
'AllowEnemyZeroDamage': True,
'ShuffleEnemyDamageGroups': world.enemy_damage[player] != 'default',
'EnemyDamageChaosMode': world.enemy_damage[player] == 'chaos',
'EnemyDamageChaosMode': world.enemy_damage[player] == 'random',
'EasyModeEscape': False,
'EnemiesAbsorbable': False,
'AbsorbableSpawnRate': 10,
@@ -218,9 +218,9 @@ def patch_enemizer(world, player, rom, baserom_path, enemizercli, shufflepots, r
'SwordGraphics': "sword_gfx/normal.gfx",
'BeeMizer': False,
'BeesLevel': 0,
'RandomizeTileTrapPattern': world.enemy_shuffle[player] == 'chaos',
'RandomizeTileTrapPattern': world.enemy_shuffle[player] == 'random',
'RandomizeTileTrapFloorTile': False,
'AllowKillableThief': bool(random.randint(0,1)) if world.enemy_shuffle[player] == 'chaos' else world.enemy_shuffle[player] != 'none',
'AllowKillableThief': bool(random.randint(0, 1)) if world.enemy_shuffle[player] == 'random' else world.enemy_shuffle[player] != 'none',
'RandomizeSpriteOnHit': random_sprite_on_hit,
'DebugMode': False,
'DebugForceEnemy': False,

View File

@@ -203,6 +203,8 @@ def global_rules(world, player):
set_rule(world.get_entrance('Swamp Drain WN', player), lambda state: state.has('Drained Swamp', player))
set_rule(world.get_entrance('Swamp Flooded Room WS', player), lambda state: state.has('Drained Swamp', player))
set_rule(world.get_entrance('Swamp Flooded Room Ladder', player), lambda state: state.has('Drained Swamp', player))
set_rule(world.get_entrance('Swamp Flooded Spot Ladder', player), lambda state: state.has('Drained Swamp', player) or state.has('Flippers', player))
set_rule(world.get_entrance('Swamp Drain Left Up Stairs', player), lambda state: state.has('Drained Swamp', player) or state.has('Flippers', player))
set_rule(world.get_location('Swamp Palace - Flooded Room - Left', player), lambda state: state.has('Drained Swamp', player))
set_rule(world.get_location('Swamp Palace - Flooded Room - Right', player), lambda state: state.has('Drained Swamp', player))
set_rule(world.get_entrance('Swamp Waterway NW', player), lambda state: state.has('Flippers', player))

View File

@@ -62,23 +62,25 @@ door_pair_offset_table = {
0xd6: 0x01fa, 0xd8: 0x01fd, 0xd9: 0x0200, 0xda: 0x0203, 0xdb: 0x0204, 0xdc: 0x0206, 0xe0: 0x020
}
# Note: 0-7 correspond to 1,2,3,4,5,6,a,14 respectively, see doortables.asm : MultDivInfo
multiply_lookup = {
0x08: {0x8: 1, 0x10: 2, 0x18: 3, 0x20: 4, 0x30: 6, 0x50: 0xa, 0xa0: 0x14},
0x10: {0x8: 1, 0x10: 1, 0x18: 3, 0x20: 2, 0x30: 3, 0x50: 0x4, 0xa0: 0xa},
0x18: {0x8: 1, 0x10: 2, 0x18: 1, 0x20: 4, 0x30: 2, 0x50: 0xa, 0xa0: 0x14},
0x20: {0x8: 1, 0x10: 1, 0x18: 3, 0x20: 1, 0x30: 3, 0x50: 5, 0xa0: 5},
0x30: {0x8: 1, 0x10: 1, 0x18: 1, 0x20: 2, 0x30: 1, 0x50: 5, 0xa0: 0xa},
0x50: {0x8: 1, 0x10: 1, 0x18: 3, 0x20: 2, 0x30: 3, 0x50: 1, 0xa0: 2},
0xa0: {0x8: 1, 0x10: 1, 0x18: 3, 0x20: 1, 0x30: 3, 0x50: 1, 0xa0: 1},
0x08: {0x8: 0, 0x10: 1, 0x18: 2, 0x20: 3, 0x30: 5, 0x50: 6, 0xa0: 7},
0x10: {0x8: 0, 0x10: 0, 0x18: 2, 0x20: 1, 0x30: 2, 0x50: 3, 0xa0: 6},
0x18: {0x8: 0, 0x10: 1, 0x18: 0, 0x20: 3, 0x30: 1, 0x50: 6, 0xa0: 7},
0x20: {0x8: 0, 0x10: 0, 0x18: 2, 0x20: 0, 0x30: 2, 0x50: 4, 0xa0: 4},
0x30: {0x8: 0, 0x10: 0, 0x18: 0, 0x20: 1, 0x30: 0, 0x50: 4, 0xa0: 6},
0x50: {0x8: 0, 0x10: 0, 0x18: 2, 0x20: 1, 0x30: 2, 0x50: 0, 0xa0: 1},
0xa0: {0x8: 0, 0x10: 0, 0x18: 2, 0x20: 0, 0x30: 2, 0x50: 0, 0xa0: 0},
}
divisor_lookup = {
0x08: {0x8: 1, 0x10: 1, 0x18: 1, 0x20: 1, 0x30: 1, 0x50: 1, 0xa0: 1},
0x10: {0x8: 2, 0x10: 1, 0x18: 2, 0x20: 1, 0x30: 1, 0x50: 1, 0xa0: 1},
0x18: {0x8: 3, 0x10: 3, 0x18: 1, 0x20: 3, 0x30: 1, 0x50: 3, 0xa0: 3},
0x20: {0x8: 4, 0x10: 2, 0x18: 4, 0x20: 1, 0x30: 2, 0x50: 2, 0xa0: 1},
0x30: {0x8: 6, 0x10: 3, 0x18: 2, 0x20: 3, 0x30: 1, 0x50: 3, 0xa0: 3},
0x50: {0x8: 0xa, 0x10: 4, 0x18: 0xa, 0x20: 5, 0x30: 5, 0x50: 1, 0xa0: 1},
0xa0: {0x8: 0x14, 0x10: 0xa, 0x18: 0x14, 0x20: 5, 0x30: 0xa, 0x50: 2, 0xa0: 1},
0x08: {0x8: 0, 0x10: 0, 0x18: 0, 0x20: 0, 0x30: 0, 0x50: 0, 0xa0: 0},
0x10: {0x8: 1, 0x10: 0, 0x18: 1, 0x20: 0, 0x30: 0, 0x50: 0, 0xa0: 0},
0x18: {0x8: 2, 0x10: 2, 0x18: 0, 0x20: 2, 0x30: 0, 0x50: 2, 0xa0: 2},
0x20: {0x8: 3, 0x10: 1, 0x18: 3, 0x20: 0, 0x30: 1, 0x50: 1, 0xa0: 0},
0x30: {0x8: 5, 0x10: 2, 0x18: 1, 0x20: 2, 0x30: 0, 0x50: 2, 0xa0: 2},
0x50: {0x8: 6, 0x10: 3, 0x18: 6, 0x20: 4, 0x30: 4, 0x50: 0, 0xa0: 0},
0xa0: {0x8: 7, 0x10: 6, 0x18: 7, 0x20: 4, 0x30: 6, 0x50: 1, 0xa0: 0},
}

View File

@@ -543,8 +543,9 @@ db $68,$10,$60, $84,$18,$78 ; HC Guards
db $a0,$a0,$50 ; DP Main Lobby
db $58,$50,$30, $98,$50,$70 ; TT Ambush
db $58,$50,$30 ; TT Nook
MultDivInfo: ; (1placeholder, 1, 2, 3, 4, 5, 6, 10, 20)
db $01, $01, $02, $03, $04, $05, $06, $0a, $14
MultDivInfo: ; (1, 2, 3, 4, 5, 6, 10, 20)
db $01, $02, $03, $04, $05, $06, $0a, $14
; indices: 0-7
; dungeon tables

View File

@@ -17,7 +17,9 @@ cpy #$0003 : bne ++
;Divisor in Y. Width of division is in X for rounding toward middle
DivideByY:
.loop cpy #$0001 : beq .done
.loop
cpy #$0000 : beq .done
cpy #$0001 : beq .done
cpy #$0003 : bne ++
jsr DivideBy3 : bra .done
++ cpy #$0005 : bne ++

File diff suppressed because one or more lines are too long

View File

@@ -70,25 +70,25 @@
"randomizer.enemizer.potshuffle": "Pot Shuffle",
"randomizer.enemizer.enemyshuffle": "Enemy Shuffle",
"randomizer.enemizer.enemyshuffle.none": "Vanilla",
"randomizer.enemizer.enemyshuffle.none": "None",
"randomizer.enemizer.enemyshuffle.shuffled": "Shuffled",
"randomizer.enemizer.enemyshuffle.chaos": "Chaos",
"randomizer.enemizer.enemyshuffle.random": "Random",
"randomizer.enemizer.bossshuffle": "Boss Shuffle",
"randomizer.enemizer.bossshuffle.none": "Vanilla",
"randomizer.enemizer.bossshuffle.basic": "Basic",
"randomizer.enemizer.bossshuffle.shuffled": "Shuffled",
"randomizer.enemizer.bossshuffle.chaos": "Chaos",
"randomizer.enemizer.bossshuffle.none": "None",
"randomizer.enemizer.bossshuffle.simple": "Simple",
"randomizer.enemizer.bossshuffle.full": "Full",
"randomizer.enemizer.bossshuffle.random": "Random",
"randomizer.enemizer.enemydamage": "Enemy Damage",
"randomizer.enemizer.enemydamage.default": "Vanilla",
"randomizer.enemizer.enemydamage.default": "Default",
"randomizer.enemizer.enemydamage.shuffled": "Shuffled",
"randomizer.enemizer.enemydamage.chaos": "Chaos",
"randomizer.enemizer.enemydamage.random": "Random",
"randomizer.enemizer.enemyhealth": "Enemy Health",
"randomizer.enemizer.enemyhealth.default": "Vanilla",
"randomizer.enemizer.enemyhealth.default": "Default",
"randomizer.enemizer.enemyhealth.easy": "Easy",
"randomizer.enemizer.enemyhealth.normal": "Normal",
"randomizer.enemizer.enemyhealth.normal": "Medium",
"randomizer.enemizer.enemyhealth.hard": "Hard",
"randomizer.enemizer.enemyhealth.expert": "Expert",

View File

@@ -8,16 +8,16 @@
"options": [
"none",
"shuffled",
"chaos"
"random"
]
},
"bossshuffle": {
"type": "selectbox",
"options": [
"none",
"basic",
"shuffled",
"chaos"
"simple",
"full",
"random"
]
}
},
@@ -27,7 +27,7 @@
"options": [
"default",
"shuffled",
"chaos"
"random"
]
},
"enemyhealth": {

View File

@@ -78,8 +78,8 @@ def bottom_frame(self, parent, args=None):
argsDump = vars(guiargs)
hasEnemizer = "enemizercli" in argsDump and os.path.isfile(argsDump["enemizercli"])
needEnemizer = False
if not hasEnemizer:
falsey = [ "none", "default", "vanilla", False, 0 ]
if hasEnemizer:
falsey = ["none", "default", False, 0]
for enemizerOption in [ "shufflepots", "shuffleenemies", "enemy_damage", "shufflebosses", "enemy_health" ]:
if enemizerOption in argsDump:
if isinstance(argsDump[enemizerOption], dict):