KH2: Ability dupe fix and stat increase fix (#2621)
Makes the client make sure the player has the correct amount of stat increase instead of letting the goa mod (apcompanion) do it abilities: checks the slot where abilities could dupe unless that slot is being used for an actual abiliity given to the player
This commit is contained in:
		
							parent
							
								
									88c7484b3a
								
							
						
					
					
						commit
						e5c739ee31
					
				|  | @ -80,11 +80,6 @@ class KH2Context(CommonContext): | |||
|                 }, | ||||
|             }, | ||||
|         } | ||||
|         self.front_of_inventory = { | ||||
|             "Sora":   0x2546, | ||||
|             "Donald": 0x2658, | ||||
|             "Goofy":  0x276C, | ||||
|         } | ||||
|         self.kh2seedname = None | ||||
|         self.kh2slotdata = None | ||||
|         self.itemamount = {} | ||||
|  | @ -169,6 +164,14 @@ class KH2Context(CommonContext): | |||
|         self.ability_code_list = None | ||||
|         self.master_growth = {"High Jump", "Quick Run", "Dodge Roll", "Aerial Dodge", "Glide"} | ||||
| 
 | ||||
|         self.base_hp = 20 | ||||
|         self.base_mp = 100 | ||||
|         self.base_drive = 5 | ||||
|         self.base_accessory_slots = 1 | ||||
|         self.base_armor_slots = 1 | ||||
|         self.base_item_slots = 3 | ||||
|         self.front_ability_slots = [0x2546, 0x2658, 0x276C, 0x2548, 0x254A, 0x254C, 0x265A, 0x265C, 0x265E, 0x276E, 0x2770, 0x2772] | ||||
| 
 | ||||
|     async def server_auth(self, password_requested: bool = False): | ||||
|         if password_requested and not self.password: | ||||
|             await super(KH2Context, self).server_auth(password_requested) | ||||
|  | @ -219,6 +222,12 @@ class KH2Context(CommonContext): | |||
|     def kh2_read_byte(self, address): | ||||
|         return int.from_bytes(self.kh2.read_bytes(self.kh2.base_address + address, 1), "big") | ||||
| 
 | ||||
|     def kh2_read_int(self, address): | ||||
|         return self.kh2.read_int(self.kh2.base_address + address) | ||||
| 
 | ||||
|     def kh2_write_int(self, address, value): | ||||
|         self.kh2.write_int(self.kh2.base_address + address, value) | ||||
| 
 | ||||
|     def on_package(self, cmd: str, args: dict): | ||||
|         if cmd in {"RoomInfo"}: | ||||
|             self.kh2seedname = args['seed_name'] | ||||
|  | @ -476,7 +485,7 @@ class KH2Context(CommonContext): | |||
| 
 | ||||
|     async def give_item(self, item, location): | ||||
|         try: | ||||
|             # todo: ripout all the itemtype stuff and just have one dictionary. the only thing that needs to be tracked from the server/local is abilites  | ||||
|             # todo: ripout all the itemtype stuff and just have one dictionary. the only thing that needs to be tracked from the server/local is abilites | ||||
|             itemname = self.lookup_id_to_item[item] | ||||
|             itemdata = self.item_name_to_data[itemname] | ||||
|             # itemcode = self.kh2_item_name_to_id[itemname] | ||||
|  | @ -507,6 +516,8 @@ class KH2Context(CommonContext): | |||
|                             ability_slot = self.kh2_seed_save_cache["GoofyInvo"][1] | ||||
|                             self.kh2_seed_save_cache["AmountInvo"]["Ability"][itemname].append(ability_slot) | ||||
|                             self.kh2_seed_save_cache["GoofyInvo"][1] -= 2 | ||||
|                         if ability_slot in self.front_ability_slots: | ||||
|                             self.front_ability_slots.remove(ability_slot) | ||||
| 
 | ||||
|                 elif len(self.kh2_seed_save_cache["AmountInvo"]["Ability"][itemname]) < \ | ||||
|                         self.AbilityQuantityDict[itemname]: | ||||
|  | @ -518,11 +529,14 @@ class KH2Context(CommonContext): | |||
|                         ability_slot = self.kh2_seed_save_cache["DonaldInvo"][0] | ||||
|                         self.kh2_seed_save_cache["AmountInvo"]["Ability"][itemname].append(ability_slot) | ||||
|                         self.kh2_seed_save_cache["DonaldInvo"][0] -= 2 | ||||
|                     elif itemname in self.goofy_ability_set: | ||||
|                     else: | ||||
|                         ability_slot = self.kh2_seed_save_cache["GoofyInvo"][0] | ||||
|                         self.kh2_seed_save_cache["AmountInvo"]["Ability"][itemname].append(ability_slot) | ||||
|                         self.kh2_seed_save_cache["GoofyInvo"][0] -= 2 | ||||
| 
 | ||||
