Skip to content

Commit

Permalink
world cleanup
Browse files Browse the repository at this point in the history
  • Loading branch information
Silvris committed Feb 21, 2024
1 parent 78a4512 commit 6fb8258
Show file tree
Hide file tree
Showing 8 changed files with 67 additions and 71 deletions.
6 changes: 3 additions & 3 deletions worlds/kdl3/Client.py
Original file line number Diff line number Diff line change
Expand Up @@ -239,10 +239,10 @@ async def pick_gift_recipient(self, ctx, gift):
# only send to ourselves if no one else will take it
most_applicable_slot = int(slot)
# print(most_applicable, most_applicable_slot)
UUID = uuid.uuid4().hex
item_uuid = uuid.uuid4().hex
item = {
**gift_base,
"ID": UUID,
"ID": item_uuid,
"Sender": ctx.player_names[ctx.slot],
"Receiver": ctx.player_names[most_applicable_slot],
"SenderTeam": ctx.team,
Expand All @@ -251,7 +251,7 @@ async def pick_gift_recipient(self, ctx, gift):
}
# print(item)
await update_object(ctx, f"Giftbox;{ctx.team};{most_applicable_slot}", {
UUID: item,
item_uuid: item,
})

async def game_watcher(self, ctx) -> None:
Expand Down
2 changes: 1 addition & 1 deletion worlds/kdl3/ClientAddrs.py
Original file line number Diff line number Diff line change
Expand Up @@ -813,4 +813,4 @@
0x7706fd: 1831,
0x7706fe: 1832,
0x7706ff: 1858,
}
}
18 changes: 9 additions & 9 deletions worlds/kdl3/Compression.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,23 +5,23 @@ def hal_decompress(comp: bytes) -> bytes:
"""
inpos = 0

input = 0
inval = 0
output = bytearray()
while input != 0xFF:
while inval != 0xFF:
remaining = 65536 - inpos
if remaining < 1:
return bytes()
input = comp[inpos]
inval = comp[inpos]
inpos += 1
if input == 0xFF:
if inval == 0xFF:
break
if (input & 0xE0) == 0xE0:
command = (input >> 2) & 0x07
length = (((input & 0x03) << 8) | comp[inpos]) + 1
if (inval & 0xE0) == 0xE0:
command = (inval >> 2) & 0x07
length = (((inval & 0x03) << 8) | comp[inpos]) + 1
inpos += 1
else:
command = input >> 5
length = (input & 0x1F) + 1
command = inval >> 5
length = (inval & 0x1F) + 1
if (command == 2 and ((len(output) + 2*length) > 65536)) or (len(output) + length) > 65536:
return bytes()
if command == 0:
Expand Down
4 changes: 2 additions & 2 deletions worlds/kdl3/Options.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,8 @@
import random
from dataclasses import dataclass

from Options import Option, DeathLink, Choice, Toggle, OptionDict, Range, PlandoBosses, DefaultOnToggle, \
from Options import DeathLink, Choice, Toggle, OptionDict, Range, PlandoBosses, DefaultOnToggle, \
PerGameCommonOptions
import typing
from .Names import LocationName


Expand Down Expand Up @@ -399,6 +398,7 @@ class Gifting(Toggle):
"""
display_name = "Gifting"


@dataclass
class KDL3Options(PerGameCommonOptions):
death_link: DeathLink
Expand Down
8 changes: 5 additions & 3 deletions worlds/kdl3/Regions.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import json
import orjson
import os
import typing
from pkgutil import get_data
Expand All @@ -22,6 +22,7 @@
}

