handle local items for real, appp cleanup

This commit is contained in:
Silvris
2024-03-21 01:38:27 -05:00
parent fbf26f7191
commit 1912cd9d4c
4 changed files with 52 additions and 46 deletions

View File

@@ -139,7 +139,7 @@ class KDL3SNIClient(SNIClient):
ctx.game = self.game
ctx.rom = rom_name
ctx.items_handling = 0b111 # always remote items
ctx.items_handling = 0b101 # default local items with remote start inventory
ctx.allow_collect = True
if "gift" not in ctx.command_processor.commands:
ctx.command_processor.commands["gift"] = cmd_gift
@@ -147,6 +147,7 @@ class KDL3SNIClient(SNIClient):
death_link = await snes_read(ctx, KDL3_DEATH_LINK_ADDR, 1)
if death_link:
await ctx.update_death_link(bool(death_link[0] & 0b1))
ctx.items_handling |= (death_link[0] & 0b10) # set local items if enabled
return True
async def pop_item(self, ctx, in_stage):

View File

@@ -1,11 +1,18 @@
import random
from dataclasses import dataclass
from Options import DeathLink, Choice, Toggle, OptionDict, Range, PlandoBosses, DefaultOnToggle, \
from Options import DeathLinkMixin, Choice, Toggle, OptionDict, Range, PlandoBosses, DefaultOnToggle, \
PerGameCommonOptions
from .Names import LocationName
class RemoteItems(DefaultOnToggle):
"""
Enables receiving items from your own world, primarily for co-op play.
"""
display_name = "Remote Items"
class Goal(Choice):
"""
Zero: collect the Heart Stars, and defeat Zero in the Hyper Zone.
@@ -26,6 +33,7 @@ class Goal(Choice):
return cls.name_lookup[value].upper()
return super().get_option_name(value)
class GoalSpeed(Choice):
"""
Normal: the goal is unlocked after purifying the five bosses
@@ -292,6 +300,7 @@ class KirbyFlavor(OptionDict):
A custom color for Kirby. To use a custom color, set the preset to Custom and then define a dict of keys from "1" to
"15", with their values being an HTML hex color.
"""
display_name = "Custom Kirby Flavor"
default = {
"1": "B01810",
"2": "F0E0E8",
@@ -348,6 +357,7 @@ class GooeyFlavor(OptionDict):
A custom color for Gooey. To use a custom color, set the preset to Custom and then define a dict of keys from "1" to
"15", with their values being an HTML hex color.
"""
display_name = "Custom Gooey Flavor"
default = {
"1": "000808",
"2": "102838",
@@ -399,8 +409,8 @@ class Gifting(Toggle):
@dataclass
class KDL3Options(PerGameCommonOptions):
death_link: DeathLink
class KDL3Options(PerGameCommonOptions, DeathLinkMixin):
remote_items: RemoteItems
game_language: GameLanguage
goal: Goal
goal_speed: GoalSpeed

View File

@@ -273,11 +273,6 @@ class RomData:
def write_bytes(self, offset: int, values: typing.Sequence) -> None:
self.file[offset:offset + len(values)] = values
def write_crc(self) -> None:
crc = (sum(self.file[:0x7FDC] + self.file[0x7FE0:]) + 0x01FE) & 0xFFFF
inv = crc ^ 0xFFFF
self.write_bytes(0x7FDC, [inv & 0xFF, (inv >> 8) & 0xFF, crc & 0xFF, (crc >> 8) & 0xFF])
def get_bytes(self) -> bytes:
return bytes(self.file)
@@ -342,8 +337,9 @@ def write_consumable_sprites(rom: RomData, consumables: bool, stars: bool):
class KDL3PatchExtensions(APPatchExtension):
game = "Kirby's Dream Land 3"
@staticmethod
def apply_post_patch(caller: APProcedurePatch, rom: bytes):
def apply_post_patch(_: APProcedurePatch, rom: bytes):
rom_data = RomData(rom)
target_language = rom_data.read_byte(0x3C020)
rom_data.write_byte(0x7FD9, target_language)
@@ -361,9 +357,6 @@ class KDL3PatchExtensions(APPatchExtension):
rom_data.write_bytes(0x460A, [0x00, 0xA0, 0x39, 0x20, 0xA9, 0x39, 0x30, 0xB2, 0x39, 0x40, 0xBB, 0x39,
0x50, 0xC4, 0x39])
write_consumable_sprites(rom_data, rom_data.read_byte(0x3D018) > 0, rom_data.read_byte(0x3D01A) > 0)
rom_name = rom_data.read_bytes(0x3C000, 21)
rom_data.write_bytes(0x7FC0, rom_name)
rom_data.write_crc()
return rom_data.get_bytes()
@@ -375,6 +368,7 @@ class KDL3ProcedurePatch(APProcedurePatch, APTokenMixin):
("apply_bsdiff4", ["kdl3_basepatch.bsdiff4"]),
("apply_tokens", ["token_patch.bin"]),
("apply_post_patch", []),
("write_snes_crc", [])
]
name: bytes # used to pass to init
@@ -435,10 +429,12 @@ def patch_rom(world: "KDL3World", patch: KDL3ProcedurePatch):
for room in rooms:
room.music = world.random.choice(music_choices)
for room in room_music:
patch.write_token(APTokenTypes.WRITE, room + 2, world.random.choice(music_choices).to_bytes(1, "little"))
patch.write_token(APTokenTypes.WRITE, room + 2,
world.random.choice(music_choices).to_bytes(1, "little"))
for i in range(5):
# level themes
patch.write_token(APTokenTypes.WRITE, 0x133F2 + i, world.random.choice(music_choices).to_bytes(1, "little"))
patch.write_token(APTokenTypes.WRITE, 0x133F2 + i,
world.random.choice(music_choices).to_bytes(1, "little"))
# Zero
patch.write_token(APTokenTypes.WRITE, 0x9AE79, world.random.choice(music_choices).to_bytes(1, "little"))
# Heart Star success and fail
@@ -446,7 +442,7 @@ def patch_rom(world: "KDL3World", patch: KDL3ProcedurePatch):
patch.write_token(APTokenTypes.WRITE, 0x4A38D, world.random.choice(music_choices).to_bytes(1, "little"))
for room in rooms:
room.patch(patch, bool(world.options.consumables.value), True)
room.patch(patch, bool(world.options.consumables.value), not bool(world.options.remote_items.value))
if world.options.virtual_console in [1, 3]:
# Flash Reduction
@@ -471,14 +467,15 @@ def patch_rom(world: "KDL3World", patch: KDL3ProcedurePatch):
struct.pack("H", world.required_heart_stars if world.options.goal_speed == 1 else 0xFFFF))
patch.write_token(APTokenTypes.WRITE, 0x3D00C, world.options.goal_speed.value.to_bytes(2, "little"))
patch.write_token(APTokenTypes.WRITE, 0x3D00E, world.options.open_world.value.to_bytes(2, "little"))
patch.write_token(APTokenTypes.WRITE, 0x3D010, world.options.death_link.value.to_bytes(2, "little"))
patch.write_token(APTokenTypes.WRITE, 0x3D010, ((world.options.remote_items.value << 1) +
world.options.death_link.value).to_bytes(2, "little"))
patch.write_token(APTokenTypes.WRITE, 0x3D012, world.options.goal.value.to_bytes(2, "little"))
patch.write_token(APTokenTypes.WRITE, 0x3D014, world.options.stage_shuffle.value.to_bytes(2, "little"))
patch.write_token(APTokenTypes.WRITE, 0x3D016, world.options.ow_boss_requirement.value.to_bytes(2, "little"))
patch.write_token(APTokenTypes.WRITE, 0x3D018, world.options.consumables.value.to_bytes(2, "little"))
patch.write_token(APTokenTypes.WRITE, 0x3D01A, world.options.starsanity.value.to_bytes(2, "little"))
patch.write_token(APTokenTypes.WRITE, 0x3D01C, world.options.gifting.value.to_bytes(2, "little")
if world.multiworld.players > 1 else bytes([0]))
if world.multiworld.players > 1 else bytes([0]))
patch.write_token(APTokenTypes.WRITE, 0x3D01E, world.options.strict_bosses.value.to_bytes(2, "little"))
# don't write gifting for solo game, since there's no one to send anything to
@@ -558,6 +555,9 @@ def patch_rom(world: "KDL3World", patch: KDL3ProcedurePatch):
patch.write_token(APTokenTypes.WRITE, 0x3C000, bytes(patch.name))
patch.write_token(APTokenTypes.WRITE, 0x3C020, world.options.game_language.value.to_bytes(1, "little"))
patch.write_token(APTokenTypes.COPY, 0x7FC0, (0x3C000, 21))
patch.write_token(APTokenTypes.COPY, 0x7FD9, (0x3C020, 1))
# handle palette
if world.options.kirby_flavor_preset.value != 0:
for addr in kirby_target_palettes:

