KH2: New Unit Test and better keyblade fill (#1744)
__init__: - Added exception for if the player has too many excluded abilities on keyblades. - Fixed Action Abilities only on keyblades from breaking. - Added proper support for ability quantity's instead of 1 of the ability - Moved filling the localitems slot data to init instead of generate_output so I could easily unit test it TestSlotData: - Checks if the "localItems" part of slot data is filled. This is used for keeping track of local items and making sure nothing dupes
This commit is contained in:
parent
62a265cc31
commit
06a25a903e
|
@ -6,8 +6,7 @@ import Utils
|
|||
import zipfile
|
||||
|
||||
from .Items import item_dictionary_table, CheckDupingItems
|
||||
from .Locations import all_locations, SoraLevels, exclusion_table, AllWeaponSlot
|
||||
from .Names import LocationName
|
||||
from .Locations import all_locations, SoraLevels, exclusion_table
|
||||
from .XPValues import lvlStats, formExp, soraExp
|
||||
from worlds.Files import APContainer
|
||||
|
||||
|
@ -83,7 +82,7 @@ def patch_kh2(self, output_directory):
|
|||
elif self.multiworld.LevelDepth[self.player] == "level_99":
|
||||
levelsetting.extend(exclusion_table["Level99"])
|
||||
|
||||
elif self.multiworld.LevelDepth[self.player] in ["level_50_sanity", "level_99_sanity"]:
|
||||
elif self.multiworld.LevelDepth[self.player] != "level_1":
|
||||
levelsetting.extend(exclusion_table["Level50Sanity"])
|
||||
|
||||
if self.multiworld.LevelDepth[self.player] == "level_99_sanity":
|
||||
|
@ -96,9 +95,6 @@ def patch_kh2(self, output_directory):
|
|||
data = all_locations[location.name]
|
||||
if location.item.player == self.player:
|
||||
itemcode = item_dictionary_table[location.item.name].kh2id
|
||||
if location.item.name in slotDataDuping and \
|
||||
location.name not in AllWeaponSlot:
|
||||
self.LocalItems[location.address] = item_dictionary_table[location.item.name].code
|
||||
else:
|
||||
itemcode = 90 # castle map
|
||||
|
||||
|
|
|
@ -2,7 +2,7 @@ from BaseClasses import Tutorial, ItemClassification
|
|||
import logging
|
||||
|
||||
from .Items import *
|
||||
from .Locations import all_locations, setup_locations, exclusion_table
|
||||
from .Locations import all_locations, setup_locations, exclusion_table, AllWeaponSlot
|
||||
from .Names import ItemName, LocationName
|
||||
from .OpenKH import patch_kh2
|
||||
from .Options import KH2_Options
|
||||
|
@ -62,8 +62,22 @@ class KH2World(World):
|
|||
self.growth_list = list()
|
||||
for x in range(4):
|
||||
self.growth_list.extend(Movement_Table.keys())
|
||||
self.slotDataDuping = set()
|
||||
self.localItems = dict()
|
||||
|
||||
def fill_slot_data(self) -> dict:
|
||||
for values in CheckDupingItems.values():
|
||||
if isinstance(values, set):
|
||||
self.slotDataDuping = self.slotDataDuping.union(values)
|
||||
else:
|
||||
for inner_values in values.values():
|
||||
self.slotDataDuping = self.slotDataDuping.union(inner_values)
|
||||
self.LocalItems = {location.address: item_dictionary_table[location.item.name].code
|
||||
for location in self.multiworld.get_filled_locations(self.player)
|
||||
if location.item.player == self.player
|
||||
and location.item.name in self.slotDataDuping
|
||||
and location.name not in AllWeaponSlot}
|
||||
|
||||
return {"hitlist": self.hitlist,
|
||||
"LocalItems": self.LocalItems,
|
||||
"Goal": self.multiworld.Goal[self.player].value,
|
||||
|
@ -132,7 +146,7 @@ class KH2World(World):
|
|||
|
||||
# Creating filler for unfilled locations
|
||||
itempool += [self.create_filler()
|
||||
for _ in range(self.totalLocations-len(itempool))]
|
||||
for _ in range(self.totalLocations - len(itempool))]
|
||||
self.multiworld.itempool += itempool
|
||||
|
||||
def generate_early(self) -> None:
|
||||
|
@ -245,10 +259,12 @@ class KH2World(World):
|
|||
ItemName.FinishingPlus: 1}}
|
||||
|
||||
elif self.multiworld.KeybladeAbilities[self.player] == "action":
|
||||
self.sora_keyblade_ability_pool = {item: data for item, data in self.item_quantity_dict.items() if item in ActionAbility_Table}
|
||||
self.sora_keyblade_ability_pool = {item: data for item, data in self.item_quantity_dict.items() if
|
||||
item in ActionAbility_Table}
|
||||
# there are too little action abilities so 2 random support abilities are placed
|
||||
for _ in range(3):
|
||||
randomSupportAbility = self.multiworld.per_slot_randoms[self.player].choice(list(SupportAbility_Table.keys()))
|
||||
randomSupportAbility = self.multiworld.per_slot_randoms[self.player].choice(
|
||||
list(SupportAbility_Table.keys()))
|
||||
while randomSupportAbility in self.sora_keyblade_ability_pool:
|
||||
randomSupportAbility = self.multiworld.per_slot_randoms[self.player].choice(
|
||||
list(SupportAbility_Table.keys()))
|
||||
|
@ -259,7 +275,8 @@ class KH2World(World):
|
|||
self.sora_keyblade_ability_pool = {
|
||||
**{item: data for item, data in self.item_quantity_dict.items() if item in SupportAbility_Table},
|
||||
**{item: data for item, data in self.item_quantity_dict.items() if item in ActionAbility_Table},
|
||||
**{ItemName.NegativeCombo: 1, ItemName.AirComboPlus: 1, ItemName.ComboPlus: 1, ItemName.FinishingPlus: 1}}
|
||||
**{ItemName.NegativeCombo: 1, ItemName.AirComboPlus: 1, ItemName.ComboPlus: 1,
|
||||
ItemName.FinishingPlus: 1}}
|
||||
|
||||
for ability in self.multiworld.BlacklistKeyblade[self.player].value:
|
||||
if ability in self.sora_keyblade_ability_pool:
|
||||
|
@ -267,7 +284,8 @@ class KH2World(World):
|
|||
|
||||
# magic number for amount of keyblades
|
||||
if sum(self.sora_keyblade_ability_pool.values()) < 28:
|
||||
raise Exception(f"{self.multiworld.get_file_safe_player_name(self.player)} has too little Keyblade Abilities in the Keyblade Pool")
|
||||
raise Exception(
|
||||
f"{self.multiworld.get_file_safe_player_name(self.player)} has too little Keyblade Abilities in the Keyblade Pool")
|
||||
|
||||
self.valid_abilities = list(self.sora_keyblade_ability_pool.keys())
|
||||
# Kingdom Key cannot have No Experience so plandoed here instead of checking 26 times if its kingdom key
|
||||
|
@ -379,4 +397,5 @@ class KH2World(World):
|
|||
self.totalLocations -= 76
|
||||
|
||||
def get_filler_item_name(self) -> str:
|
||||
return self.multiworld.random.choice([ItemName.PowerBoost, ItemName.MagicBoost, ItemName.DefenseBoost, ItemName.APBoost])
|
||||
return self.multiworld.random.choice(
|
||||
[ItemName.PowerBoost, ItemName.MagicBoost, ItemName.DefenseBoost, ItemName.APBoost])
|
||||
|
|
|
@ -0,0 +1,21 @@
|
|||
import unittest
|
||||
|
||||
from test.general import setup_solo_multiworld
|
||||
from . import KH2TestBase
|
||||
from .. import KH2World, all_locations, item_dictionary_table, CheckDupingItems, AllWeaponSlot, KH2Item
|
||||
from ..Names import ItemName
|
||||
from ... import AutoWorldRegister
|
||||
from ...AutoWorld import call_all
|
||||
|
||||
|
||||
class TestLocalItems(KH2TestBase):
|
||||
|
||||
def testSlotData(self):
|
||||
gen_steps = ("generate_early", "create_regions", "create_items", "set_rules", "generate_basic", "pre_fill")
|
||||
multiworld = setup_solo_multiworld(KH2World, gen_steps)
|
||||
for location in multiworld.get_locations():
|
||||
if location.item is None:
|
||||
location.place_locked_item(multiworld.worlds[1].create_item(ItemName.NoExperience))
|
||||
call_all(multiworld, "fill_slot_data")
|
||||
slotdata = multiworld.worlds[1].fill_slot_data()
|
||||
assert len(slotdata["LocalItems"]) > 0, f"{slotdata['LocalItems']} is empty"
|
Loading…
Reference in New Issue