first_stage_blacklist = {
# We want to confirm that the first stage can be completed without any items
0x77000B, # 2-5 needs Kine
0x770011, # 3-5 needs Cutter
0x77001C, # 5-4 needs Burning
Expand All @@ -38,7 +39,7 @@ def generate_valid_level(level, stage, possible_stages, slot_random):

def generate_rooms(world: "KDL3World", door_shuffle: bool, level_regions: typing.Dict[int, Region]):
level_names = {LocationName.level_names[level]: level for level in LocationName.level_names}
room_data = json.loads(get_data(__name__, os.path.join("data", "Rooms.json")))
room_data = orjson.loads(get_data(__name__, os.path.join("data", "Rooms.json")))
rooms: typing.Dict[str, KDL3Room] = dict()
for room_entry in room_data:
room = KDL3Room(room_entry["name"], world.player, world.multiworld, None, room_entry["level"],
Expand All @@ -48,7 +49,8 @@ def generate_rooms(world: "KDL3World", door_shuffle: bool, level_regions: typing
room.add_locations({location: world.location_name_to_id[location] if location in world.location_name_to_id else
None for location in room_entry["locations"]
if (not any([x in location for x in ["1-Up", "Maxim"]]) or
world.options.consumables.value) and (not "Star" in location or world.options.starsanity.value)},
world.options.consumables.value) and ("Star" not in location
or world.options.starsanity.value)},
KDL3Location)
rooms[room.name] = room
for location in room.locations:
Expand Down
90 changes: 44 additions & 46 deletions worlds/kdl3/Rom.py
Original file line number Diff line number Diff line change
@@ -1,15 +1,13 @@
import typing
from pkgutil import get_data
from random import Random

import Utils
from typing import Optional, Dict, List, TYPE_CHECKING
from typing import Optional, TYPE_CHECKING
import hashlib
import os
import struct

import settings
from BaseClasses import MultiWorld
from worlds.Files import APDeltaPatch
from .Aesthetics import get_palette_bytes, kirby_target_palettes, get_kirby_palette, gooey_target_palettes, \
get_gooey_palette
Expand Down Expand Up @@ -335,7 +333,7 @@ def write_heart_star_sprites(rom: RomData):
rom.write_bytes(0x3F0EBF, [0x00, 0xD0, 0x39])


def write_consumable_sprites(rom: RomData, consumables, stars):
def write_consumable_sprites(rom: RomData, consumables: bool, stars: bool):
compressed = rom.read_bytes(consumable_address, consumable_size)
decompressed = hal_decompress(compressed)
patched = bytearray(decompressed)
Expand Down Expand Up @@ -385,9 +383,7 @@ def patch(self, target: str):
rom.write_to_file(target)


def patch_rom(world: "KDL3World", multiworld: MultiWorld, player: int, rom: RomData, heart_stars_required: int,
boss_requirements: Dict[int, int], shuffled_levels: Dict[int, List[int]], bb_boss_enabled: List[bool],
copy_abilities: Dict[str, str], slot_random: Random):
def patch_rom(world: "KDL3World", rom: RomData):
rom.apply_patch(get_data(__name__, os.path.join("data", "kdl3_basepatch.bsdiff4")))
tiles = get_data(__name__, os.path.join("data", "APPauseIcons.dat"))
rom.write_bytes(0x3F000, tiles)
Expand Down Expand Up @@ -417,12 +413,12 @@ def patch_rom(world: "KDL3World", multiworld: MultiWorld, player: int, rom: RomD
if world.options.music_shuffle > 0:
if world.options.music_shuffle == 1:
shuffled_music = music_choices.copy()
slot_random.shuffle(shuffled_music)
world.random.shuffle(shuffled_music)
music_map = dict(zip(music_choices, shuffled_music))
# Avoid putting star twinkle in the pool
music_map[5] = slot_random.choice(music_choices)
music_map[5] = world.random.choice(music_choices)
# Heart Star music doesn't work on regular stages
music_map[8] = slot_random.choice(music_choices)
music_map[8] = world.random.choice(music_choices)
for room in rooms:
room.music = music_map[room.music]
for room in room_pointers:
Expand All @@ -439,17 +435,17 @@ def patch_rom(world: "KDL3World", multiworld: MultiWorld, player: int, rom: RomD
rom.write_byte(0x4A38D, music_map[0x1D])
elif world.options.music_shuffle == 2:
for room in rooms:
room.music = slot_random.choice(music_choices)
room.music = world.random.choice(music_choices)
for room in room_pointers:
rom.write_byte(room + 2, slot_random.choice(music_choices))
rom.write_byte(room + 2, world.random.choice(music_choices))
for i in range(5):
# level themes
rom.write_byte(0x133F2 + i, slot_random.choice(music_choices))
rom.write_byte(0x133F2 + i, world.random.choice(music_choices))
# Zero
rom.write_byte(0x9AE79, slot_random.choice(music_choices))
rom.write_byte(0x9AE79, world.random.choice(music_choices))
# Heart Star success and fail
rom.write_byte(0x4A388, slot_random.choice(music_choices))
rom.write_byte(0x4A38D, slot_random.choice(music_choices))
rom.write_byte(0x4A388, world.random.choice(music_choices))
rom.write_byte(0x4A38D, world.random.choice(music_choices))

for room in rooms:
room.patch(rom)
Expand All @@ -469,9 +465,10 @@ def patch_rom(world: "KDL3World", multiworld: MultiWorld, player: int, rom: RomD
rom.write_bytes(0x2C8217, [0xFF, 0x1E, ])

# boss requirements
rom.write_bytes(0x3D000, struct.pack("HHHHH", boss_requirements[0], boss_requirements[1], boss_requirements[2],
boss_requirements[3], boss_requirements[4]))
rom.write_bytes(0x3D00A, struct.pack("H", heart_stars_required if world.options.goal_speed == 1 else 0xFFFF))
rom.write_bytes(0x3D000, struct.pack("HHHHH", world.boss_requirements[0], world.boss_requirements[1],
world.boss_requirements[2], world.boss_requirements[3],
world.boss_requirements[4]))
rom.write_bytes(0x3D00A, struct.pack("H", world.required_heart_stars if world.options.goal_speed == 1 else 0xFFFF))
rom.write_byte(0x3D00C, world.options.goal_speed.value)
rom.write_byte(0x3D00E, world.options.open_world.value)
rom.write_byte(0x3D010, world.options.death_link.value)
Expand All @@ -484,59 +481,60 @@ def patch_rom(world: "KDL3World", multiworld: MultiWorld, player: int, rom: RomD
rom.write_byte(0x3D01E, world.options.strict_bosses.value)
# don't write gifting for solo game, since there's no one to send anything to

for level in shuffled_levels:
for i in range(len(shuffled_levels[level])):
for level in world.player_levels:
for i in range(len(world.player_levels[level])):
rom.write_bytes(0x3F002E + ((level - 1) * 14) + (i * 2),
struct.pack("H", level_pointers[shuffled_levels[level][i]]))
struct.pack("H", level_pointers[world.player_levels[level][i]]))
rom.write_bytes(0x3D020 + (level - 1) * 14 + (i * 2),
struct.pack("H", shuffled_levels[level][i] & 0x00FFFF))
struct.pack("H", world.player_levels[level][i] & 0x00FFFF))
if (i == 0) or (i > 0 and i % 6 != 0):
rom.write_bytes(0x3D080 + (level - 1) * 12 + (i * 2),
struct.pack("H", (shuffled_levels[level][i] & 0x00FFFF) % 6))
struct.pack("H", (world.player_levels[level][i] & 0x00FFFF) % 6))

for i in range(6):
if bb_boss_enabled[i]:
if world.boss_butch_bosses[i]:
rom.write_bytes(0x3F0000 + (level_pointers[0x770200 + i]), struct.pack("I", bb_bosses[0x770200 + i]))

# copy ability shuffle
if world.options.copy_ability_randomization.value > 0:
for enemy in copy_abilities:
for enemy in world.copy_abilities:
if enemy in miniboss_remap:
rom.write_bytes(0xB417E + (miniboss_remap[enemy] << 1),
struct.pack("H", ability_remap[copy_abilities[enemy]]))
struct.pack("H", ability_remap[world.copy_abilities[enemy]]))
else:
rom.write_bytes(0xB3CAC + (enemy_remap[enemy] << 1),
struct.pack("H", ability_remap[copy_abilities[enemy]]))
struct.pack("H", ability_remap[world.copy_abilities[enemy]]))
# following only needs done on non-door rando
# incredibly lucky this follows the same order (including 5E == star block)
rom.write_byte(0x2F77EA, 0x5E + (ability_remap[copy_abilities["Sparky"]] << 1))
rom.write_byte(0x2F7811, 0x5E + (ability_remap[copy_abilities["Sparky"]] << 1))
rom.write_byte(0x2F9BC4, 0x5E + (ability_remap[copy_abilities["Blocky"]] << 1))
rom.write_byte(0x2F9BEB, 0x5E + (ability_remap[copy_abilities["Blocky"]] << 1))
rom.write_byte(0x2FAC06, 0x5E + (ability_remap[copy_abilities["Jumper Shoot"]] << 1))
rom.write_byte(0x2FAC2D, 0x5E + (ability_remap[copy_abilities["Jumper Shoot"]] << 1))
rom.write_byte(0x2F9E7B, 0x5E + (ability_remap[copy_abilities["Yuki"]] << 1))
rom.write_byte(0x2F9EA2, 0x5E + (ability_remap[copy_abilities["Yuki"]] << 1))
rom.write_byte(0x2FA951, 0x5E + (ability_remap[copy_abilities["Sir Kibble"]] << 1))
rom.write_byte(0x2FA978, 0x5E + (ability_remap[copy_abilities["Sir Kibble"]] << 1))
rom.write_byte(0x2FA132, 0x5E + (ability_remap[copy_abilities["Haboki"]] << 1))
rom.write_byte(0x2FA159, 0x5E + (ability_remap[copy_abilities["Haboki"]] << 1))
rom.write_byte(0x2FA3E8, 0x5E + (ability_remap[copy_abilities["Boboo"]] << 1))
rom.write_byte(0x2FA40F, 0x5E + (ability_remap[copy_abilities["Boboo"]] << 1))
rom.write_byte(0x2F90E2, 0x5E + (ability_remap[copy_abilities["Captain Stitch"]] << 1))
rom.write_byte(0x2F9109, 0x5E + (ability_remap[copy_abilities["Captain Stitch"]] << 1))
rom.write_byte(0x2F77EA, 0x5E + (ability_remap[world.copy_abilities["Sparky"]] << 1))
rom.write_byte(0x2F7811, 0x5E + (ability_remap[world.copy_abilities["Sparky"]] << 1))
rom.write_byte(0x2F9BC4, 0x5E + (ability_remap[world.copy_abilities["Blocky"]] << 1))
rom.write_byte(0x2F9BEB, 0x5E + (ability_remap[world.copy_abilities["Blocky"]] << 1))
rom.write_byte(0x2FAC06, 0x5E + (ability_remap[world.copy_abilities["Jumper Shoot"]] << 1))
rom.write_byte(0x2FAC2D, 0x5E + (ability_remap[world.copy_abilities["Jumper Shoot"]] << 1))
rom.write_byte(0x2F9E7B, 0x5E + (ability_remap[world.copy_abilities["Yuki"]] << 1))
rom.write_byte(0x2F9EA2, 0x5E + (ability_remap[world.copy_abilities["Yuki"]] << 1))
rom.write_byte(0x2FA951, 0x5E + (ability_remap[world.copy_abilities["Sir Kibble"]] << 1))
rom.write_byte(0x2FA978, 0x5E + (ability_remap[world.copy_abilities["Sir Kibble"]] << 1))
rom.write_byte(0x2FA132, 0x5E + (ability_remap[world.copy_abilities["Haboki"]] << 1))
rom.write_byte(0x2FA159, 0x5E + (ability_remap[world.copy_abilities["Haboki"]] << 1))
rom.write_byte(0x2FA3E8, 0x5E + (ability_remap[world.copy_abilities["Boboo"]] << 1))
rom.write_byte(0x2FA40F, 0x5E + (ability_remap[world.copy_abilities["Boboo"]] << 1))
rom.write_byte(0x2F90E2, 0x5E + (ability_remap[world.copy_abilities["Captain Stitch"]] << 1))
rom.write_byte(0x2F9109, 0x5E + (ability_remap[world.copy_abilities["Captain Stitch"]] << 1))