View File

@@ -160,7 +160,6 @@ CopyAbilityAnimalOverride:
STA $39DF, X
RTL
org $079A00
HeartStarCheck:
TXA
CMP #$0000 ; is this level 1
@@ -201,7 +200,6 @@ HeartStarCheck:
SEC
RTL
org $079A80
OpenWorldUnlock:
PHX
LDX $900E ; Are we on open world?
@@ -224,7 +222,6 @@ OpenWorldUnlock:
PLX
RTL
org $079B00
MainLoopHook:
STA $D4
INC $3524
@@ -265,7 +262,6 @@ MainLoopHook:
.Return:
RTL
org $079B80
HeartStarGraphicFix:
LDA #$0000
PHX
@@ -299,7 +295,6 @@ HeartStarGraphicFix:
PLX
RTL
org $079BF0
ParseItemQueue:
; Local item queue parsing
NOP
@@ -427,7 +422,6 @@ ParseItemQueue:
LDA #$0000
BRA .PlaySFXLong
org $079D00
AnimalFriendSpawn:
PHA
CPX #$0002 ; is this an animal friend?
@@ -446,7 +440,6 @@ AnimalFriendSpawn:
LDA #$9999
RTL
org $079E00
WriteBWRAM:
LDY #$6001 ;starting addr
LDA #$1FFE ;bytes to write
@@ -479,7 +472,6 @@ WriteBWRAM:
.Return:
RTL
org $079E80
ConsumableSet:
PHA
PHX
@@ -536,7 +528,6 @@ ConsumableSet:
AND #$00FF
RTL
org $079F00
NormalGoalSet:
PHX
LDA $07D012
@@ -557,7 +548,6 @@ NormalGoalSet:
STA $5AC1 ; cutscene
RTL
org $079F80
FinalIcebergFix:
PHX
PHY
@@ -591,7 +581,6 @@ FinalIcebergFix:
PLX
RTL
org $07A000
StrictBosses:
PHX
LDA $901E ; Do we have strict bosses enabled?
@@ -618,7 +607,6 @@ StrictBosses:
LDA $53CD
RTL
org $07A030
NintenHalken:
LDX #$0005
.Halken:
@@ -636,7 +624,6 @@ NintenHalken:
LDA #$0001
RTL
org $07A080
StageCompleteSet:
PHX
LDA $5AC1 ; completed stage cutscene
@@ -667,6 +654,16 @@ StageCompleteSet:
DEC
ASL
TAX
PHX
LDA $8200, X
AND #$00FF
BNE .ApplyClear
TXA
LSR
INC
JSL ApplyLocalCheck
.ApplyClear:
PLX
LDA #$0001
ORA $8200, X
STA $8200, X
@@ -676,7 +673,6 @@ StageCompleteSet:
CMP $53CB
RTL
org $07A100
OpenWorldBossUnlock:
PHX
PHY
@@ -740,7 +736,6 @@ OpenWorldBossUnlock:
PLX
RTL
org $07A180
GooeySpawn:
PHY
PHX
@@ -776,7 +771,6 @@ GooeySpawn:
PLY
RTL
org $07A200
SpeedTrap:
PHX
LDX $8082 ; do we have slowness
@@ -788,7 +782,6 @@ SpeedTrap:
EOR #$FFFF
RTL
org $07A280
HeartStarVisual:
CPX #$0000
BEQ .SkipInx
@@ -852,7 +845,6 @@ HeartStarVisual:
.Return:
RTL
org $07A300
LoadFont:
JSL $00D29F ; play sfx
PHX
@@ -923,7 +915,6 @@ LoadFont:
PLX
RTL
org $07A380
HeartStarVisual2:
LDA #$2C80
STA $0000, Y
@@ -1037,7 +1028,6 @@ HeartStarVisual2:
STA $0000, Y
RTL
org $07A480
HeartStarSelectFix:
PHX
TXA
@@ -1059,15 +1049,22 @@ HeartStarSelectFix:
AND #$00FF
RTL
org $07A500
HeartStarCutsceneFix:
TAX
LDA $53D3
DEC
STA $5AC3
LDA $53A7, X
AND #$00FF
BNE .Return
PHX
TXA
ORA #$0100
JSL ApplyLocalCheck
PLX
.Return
RTL
org $07A510
GiftGiving:
CMP #$0008
.This:
@@ -1083,7 +1080,6 @@ GiftGiving:
PLX
JML $CABC18
org $07A550
PauseMenu:
JSL $00D29F
PHX
@@ -1144,7 +1140,6 @@ PauseMenu:
PLX
RTL
org $07A600
StarsSet:
PHA
PHX
@@ -1214,11 +1209,10 @@ StarsSet:
STA $39D7
BRA .Return
org $07A680
ApplyLocalCheck:
; args: A-address of check following $08B000
TAX
LDA $08B000, X
LDA $09B000, X
AND #$00FF
TAY
LDX #$0000
@@ -1231,7 +1225,8 @@ ApplyLocalCheck:
BCC .Loop
BRA .Return ; this is dangerous, could lose a check here
.Apply:
STY $C000, X
TYA
STA $C000, X
.Return:
RTL
@@ -1272,4 +1267,4 @@ org $07E040
db $3D, $05
org $07F000
incbin "APPauseIcons.bin"
incbin "APPauseIcons.dat"