mirror of
				https://github.com/MarioSpore/Grinch-AP.git
				synced 2025-10-21 20:21:32 -06:00 
			
		
		
		
	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:
		| @@ -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,13 +259,15 @@ 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())) | ||||
|                             list(SupportAbility_Table.keys())) | ||||
|                 self.sora_keyblade_ability_pool[randomSupportAbility] = 1 | ||||
|         else: | ||||
|             # both action and support on keyblades. | ||||
| @@ -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]) | ||||
|   | ||||
							
								
								
									
										21
									
								
								worlds/kh2/test/TestSlotData.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										21
									
								
								worlds/kh2/test/TestSlotData.py
									
									
									
									
									
										Normal file
									
								
							| @@ -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" | ||||
		Reference in New Issue
	
	Block a user
	 JaredWeakStrike
					JaredWeakStrike