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:
@@ -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')
|
||||
|
||||
@@ -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:
|
||||
|
||||
2
Main.py
2
Main.py
@@ -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
|
||||
|
||||
@@ -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
10
Rom.py
@@ -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,
|
||||
|
||||
2
Rules.py
2
Rules.py
@@ -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))
|
||||
|
||||
30
Tables.py
30
Tables.py
@@ -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},
|
||||
}
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
@@ -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",
|
||||
|
||||
|
||||
@@ -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": {
|
||||
|
||||
@@ -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):
|
||||
|
||||
Reference in New Issue
Block a user