diff --git a/BaseClasses.py b/BaseClasses.py index bc168cb4..c5338757 100644 --- a/BaseClasses.py +++ b/BaseClasses.py @@ -3095,7 +3095,7 @@ class Settings(object): args.intensity[p] = "random" if intensity == 0 else intensity args.shuffletavern[p] = True if settings[4] & 0x80 else False - args.dropshuffle[p] = r(drop_shuffle_mode)[settings[4] & 0x70] + args.dropshuffle[p] = r(drop_shuffle_mode)[(settings[4] & 0x70) >> 4] args.pottery[p] = r(pottery_mode)[settings[4] & 0x0F] args.dungeon_counters[p] = r(counter_mode)[(settings[5] & 0x6) >> 1] diff --git a/ItemList.py b/ItemList.py index a5c895c2..7a20c7a0 100644 --- a/ItemList.py +++ b/ItemList.py @@ -1164,20 +1164,19 @@ def make_custom_item_pool(world, player, progressive, shuffle, difficulty, timer pool.extend(['Nothing'] * nothings) start_inventory = [x for x in world.precollected_items if x.player == player] - if not start_inventory: - if world.logic[player] in ['owglitches', 'nologic']: - precollected_items.append('Pegasus Boots') - if 'Pegasus Boots' in pool: - pool.remove('Pegasus Boots') - pool.append('Rupees (20)') - if world.swords[player] == 'assured': - precollected_items.append('Progressive Sword') - if 'Progressive Sword' in pool: - pool.remove('Progressive Sword') - pool.append('Rupees (50)') - elif 'Fighter Sword' in pool: - pool.remove('Fighter Sword') - pool.append('Rupees (50)') + if world.logic[player] in ['owglitches', 'nologic'] and all(x !=' Pegasus Boots' for x in start_inventory): + precollected_items.append('Pegasus Boots') + if 'Pegasus Boots' in pool: + pool.remove('Pegasus Boots') + pool.append('Rupees (20)') + if world.swords[player] == 'assured' and all(' Sword' not in x for x in start_inventory): + precollected_items.append('Progressive Sword') + if 'Progressive Sword' in pool: + pool.remove('Progressive Sword') + pool.append('Rupees (50)') + elif 'Fighter Sword' in pool: + pool.remove('Fighter Sword') + pool.append('Rupees (50)') return (pool, placed_items, precollected_items, clock_mode, treasure_hunt_count, treasure_hunt_icon, lamps_needed_for_dark_rooms) diff --git a/Main.py b/Main.py index eaba8769..b159eac3 100644 --- a/Main.py +++ b/Main.py @@ -37,7 +37,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.3.0.0' +version_number = '1.3.0.1' version_branch = '-v' __version__ = f'{version_number}{version_branch}' diff --git a/RELEASENOTES.md b/RELEASENOTES.md index 391ec6a4..60b9a8e5 100644 --- a/RELEASENOTES.md +++ b/RELEASENOTES.md @@ -141,6 +141,14 @@ These are now independent of retro mode and have three options: None, Random, an # Bug Fixes and Notes +* 1.3.0.1v + * Fixed bugs with item duping and disappearing drops + * Fixed multiworld crash + * Fixed assured sword missing when using start inventory (via GUI/CLI) + * Forbid extra statues in Swamp Push Statue room + * Forbid bumpers on OW waterr + * Forbid Stal on pits + * Text fix on sprite author (thanks Synack) * 1.2.0.19u * Added min/max for triforce pool, goal, and difference for CLI and Customizer. (Thanks Catobat) * Fixed a bug with dungeon generation diff --git a/Rom.py b/Rom.py index 53094d0b..bcbadd1b 100644 --- a/Rom.py +++ b/Rom.py @@ -40,7 +40,7 @@ from source.enemizer.Enemizer import write_enemy_shuffle_settings JAP10HASH = '03a63945398191337e896e5771f77173' -RANDOMIZERBASEHASH = 'c8b9a36f11cb3cd070f83f31219f5cba' +RANDOMIZERBASEHASH = '3302050481ab0c324fb6da95c8f3f099' class JsonRom(object): diff --git a/data/base2current.bps b/data/base2current.bps index a77da83b..54d6688c 100644 Binary files a/data/base2current.bps and b/data/base2current.bps differ diff --git a/source/enemizer/Enemizer.py b/source/enemizer/Enemizer.py index 93203acc..d303cc83 100644 --- a/source/enemizer/Enemizer.py +++ b/source/enemizer/Enemizer.py @@ -358,6 +358,10 @@ def filter_choices(options, room_id, sprite_idx, denials): return [x for x in options if key not in denials or x.sprite not in denials[key]] +def filter_water_phobic(options, sprite): + return [x for x in options if not x.water_phobic or not sprite.water] + + def randomize_overworld_enemies(data_tables, custom_ow): ow_candidates, ow_sheets, all_sheets = find_candidate_sprites(data_tables, range(1, 64), False) areas_to_randomize = [0, 2, 3, 5, 7, 0xA, 0xF, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, @@ -382,6 +386,7 @@ def randomize_overworld_enemies(data_tables, custom_ow): sprite.kind = sprite_translation[custom_ow[area_id][i]] else: candidate_sprites = filter_choices(candidate_sprites, area_id, i, data_tables.ow_enemy_denials) + candidate_sprites = filter_water_phobic(candidate_sprites, sprite) weight = [data_tables.ow_weights[r.sprite] for r in candidate_sprites] chosen = random.choices(candidate_sprites, weight, k=1)[0] sprite.kind = chosen.sprite diff --git a/source/enemizer/SpriteSheets.py b/source/enemizer/SpriteSheets.py index f101ab0c..12ea66fd 100644 --- a/source/enemizer/SpriteSheets.py +++ b/source/enemizer/SpriteSheets.py @@ -20,6 +20,7 @@ class SpriteRequirement: self.ow_valid = True self.uw_valid = True self.can_randomize = True + self.water_phobic = False self.groups = [] self.sub_groups = defaultdict(list) @@ -77,6 +78,10 @@ class SpriteRequirement: self.water_only = True return self + def aquaphobia(self): + self.water_phobic = True + return self + def skip(self): self.dont_use = True return self @@ -290,7 +295,7 @@ def init_sprite_requirements(): .allow(WallmasterValidRooms), SpriteRequirement(EnemySprite.StalfosKnight).sub_group(1, 0x20).exclude({0x10c}), SpriteRequirement(EnemySprite.HelmasaurKing).exalt().sub_group(2, 0x3a).sub_group(3, 0x3e), - SpriteRequirement(EnemySprite.Bumper).immune().sub_group(3, [0x52, 0x53]), + SpriteRequirement(EnemySprite.Bumper).immune().aquaphobia().sub_group(3, [0x52, 0x53]), SpriteRequirement(EnemySprite.LaserEyeLeft).affix().sub_group(3, [0x52, 0x53]), SpriteRequirement(EnemySprite.LaserEyeRight).affix().sub_group(3, [0x52, 0x53]), SpriteRequirement(EnemySprite.LaserEyeTop).affix().sub_group(3, [0x52, 0x53]), diff --git a/source/enemizer/enemy_deny.yaml b/source/enemizer/enemy_deny.yaml index a3c8e307..d2916e84 100644 --- a/source/enemizer/enemy_deny.yaml +++ b/source/enemizer/enemy_deny.yaml @@ -34,8 +34,10 @@ UwGeneralDeny: - [ 0x0021, 4, [ "RollerVerticalDown", "RollerVerticalUp" ] ] #"Sewers - Dark U - Rat 3" - [ 0x0024, 6, [ "Wizzrobe" ] ] # Wizzrobes can't spawn on pots - [ 0x0026, 1, [ "SparkCW", "SparkCCW", "RollerVerticalDown", "RollerVerticalUp", "RollerHorizontalRight", "RollerHorizontalLeft", "Beamos", "AntiFairyCircle", "BigSpike", "SpikeBlock", "Bumper" ] ] #"Swamp Palace - Big Spoon - Red Bari 1" - - [ 0x0026, 8, [ "AntiFairyCircle", "Bumper" ] ] #"Swamp Palace - Big Spoon - Red Bari 3" - - [ 0x0026, 9, [ "RollerHorizontalRight" ] ] #"Swamp Palace - Big Spoon - Kyameron" + - [ 0x0026, 8, [ "AntiFairyCircle", "Bumper", "Statue" ] ] #"Swamp Palace - Big Spoon - Red Bari 3" + - [ 0x0026, 9, [ "RollerHorizontalRight", "Statue" ] ] #"Swamp Palace - Big Spoon - Kyameron" + - [ 0x0026, 10, [ "Statue" ] ] # multiple push statues in this room can cause issues + - [ 0x0026, 11, [ "Statue" ] ] # multiple push statues in this room can cause issues - [ 0x0027, 0, [ "SparkCW", "SparkCCW", "RollerVerticalDown", "RollerVerticalUp", "RollerHorizontalLeft", "FirebarCW" ] ] #"Tower Of Hera - Petting Zoo - Mini Moldorm 1" - [ 0x0027, 1, [ "RollerVerticalDown", "RollerVerticalUp", "RollerHorizontalRight", "RollerHorizontalLeft", "AntiFairyCircle", "SpikeBlock", "Bumper" ] ] #"Tower Of Hera - Petting Zoo - Mini Moldorm 2" - [ 0x0027, 2, [ "RollerVerticalDown", "RollerVerticalUp", "RollerHorizontalRight", "RollerHorizontalLeft", "AntiFairyCircle", "SpikeBlock", "Bumper" ] ] #"Tower Of Hera - Petting Zoo - Mini Moldorm 3" @@ -350,43 +352,43 @@ UwEnemyDrop: - [0x010C, 2, ["StalfosKnight", "Geldman", "Blob"]] - [0x010C, 3, ["StalfosKnight", "Geldman", "Blob"]] # the following are not allowed at certain pits -# because they despawned or clipped away or immediately fell +# because they despawned or clipped away or immediately fell, etc - [0x007f, 0, ["HardhatBeetle", "Wizzrobe", "MiniHelmasaur", "BlueGuard", "GreenGuard", "RedSpearGuard", "BluesainBolt", "UsainBolt", "BlueArcher", "GreenBushGuard", "RedJavelinGuard", "RedBushGuard", - "BombGuard", "GreenKnifeGuard"]] + "BombGuard", "GreenKnifeGuard", "Stal"]] - [0x007f, 1, ["HardhatBeetle", "Wizzrobe", "MiniHelmasaur", "BlueGuard", "GreenGuard", "RedSpearGuard", "BluesainBolt", "UsainBolt", "BlueArcher", "GreenBushGuard", "RedJavelinGuard", "RedBushGuard", - "BombGuard", "GreenKnifeGuard"]] + "BombGuard", "GreenKnifeGuard", "Stal"]] - [0x007f, 2, ["HardhatBeetle", "Wizzrobe", "MiniHelmasaur", "BlueGuard", "GreenGuard", "RedSpearGuard", "BluesainBolt", "UsainBolt", "BlueArcher", "GreenBushGuard", "RedJavelinGuard", "RedBushGuard", - "BombGuard", "GreenKnifeGuard"]] + "BombGuard", "GreenKnifeGuard", "Stal"]] - [0x007f, 3, ["HardhatBeetle", "Wizzrobe", "MiniHelmasaur", "BlueGuard", "GreenGuard", "RedSpearGuard", "BluesainBolt", "UsainBolt", "BlueArcher", "GreenBushGuard", "RedJavelinGuard", "RedBushGuard", - "BombGuard", "GreenKnifeGuard"]] + "BombGuard", "GreenKnifeGuard", "Stal"]] - [0x00b5, 0, ["HardhatBeetle", "Wizzrobe", "MiniHelmasaur", "BlueGuard", "GreenGuard", "RedSpearGuard", "BluesainBolt", "UsainBolt", "BlueArcher", "GreenBushGuard", "RedJavelinGuard", "RedBushGuard", - "BombGuard", "GreenKnifeGuard"]] + "BombGuard", "GreenKnifeGuard", "Stal"]] - [0x00b5, 1, ["HardhatBeetle", "Wizzrobe", "MiniHelmasaur", "BlueGuard", "GreenGuard", "RedSpearGuard", "BluesainBolt", "UsainBolt", "BlueArcher", "GreenBushGuard", "RedJavelinGuard", "RedBushGuard", - "BombGuard", "GreenKnifeGuard"]] + "BombGuard", "GreenKnifeGuard", "Stal"]] - [0x00b5, 2, ["HardhatBeetle", "Wizzrobe", "MiniHelmasaur", "BlueGuard", "GreenGuard", "RedSpearGuard", "BluesainBolt", "UsainBolt", "BlueArcher", "GreenBushGuard", "RedJavelinGuard", "RedBushGuard", - "BombGuard", "GreenKnifeGuard"]] + "BombGuard", "GreenKnifeGuard", "Stal"]] - [0x00c6, 2, ["HardhatBeetle", "Wizzrobe", "MiniHelmasaur", "BlueGuard", "GreenGuard", "RedSpearGuard", "BluesainBolt", "UsainBolt", "BlueArcher", "GreenBushGuard", "RedJavelinGuard", "RedBushGuard", - "BombGuard", "GreenKnifeGuard"]] + "BombGuard", "GreenKnifeGuard", "Stal"]] - [0x00c6, 3, ["HardhatBeetle", "Wizzrobe", "MiniHelmasaur", "BlueGuard", "GreenGuard", "RedSpearGuard", "BluesainBolt", "UsainBolt", "BlueArcher", "GreenBushGuard", "RedJavelinGuard", "RedBushGuard", - "BombGuard", "GreenKnifeGuard"]] + "BombGuard", "GreenKnifeGuard", "Stal"]] - [0x00c6, 4, ["HardhatBeetle", "Wizzrobe", "MiniHelmasaur", "BlueGuard", "GreenGuard", "RedSpearGuard", "BluesainBolt", "UsainBolt", "BlueArcher", "GreenBushGuard", "RedJavelinGuard", "RedBushGuard", - "BombGuard", "GreenKnifeGuard"]] + "BombGuard", "GreenKnifeGuard", "Stal"]] - [0x00c6, 5, ["HardhatBeetle", "Wizzrobe", "MiniHelmasaur", "BlueGuard", "GreenGuard", "RedSpearGuard", "BluesainBolt", "UsainBolt", "BlueArcher", "GreenBushGuard", "RedJavelinGuard", "RedBushGuard", - "BombGuard", "GreenKnifeGuard", "Bumper"]] + "BombGuard", "GreenKnifeGuard", "Bumper", "Stal"]] - [0x00c6, 6, ["HardhatBeetle", "Wizzrobe", "MiniHelmasaur", "BlueGuard", "GreenGuard", "RedSpearGuard", "BluesainBolt", "UsainBolt", "BlueArcher", "GreenBushGuard", "RedJavelinGuard", "RedBushGuard", - "BombGuard", "GreenKnifeGuard"]] + "BombGuard", "GreenKnifeGuard", "Stal"]] # wizzrobe despawn issues - on pots/blocks - [0x004e, 3, ["Wizzrobe"]] - [0x005e, 4, ["Wizzrobe"]]