|                     if ability_slot in self.front_ability_slots: | ||||
|                         self.front_ability_slots.remove(ability_slot) | ||||
| 
 | ||||
|             elif itemdata.memaddr in {0x36C4, 0x36C5, 0x36C6, 0x36C0, 0x36CA}: | ||||
|                 # if memaddr is in a bitmask location in memory | ||||
|                 if itemname not in self.kh2_seed_save_cache["AmountInvo"]["Bitmask"]: | ||||
|  | @ -615,7 +629,7 @@ class KH2Context(CommonContext): | |||
|             master_sell = master_equipment | master_staff | master_shield | ||||
| 
 | ||||
|             await asyncio.create_task(self.IsInShop(master_sell)) | ||||
| 
 | ||||
|             # print(self.kh2_seed_save_cache["AmountInvo"]["Ability"]) | ||||
|             for item_name in master_amount: | ||||
|                 item_data = self.item_name_to_data[item_name] | ||||
|                 amount_of_items = 0 | ||||
|  | @ -673,10 +687,10 @@ class KH2Context(CommonContext): | |||
|                             self.kh2_write_short(self.Save + slot, item_data.memaddr) | ||||
|             # removes the duped ability if client gave faster than the game. | ||||
| 
 | ||||
|             for charInvo in {"Sora", "Donald", "Goofy"}: | ||||
|                 if self.kh2_read_short(self.Save + self.front_of_inventory[charInvo]) != 0: | ||||
|                     print(f"removed {self.Save + self.front_of_inventory[charInvo]} from {charInvo}") | ||||
|                     self.kh2_write_short(self.Save + self.front_of_inventory[charInvo], 0) | ||||
|             for ability in self.front_ability_slots: | ||||
|                 if self.kh2_read_short(self.Save + ability) != 0: | ||||
|                     print(f"removed {self.Save + ability} from {ability}") | ||||
|                     self.kh2_write_short(self.Save + ability, 0) | ||||
| 
 | ||||
|             # remove the dummy level 1 growths if they are in these invo slots. | ||||
|             for inventorySlot in {0x25CE, 0x25D0, 0x25D2, 0x25D4, 0x25D6, 0x25D8}: | ||||
|  | @ -740,15 +754,60 @@ class KH2Context(CommonContext): | |||
|                     self.kh2_write_byte(self.Save + item_data.memaddr, amount_of_items) | ||||
| 
 | ||||
|             for item_name in master_stat: | ||||
|                 item_data = self.item_name_to_data[item_name] | ||||
|                 amount_of_items = 0 | ||||
|                 amount_of_items += self.kh2_seed_save_cache["AmountInvo"]["StatIncrease"][item_name] | ||||
|                 if self.kh2_read_byte(self.Slot1 + 0x1B2) >= 5: | ||||
|                     if item_name == ItemName.MaxHPUp: | ||||
|                         if self.kh2_read_byte(self.Save + 0x2498) < 3:  # Non-Critical | ||||
|                             Bonus = 5 | ||||
|                         else:  # Critical | ||||
|                             Bonus = 2 | ||||
|                         if self.kh2_read_int(self.Slot1 + 0x004) != self.base_hp + (Bonus * amount_of_items): | ||||
|                             self.kh2_write_int(self.Slot1 + 0x004, self.base_hp + (Bonus * amount_of_items)) | ||||
| 
 | ||||
|                     elif item_name == ItemName.MaxMPUp: | ||||
|                         if self.kh2_read_byte(self.Save + 0x2498) < 3:  # Non-Critical | ||||
|                             Bonus = 10 | ||||
|                         else:  # Critical | ||||
|                             Bonus = 5 | ||||
|                         if self.kh2_read_int(self.Slot1 + 0x184) != self.base_mp + (Bonus * amount_of_items): | ||||
|                             self.kh2_write_int(self.Slot1 + 0x184, self.base_mp + (Bonus * amount_of_items)) | ||||
| 
 | ||||
|                     elif item_name == ItemName.DriveGaugeUp: | ||||
|                         current_max_drive = self.kh2_read_byte(self.Slot1 + 0x1B2) | ||||
|                         # change when max drive is changed from 6 to 4 | ||||
|                         if current_max_drive < 9 and current_max_drive != self.base_drive + amount_of_items: | ||||
|                             self.kh2_write_byte(self.Slot1 + 0x1B2, self.base_drive + amount_of_items) | ||||
| 
 | ||||
|                     elif item_name == ItemName.AccessorySlotUp: | ||||
|                         current_accessory = self.kh2_read_byte(self.Save + 0x2501) | ||||
|                         if current_accessory != self.base_accessory_slots + amount_of_items: | ||||
|                             if 4 > current_accessory < self.base_accessory_slots + amount_of_items: | ||||
|                                 self.kh2_write_byte(self.Save + 0x2501, current_accessory + 1) | ||||
|                             elif self.base_accessory_slots + amount_of_items < 4: | ||||
|                                 self.kh2_write_byte(self.Save + 0x2501, self.base_accessory_slots + amount_of_items) | ||||
| 
 | ||||
