Skip to content

Commit

Permalink
Merge branch 'main' into core_optimize_deprecatedict
Browse files Browse the repository at this point in the history
  • Loading branch information
Berserker66 authored Jan 3, 2024
2 parents 8996786 + 0df0955 commit 16487a8
Show file tree
Hide file tree
Showing 8 changed files with 596 additions and 526 deletions.
505 changes: 5 additions & 500 deletions ZillionClient.py

Large diffs are not rendered by default.

1 change: 1 addition & 0 deletions data/lua/connector_bizhawk_generic.lua
Original file line number Diff line number Diff line change
Expand Up @@ -456,6 +456,7 @@ function send_receive ()
failed_guard_response = response
end
else
if type(response) ~= "string" then response = "Unknown error" end
res[i] = {type = "ERROR", err = response}
end
end
Expand Down
1 change: 1 addition & 0 deletions worlds/ff1/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,7 @@ def create_regions(self):
items = get_options(self.multiworld, 'items', self.player)
goal_rule = generate_rule([[name for name in items.keys() if name in FF1_PROGRESSION_LIST and name != "Shard"]],
self.player)
terminated_event.access_rule = goal_rule
if "Shard" in items.keys():
def goal_rule_and_shards(state):
return goal_rule(state) and state.has("Shard", self.player, 32)
Expand Down
12 changes: 8 additions & 4 deletions worlds/generic/Rules.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import collections
import logging
import typing

from BaseClasses import LocationProgressType, MultiWorld, Location, Region, Entrance
Expand Down Expand Up @@ -81,15 +82,18 @@ def forbid(sender: int, receiver: int, items: typing.Set[str]):
i.name not in sending_blockers[i.player] and old_rule(i)


def exclusion_rules(world: MultiWorld, player: int, exclude_locations: typing.Set[str]) -> None:
def exclusion_rules(multiworld: MultiWorld, player: int, exclude_locations: typing.Set[str]) -> None:
for loc_name in exclude_locations:
try:
location = world.get_location(loc_name, player)
location = multiworld.get_location(loc_name, player)
except KeyError as e: # failed to find the given location. Check if it's a legitimate location
if loc_name not in world.worlds[player].location_name_to_id:
if loc_name not in multiworld.worlds[player].location_name_to_id:
raise Exception(f"Unable to exclude location {loc_name} in player {player}'s world.") from e
else:
location.progress_type = LocationProgressType.EXCLUDED
if not location.event:
location.progress_type = LocationProgressType.EXCLUDED
else:
logging.warning(f"Unable to exclude location {loc_name} in player {player}'s world.")


def set_rule(spot: typing.Union["BaseClasses.Location", "BaseClasses.Entrance"], rule: CollectionRule):
Expand Down
95 changes: 77 additions & 18 deletions worlds/kh2/Client.py
Original file line number Diff line number Diff line change
Expand Up @@ -80,11 +80,6 @@ def __init__(self, server_address, password):
},
},
}
self.front_of_inventory = {
"Sora": 0x2546,
"Donald": 0x2658,
"Goofy": 0x276C,
}
self.kh2seedname = None
self.kh2slotdata = None
self.itemamount = {}
Expand Down Expand Up @@ -169,6 +164,14 @@ def __init__(self, server_address, password):
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)
Expand Down Expand Up @@ -219,6 +222,12 @@ def kh2_write_byte(self, address, value):
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']
Expand Down Expand Up @@ -476,7 +485,7 @@ async def verifyLevel(self):

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]
Expand Down Expand Up @@ -507,6 +516,8 @@ async def give_item(self, item, location):
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]:
Expand All @@ -518,11 +529,14 @@ async def give_item(self, item, location):
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"]:
Expand Down Expand Up @@ -615,7 +629,7 @@ async def verifyItems(self):
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
Expand Down Expand Up @@ -673,10 +687,10 @@ async def verifyItems(self):
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}:
Expand Down Expand Up @@ -740,15 +754,60 @@ async def verifyItems(self):
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)
Expand Down
5 changes: 2 additions & 3 deletions worlds/kh2/Rules.py
Original file line number Diff line number Diff line change
Expand Up @@ -268,7 +268,6 @@ def set_kh2_rules(self) -> None:
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)
Expand All @@ -291,8 +290,8 @@ def set_kh2_goal(self):
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:
Expand Down
2 changes: 1 addition & 1 deletion worlds/shivers/Rules.py
Original file line number Diff line number Diff line change
Expand Up @@ -157,7 +157,7 @@ def get_rules_lookup(player: int):
"Puzzle Solved Underground Elevator": lambda state: ((state.can_reach("Underground Lake", "Region", player) or state.can_reach("Office", "Region", player)
and state.has("Key for Office Elevator", player))),
"Puzzle Solved Bedroom Elevator": lambda state: (state.can_reach("Office", "Region", player) and state.has_all({"Key for Bedroom Elevator","Crawling"}, player)),
"Puzzle Solved Three Floor Elevator": lambda state: ((state.can_reach("Maintenance Tunnels", "Region", player) or state.can_reach("Blue Maze", "Region", player)
"Puzzle Solved Three Floor Elevator": lambda state: (((state.can_reach("Maintenance Tunnels", "Region", player) or state.can_reach("Blue Maze", "Region", player))
and state.has("Key for Three Floor Elevator", player)))
},
"lightning": {
Expand Down
Loading

0 comments on commit 16487a8

Please sign in to comment.