mirror of
https://github.com/ArchipelagoMW/Archipelago.git
synced 2026-03-28 04:23:23 -07:00
fix animal duplication bug
This commit is contained in:
@@ -9,7 +9,7 @@ from .items import item_table, item_names, copy_ability_table, animal_friend_tab
|
||||
trap_item_table, copy_ability_access_table, star_item_weights, total_filler_weights, animal_friend_spawn_table,\
|
||||
lookup_item_to_id
|
||||
from .locations import location_table, KDL3Location, level_consumables, consumable_locations, star_locations
|
||||
from .names.animal_friend_spawns import animal_friend_spawns
|
||||
from .names.animal_friend_spawns import animal_friend_spawns, problematic_sets
|
||||
from .names.enemy_abilities import vanilla_enemies, enemy_mapping, enemy_restrictive
|
||||
from .regions import create_levels, default_levels
|
||||
from .options import KDL3Options, kdl3_option_groups
|
||||
@@ -213,6 +213,24 @@ class KDL3World(World):
|
||||
self.collect(allstate, self.create_item(item))
|
||||
self.random.shuffle(locations)
|
||||
fill_restrictive(self.multiworld, allstate, locations, items, True, True)
|
||||
|
||||
# Need to ensure all of these are unique items, and replace them if they aren't
|
||||
for spawns in problematic_sets:
|
||||
placed = [self.get_location(spawn).item for spawn in spawns]
|
||||
placed_names = set([item.name for item in placed])
|
||||
if len(placed_names) != len(placed):
|
||||
# have a duplicate
|
||||
animals = []
|
||||
for spawn in spawns:
|
||||
spawn_location = self.get_location(spawn)
|
||||
if spawn_location.item.name not in animals:
|
||||
animals.append(spawn_location.item.name)
|
||||
else:
|
||||
new_animal = self.random.choice([x for x in ["Rick Spawn", "Coo Spawn", "Kine Spawn",
|
||||
"ChuChu Spawn", "Nago Spawn", "Pitch Spawn"]
|
||||
if x not in placed_names])
|
||||
spawn_location.item = self.create_item(new_animal)
|
||||
# logically, this should be sound pre-ER. May need to adjust around it with ER in the future
|
||||
else:
|
||||
animal_friends = animal_friend_spawns.copy()
|
||||
for animal in animal_friends:
|
||||
|
||||
Binary file not shown.
@@ -1,3 +1,5 @@
|
||||
from typing import List
|
||||
|
||||
grass_land_1_a1 = "Grass Land 1 - Animal 1" # Nago
|
||||
grass_land_1_a2 = "Grass Land 1 - Animal 2" # Rick
|
||||
grass_land_2_a1 = "Grass Land 2 - Animal 1" # ChuChu
|
||||
@@ -197,3 +199,12 @@ animal_friend_spawns = {
|
||||
iceberg_6_a5: "ChuChu Spawn",
|
||||
iceberg_6_a6: "Nago Spawn",
|
||||
}
|
||||
|
||||
problematic_sets: List[List[str]] = [
|
||||
# Animal groups that must be guaranteed unique. Potential for softlocks on future-ER if not.
|
||||
[ripple_field_4_a1, ripple_field_4_a2, ripple_field_4_a3],
|
||||
[sand_canyon_3_a1, sand_canyon_3_a2, sand_canyon_3_a3],
|
||||
[cloudy_park_6_a1, cloudy_park_6_a2, cloudy_park_6_a3],
|
||||
[iceberg_6_a1, iceberg_6_a2, iceberg_6_a3],
|
||||
[iceberg_6_a4, iceberg_6_a5, iceberg_6_a6]
|
||||
]
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
from worlds.generic.Rules import set_rule, add_rule
|
||||
from .names import location_name, enemy_abilities
|
||||
from .names import location_name, enemy_abilities, animal_friend_spawns
|
||||
from .locations import location_table
|
||||
from .options import GoalSpeed
|
||||
import typing
|
||||
@@ -302,6 +302,13 @@ def set_rules(world: "KDL3World") -> None:
|
||||
set_rule(world.multiworld.get_location(enemy_abilities.Sand_Canyon_4_E10, world.player),
|
||||
lambda state: can_reach_kine(state, world.player) or can_reach_chuchu(state, world.player))
|
||||
|
||||
# animal friend rules
|
||||
set_rule(world.multiworld.get_location(animal_friend_spawns.iceberg_4_a2, world.player),
|
||||
lambda state: can_reach_coo(state, world.player) and can_reach_burning(state, world.player))
|
||||
set_rule(world.multiworld.get_location(animal_friend_spawns.iceberg_4_a3, world.player),
|
||||
lambda state: can_reach_chuchu(state, world.player) and can_reach_coo(state, world.player)
|
||||
and can_reach_burning(state, world.player))
|
||||
|
||||
for boss_flag, purification, i in zip(["Level 1 Boss - Purified", "Level 2 Boss - Purified",
|
||||
"Level 3 Boss - Purified", "Level 4 Boss - Purified",
|
||||
"Level 5 Boss - Purified"],
|
||||
|
||||
@@ -240,6 +240,9 @@ MainLoopHook:
|
||||
BEQ .Return ; return if we are
|
||||
LDA $5541 ; gooey status
|
||||
BPL .Slowness ; gooey is already spawned
|
||||
LDA $39D1 ; is kirby alive?
|
||||
BEQ .Slowness ; branch if he isn't
|
||||
; maybe BMI here too?
|
||||
LDA $8080
|
||||
CMP #$0000 ; did we get a gooey trap
|
||||
BEQ .Slowness ; branch if we did not
|
||||
@@ -432,17 +435,47 @@ AnimalFriendSpawn:
|
||||
BNE .Return
|
||||
XBA
|
||||
PHA
|
||||
PHX
|
||||
PHA
|
||||
LDX #$0000
|
||||
.CheckSpawned:
|
||||
LDA $05CA, X
|
||||
BNE .Continue
|
||||
LDA #$0002
|
||||
CMP $074A, X
|
||||
BNE .ContinueCheck
|
||||
PLA
|
||||
PHA
|
||||
XBA
|
||||
CMP $07CA, X
|
||||
BEQ .AlreadySpawned
|
||||
.ContinueCheck:
|
||||
INX
|
||||
INX
|
||||
BRA .CheckSpawned
|
||||
.Continue:
|
||||
PLA
|
||||
PLX
|
||||
ASL
|
||||
TAY
|
||||
PLA
|
||||
INC
|
||||
CMP $8000, Y ; do we have this animal friend
|
||||
BEQ .Return ; we have this animal friend
|
||||
.False:
|
||||
INX
|
||||
.Return:
|
||||
PLY
|
||||
LDA #$9999
|
||||
RTL
|
||||
.AlreadySpawned:
|
||||
PLA
|
||||
PLX
|
||||
ASL
|
||||
TAY
|
||||
PLA
|
||||
BRA .False
|
||||
|
||||
|
||||
WriteBWRAM:
|
||||
LDY #$6001 ;starting addr
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
from typing import List, Tuple, Optional
|
||||
from . import KDL3TestBase
|
||||
from ..room import KDL3Room
|
||||
from ..names import animal_friend_spawns
|
||||
|
||||
|
||||
class TestCopyAbilityShuffle(KDL3TestBase):
|
||||
@@ -174,6 +175,14 @@ class TestAnimalShuffle(KDL3TestBase):
|
||||
self.assertTrue(sand_canyon_6.item is not None and sand_canyon_6.item.name in
|
||||
{"Kine Spawn", "Coo Spawn"}, f"Multiworld did not place Coo/Kine, Seed: {self.multiworld.seed}")
|
||||
|
||||
def test_problematic(self) -> None:
|
||||
for spawns in animal_friend_spawns.problematic_sets:
|
||||
placed = [self.multiworld.get_location(spawn, 1).item for spawn in spawns]
|
||||
placed_names = set([item.name for item in placed])
|
||||
self.assertEqual(len(placed), len(placed_names),
|
||||
f"Duplicate animal placed in problematic locations:"
|
||||
f" {[spawn.location for spawn in placed]}")
|
||||
|
||||
|
||||
class TestAllShuffle(KDL3TestBase):
|
||||
options = {
|
||||
@@ -238,6 +247,14 @@ class TestAllShuffle(KDL3TestBase):
|
||||
self.assertTrue(sand_canyon_6.item is not None and sand_canyon_6.item.name in
|
||||
{"Kine Spawn", "Coo Spawn"}, f"Multiworld did not place Coo/Kine, Seed: {self.multiworld.seed}")
|
||||
|
||||
def test_problematic(self) -> None:
|
||||
for spawns in animal_friend_spawns.problematic_sets:
|
||||
placed = [self.multiworld.get_location(spawn, 1).item for spawn in spawns]
|
||||
placed_names = set([item.name for item in placed])
|
||||
self.assertEqual(len(placed), len(placed_names),
|
||||
f"Duplicate animal placed in problematic locations:"
|
||||
f" {[spawn.location for spawn in placed]}")
|
||||
|
||||
def test_cutter_and_burning_reachable(self) -> None:
|
||||
rooms = self.multiworld.worlds[1].rooms
|
||||
copy_abilities = self.multiworld.worlds[1].copy_abilities
|
||||
|
||||
Reference in New Issue
Block a user