properly fix deathlink messages, fix fill error

This commit is contained in:
Silvris
2024-03-24 00:53:57 -05:00
parent 156838d63e
commit 8fecb741b7
3 changed files with 39 additions and 19 deletions

View File

@@ -36,8 +36,10 @@ KDL3_STARS_FLAG = SRAM_1_START + 0x901A
KDL3_GIFTING_FLAG = SRAM_1_START + 0x901C
KDL3_LEVEL_ADDR = SRAM_1_START + 0x9020
KDL3_IS_DEMO = SRAM_1_START + 0x5AD5
KDL3_GAME_STATE = SRAM_1_START + 0x36D0
KDL3_GAME_SAVE = SRAM_1_START + 0x3617
KDL3_CURRENT_WORLD = SRAM_1_START + 0x363F
KDL3_CURRENT_LEVEL = SRAM_1_START + 0x3641
KDL3_GAME_STATE = SRAM_1_START + 0x36D0
KDL3_LIFE_COUNT = SRAM_1_START + 0x39CF
KDL3_KIRBY_HP = SRAM_1_START + 0x39D1
KDL3_BOSS_HP = SRAM_1_START + 0x39D5
@@ -46,8 +48,6 @@ KDL3_LIFE_VISUAL = SRAM_1_START + 0x39E3
KDL3_HEART_STARS = SRAM_1_START + 0x53A7
KDL3_WORLD_UNLOCK = SRAM_1_START + 0x53CB
KDL3_LEVEL_UNLOCK = SRAM_1_START + 0x53CD
KDL3_CURRENT_WORLD = SRAM_1_START + 0x53CF
KDL3_CURRENT_LEVEL = SRAM_1_START + 0x53D3
KDL3_BOSS_STATUS = SRAM_1_START + 0x53D5
KDL3_INVINCIBILITY_TIMER = SRAM_1_START + 0x54B1
KDL3_MG5_STATUS = SRAM_1_START + 0x5EE4
@@ -74,7 +74,9 @@ deathlink_messages = defaultdict(lambda: " was defeated.", {
0x0202: " was out-numbered by Pon & Con.",
0x0203: " was defeated by Ado's powerful paintings.",
0x0204: " was clobbered by King Dedede.",
0x0205: " lost their battle against Dark Matter."
0x0205: " lost their battle against Dark Matter.",
0x0300: " couldn't overcome the Boss Butch.",
0x0400: " is bad at jumping.",
})
@@ -281,7 +283,11 @@ class KDL3SNIClient(SNIClient):
for i in range(5):
level_data = await snes_read(ctx, KDL3_LEVEL_ADDR + (14 * i), 14)
self.levels[i] = unpack("HHHHHHH", level_data)
self.levels[5] = [0x205, 0, 0, 0, 0, 0, 0]
self.levels[5] = [0x0205, # Hyper Zone
0, # MG-5, can't send from here
0x0300, # Boss Butch
0x0400, # Jumping
0, 0, 0]
if self.consumables is None:
consumables = await snes_read(ctx, KDL3_CONSUMABLE_FLAG, 1)
@@ -315,7 +321,7 @@ class KDL3SNIClient(SNIClient):
current_world = struct.unpack("H", await snes_read(ctx, KDL3_CURRENT_WORLD, 2))[0]
current_level = struct.unpack("H", await snes_read(ctx, KDL3_CURRENT_LEVEL, 2))[0]
currently_dead = current_hp[0] == 0x00
message = deathlink_messages[self.levels[current_world][current_level - 1]]
message = deathlink_messages[self.levels[current_world][current_level]]
await ctx.handle_deathlink_state(currently_dead, f"{ctx.player_names[ctx.slot]}{message}")
recv_count = await snes_read(ctx, KDL3_RECV_COUNT, 2)

View File

@@ -28,13 +28,27 @@ first_stage_blacklist = {
0x77001C, # 5-4 needs Burning
}
first_world_limit = {
# We need to limit the number of very restrictive stages in level 1 on solo gens
*first_stage_blacklist, # all three of the blacklist stages need 2+ items for both checks
0x770007,
0x770008,
0x770013,
0x77001E,
def generate_valid_level(level, stage, possible_stages, slot_random):
new_stage = slot_random.choice(possible_stages)
if level == 1 and stage == 0 and new_stage in first_stage_blacklist:
return generate_valid_level(level, stage, possible_stages, slot_random)
else:
return new_stage
}
def generate_valid_level(world: "KDL3World", level, stage, possible_stages, placed_stages):
new_stage = world.random.choice(possible_stages)
if level == 1:
if stage == 0 and new_stage in first_stage_blacklist:
return generate_valid_level(world, level, stage, possible_stages, placed_stages)
elif not (world.multiworld.players > 1 or world.options.consumables or world.options.starsanity) and \
new_stage in first_world_limit and \
sum(p_stage in first_world_limit for p_stage in placed_stages) >= 2:
return generate_valid_level(world, level, stage, possible_stages, placed_stages)
return new_stage
def generate_rooms(world: "KDL3World", level_regions: typing.Dict[int, Region]):
@@ -49,8 +63,8 @@ def generate_rooms(world: "KDL3World", level_regions: typing.Dict[int, Region]):
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 ("Star" not 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:
@@ -94,7 +108,7 @@ def generate_rooms(world: "KDL3World", level_regions: typing.Dict[int, Region]):
if world.options.open_world or stage == 0:
level_regions[level].add_exits([first_rooms[proper_stage].name])
else:
world.multiworld.get_location(world.location_id_to_name[world.player_levels[level][stage-1]],
world.multiworld.get_location(world.location_id_to_name[world.player_levels[level][stage - 1]],
world.player).parent_region.add_exits([first_rooms[proper_stage].name])
level_regions[level].add_exits([first_rooms[0x770200 + level - 1].name])
@@ -133,8 +147,7 @@ def generate_valid_levels(world: "KDL3World", enforce_world: bool, enforce_patte
or (enforce_pattern and ((candidate - 1) & 0x00FFFF) % 6 == stage)
or (enforce_pattern == enforce_world)
]
new_stage = generate_valid_level(level, stage, stage_candidates,
world.random)
new_stage = generate_valid_level(world, level, stage, stage_candidates, levels[level])
possible_stages.remove(new_stage)
levels[level][stage] = new_stage
except Exception:
@@ -210,7 +223,7 @@ def create_levels(world: "KDL3World") -> None:
level_shuffle == 1,
level_shuffle == 2)
generate_rooms(world, False, levels)
generate_rooms(world, levels)
level6.add_locations({LocationName.goals[world.options.goal]: None}, KDL3Location)

View File

@@ -33,7 +33,8 @@ class TestLocations(KDL3TestBase):
self.run_location_test(LocationName.iceberg_kogoesou, ["Burning"])
self.run_location_test(LocationName.iceberg_samus, ["Ice"])
self.run_location_test(LocationName.iceberg_name, ["Burning", "Coo", "ChuChu"])
self.run_location_test(LocationName.iceberg_angel, ["Cutter", "Burning", "Spark", "Parasol", "Needle", "Clean", "Stone", "Ice"])
self.run_location_test(LocationName.iceberg_angel, ["Cutter", "Burning", "Spark", "Parasol", "Needle", "Clean",
"Stone", "Ice"])
def run_location_test(self, location: str, itempool: typing.List[str]):
items = itempool.copy()