if world.options.copy_ability_randomization == 2:
for enemy in enemy_remap:
# we just won't include it for minibosses
rom.write_bytes(0xB3E40 + (enemy_remap[enemy] << 1), struct.pack("h", slot_random.randint(-1, 2)))
rom.write_bytes(0xB3E40 + (enemy_remap[enemy] << 1), struct.pack("h", world.random.randint(-1, 2)))

# write jumping goal
rom.write_bytes(0x94F8, struct.pack("H", world.options.jumping_target))
rom.write_bytes(0x944E, struct.pack("H", world.options.jumping_target))

from Utils import __version__
rom.name = bytearray(f'KDL3{__version__.replace(".", "")[0:3]}_{player}_{multiworld.seed:11}\0', 'utf8')[:21]
rom.name = bytearray(
f'KDL3{__version__.replace(".", "")[0:3]}_{world.player}_{world.multiworld.seed:11}\0', 'utf8')[:21]
rom.name.extend([0] * (21 - len(rom.name)))
rom.write_bytes(0x3C000, rom.name)
rom.write_byte(0x3C020, world.options.game_language.value)
Expand Down
3 changes: 2 additions & 1 deletion worlds/kdl3/Room.py
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,8 @@ def patch(self, rom: "RomData"):
self.entity_load.append([2, 22])
if load_len < len(self.entity_load):
rom.write_bytes(self.pointer + 88 + (load_len * 2), bytes(self.entity_load[load_len]))
rom.write_bytes(self.pointer + 104 + (load_len * 2), bytes(struct.pack("H", self.consumable_pointer)))
rom.write_bytes(self.pointer + 104 + (load_len * 2),
bytes(struct.pack("H", self.consumable_pointer)))
if is_progression:
if [1, 22] in self.entity_load:
vtype = 1
Expand Down
7 changes: 1 addition & 6 deletions worlds/kdl3/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -268,12 +268,7 @@ def generate_output(self, output_directory: str):
player = self.player

rom = RomData(get_base_rom_path())
patch_rom(self, self.multiworld, self.player, rom, self.required_heart_stars,
self.boss_requirements,
self.player_levels,
self.boss_butch_bosses,
self.copy_abilities,
self.random)
patch_rom(self, rom)

rom_path = os.path.join(output_directory, f"{self.multiworld.get_out_file_name_base(self.player)}.sfc")
rom.write_to_file(rom_path)
Expand Down

0 comments on commit 6fb8258

Please sign in to comment.