|                     elif item_name == ItemName.ArmorSlotUp: | ||||
|                         current_armor_slots = self.kh2_read_byte(self.Save + 0x2500) | ||||
|                         if current_armor_slots != self.base_armor_slots + amount_of_items: | ||||
|                             if 4 > current_armor_slots < self.base_armor_slots + amount_of_items: | ||||
|                                 self.kh2_write_byte(self.Save + 0x2500, current_armor_slots + 1) | ||||
|                             elif self.base_armor_slots + amount_of_items < 4: | ||||
|                                 self.kh2_write_byte(self.Save + 0x2500, self.base_armor_slots + amount_of_items) | ||||
| 
 | ||||
|                     elif item_name == ItemName.ItemSlotUp: | ||||
|                         current_item_slots = self.kh2_read_byte(self.Save + 0x2502) | ||||
|                         if current_item_slots != self.base_item_slots + amount_of_items: | ||||
|                             if 8 > current_item_slots < self.base_item_slots + amount_of_items: | ||||
|                                 self.kh2_write_byte(self.Save + 0x2502, current_item_slots + 1) | ||||
|                             elif self.base_item_slots + amount_of_items < 8: | ||||
|                                 self.kh2_write_byte(self.Save + 0x2502, self.base_item_slots + amount_of_items) | ||||
|                                  | ||||
|                 # if self.kh2_read_byte(self.Save + item_data.memaddr) != amount_of_items \ | ||||
|                 #        and self.kh2_read_byte(self.Slot1 + 0x1B2) >= 5 and \ | ||||
|                 #        self.kh2_read_byte(self.Save + 0x23DF) & 0x1 << 3 > 0 and self.kh2_read_byte(0x741320) in {10, 8}: | ||||
|                 #    self.kh2_write_byte(self.Save + item_data.memaddr, amount_of_items) | ||||
| 
 | ||||
|                 # if slot1 has 5 drive gauge and goa lost illusion is checked and they are not in a cutscene | ||||
|                 if self.kh2_read_byte(self.Save + item_data.memaddr) != amount_of_items \ | ||||
|                         and self.kh2_read_byte(self.Slot1 + 0x1B2) >= 5 and \ | ||||
|                         self.kh2_read_byte(self.Save + 0x23DF) & 0x1 << 3 > 0 and self.kh2_read_byte(0x741320) in {10, 8}: | ||||
|                     self.kh2_write_byte(self.Save + item_data.memaddr, amount_of_items) | ||||
|             if "PoptrackerVersionCheck" in self.kh2slotdata: | ||||
|                 if self.kh2slotdata["PoptrackerVersionCheck"] > 4.2 and self.kh2_read_byte(self.Save + 0x3607) != 1:  # telling the goa they are on version 4.3 | ||||
|                     self.kh2_write_byte(self.Save + 0x3607, 1) | ||||
|  |  | |||
|  | @ -268,7 +268,6 @@ class KH2WorldRules(KH2Rules): | |||
|                 add_item_rule(location, lambda item: item.player == self.player and item.name in DonaldAbility_Table.keys()) | ||||
| 
 | ||||
|     def set_kh2_goal(self): | ||||
| 
 | ||||
|         final_xemnas_location = self.multiworld.get_location(LocationName.FinalXemnas, self.player) | ||||
|         if self.multiworld.Goal[self.player] == "three_proofs": | ||||
|             final_xemnas_location.access_rule = lambda state: self.kh2_has_all(three_proofs, state) | ||||
|  | @ -291,8 +290,8 @@ class KH2WorldRules(KH2Rules): | |||
|             else: | ||||
|                 self.multiworld.completion_condition[self.player] = lambda state: state.has(ItemName.Bounty, self.player, self.multiworld.BountyRequired[self.player].value) | ||||
|         else: | ||||
|             final_xemnas_location.access_rule = lambda state: state.has(ItemName.Bounty, self.player, self.multiworld.BountyRequired[self.player].value) and\ | ||||
|                                   state.has(ItemName.LuckyEmblem, self.player, self.multiworld.LuckyEmblemsRequired[self.player].value) | ||||
|             final_xemnas_location.access_rule = lambda state: state.has(ItemName.Bounty, self.player, self.multiworld.BountyRequired[self.player].value) and \ | ||||
|                                                               state.has(ItemName.LuckyEmblem, self.player, self.multiworld.LuckyEmblemsRequired[self.player].value) | ||||
|             if self.multiworld.FinalXemnas[self.player]: | ||||
|                 self.multiworld.completion_condition[self.player] = lambda state: state.has(ItemName.Victory, self.player, 1) | ||||
|             else: | ||||
|  |  | |||
		Loading…
	
		Reference in New Issue