Kh2 rc2 fixes (#1608)
This commit is contained in:
parent
21c6c28755
commit
e62f989ce8
105
KH2Client.py
105
KH2Client.py
|
@ -119,7 +119,12 @@ class KH2Context(CommonContext):
|
||||||
"LimitLevel": 0,
|
"LimitLevel": 0,
|
||||||
"MasterLevel": 0,
|
"MasterLevel": 0,
|
||||||
"FinalLevel": 0,
|
"FinalLevel": 0,
|
||||||
}
|
},
|
||||||
|
"SoldEquipment": [],
|
||||||
|
"SoldBoosts": {"Power Boost": 0,
|
||||||
|
"Magic Boost": 0,
|
||||||
|
"Defense Boost": 0,
|
||||||
|
"AP Boost": 0}
|
||||||
}
|
}
|
||||||
self.slotDataProgressionNames = {}
|
self.slotDataProgressionNames = {}
|
||||||
self.kh2seedname = None
|
self.kh2seedname = None
|
||||||
|
@ -137,23 +142,23 @@ class KH2Context(CommonContext):
|
||||||
self.finalxemnas = False
|
self.finalxemnas = False
|
||||||
self.worldid = {
|
self.worldid = {
|
||||||
# 1: {}, # world of darkness (story cutscenes)
|
# 1: {}, # world of darkness (story cutscenes)
|
||||||
2: TT_Checks,
|
2: TT_Checks,
|
||||||
# 3: {}, # destiny island doesn't have checks to ima put tt checks here
|
# 3: {}, # destiny island doesn't have checks to ima put tt checks here
|
||||||
4: HB_Checks,
|
4: HB_Checks,
|
||||||
5: BC_Checks,
|
5: BC_Checks,
|
||||||
6: Oc_Checks,
|
6: Oc_Checks,
|
||||||
7: AG_Checks,
|
7: AG_Checks,
|
||||||
8: LoD_Checks,
|
8: LoD_Checks,
|
||||||
9: HundredAcreChecks,
|
9: HundredAcreChecks,
|
||||||
10: PL_Checks,
|
10: PL_Checks,
|
||||||
11: DC_Checks, # atlantica isn't a supported world. if you go in atlantica it will check dc
|
11: DC_Checks, # atlantica isn't a supported world. if you go in atlantica it will check dc
|
||||||
12: DC_Checks,
|
12: DC_Checks,
|
||||||
13: TR_Checks,
|
13: TR_Checks,
|
||||||
14: HT_Checks,
|
14: HT_Checks,
|
||||||
15: HB_Checks, # world map, but you only go to the world map while on the way to goa so checking hb
|
15: HB_Checks, # world map, but you only go to the world map while on the way to goa so checking hb
|
||||||
16: PR_Checks,
|
16: PR_Checks,
|
||||||
17: SP_Checks,
|
17: SP_Checks,
|
||||||
18: TWTNW_Checks,
|
18: TWTNW_Checks,
|
||||||
# 255: {}, # starting screen
|
# 255: {}, # starting screen
|
||||||
}
|
}
|
||||||
# 0x2A09C00+0x40 is the sve anchor. +1 is the last saved room
|
# 0x2A09C00+0x40 is the sve anchor. +1 is the last saved room
|
||||||
|
@ -412,7 +417,7 @@ class KH2Context(CommonContext):
|
||||||
logger.info(e)
|
logger.info(e)
|
||||||
|
|
||||||
async def verifyLevel(self):
|
async def verifyLevel(self):
|
||||||
for leveltype, anchor in {"SoraLevel": 0x24FF,
|
for leveltype, anchor in {"SoraLevel": 0x24FF,
|
||||||
"ValorLevel": 0x32F6,
|
"ValorLevel": 0x32F6,
|
||||||
"WisdomLevel": 0x332E,
|
"WisdomLevel": 0x332E,
|
||||||
"LimitLevel": 0x3366,
|
"LimitLevel": 0x3366,
|
||||||
|
@ -536,6 +541,34 @@ class KH2Context(CommonContext):
|
||||||
self.ui = KH2Manager(self)
|
self.ui = KH2Manager(self)
|
||||||
self.ui_task = asyncio.create_task(self.ui.async_run(), name="UI")
|
self.ui_task = asyncio.create_task(self.ui.async_run(), name="UI")
|
||||||
|
|
||||||
|
async def IsInShop(self, sellable, master_boost):
|
||||||
|
# journal = 0x741230 shop = 0x741320
|
||||||
|
# if journal=-1 and shop = 5 then in shop
|
||||||
|
# if journam !=-1 and shop = 10 then journal
|
||||||
|
journal = self.kh2.read_short(self.kh2.base_address + 0x741230)
|
||||||
|
shop = self.kh2.read_short(self.kh2.base_address + 0x741320)
|
||||||
|
if (journal == -1 and shop == 5) or (journal != -1 and shop == 10):
|
||||||
|
# print("your in the shop")
|
||||||
|
sellable_dict = {}
|
||||||
|
for itemName in sellable:
|
||||||
|
itemdata = self.item_name_to_data[itemName]
|
||||||
|
amount = int.from_bytes(
|
||||||
|
self.kh2.read_bytes(self.kh2.base_address + self.Save + itemdata.memaddr, 1), "big")
|
||||||
|
sellable_dict[itemName] = amount
|
||||||
|
while (journal == -1 and shop == 5) or (journal != -1 and shop == 10):
|
||||||
|
journal = self.kh2.read_short(self.kh2.base_address + 0x741230)
|
||||||
|
shop = self.kh2.read_short(self.kh2.base_address + 0x741320)
|
||||||
|
await asyncio.sleep(0.5)
|
||||||
|
for item, amount in sellable_dict.items():
|
||||||
|
itemdata = self.item_name_to_data[item]
|
||||||
|
afterShop = int.from_bytes(
|
||||||
|
self.kh2.read_bytes(self.kh2.base_address + self.Save + itemdata.memaddr, 1), "big")
|
||||||
|
if afterShop < amount:
|
||||||
|
if item in master_boost:
|
||||||
|
self.kh2seedsave["SoldBoosts"][item] += (amount - afterShop)
|
||||||
|
else:
|
||||||
|
self.kh2seedsave["SoldEquipment"].append(item)
|
||||||
|
|
||||||
async def verifyItems(self):
|
async def verifyItems(self):
|
||||||
try:
|
try:
|
||||||
local_amount = set(self.kh2seedsave["AmountInvo"]["LocalItems"]["Amount"].keys())
|
local_amount = set(self.kh2seedsave["AmountInvo"]["LocalItems"]["Amount"].keys())
|
||||||
|
@ -578,6 +611,8 @@ class KH2Context(CommonContext):
|
||||||
server_boost = set(self.kh2seedsave["AmountInvo"]["ServerItems"]["Boost"].keys())
|
server_boost = set(self.kh2seedsave["AmountInvo"]["ServerItems"]["Boost"].keys())
|
||||||
master_boost = local_boost | server_boost
|
master_boost = local_boost | server_boost
|
||||||
|
|
||||||
|
master_sell = master_equipment | master_staff | master_shield | master_boost
|
||||||
|
await asyncio.create_task(self.IsInShop(master_sell, master_boost))
|
||||||
for itemName in master_amount:
|
for itemName in master_amount:
|
||||||
itemData = self.item_name_to_data[itemName]
|
itemData = self.item_name_to_data[itemName]
|
||||||
amountOfItems = 0
|
amountOfItems = 0
|
||||||
|
@ -603,7 +638,8 @@ class KH2Context(CommonContext):
|
||||||
itemData = self.item_name_to_data[itemName]
|
itemData = self.item_name_to_data[itemName]
|
||||||
# if the inventory slot for that keyblade is less than the amount they should have
|
# if the inventory slot for that keyblade is less than the amount they should have
|
||||||
if int.from_bytes(self.kh2.read_bytes(self.kh2.base_address + self.Save + itemData.memaddr, 1),
|
if int.from_bytes(self.kh2.read_bytes(self.kh2.base_address + self.Save + itemData.memaddr, 1),
|
||||||
"big") <= 0:
|
"big") != 1 and int.from_bytes(self.kh2.read_bytes(self.kh2.base_address + 0x1CFF, 1),
|
||||||
|
"big") != 13:
|
||||||
# Checking form anchors for the keyblade
|
# Checking form anchors for the keyblade
|
||||||
if self.kh2.read_short(self.kh2.base_address + self.Save + 0x24F0) == itemData.kh2id \
|
if self.kh2.read_short(self.kh2.base_address + self.Save + 0x24F0) == itemData.kh2id \
|
||||||
or self.kh2.read_short(self.kh2.base_address + self.Save + 0x32F4) == itemData.kh2id \
|
or self.kh2.read_short(self.kh2.base_address + self.Save + 0x32F4) == itemData.kh2id \
|
||||||
|
@ -618,7 +654,8 @@ class KH2Context(CommonContext):
|
||||||
itemData = self.item_name_to_data[itemName]
|
itemData = self.item_name_to_data[itemName]
|
||||||
if int.from_bytes(self.kh2.read_bytes(self.kh2.base_address + self.Save + itemData.memaddr, 1),
|
if int.from_bytes(self.kh2.read_bytes(self.kh2.base_address + self.Save + itemData.memaddr, 1),
|
||||||
"big") != 1 \
|
"big") != 1 \
|
||||||
and self.kh2.read_short(self.kh2.base_address + self.Save + 0x2604) != itemData.kh2id:
|
and self.kh2.read_short(self.kh2.base_address + self.Save + 0x2604) != itemData.kh2id \
|
||||||
|
and itemName not in self.kh2seedsave["SoldEquipment"]:
|
||||||
self.kh2.write_bytes(self.kh2.base_address + self.Save + itemData.memaddr,
|
self.kh2.write_bytes(self.kh2.base_address + self.Save + itemData.memaddr,
|
||||||
(1).to_bytes(1, 'big'), 1)
|
(1).to_bytes(1, 'big'), 1)
|
||||||
|
|
||||||
|
@ -626,7 +663,8 @@ class KH2Context(CommonContext):
|
||||||
itemData = self.item_name_to_data[itemName]
|
itemData = self.item_name_to_data[itemName]
|
||||||
if int.from_bytes(self.kh2.read_bytes(self.kh2.base_address + self.Save + itemData.memaddr, 1),
|
if int.from_bytes(self.kh2.read_bytes(self.kh2.base_address + self.Save + itemData.memaddr, 1),
|
||||||
"big") != 1 \
|
"big") != 1 \
|
||||||
and self.kh2.read_short(self.kh2.base_address + self.Save + 0x2718) != itemData.kh2id:
|
and self.kh2.read_short(self.kh2.base_address + self.Save + 0x2718) != itemData.kh2id \
|
||||||
|
and itemName not in self.kh2seedsave["SoldEquipment"]:
|
||||||
self.kh2.write_bytes(self.kh2.base_address + self.Save + itemData.memaddr,
|
self.kh2.write_bytes(self.kh2.base_address + self.Save + itemData.memaddr,
|
||||||
(1).to_bytes(1, 'big'), 1)
|
(1).to_bytes(1, 'big'), 1)
|
||||||
|
|
||||||
|
@ -679,16 +717,18 @@ class KH2Context(CommonContext):
|
||||||
Equipment_Anchor_List = self.Equipment_Anchor_Dict["Accessories"]
|
Equipment_Anchor_List = self.Equipment_Anchor_Dict["Accessories"]
|
||||||
else:
|
else:
|
||||||
Equipment_Anchor_List = self.Equipment_Anchor_Dict["Armor"]
|
Equipment_Anchor_List = self.Equipment_Anchor_Dict["Armor"]
|
||||||
if int.from_bytes(self.kh2.read_bytes(self.kh2.base_address + self.Save + itemData.memaddr, 1),
|
|
||||||
"big") != 1:
|
|
||||||
# Checking form anchors for the equipment
|
# Checking form anchors for the equipment
|
||||||
for slot in Equipment_Anchor_List:
|
for slot in Equipment_Anchor_List:
|
||||||
if self.kh2.read_short(self.kh2.base_address + self.Save + slot) == itemData.kh2id:
|
if self.kh2.read_short(self.kh2.base_address + self.Save + slot) == itemData.kh2id:
|
||||||
isThere = True
|
isThere = True
|
||||||
|
if int.from_bytes(self.kh2.read_bytes(self.kh2.base_address + self.Save + itemData.memaddr, 1),
|
||||||
|
"big") != 0:
|
||||||
self.kh2.write_bytes(self.kh2.base_address + self.Save + itemData.memaddr,
|
self.kh2.write_bytes(self.kh2.base_address + self.Save + itemData.memaddr,
|
||||||
(0).to_bytes(1, 'big'), 1)
|
(0).to_bytes(1, 'big'), 1)
|
||||||
break
|
break
|
||||||
if not isThere:
|
if not isThere and itemName not in self.kh2seedsave["SoldEquipment"]:
|
||||||
|
if int.from_bytes(self.kh2.read_bytes(self.kh2.base_address + self.Save + itemData.memaddr, 1),
|
||||||
|
"big") != 1:
|
||||||
self.kh2.write_bytes(self.kh2.base_address + self.Save + itemData.memaddr,
|
self.kh2.write_bytes(self.kh2.base_address + self.Save + itemData.memaddr,
|
||||||
(1).to_bytes(1, 'big'), 1)
|
(1).to_bytes(1, 'big'), 1)
|
||||||
|
|
||||||
|
@ -736,7 +776,8 @@ class KH2Context(CommonContext):
|
||||||
# Ap Boots start at +50 for some reason
|
# Ap Boots start at +50 for some reason
|
||||||
if itemName == "AP Boost":
|
if itemName == "AP Boost":
|
||||||
amountOfUsedBoosts -= 50
|
amountOfUsedBoosts -= 50
|
||||||
if (amountOfBoostsInInvo + amountOfUsedBoosts) <= amountOfItems and amountOfBoostsInInvo < 255:
|
totalBoosts = (amountOfBoostsInInvo + amountOfUsedBoosts)
|
||||||
|
if totalBoosts <= amountOfItems - self.kh2seedsave["SoldBoosts"][itemName] and amountOfBoostsInInvo < 255:
|
||||||
self.kh2.write_bytes(self.kh2.base_address + self.Save + itemData.memaddr,
|
self.kh2.write_bytes(self.kh2.base_address + self.Save + itemData.memaddr,
|
||||||
(amountOfBoostsInInvo + 1).to_bytes(1, 'big'), 1)
|
(amountOfBoostsInInvo + 1).to_bytes(1, 'big'), 1)
|
||||||
|
|
||||||
|
@ -821,9 +862,9 @@ async def kh2_watcher(ctx: KH2Context):
|
||||||
currentWorld = int.from_bytes(ctx.kh2.read_bytes(ctx.kh2.base_address + 0x0714DB8, 1), "big")
|
currentWorld = int.from_bytes(ctx.kh2.read_bytes(ctx.kh2.base_address + 0x0714DB8, 1), "big")
|
||||||
if location not in ctx.kh2seedsave["worldIdChecks"][str(currentWorld)]:
|
if location not in ctx.kh2seedsave["worldIdChecks"][str(currentWorld)]:
|
||||||
ctx.kh2seedsave["worldIdChecks"][str(currentWorld)].append(location)
|
ctx.kh2seedsave["worldIdChecks"][str(currentWorld)].append(location)
|
||||||
if location in ctx.kh2LocalItems:
|
if location in ctx.kh2LocalItems:
|
||||||
item = ctx.kh2slotdata["LocalItems"][str(location)]
|
item = ctx.kh2slotdata["LocalItems"][str(location)]
|
||||||
await asyncio.create_task(ctx.give_item(item, "LocalItems"))
|
await asyncio.create_task(ctx.give_item(item, "LocalItems"))
|
||||||
await ctx.send_msgs(message)
|
await ctx.send_msgs(message)
|
||||||
elif not ctx.kh2connected and ctx.serverconneced:
|
elif not ctx.kh2connected and ctx.serverconneced:
|
||||||
logger.info("Game is not open. Disconnecting from Server.")
|
logger.info("Game is not open. Disconnecting from Server.")
|
||||||
|
|
|
@ -856,31 +856,19 @@ Progression_Dicts = {
|
||||||
ItemName.NamineSketches
|
ItemName.NamineSketches
|
||||||
},
|
},
|
||||||
"AllVisitLocking": {
|
"AllVisitLocking": {
|
||||||
ItemName.CastleKey,
|
ItemName.CastleKey: 2,
|
||||||
ItemName.CastleKey,
|
ItemName.BattlefieldsofWar: 2,
|
||||||
ItemName.BattlefieldsofWar,
|
ItemName.SwordoftheAncestor: 2,
|
||||||
ItemName.BattlefieldsofWar,
|
ItemName.BeastsClaw: 2,
|
||||||
ItemName.SwordoftheAncestor,
|
ItemName.BoneFist: 2,
|
||||||
ItemName.SwordoftheAncestor,
|
ItemName.ProudFang: 2,
|
||||||
ItemName.BeastsClaw,
|
ItemName.SkillandCrossbones: 2,
|
||||||
ItemName.BeastsClaw,
|
ItemName.Scimitar: 2,
|
||||||
ItemName.BoneFist,
|
ItemName.MembershipCard: 2,
|
||||||
ItemName.BoneFist,
|
ItemName.WaytotheDawn: 1,
|
||||||
ItemName.ProudFang,
|
ItemName.IdentityDisk: 2,
|
||||||
ItemName.ProudFang,
|
ItemName.IceCream: 3,
|
||||||
ItemName.SkillandCrossbones,
|
ItemName.NamineSketches: 1,
|
||||||
ItemName.SkillandCrossbones,
|
|
||||||
ItemName.Scimitar,
|
|
||||||
ItemName.Scimitar,
|
|
||||||
ItemName.MembershipCard,
|
|
||||||
ItemName.MembershipCard,
|
|
||||||
ItemName.WaytotheDawn,
|
|
||||||
ItemName.IdentityDisk,
|
|
||||||
ItemName.IdentityDisk,
|
|
||||||
ItemName.IceCream,
|
|
||||||
ItemName.IceCream,
|
|
||||||
ItemName.IceCream,
|
|
||||||
ItemName.NamineSketches,
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1483,7 +1483,6 @@ exclusion_table = {
|
||||||
LocationName.OasisMap,
|
LocationName.OasisMap,
|
||||||
LocationName.OasisTornPages,
|
LocationName.OasisTornPages,
|
||||||
LocationName.OasisAPBoost,
|
LocationName.OasisAPBoost,
|
||||||
LocationName.StationofSerenityPotion,
|
|
||||||
LocationName.StationofCallingPotion,
|
LocationName.StationofCallingPotion,
|
||||||
LocationName.CentralStationPotion1,
|
LocationName.CentralStationPotion1,
|
||||||
LocationName.STTCentralStationHiPotion,
|
LocationName.STTCentralStationHiPotion,
|
||||||
|
|
|
@ -59,7 +59,7 @@ class SummonEXP(Range):
|
||||||
|
|
||||||
|
|
||||||
class Schmovement(Choice):
|
class Schmovement(Choice):
|
||||||
"""Level of Growth You Start With"""
|
"""Level of Progressive Movement You Start With"""
|
||||||
display_name = "Schmovement"
|
display_name = "Schmovement"
|
||||||
option_level_0 = 0
|
option_level_0 = 0
|
||||||
option_level_1 = 1
|
option_level_1 = 1
|
||||||
|
@ -106,9 +106,10 @@ class Visitlocking(Choice):
|
||||||
|
|
||||||
|
|
||||||
class RandomVisitLockingItem(Range):
|
class RandomVisitLockingItem(Range):
|
||||||
|
"""Start with random amount of visit locking items."""
|
||||||
display_name = "Random Visit Locking Item"
|
display_name = "Random Visit Locking Item"
|
||||||
range_start = 0
|
range_start = 0
|
||||||
range_end = 27
|
range_end = 25
|
||||||
default = 3
|
default = 3
|
||||||
|
|
||||||
|
|
||||||
|
@ -191,7 +192,7 @@ class LuckyEmblemsRequired(Range):
|
||||||
"""Number of Lucky Emblems to collect to Open The Final Door bosses.
|
"""Number of Lucky Emblems to collect to Open The Final Door bosses.
|
||||||
If Goal is not Lucky Emblem Hunt this does nothing."""
|
If Goal is not Lucky Emblem Hunt this does nothing."""
|
||||||
display_name = "Lucky Emblems Required"
|
display_name = "Lucky Emblems Required"
|
||||||
range_start = 0
|
range_start = 1
|
||||||
range_end = 60
|
range_end = 60
|
||||||
default = 25
|
default = 25
|
||||||
|
|
||||||
|
@ -200,7 +201,7 @@ class LuckyEmblemsAmount(Range):
|
||||||
"""Number of Lucky Emblems that are in the pool.
|
"""Number of Lucky Emblems that are in the pool.
|
||||||
If Goal is not Lucky Emblem Hunt this does nothing."""
|
If Goal is not Lucky Emblem Hunt this does nothing."""
|
||||||
display_name = "Lucky Emblems Available"
|
display_name = "Lucky Emblems Available"
|
||||||
range_start = 0
|
range_start = 1
|
||||||
range_end = 60
|
range_end = 60
|
||||||
default = 40
|
default = 40
|
||||||
|
|
||||||
|
@ -209,7 +210,7 @@ class BountyRequired(Range):
|
||||||
"""Number of Bounties that are Required.
|
"""Number of Bounties that are Required.
|
||||||
If Goal is not Hitlist this does nothing."""
|
If Goal is not Hitlist this does nothing."""
|
||||||
display_name = "Bounties Required"
|
display_name = "Bounties Required"
|
||||||
range_start = 0
|
range_start = 1
|
||||||
range_end = 24
|
range_end = 24
|
||||||
default = 7
|
default = 7
|
||||||
|
|
||||||
|
@ -218,7 +219,7 @@ class BountyAmount(Range):
|
||||||
"""Number of Bounties that are in the pool.
|
"""Number of Bounties that are in the pool.
|
||||||
If Goal is not Hitlist this does nothing."""
|
If Goal is not Hitlist this does nothing."""
|
||||||
display_name = "Bounties Available"
|
display_name = "Bounties Available"
|
||||||
range_start = 0
|
range_start = 1
|
||||||
range_end = 24
|
range_end = 24
|
||||||
default = 13
|
default = 13
|
||||||
|
|
||||||
|
|
|
@ -52,12 +52,12 @@ class KH2World(World):
|
||||||
self.goofy_ability_pool = list()
|
self.goofy_ability_pool = list()
|
||||||
self.sora_keyblade_ability_pool = list()
|
self.sora_keyblade_ability_pool = list()
|
||||||
self.keyblade_slot_copy = list(Locations.Keyblade_Slots.keys())
|
self.keyblade_slot_copy = list(Locations.Keyblade_Slots.keys())
|
||||||
|
self.keyblade_slot_copy.remove(LocationName.KingdomKeySlot)
|
||||||
self.totalLocations = len(all_locations.items())
|
self.totalLocations = len(all_locations.items())
|
||||||
self.growth_list = list()
|
self.growth_list = list()
|
||||||
for x in range(4):
|
for x in range(4):
|
||||||
self.growth_list.extend(Movement_Table.keys())
|
self.growth_list.extend(Movement_Table.keys())
|
||||||
self.visitlockingitem = list()
|
self.visitlocking_dict = Progression_Dicts["AllVisitLocking"]
|
||||||
self.visitlockingitem.extend(Progression_Dicts["AllVisitLocking"])
|
|
||||||
|
|
||||||
def fill_slot_data(self) -> dict:
|
def fill_slot_data(self) -> dict:
|
||||||
return {"hitlist": self.hitlist,
|
return {"hitlist": self.hitlist,
|
||||||
|
@ -94,7 +94,7 @@ class KH2World(World):
|
||||||
self.sora_keyblade_ability_pool.extend(SupportAbility_Table.keys())
|
self.sora_keyblade_ability_pool.extend(SupportAbility_Table.keys())
|
||||||
|
|
||||||
for item, value in self.multiworld.start_inventory[self.player].value.items():
|
for item, value in self.multiworld.start_inventory[self.player].value.items():
|
||||||
if item in ActionAbility_Table.keys() or item in SupportAbility_Table.keys():
|
if item in ActionAbility_Table.keys() or item in SupportAbility_Table.keys() or exclusionItem_table["StatUps"]:
|
||||||
# cannot have more than the quantity for abilties
|
# cannot have more than the quantity for abilties
|
||||||
if value > item_dictionary_table[item].quantity:
|
if value > item_dictionary_table[item].quantity:
|
||||||
logging.info(f"{self.multiworld.get_file_safe_player_name(self.player)} cannot have more than {item_dictionary_table[item].quantity} of {item}"
|
logging.info(f"{self.multiworld.get_file_safe_player_name(self.player)} cannot have more than {item_dictionary_table[item].quantity} of {item}"
|
||||||
|
@ -216,6 +216,15 @@ class KH2World(World):
|
||||||
self.RandomSuperBoss.remove(randomBoss)
|
self.RandomSuperBoss.remove(randomBoss)
|
||||||
self.totalLocations -= 1
|
self.totalLocations -= 1
|
||||||
|
|
||||||
|
# Kingdom Key cannot have No Experience so plandoed here instead of checking 26 times if its kingdom key
|
||||||
|
random_ability = self.multiworld.per_slot_randoms[self.player].choice(self.sora_keyblade_ability_pool)
|
||||||
|
while random_ability == ItemName.NoExperience:
|
||||||
|
random_ability = self.multiworld.per_slot_randoms[self.player].choice(self.sora_keyblade_ability_pool)
|
||||||
|
self.multiworld.get_location(LocationName.KingdomKeySlot, self.player).place_locked_item(self.create_item(random_ability))
|
||||||
|
self.item_quantity_dict[random_ability] -= 1
|
||||||
|
self.sora_keyblade_ability_pool.remove(random_ability)
|
||||||
|
self.totalLocations -= 1
|
||||||
|
|
||||||
# plando keyblades because they can only have abilities
|
# plando keyblades because they can only have abilities
|
||||||
for keyblade in self.keyblade_slot_copy:
|
for keyblade in self.keyblade_slot_copy:
|
||||||
random_ability = self.multiworld.per_slot_randoms[self.player].choice(self.sora_keyblade_ability_pool)
|
random_ability = self.multiworld.per_slot_randoms[self.player].choice(self.sora_keyblade_ability_pool)
|
||||||
|
@ -266,25 +275,33 @@ class KH2World(World):
|
||||||
|
|
||||||
# no visit locking
|
# no visit locking
|
||||||
if self.multiworld.Visitlocking[self.player] == "no_visit_locking":
|
if self.multiworld.Visitlocking[self.player] == "no_visit_locking":
|
||||||
for item in self.visitlockingitem:
|
for item, amount in Progression_Dicts["AllVisitLocking"].items():
|
||||||
self.multiworld.push_precollected(self.create_item(item))
|
for _ in range(amount):
|
||||||
self.item_quantity_dict[item] -= 1
|
self.multiworld.push_precollected(self.create_item(item))
|
||||||
self.visitlockingitem.remove(item)
|
self.item_quantity_dict[item] -= 1
|
||||||
|
if self.visitlocking_dict[item] == 0:
|
||||||
|
self.visitlocking_dict.pop(item)
|
||||||
|
self.visitlocking_dict[item] -= 1
|
||||||
|
|
||||||
# first and second visit locking
|
# first and second visit locking
|
||||||
elif self.multiworld.Visitlocking[self.player] == "second_visit_locking":
|
elif self.multiworld.Visitlocking[self.player] == "second_visit_locking":
|
||||||
for item in Progression_Dicts["2VisitLocking"]:
|
for item in Progression_Dicts["2VisitLocking"]:
|
||||||
self.item_quantity_dict[item] -= 1
|
self.item_quantity_dict[item] -= 1
|
||||||
|
self.visitlocking_dict[item] -= 1
|
||||||
|
if self.visitlocking_dict[item] == 0:
|
||||||
|
self.visitlocking_dict.pop(item)
|
||||||
self.multiworld.push_precollected(self.create_item(item))
|
self.multiworld.push_precollected(self.create_item(item))
|
||||||
self.visitlockingitem.remove(item)
|
|
||||||
|
|
||||||
for _ in range(self.multiworld.RandomVisitLockingItem[self.player].value):
|
for _ in range(self.multiworld.RandomVisitLockingItem[self.player].value):
|
||||||
if len(self.visitlockingitem) <= 0:
|
if sum(self.visitlocking_dict.values()) <= 0:
|
||||||
break
|
break
|
||||||
item = self.multiworld.per_slot_randoms[self.player].choice(self.visitlockingitem)
|
visitlocking_set = list(self.visitlocking_dict.keys())
|
||||||
|
item = self.multiworld.per_slot_randoms[self.player].choice(visitlocking_set)
|
||||||
self.item_quantity_dict[item] -= 1
|
self.item_quantity_dict[item] -= 1
|
||||||
|
self.visitlocking_dict[item] -= 1
|
||||||
|
if self.visitlocking_dict[item] == 0:
|
||||||
|
self.visitlocking_dict.pop(item)
|
||||||
self.multiworld.push_precollected(self.create_item(item))
|
self.multiworld.push_precollected(self.create_item(item))
|
||||||
self.visitlockingitem.remove(item)
|
|
||||||
|
|
||||||
# there are levels but level 1 is there to keep code clean
|
# there are levels but level 1 is there to keep code clean
|
||||||
if self.multiworld.LevelDepth[self.player] == "level_99_sanity":
|
if self.multiworld.LevelDepth[self.player] == "level_99_sanity":
|
||||||
|
|
Loading…
Reference in New Issue