KH2: Location Groups and Subclasses (#2700)

This commit is contained in:
JaredWeakStrike 2024-01-16 07:12:33 -05:00 committed by GitHub
parent c6896c6af9
commit 0efc13fc8a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 118 additions and 103 deletions

View File

@ -821,7 +821,8 @@ class KH2Context(CommonContext):
def finishedGame(ctx: KH2Context, message): def finishedGame(ctx: KH2Context, message):
if ctx.kh2slotdata['FinalXemnas'] == 1: if ctx.kh2slotdata['FinalXemnas'] == 1:
if not ctx.final_xemnas and ctx.kh2_loc_name_to_id[LocationName.FinalXemnas] in ctx.locations_checked: if not ctx.final_xemnas and ctx.kh2_read_byte(ctx.Save + all_world_locations[LocationName.FinalXemnas].addrObtained) \
& 0x1 << all_world_locations[LocationName.FinalXemnas].bitIndex > 0:
ctx.final_xemnas = True ctx.final_xemnas = True
# three proofs # three proofs
if ctx.kh2slotdata['Goal'] == 0: if ctx.kh2slotdata['Goal'] == 0:

View File

@ -2,22 +2,7 @@ import typing
from BaseClasses import Item from BaseClasses import Item
from .Names import ItemName from .Names import ItemName
from .Subclasses import ItemData
class KH2Item(Item):
game: str = "Kingdom Hearts 2"
class ItemData(typing.NamedTuple):
quantity: int = 0
kh2id: int = 0
# Save+ mem addr
memaddr: int = 0
# some items have bitmasks. if bitmask>0 bitor to give item else
bitmask: int = 0
# if ability then
ability: bool = False
# 0x130000 # 0x130000
Reports_Table = { Reports_Table = {
@ -209,7 +194,7 @@ Armor_Table = {
ItemName.GrandRibbon: ItemData(1, 157, 0x35D4), ItemName.GrandRibbon: ItemData(1, 157, 0x35D4),
} }
Usefull_Table = { Usefull_Table = {
ItemName.MickeyMunnyPouch: ItemData(1, 535, 0x3695), # 5000 munny per ItemName.MickeyMunnyPouch: ItemData(1, 535, 0x3695), # 5000 munny per
ItemName.OletteMunnyPouch: ItemData(2, 362, 0x363C), # 2500 munny per ItemName.OletteMunnyPouch: ItemData(2, 362, 0x363C), # 2500 munny per
ItemName.HadesCupTrophy: ItemData(1, 537, 0x3696), ItemName.HadesCupTrophy: ItemData(1, 537, 0x3696),
ItemName.UnknownDisk: ItemData(1, 462, 0x365F), ItemName.UnknownDisk: ItemData(1, 462, 0x365F),
@ -349,7 +334,7 @@ GoofyAbility_Table = {
Wincon_Table = { Wincon_Table = {
ItemName.LuckyEmblem: ItemData(kh2id=367, memaddr=0x3641), # letter item ItemName.LuckyEmblem: ItemData(kh2id=367, memaddr=0x3641), # letter item
ItemName.Victory: ItemData(kh2id=263, memaddr=0x111), # ItemName.Victory: ItemData(kh2id=263, memaddr=0x111),
ItemName.Bounty: ItemData(kh2id=461, memaddr=0x365E), # Dummy 14 ItemName.Bounty: ItemData(kh2id=461, memaddr=0x365E), # Dummy 14
# ItemName.UniversalKey:ItemData(,365,0x363F,0)#Tournament Poster # ItemName.UniversalKey:ItemData(,365,0x363F,0)#Tournament Poster
} }

View File

@ -1,19 +1,9 @@
import typing import typing
from BaseClasses import Location from BaseClasses import Location
from .Names import LocationName, ItemName from .Names import LocationName, ItemName, RegionName
from .Subclasses import LocationData
from .Regions import KH2REGIONS
class KH2Location(Location):
game: str = "Kingdom Hearts 2"
class LocationData(typing.NamedTuple):
locid: int
yml: str
charName: str = "Sora"
charNumber: int = 1
# data's addrcheck sys3 addr obtained roomid bit index is eventid # data's addrcheck sys3 addr obtained roomid bit index is eventid
LoD_Checks = { LoD_Checks = {
@ -541,7 +531,7 @@ TWTNW_Checks = {
LocationName.Xemnas1: LocationData(26, "Double Get Bonus"), LocationName.Xemnas1: LocationData(26, "Double Get Bonus"),
LocationName.Xemnas1GetBonus: LocationData(26, "Second Get Bonus"), LocationName.Xemnas1GetBonus: LocationData(26, "Second Get Bonus"),
LocationName.Xemnas1SecretAnsemReport13: LocationData(537, "Chest"), LocationName.Xemnas1SecretAnsemReport13: LocationData(537, "Chest"),
LocationName.FinalXemnas: LocationData(71, "Get Bonus"), # LocationName.FinalXemnas: LocationData(71, "Get Bonus"),
LocationName.XemnasDataPowerBoost: LocationData(554, "Chest"), LocationName.XemnasDataPowerBoost: LocationData(554, "Chest"),
} }
@ -806,74 +796,75 @@ Atlantica_Checks = {
} }
event_location_to_item = { event_location_to_item = {
LocationName.HostileProgramEventLocation: ItemName.HostileProgramEvent, LocationName.HostileProgramEventLocation: ItemName.HostileProgramEvent,
LocationName.McpEventLocation: ItemName.McpEvent, LocationName.McpEventLocation: ItemName.McpEvent,
# LocationName.ASLarxeneEventLocation: ItemName.ASLarxeneEvent, # LocationName.ASLarxeneEventLocation: ItemName.ASLarxeneEvent,
LocationName.DataLarxeneEventLocation: ItemName.DataLarxeneEvent, LocationName.DataLarxeneEventLocation: ItemName.DataLarxeneEvent,
LocationName.BarbosaEventLocation: ItemName.BarbosaEvent, LocationName.BarbosaEventLocation: ItemName.BarbosaEvent,
LocationName.GrimReaper1EventLocation: ItemName.GrimReaper1Event, LocationName.GrimReaper1EventLocation: ItemName.GrimReaper1Event,
LocationName.GrimReaper2EventLocation: ItemName.GrimReaper2Event, LocationName.GrimReaper2EventLocation: ItemName.GrimReaper2Event,
LocationName.DataLuxordEventLocation: ItemName.DataLuxordEvent, LocationName.DataLuxordEventLocation: ItemName.DataLuxordEvent,
LocationName.DataAxelEventLocation: ItemName.DataAxelEvent, LocationName.DataAxelEventLocation: ItemName.DataAxelEvent,
LocationName.CerberusEventLocation: ItemName.CerberusEvent, LocationName.CerberusEventLocation: ItemName.CerberusEvent,
LocationName.OlympusPeteEventLocation: ItemName.OlympusPeteEvent, LocationName.OlympusPeteEventLocation: ItemName.OlympusPeteEvent,
LocationName.HydraEventLocation: ItemName.HydraEvent, LocationName.HydraEventLocation: ItemName.HydraEvent,
LocationName.OcPainAndPanicCupEventLocation: ItemName.OcPainAndPanicCupEvent, LocationName.OcPainAndPanicCupEventLocation: ItemName.OcPainAndPanicCupEvent,
LocationName.OcCerberusCupEventLocation: ItemName.OcCerberusCupEvent, LocationName.OcCerberusCupEventLocation: ItemName.OcCerberusCupEvent,
LocationName.HadesEventLocation: ItemName.HadesEvent, LocationName.HadesEventLocation: ItemName.HadesEvent,
# LocationName.ASZexionEventLocation: ItemName.ASZexionEvent, # LocationName.ASZexionEventLocation: ItemName.ASZexionEvent,
LocationName.DataZexionEventLocation: ItemName.DataZexionEvent, LocationName.DataZexionEventLocation: ItemName.DataZexionEvent,
LocationName.Oc2TitanCupEventLocation: ItemName.Oc2TitanCupEvent, LocationName.Oc2TitanCupEventLocation: ItemName.Oc2TitanCupEvent,
LocationName.Oc2GofCupEventLocation: ItemName.Oc2GofCupEvent, LocationName.Oc2GofCupEventLocation: ItemName.Oc2GofCupEvent,
# LocationName.Oc2CupsEventLocation: ItemName.Oc2CupsEventLocation, # LocationName.Oc2CupsEventLocation: ItemName.Oc2CupsEventLocation,
LocationName.HadesCupEventLocations: ItemName.HadesCupEvents, LocationName.HadesCupEventLocations: ItemName.HadesCupEvents,
LocationName.PrisonKeeperEventLocation: ItemName.PrisonKeeperEvent, LocationName.PrisonKeeperEventLocation: ItemName.PrisonKeeperEvent,
LocationName.OogieBoogieEventLocation: ItemName.OogieBoogieEvent, LocationName.OogieBoogieEventLocation: ItemName.OogieBoogieEvent,
LocationName.ExperimentEventLocation: ItemName.ExperimentEvent, LocationName.ExperimentEventLocation: ItemName.ExperimentEvent,
# LocationName.ASVexenEventLocation: ItemName.ASVexenEvent, # LocationName.ASVexenEventLocation: ItemName.ASVexenEvent,
LocationName.DataVexenEventLocation: ItemName.DataVexenEvent, LocationName.DataVexenEventLocation: ItemName.DataVexenEvent,
LocationName.ShanYuEventLocation: ItemName.ShanYuEvent, LocationName.ShanYuEventLocation: ItemName.ShanYuEvent,
LocationName.AnsemRikuEventLocation: ItemName.AnsemRikuEvent, LocationName.AnsemRikuEventLocation: ItemName.AnsemRikuEvent,
LocationName.StormRiderEventLocation: ItemName.StormRiderEvent, LocationName.StormRiderEventLocation: ItemName.StormRiderEvent,
LocationName.DataXigbarEventLocation: ItemName.DataXigbarEvent, LocationName.DataXigbarEventLocation: ItemName.DataXigbarEvent,
LocationName.RoxasEventLocation: ItemName.RoxasEvent, LocationName.RoxasEventLocation: ItemName.RoxasEvent,
LocationName.XigbarEventLocation: ItemName.XigbarEvent, LocationName.XigbarEventLocation: ItemName.XigbarEvent,
LocationName.LuxordEventLocation: ItemName.LuxordEvent, LocationName.LuxordEventLocation: ItemName.LuxordEvent,
LocationName.SaixEventLocation: ItemName.SaixEvent, LocationName.SaixEventLocation: ItemName.SaixEvent,
LocationName.XemnasEventLocation: ItemName.XemnasEvent, LocationName.XemnasEventLocation: ItemName.XemnasEvent,
LocationName.ArmoredXemnasEventLocation: ItemName.ArmoredXemnasEvent, LocationName.ArmoredXemnasEventLocation: ItemName.ArmoredXemnasEvent,
LocationName.ArmoredXemnas2EventLocation: ItemName.ArmoredXemnas2Event, LocationName.ArmoredXemnas2EventLocation: ItemName.ArmoredXemnas2Event,
# LocationName.FinalXemnasEventLocation: ItemName.FinalXemnasEvent, # LocationName.FinalXemnasEventLocation: ItemName.FinalXemnasEvent,
LocationName.DataXemnasEventLocation: ItemName.DataXemnasEvent, LocationName.DataXemnasEventLocation: ItemName.DataXemnasEvent,
LocationName.ThresholderEventLocation: ItemName.ThresholderEvent, LocationName.ThresholderEventLocation: ItemName.ThresholderEvent,
LocationName.BeastEventLocation: ItemName.BeastEvent, LocationName.BeastEventLocation: ItemName.BeastEvent,
LocationName.DarkThornEventLocation: ItemName.DarkThornEvent, LocationName.DarkThornEventLocation: ItemName.DarkThornEvent,
LocationName.XaldinEventLocation: ItemName.XaldinEvent, LocationName.XaldinEventLocation: ItemName.XaldinEvent,
LocationName.DataXaldinEventLocation: ItemName.DataXaldinEvent, LocationName.DataXaldinEventLocation: ItemName.DataXaldinEvent,
LocationName.TwinLordsEventLocation: ItemName.TwinLordsEvent, LocationName.TwinLordsEventLocation: ItemName.TwinLordsEvent,
LocationName.GenieJafarEventLocation: ItemName.GenieJafarEvent, LocationName.GenieJafarEventLocation: ItemName.GenieJafarEvent,
# LocationName.ASLexaeusEventLocation: ItemName.ASLexaeusEvent, # LocationName.ASLexaeusEventLocation: ItemName.ASLexaeusEvent,
LocationName.DataLexaeusEventLocation: ItemName.DataLexaeusEvent, LocationName.DataLexaeusEventLocation: ItemName.DataLexaeusEvent,
LocationName.ScarEventLocation: ItemName.ScarEvent, LocationName.ScarEventLocation: ItemName.ScarEvent,
LocationName.GroundShakerEventLocation: ItemName.GroundShakerEvent, LocationName.GroundShakerEventLocation: ItemName.GroundShakerEvent,
LocationName.DataSaixEventLocation: ItemName.DataSaixEvent, LocationName.DataSaixEventLocation: ItemName.DataSaixEvent,
LocationName.HBDemyxEventLocation: ItemName.HBDemyxEvent, LocationName.HBDemyxEventLocation: ItemName.HBDemyxEvent,
LocationName.ThousandHeartlessEventLocation: ItemName.ThousandHeartlessEvent, LocationName.ThousandHeartlessEventLocation: ItemName.ThousandHeartlessEvent,
LocationName.Mushroom13EventLocation: ItemName.Mushroom13Event, LocationName.Mushroom13EventLocation: ItemName.Mushroom13Event,
LocationName.SephiEventLocation: ItemName.SephiEvent, LocationName.SephiEventLocation: ItemName.SephiEvent,
LocationName.DataDemyxEventLocation: ItemName.DataDemyxEvent, LocationName.DataDemyxEventLocation: ItemName.DataDemyxEvent,
LocationName.CorFirstFightEventLocation: ItemName.CorFirstFightEvent, LocationName.CorFirstFightEventLocation: ItemName.CorFirstFightEvent,
LocationName.CorSecondFightEventLocation: ItemName.CorSecondFightEvent, LocationName.CorSecondFightEventLocation: ItemName.CorSecondFightEvent,
LocationName.TransportEventLocation: ItemName.TransportEvent, LocationName.TransportEventLocation: ItemName.TransportEvent,
LocationName.OldPeteEventLocation: ItemName.OldPeteEvent, LocationName.OldPeteEventLocation: ItemName.OldPeteEvent,
LocationName.FuturePeteEventLocation: ItemName.FuturePeteEvent, LocationName.FuturePeteEventLocation: ItemName.FuturePeteEvent,
# LocationName.ASMarluxiaEventLocation: ItemName.ASMarluxiaEvent, # LocationName.ASMarluxiaEventLocation: ItemName.ASMarluxiaEvent,
LocationName.DataMarluxiaEventLocation: ItemName.DataMarluxiaEvent, LocationName.DataMarluxiaEventLocation: ItemName.DataMarluxiaEvent,
LocationName.TerraEventLocation: ItemName.TerraEvent, LocationName.TerraEventLocation: ItemName.TerraEvent,
LocationName.TwilightThornEventLocation: ItemName.TwilightThornEvent, LocationName.TwilightThornEventLocation: ItemName.TwilightThornEvent,
LocationName.Axel1EventLocation: ItemName.Axel1Event, LocationName.Axel1EventLocation: ItemName.Axel1Event,
LocationName.Axel2EventLocation: ItemName.Axel2Event, LocationName.Axel2EventLocation: ItemName.Axel2Event,
LocationName.DataRoxasEventLocation: ItemName.DataRoxasEvent, LocationName.DataRoxasEventLocation: ItemName.DataRoxasEvent,
LocationName.FinalXemnasEventLocation: ItemName.Victory,
} }
all_weapon_slot = { all_weapon_slot = {
LocationName.FAKESlot, LocationName.FAKESlot,
@ -1361,3 +1352,9 @@ exclusion_table = {
location for location, data in all_locations.items() if location not in event_location_to_item.keys() and location not in popups_set and location != LocationName.StationofSerenityPotion and data.yml == "Chest" location for location, data in all_locations.items() if location not in event_location_to_item.keys() and location not in popups_set and location != LocationName.StationofSerenityPotion and data.yml == "Chest"
} }
} }
location_groups: typing.Dict[str, list]
location_groups = {
Region_Name: [loc for loc in Region_Locs if "Event" not in loc]
for Region_Name, Region_Locs in KH2REGIONS.items() if Region_Locs
}

View File

@ -1,9 +1,11 @@
import typing import typing
from BaseClasses import MultiWorld, Region from BaseClasses import MultiWorld, Region
from . import Locations
from .Locations import KH2Location, event_location_to_item from .Subclasses import KH2Location
from . import LocationName, RegionName, Events_Table from .Names import LocationName, RegionName
from .Items import Events_Table
KH2REGIONS: typing.Dict[str, typing.List[str]] = { KH2REGIONS: typing.Dict[str, typing.List[str]] = {
"Menu": [], "Menu": [],
@ -788,7 +790,7 @@ KH2REGIONS: typing.Dict[str, typing.List[str]] = {
LocationName.ArmoredXemnas2EventLocation LocationName.ArmoredXemnas2EventLocation
], ],
RegionName.FinalXemnas: [ RegionName.FinalXemnas: [
LocationName.FinalXemnas LocationName.FinalXemnasEventLocation
], ],
RegionName.DataXemnas: [ RegionName.DataXemnas: [
LocationName.XemnasDataPowerBoost, LocationName.XemnasDataPowerBoost,
@ -1020,7 +1022,8 @@ def create_regions(self):
multiworld.regions += [create_region(multiworld, player, active_locations, region, locations) for region, locations in multiworld.regions += [create_region(multiworld, player, active_locations, region, locations) for region, locations in
KH2REGIONS.items()] KH2REGIONS.items()]
# fill the event locations with events # fill the event locations with events
for location, item in event_location_to_item.items():
for location, item in Locations.event_location_to_item.items():
multiworld.get_location(location, player).place_locked_item( multiworld.get_location(location, player).place_locked_item(
multiworld.worlds[player].create_event_item(item)) multiworld.worlds[player].create_event_item(item))

View File

@ -270,7 +270,7 @@ class KH2WorldRules(KH2Rules):
add_item_rule(location, lambda item: item.player == self.player and item.name in SupportAbility_Table.keys()) add_item_rule(location, lambda item: item.player == self.player and item.name in SupportAbility_Table.keys())
def set_kh2_goal(self): def set_kh2_goal(self):
final_xemnas_location = self.multiworld.get_location(LocationName.FinalXemnas, self.player) final_xemnas_location = self.multiworld.get_location(LocationName.FinalXemnasEventLocation, self.player)
if self.multiworld.Goal[self.player] == "three_proofs": if self.multiworld.Goal[self.player] == "three_proofs":
final_xemnas_location.access_rule = lambda state: self.kh2_has_all(three_proofs, state) final_xemnas_location.access_rule = lambda state: self.kh2_has_all(three_proofs, state)
if self.multiworld.FinalXemnas[self.player]: if self.multiworld.FinalXemnas[self.player]:

29
worlds/kh2/Subclasses.py Normal file
View File

@ -0,0 +1,29 @@
import typing
from BaseClasses import Location, Item
class KH2Location(Location):
game: str = "Kingdom Hearts 2"
class LocationData(typing.NamedTuple):
locid: int
yml: str
charName: str = "Sora"
charNumber: int = 1
class KH2Item(Item):
game: str = "Kingdom Hearts 2"
class ItemData(typing.NamedTuple):
quantity: int = 0
kh2id: int = 0
# Save+ mem addr
memaddr: int = 0
# some items have bitmasks. if bitmask>0 bitor to give item else
bitmask: int = 0
# if ability then
ability: bool = False

View File

@ -12,6 +12,7 @@ from .OpenKH import patch_kh2
from .Options import KingdomHearts2Options from .Options import KingdomHearts2Options
from .Regions import create_regions, connect_regions from .Regions import create_regions, connect_regions
from .Rules import * from .Rules import *
from .Subclasses import KH2Item
def launch_client(): def launch_client():
@ -49,7 +50,9 @@ class KH2World(World):
for item_id, item in enumerate(item_dictionary_table.keys(), 0x130000)} for item_id, item in enumerate(item_dictionary_table.keys(), 0x130000)}
location_name_to_id = {item: location location_name_to_id = {item: location
for location, item in enumerate(all_locations.keys(), 0x130000)} for location, item in enumerate(all_locations.keys(), 0x130000)}
item_name_groups = item_groups item_name_groups = item_groups
location_name_groups = location_groups
visitlocking_dict: Dict[str, int] visitlocking_dict: Dict[str, int]
plando_locations: Dict[str, str] plando_locations: Dict[str, str]
@ -253,11 +256,8 @@ class KH2World(World):
self.goofy_gen_early() self.goofy_gen_early()
self.keyblade_gen_early() self.keyblade_gen_early()
if self.multiworld.FinalXemnas[self.player]: # final xemnas isn't a location anymore
self.plando_locations[LocationName.FinalXemnas] = ItemName.Victory # self.total_locations -= 1
else:
self.plando_locations[LocationName.FinalXemnas] = self.create_filler().name
self.total_locations -= 1
if self.options.WeaponSlotStartHint: if self.options.WeaponSlotStartHint:
for location in all_weapon_slot: for location in all_weapon_slot: