From a6e96720a34f25bf240f56bf29d6dcce53554a0c Mon Sep 17 00:00:00 2001 From: aerinon Date: Fri, 26 Jan 2024 13:48:34 -0700 Subject: [PATCH] fix: castle warp gate fix: potential swamola issue fix --- Main.py | 2 +- RELEASENOTES.md | 3 +++ Rom.py | 3 +-- data/base2current.bps | Bin 117538 -> 117552 bytes source/enemizer/OwEnemyList.py | 4 ++-- source/rom/DataTables.py | 42 +++++++++++++++++++++++++++++---- 6 files changed, 45 insertions(+), 9 deletions(-) diff --git a/Main.py b/Main.py index 83af5048..11589008 100644 --- a/Main.py +++ b/Main.py @@ -38,7 +38,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.4.1.3' +version_number = '1.4.1.4' version_branch = '-u' __version__ = f'{version_number}{version_branch}' diff --git a/RELEASENOTES.md b/RELEASENOTES.md index c668042b..cd256c63 100644 --- a/RELEASENOTES.md +++ b/RELEASENOTES.md @@ -141,6 +141,9 @@ These are now independent of retro mode and have three options: None, Random, an # Bug Fixes and Notes +* 1.4.1.4u + * Inverted: Castle warp should not appear after defeating Aga 1 + * Enemzier: Fixed a crash with cached sprites Zora/Swamola * 1.4.1.3v * Enemizer: Raven/Murderdactyls using the correct damage table * Enemzier: Boss drops only center when boss shuffle is on diff --git a/Rom.py b/Rom.py index ea11e06b..000b4da4 100644 --- a/Rom.py +++ b/Rom.py @@ -42,7 +42,7 @@ from source.enemizer.Enemizer import write_enemy_shuffle_settings JAP10HASH = '03a63945398191337e896e5771f77173' -RANDOMIZERBASEHASH = 'd63715be60a548e080dc84ae588307e5' +RANDOMIZERBASEHASH = 'd47bab6e3c7de77295fcdc0b0ab84a9d' class JsonRom(object): @@ -2474,7 +2474,6 @@ def set_inverted_mode(world, player, rom): rom.write_byte(snes_to_pc(0x00D0e8), 0xE0) rom.write_byte(snes_to_pc(0x00D1c7), 0x00) write_int16(rom, snes_to_pc(0x1BE8DA), 0x39AD) - rom.write_byte(0xF6E58, 0x80) # no whirlpool under castle gate rom.write_bytes(0x0086E, [0x5C, 0x00, 0xA0, 0xA1]) # TR tail rom.write_bytes(snes_to_pc(0x1BC67A), [0x2E, 0x0B, 0x82]) # add warps under rocks rom.write_bytes(snes_to_pc(0x1BC81E), [0x94, 0x1D, 0x82]) diff --git a/data/base2current.bps b/data/base2current.bps index 22fd6589399deb99ffbc392c629cf2176cc677f1..fdad6e462c0fdc8a2b5bba2b8de782f652ab615a 100644 GIT binary patch delta 988 zcmWNPYfO`O7{&h&Ewo%(I}i#*x)#{j>HvuX(zz+J3pc?bQA8qc;J|^aEMc&L@^296 z+fgokZ6BpVw{_x%!>R;|YoO3_p9ZpIm+S*hw`7ozKteL-0>0~~b53$ToaA@DHVf{U z1z+;`!+F_vhxoiFGT-aWH@XpaH7W}J8WPB(g2FZq477tLev3smCyagc)s z+s7eNMgoIq?*^$SF0xGUTa#`@vLsm=n6pISg;-kJSR76aIXsz{0@kM zsI>_zT<|%l@QDkO-~{fRfUCR3na}#m_-&^3qP60+;(c&t#0gjjh`Kwj65l{}>-nLb>2lLI};E z?_;hT_DlB3c2a9d&G1ZziD#F+LP{YpU;L`gD8z9$j~r=Ux6v~=sn zD7TCA;iT)5b$lC-OoMz+a9kK2BOKxE9LH^NYn#1)%Kohd@8Kd)#(1r``9WD`5cZTox>_ybg!a=xzbF-k7)m#XqSREWhyEn*x zWZT};K+^}^(Uh%0-W-&MWS{)O5Jcp}-DM&Ia)}shIaoUf*-(TNbC4Lb!%s??Qo`}H zxrJfW9jDS8(>|HkZn7$u!9$vf72+^>9va_!Cq9_EJDidCJ0&*;Z5?4{6x4IMQycD@wn+nd`mb3X{@7Ai6-X`h_-G!& z1iX|Z-jWQr=DncfFm3@--z}&b)i$vjdaL1j|5e+?qC{$V?&XDrDc9~@VTmM^cE&m} w>#}z1$B4J|4%Hj_7D8O2N-@Rovtrt(tZ42zy^)AF7NAzxeY@N~T{g1(KP|PGEdT%j delta 1003 zcmWMkZA_C_7`;ymwovE_Eg-Fw0v+2B1R|eZK?+L*5lk2}Lbs7kpa_#1odPS$eS>IQ zR=~b1SIVH9WjJ9Q&c*<%P-wAyY_9y7n}3-5%2*^R3CWzB`mVp8b53%Sb8?=WgPd!F zoKM(67pkdAM-cm0F?);}p&!M?!2?H#G?5!PsmVWt!dEmaGYw|xjLa+;b2MbWSO|;V zz1rzsE!-@J-=~#MIKm2l;Nwy`>#Q5yZdqt38JmOqP(^g}AcY!Yod=1yIW!E9Y@>GM zLK}#DZqaWF)&=VmE5mH!n}>$*!kRU+e#&S-&(U=?QMq8>uH^7AY&${Dy5Iv4k!=@b zf{G+Az}3C&2cL`|54vpeAKR+ks-0*Gx=gF(_lPp(o~Z~GA$OkzVWdJCcI`Rx#{ygg z1!-P{%0QOcMMx6n6@TZJmKw~#otLOQdpRCHbCUQMp`O#UPl!u!IjMC+oZOI+1Z*^V_)VdhsG9#C|Bx;wln3IVfY>|`vrFE7 z6c1OBJ03`aJo3;3DG)_?OYk16RZTjUKq}|8O1aEGEV;@RM|+z6;Wf&g5u3hZw|6F$}ZKZ0(HvCjQfw ze=Z7B@z&g`&8e&a>|q$X%hrRiy^h?t3zadI^=Wu6j%jB$^8K+4_c6Ck-=_ER2;U27 zASX&M>e|nYLp;KHY z59&s?mSiGZh0d;wv`Fmkb4q6W1=lAA=>6(wZ0^X`51|7n21$^s>X5-!C<}b=4tj!q zLYv5?3NUiIg@*@obzfVaAsu@B&!A%WFT?KywBdJS0+~0^5aQ4ZJSwao>z7|L>+L7A zD*~q23hXx86U~&L7J509h|Cko8pJ{b$zFrpgUXf}s*Bd*N!`ceSM8c(>Dcrx!84bE~!5s!X+ IV^tUVKheORIRF3v diff --git a/source/enemizer/OwEnemyList.py b/source/enemizer/OwEnemyList.py index 39f2b150..ffbf79d4 100644 --- a/source/enemizer/OwEnemyList.py +++ b/source/enemizer/OwEnemyList.py @@ -521,7 +521,7 @@ def init_vanilla_sprites_ow(): create_sprite(0x1a, EnemySprite.GreenGuard, 0x0C, 0x0E, '', 0x09D0A3) create_sprite(0x1a, EnemySprite.Faerie, 0x0D, 0x11, '', 0x09D0A6, fix=True) create_sprite(0x1a, EnemySprite.BlueRupee, 0x17, 0x17, '', 0x09D0A9) - # create_sprite(0x1a, EnemySprite.SmallHeart, 0x0A, 0x18, '', 0x09D0AC) + create_sprite(0x1a, EnemySprite.SmallHeart, 0x0A, 0x18, '', 0x09D0AC) create_sprite(0x1a, EnemySprite.RedSpearGuard, 0x0F, 0x18, '', 0x09D0AC) # was 0x09D0AF # Screen1B_1: create_sprite(0x1b, EnemySprite.Wiseman, 0x19, 0x12, '', 0x09D0B0) @@ -843,7 +843,7 @@ def init_vanilla_sprites_ow(): create_sprite(0xaa, EnemySprite.BlueGuard, 0x0F, 0x08, '', 0x09D418) create_sprite(0xaa, EnemySprite.BlueGuard, 0x0C, 0x0E, '', 0x09D41B) create_sprite(0xaa, EnemySprite.Faerie, 0x0D, 0x11, '', 0x09D41E, fix=True) - # create_sprite(0xaa, EnemySprite.SmallHeart, 0x0A, 0x18, '', 0x09D421) + create_sprite(0xaa, EnemySprite.SmallHeart, 0x0A, 0x18, '', 0x09D421) create_sprite(0xaa, EnemySprite.UsainBolt, 0x0F, 0x18, '', 0x09D421) # was 0x09D424 # Screen1B_2: create_sprite(0xab, EnemySprite.Wiseman, 0x19, 0x12, '', 0x09D425) diff --git a/source/rom/DataTables.py b/source/rom/DataTables.py index c818dfc4..6c732d29 100644 --- a/source/rom/DataTables.py +++ b/source/rom/DataTables.py @@ -1,6 +1,6 @@ from collections import defaultdict -from Utils import snes_to_pc, int24_as_bytes, int16_as_bytes, load_cached_yaml +from Utils import snes_to_pc, int24_as_bytes, int16_as_bytes, load_cached_yaml, pc_to_snes from source.dungeon.EnemyList import EnemyTable, init_vanilla_sprites, vanilla_sprites, init_enemy_stats, EnemySprite from source.dungeon.EnemyList import sprite_translation @@ -94,9 +94,7 @@ class DataTables: # _00FA81 is LW normal # _00FAC1 is LW post-aga # _00FB01 is DW - for area, sprite_list in self.ow_enemy_table.items(): - for sprite in sprite_list: - rom.write_bytes(snes_to_pc(sprite.original_address), sprite.sprite_data_ow()) + self.write_ow_sprite_data_to_rom(rom) for sprite, stats in self.enemy_stats.items(): # write health to rom if stats.health is not None: @@ -132,6 +130,42 @@ class DataTables: 0x0F, 0x01, 0x0F, 0x0F, 0x11, 0x0F, 0x0F, 0x03 ]) + def write_ow_sprite_data_to_rom(self, rom): + max_per_state = {0: 0x40, 1: 0x90, 2: 0x8D} # dropped max on state 2 to steal space for a couple extra sprites (Murahdahla) + pointer_address = snes_to_pc(0x09C881) + data_pointer = snes_to_pc(0x09CB3B) # was originally 0x09CB41 - stealing space for a couple extra sprites (Murahdahla) + empty_pointer = pc_to_snes(data_pointer) & 0xFFFF + rom.write_byte(data_pointer, 0xff) + cached_dark_world = {} + data_pointer += 1 + for state in range(0, 3): + if state > 0: # move pointer to next section + pointer_address += max_per_state[state-1] * 2 + for screen in range(0, max_per_state[state]): + internal_screen_id = screen + if state == 0: + internal_screen_id += 0x200 + if state == 2 and screen < 0x40: + internal_screen_id += 0x90 + if internal_screen_id not in self.ow_enemy_table: # has no sprites + rom.write_bytes(pointer_address + screen * 2, int16_as_bytes(empty_pointer)) + else: + if state == 2 and screen >= 0x40: # state 2 uses state 1 pointer for screens >= 0x40 + rom.write_bytes(pointer_address + screen * 2, cached_dark_world[screen]) + # the sprites are already written out + else: + data_address = pc_to_snes(data_pointer) & 0xFFFF + ref = int16_as_bytes(data_address) + if screen >= 40: + cached_dark_world[screen] = ref + rom.write_bytes(pointer_address + screen * 2, ref) + for sprite in self.ow_enemy_table[internal_screen_id]: + data = sprite.sprite_data() + rom.write_bytes(data_pointer, data) + data_pointer += len(data) + rom.write_byte(data_pointer, 0xff) + data_pointer += 1 + special_health_table = { EnemySprite.Octorok: (0x068F76, 0x068F77),