Skip to content

Commit

Permalink
pre-v1.5.0
Browse files Browse the repository at this point in the history
  • Loading branch information
jamesbrq committed Jul 23, 2024
1 parent f41c150 commit 76e0c18
Show file tree
Hide file tree
Showing 5 changed files with 52 additions and 53 deletions.
13 changes: 10 additions & 3 deletions worlds/gl/GauntletLegendsClient.py
Original file line number Diff line number Diff line change
Expand Up @@ -164,6 +164,13 @@ def _cmd_deathlink_toggle(self):
self.ctx.deathlink_enabled = not self.ctx.deathlink_enabled
logger.info(f"Deathlink {'Enabled.' if self.ctx.deathlink_enabled else 'Disabled.'}")

def _cmd_players(self, value: int):
"""Set number of local players"""
if type(value) is not int:
logger.info(f"Invalid Parameters. Usage: /players [number]")
self.ctx.players = min(value, 4)
logger.info(f"Players set to {min(value, 4)}.")


class GauntletLegendsContext(CommonContext):
command_processor = GauntletLegendsCommandProcessor
Expand Down Expand Up @@ -491,7 +498,6 @@ def on_package(self, cmd: str, args: dict):
self.glslotdata = args["slot_data"]
if self.socket.status():
self.retro_connected = True
self.players = self.glslotdata["players"]
self.deathlink_enabled = self.glslotdata["death_link"]
else:
raise Exception("Retroarch not detected. Please open you patched ROM in Retroarch.")
Expand Down Expand Up @@ -575,11 +581,11 @@ async def scale(self):
level = [0x1, 0xF]
players = await self.active_players()
player_level = await self.player_level()
max_value: int = self.glslotdata["max"]
max_value: int = max(self.glslotdata["max"], self.players)
scale_value = min(max(((player_level - difficulty_convert[level[1]]) // 5), 0), 3)
if self.glslotdata["instant_max"] == 1:
scale_value = max_value
mountain_value = min(player_level // 10, 3)
# mountain_value = min(player_level // 10, 3)
await self.socket.write(
message_format(WRITE, f"0x{format(PLAYER_COUNT, 'x')} 0x{format(min(players + scale_value, max_value), 'x')}"),
)
Expand Down Expand Up @@ -799,6 +805,7 @@ async def _patch_and_run_game(patch_file: str):
# Checks location status inside of levels
async def gl_sync_task(ctx: GauntletLegendsContext):
logger.info("Starting N64 connector...")
logger.info("Use /players to set the number of people playing locally. This is required for the client to function.")
while not ctx.exit_event.is_set():
if ctx.retro_connected:
cc_str: str = f"gl_cc_T{ctx.team}_P{ctx.slot}"
Expand Down
13 changes: 0 additions & 13 deletions worlds/gl/Options.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,18 +3,6 @@
from Options import Choice, PerGameCommonOptions, StartInventoryPool, Toggle, Range


class PlayerCount(Range):
"""
Select how many players will be playing this world locally.
If 3 players will be active then change this to 3, etc.
"""

display_name = "Local Players"
range_start = 1
range_end = 4
default = 1


class ChestBarrels(Choice):
"""
Choose how you want Chests and Barrels to be randomized.
Expand Down Expand Up @@ -213,7 +201,6 @@ class UnlockCharacterFour(Choice):
@dataclass
class GLOptions(PerGameCommonOptions):
start_inventory_from_pool: StartInventoryPool
local_players: PlayerCount
chests_barrels: ChestBarrels
obelisks: Obelisks
mirror_shards: MirrorShards
Expand Down
10 changes: 5 additions & 5 deletions worlds/gl/Regions.py
Original file line number Diff line number Diff line change
Expand Up @@ -104,7 +104,7 @@ def connect_regions(world: "GauntletLegendsWorld"):
connect(
world,
names,
"Valley of Fire",
"Menu",
"Castle Courtyard",
lambda state: state.has("Mountain Obelisk 1", world.player)
and state.has("Mountain Obelisk 2", world.player)
Expand All @@ -117,7 +117,7 @@ def connect_regions(world: "GauntletLegendsWorld"):
connect(
world,
names,
"Valley of Fire",
"Menu",
"Poisonous Fields",
lambda state: state.has("Castle Obelisk 1", world.player)
and state.has("Castle Obelisk 2", world.player),
Expand All @@ -129,7 +129,7 @@ def connect_regions(world: "GauntletLegendsWorld"):
connect(
world,
names,
"Valley of Fire",
"Menu",
"Arctic Docks",
lambda state: state.has("Town Obelisk 1", world.player)
and state.has("Town Obelisk 2", world.player),
Expand All @@ -141,7 +141,7 @@ def connect_regions(world: "GauntletLegendsWorld"):
connect(
world,
names,
"Valley of Fire",
"Menu",
"Desecrated Temple",
lambda state: state.has("Dragon Mirror Shard", world.player)
and state.has("Chimera Mirror Shard", world.player)
Expand All @@ -154,7 +154,7 @@ def connect_regions(world: "GauntletLegendsWorld"):
connect(
world,
names,
"Valley of Fire",
"Menu",
"Gates of the Underworld",
lambda state: state.has("Runestone 1", world.player)
and state.has("Runestone 2", world.player)
Expand Down
60 changes: 34 additions & 26 deletions worlds/gl/Rom.py
Original file line number Diff line number Diff line change
Expand Up @@ -53,8 +53,9 @@ class LevelData:
objects: List[bytearray]
chests: List[bytearray]
end: bytes
obelisk = 0
item = 0
obelisk_items: int = 0
obelisk_chests: int = 0
item: int = 0

def __init__(self):
self.items = []
Expand Down Expand Up @@ -136,15 +137,15 @@ def patch_items(caller: APProcedurePatch, rom: bytes):
if "Chest" in location_name or (
"Barrel" in location_name and "Barrel of Gold" not in location_name
):
data.chests[j - (len(data.items) + data.obelisk)][12] = 0x27
data.chests[j - (len(data.items) + data.obelisk)][13] = 0x4
data.chests[j - (len(data.items) + data.obelisk_items + data.obelisk_chests)][12] = 0x27
data.chests[j - (len(data.items) + data.obelisk_items + data.obelisk_chests)][13] = 0x4
else:
data.items[j - data.obelisk][6] = 0x27
data.items[j - data.obelisk][7] = 0x4
data.items[j - data.obelisk_items][6] = 0x27
data.items[j - data.obelisk_items][7] = 0x4
else:
if "Obelisk" in items_by_id[item[0]].item_name:
data.objects += [
bytearray(data.items[j - data.obelisk][0:6])
bytearray(data.items[j - data.obelisk_items][0:6])
+ bytearray(
[
0x0,
Expand All @@ -168,17 +169,19 @@ def patch_items(caller: APProcedurePatch, rom: bytes):
],
),
]
del data.items[j - data.obelisk]
data.obelisk += 1
if chest_barrel(location_name):
del data.chests[j - (len(data.items) + data.obelisk_items + data.obelisk_chests)]
data.obelisk_chests += 1
else:
del data.items[j - data.obelisk_items]
data.obelisk_items += 1
else:
if "Chest" in location_name or (
"Barrel" in location_name and "Barrel of Gold" not in location_name
):
data.chests[j - (len(data.items) + data.obelisk)][12] = item_dict[item[0]][0]
data.chests[j - (len(data.items) + data.obelisk)][13] = item_dict[item[0]][1]
if chest_barrel(location_name):
data.chests[j - (len(data.items) + data.obelisk_items + data.obelisk_chests)][12] = item_dict[item[0]][0]
data.chests[j - (len(data.items) + data.obelisk_items + data.obelisk_chests)][13] = item_dict[item[0]][1]
else:
data.items[j - data.obelisk][6] = item_dict[item[0]][0]
data.items[j - data.obelisk][7] = item_dict[item[0]][1]
data.items[j - data.obelisk_items][6] = item_dict[item[0]][0]
data.items[j - data.obelisk_items][7] = item_dict[item[0]][1]
uncompressed = level_data_reformat(data)
compressed = zenc(uncompressed)
stream.seek(level_header[i] + 4, 0)
Expand Down Expand Up @@ -290,25 +293,30 @@ def get_level_data(stream: io.BytesIO, size: int) -> (io.BytesIO, LevelData):
# Format is header, items, spawners, objects, barrels/chests, then traps.
def level_data_reformat(data: LevelData) -> bytes:
stream = io.BytesIO()
obelisk_offset = 24 * (data.obelisk - data.item)
obelisk_offset = 24 * (data.obelisk_items - data.item)
stream.write(int.to_bytes(0x5C, 4, "big"))
stream.write(int.to_bytes(data.spawner_addr + (12 * (data.item - data.obelisk)), 4, "big"))
stream.write(int.to_bytes(data.spawner_addr + (12 * (data.item - data.obelisk)), 4, "big"))
stream.write(int.to_bytes(data.obj_addr + (12 * (data.item - data.obelisk)), 4, "big"))
stream.write(int.to_bytes(data.end_addr + ((12 * (data.item - data.obelisk)) + obelisk_offset), 4, "big"))
stream.write(int.to_bytes(data.portal_addr + ((12 * (data.item - data.obelisk)) + obelisk_offset), 4, "big"))
stream.write(int.to_bytes(data.chest_addr + ((12 * (data.item - data.obelisk)) + obelisk_offset), 4, "big"))
stream.write(int.to_bytes(data.end_addr2 + ((12 * (data.item - data.obelisk)) + obelisk_offset), 4, "big"))
stream.write(int.to_bytes(data.end_addr3 + ((12 * (data.item - data.obelisk)) + obelisk_offset), 4, "big"))
stream.write(int.to_bytes(data.spawner_addr + (12 * (data.item - data.obelisk_items)), 4, "big"))
stream.write(int.to_bytes(data.spawner_addr + (12 * (data.item - data.obelisk_items)), 4, "big"))
stream.write(int.to_bytes(data.obj_addr + (12 * (data.item - data.obelisk_items)), 4, "big"))
stream.write(int.to_bytes(data.end_addr + ((12 * (data.item - data.obelisk_items)) + obelisk_offset - (data.obelisk_chests * 16)), 4, "big"))
stream.write(int.to_bytes(data.portal_addr + ((12 * (data.item - data.obelisk_items)) + obelisk_offset - (data.obelisk_chests * 16)), 4, "big"))
stream.write(int.to_bytes(data.chest_addr + ((12 * (data.item - data.obelisk_items)) + obelisk_offset), 4, "big"))
stream.write(int.to_bytes(data.end_addr2 + ((12 * (data.item - data.obelisk_items)) + obelisk_offset - (data.obelisk_chests * 16)), 4, "big"))
stream.write(int.to_bytes(data.end_addr3 + ((12 * (data.item - data.obelisk_items)) + obelisk_offset - (data.obelisk_chests * 16)), 4, "big"))
stream.seek(1, 1)
stream.write(bytes([len(data.items)]))
stream.write(bytes([0x0, 0x0, 0x0]))
stream.write(bytes([len(data.spawners)]))
stream.write(bytes([0x0]))
stream.write(bytes([len(data.objects)]))
data.stream.seek(stream.tell())
stream.write(data.stream.read(48))
temp = bytearray(data.stream.read(48))
temp[7] = len(data.chests)
stream.write(temp)
for item in data.items + data.spawners + data.objects + data.chests:
stream.write(bytes(item))
stream.write(data.end)
return stream.getvalue()

def chest_barrel(name: str):
return ("Chest" in name or ("Barrel" in name and "Barrel of Gold" not in name))
9 changes: 3 additions & 6 deletions worlds/gl/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -78,9 +78,6 @@ class GauntletLegendsWorld(World):

disabled_locations: typing.List[LocationData]

def generate_early(self) -> None:
self.options.max_difficulty_value = max(self.options.max_difficulty_value.value, self.options.local_players.value)

def create_regions(self) -> None:
self.disabled_locations = []
if self.options.chests_barrels == 0:
Expand Down Expand Up @@ -152,7 +149,6 @@ def fill_slot_data(self) -> dict:
]
return {
"player": self.player,
"players": self.options.local_players.value,
"shards": shard_values,
"speed": self.options.permanent_speed.value,
"keys": self.options.infinite_keys.value,
Expand Down Expand Up @@ -228,8 +224,9 @@ def set_rules(self) -> None:
"Gates of the Underworld", "Region", self.player,
)

def post_fill(self) -> None:
fast_fill(self.multiworld, self.death, self.multiworld.get_unfilled_locations(player=self.player))
def pre_fill(self) -> None:
self.random.shuffle(self.multiworld.get_unfilled_locations(self.player))
fast_fill(self.multiworld, self.death, self.multiworld.get_unfilled_locations(self.player))

def create_item(self, name: str) -> GLItem:
item = item_table[name]
Expand Down

0 comments on commit 76e0c18

Please sign in to comment.