Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Kingdom Hearts RE Chain of Memories: Implement New Game #3819

Draft
wants to merge 52 commits into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from 42 commits
Commits
Show all changes
52 commits
Select commit Hold shift + click to select a range
30caaf2
Initial Commit
gaithern Jan 22, 2024
f365441
Added new Final Marluxia logic
gaithern Jan 30, 2024
1729028
Update Items.py
gaithern Feb 1, 2024
447dd7b
Documentation update
gaithern Feb 12, 2024
539eefb
Merge branch 'main' into main
gaithern Feb 12, 2024
d14373b
Merge branch 'main' into main
gaithern Feb 16, 2024
332745b
Removed test command from client, using self.random
gaithern Feb 16, 2024
6e2885f
Added EXP Multiplier Settings
gaithern Feb 19, 2024
44551a4
Update Options.py
gaithern Feb 19, 2024
c6e4a3d
So many changes
gaithern Feb 20, 2024
57c4ec2
Fix sleights option toggled off makes generation fail
gaithern Feb 24, 2024
c9c8e3c
Update Locations.py
gaithern Feb 24, 2024
db18d13
Update __init__.py
gaithern Feb 24, 2024
13cba4f
Update __init__.py
gaithern Feb 24, 2024
d174a0e
Restructuring + Adding Sleights
gaithern Mar 6, 2024
c713436
Changes
gaithern Mar 6, 2024
27c1edb
Update Items.py
gaithern Mar 7, 2024
2586d4e
Fixes
gaithern Mar 7, 2024
3497e47
Merge pull request #1 from gaithernOrg/dev
gaithern Mar 7, 2024
540fc2d
Add options for starting worlds, renamed locations
gaithern Mar 18, 2024
d103de4
Merge pull request #2 from gaithernOrg/dev
gaithern Mar 18, 2024
017b0b2
Update Regions.py
gaithern Mar 18, 2024
d192fa0
Merge pull request #3 from gaithernOrg/dev
gaithern Mar 18, 2024
ebaf682
Merge branch 'ArchipelagoMW:main' into main
gaithern Apr 22, 2024
92a7fa9
Update Client.py
gaithern May 25, 2024
f8f2911
Update Options.py
gaithern May 25, 2024
f76b822
Too many changes to list
gaithern May 26, 2024
fd7516d
Fixed location groups, turned bosses back on
gaithern May 31, 2024
132e8cb
Merge branch 'ArchipelagoMW:main' into main
gaithern Jun 10, 2024
b881bd4
fix starting worlds and formatting
gaithern Jun 24, 2024
90219ea
Merge branch 'ArchipelagoMW:main' into main
gaithern Jul 28, 2024
48a2c05
Update Rules.py
gaithern Aug 7, 2024
07405f1
Update Rules.py
gaithern Aug 18, 2024
cf5f053
RECOM update going into PR
gaithern Aug 19, 2024
078bb11
Formatting
gaithern Aug 19, 2024
3c54125
Merge branch 'ArchipelagoMW:main' into main
gaithern Aug 19, 2024
8339a09
Documentation
gaithern Aug 19, 2024
b964a40
Merge branch 'main' into main
gaithern Aug 20, 2024
e182ebb
Fix some things for PR
gaithern Aug 20, 2024
e5e8ec8
Update __init__.py
gaithern Aug 20, 2024
1053558
PR updates
gaithern Aug 20, 2024
c5579d7
Merge branch 'main' into main
gaithern Aug 21, 2024
169ff1f
Removing syncing variable as it is not used
gaithern Aug 21, 2024
e0fb85d
Merge branch 'main' of https://github.com/gaithernOrg/ArchipelagoKHRECOM
gaithern Aug 21, 2024
43c71ea
Merge branch 'main' into main
gaithern Aug 21, 2024
efee432
Adding item and location groups
gaithern Aug 24, 2024
0b522a9
Fix item group having same name as item
gaithern Aug 24, 2024
7e8fd69
Update Options.py
gaithern Sep 2, 2024
43ecb85
Update Client.py
gaithern Nov 2, 2024
9ba10c6
Merge branch 'ArchipelagoMW:main' into main
gaithern Nov 5, 2024
b509f66
Add deathlink support
gaithern Nov 5, 2024
3c5580d
Merge branch 'ArchipelagoMW:main' into main
gaithern Nov 22, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 12 additions & 0 deletions KHRECOMClient.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
from __future__ import annotations

import ModuleUpdate
ModuleUpdate.update()

from worlds.khrecom.Client import check_stdin, launch
import Utils

if __name__ == "__main__":
Utils.init_logging("KHRECOMClient", exception_logger="Client")
check_stdin()
launch()
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,7 @@ Currently, the following games are supported:
* Old School Runescape
* Kingdom Hearts 1
* Mega Man 2
* Kingdom Hearts RE: Chain of Memories

For setup and instructions check out our [tutorials page](https://archipelago.gg/tutorial/).
Downloads can be found at [Releases](https://github.com/ArchipelagoMW/Archipelago/releases), including compiled
Expand Down
3 changes: 3 additions & 0 deletions docs/CODEOWNERS
Validating CODEOWNERS rules …
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,9 @@
# Kingdom Hearts
/worlds/kh1/ @gaithern

# Kingdom Hearts RE: Chain of Memories
/worlds/khrecom/ @gaithern

# Kingdom Hearts 2
/worlds/kh2/ @JaredWeakStrike

Expand Down
187 changes: 187 additions & 0 deletions worlds/khrecom/Client.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,187 @@
from __future__ import annotations
import os
import sys
import asyncio
import shutil
import logging

import ModuleUpdate
ModuleUpdate.update()

import Utils

item_num = 1

logger = logging.getLogger("Client")

if __name__ == "__main__":
Utils.init_logging("KHRECOMClient", exception_logger="Client")

from NetUtils import NetworkItem, ClientStatus
from CommonClient import gui_enabled, logger, get_base_parser, ClientCommandProcessor, \
CommonContext, server_loop


def check_stdin() -> None:
if Utils.is_windows and sys.stdin:
print("WARNING: Console input is not routed reliably on Windows, use the GUI instead.")

class KHRECOMClientCommandProcessor(ClientCommandProcessor):
pass


class KHRECOMContext(CommonContext):
command_processor: int = KHRECOMClientCommandProcessor
game = "Kingdom Hearts RE Chain of Memories"
items_handling = 0b111 # full remote

def __init__(self, server_address, password):
super(KHRECOMContext, self).__init__(server_address, password)
self.send_index: int = 0
self.syncing = False
self.awaiting_bridge = False
# self.game_communication_path: files go in this path to pass data between us and the actual game
if "localappdata" in os.environ:
self.game_communication_path = os.path.expandvars(r"%localappdata%/KHRECOM")
else:
self.game_communication_path = os.path.expandvars(r"$HOME/KHRECOM")
if not os.path.exists(self.game_communication_path):
os.makedirs(self.game_communication_path)
for root, dirs, files in os.walk(self.game_communication_path):
for file in files:
if file.find("obtain") <= -1:
os.remove(root+"/"+file)

async def server_auth(self, password_requested: bool = False):
if password_requested and not self.password:
await super(KHRECOMContext, self).server_auth(password_requested)
await self.get_username()
await self.send_connect()

async def connection_closed(self):
await super(KHRECOMContext, self).connection_closed()
for root, dirs, files in os.walk(self.game_communication_path):
for file in files:
if file.find("obtain") <= -1:
os.remove(root + "/" + file)
global item_num
item_num = 1

@property
def endpoints(self):
if self.server:
return [self.server]
else:
return []

async def shutdown(self):
await super(KHRECOMContext, self).shutdown()
for root, dirs, files in os.walk(self.game_communication_path):
for file in files:
if file.find("obtain") <= -1:
os.remove(root+"/"+file)
global item_num
item_num = 1

def on_package(self, cmd: str, args: dict):
if cmd in {"Connected"}:
if not os.path.exists(self.game_communication_path):
os.makedirs(self.game_communication_path)
for ss in self.checked_locations:
filename = f"send{ss}"
with open(os.path.join(self.game_communication_path, filename), 'w') as f:
f.close()
for key in list(args['slot_data'].keys()):
with open(os.path.join(self.game_communication_path, key + ".cfg"), 'w') as f:
f.write(str(args['slot_data'][key]))
f.close()
if cmd in {"ReceivedItems"}:
start_index = args["index"]
if start_index != len(self.items_received):
global item_num
for item in args['items']:
found = False
item_filename = f"AP_{str(item_num)}.item"
for filename in os.listdir(self.game_communication_path):
if filename == item_filename:
found = True
if not found:
with open(os.path.join(self.game_communication_path, item_filename), 'w') as f:
f.write(str(NetworkItem(*item).item) + "\n" + str(NetworkItem(*item).location) + "\n" + str(NetworkItem(*item).player))
f.close()
item_num = item_num + 1

if cmd in {"RoomUpdate"}:
if "checked_locations" in args:
for ss in self.checked_locations:
filename = f"send{ss}"
with open(os.path.join(self.game_communication_path, filename), 'w') as f:
f.close()

def run_gui(self):
"""Import kivy UI system and start running it as self.ui_task."""
from kvui import GameManager

class KHRECOMManager(GameManager):
logging_pairs = [
("Client", "Archipelago")
]
base_title = "Archipelago KHRECOM Client"

self.ui = KHRECOMManager(self)
self.ui_task = asyncio.create_task(self.ui.async_run(), name="UI")


async def game_watcher(ctx: KHRECOMContext):
from .Locations import lookup_id_to_name
while not ctx.exit_event.is_set():
if ctx.syncing == True:
gaithern marked this conversation as resolved.
Show resolved Hide resolved
sync_msg = [{'cmd': 'Sync'}]
if ctx.locations_checked:
sync_msg.append({"cmd": "LocationChecks", "locations": list(ctx.locations_checked)})
await ctx.send_msgs(sync_msg)
ctx.syncing = False
sending = []
victory = False
for root, dirs, files in os.walk(ctx.game_communication_path):
for file in files:
if file.find("send") > -1:
st = file.split("send", -1)[1]
if st != "nil":
sending = sending+[(int(st))]
if file.find("victory") > -1:
victory = True
ctx.locations_checked = sending
message = [{"cmd": 'LocationChecks', "locations": sending}]
await ctx.send_msgs(message)
if not ctx.finished_game and victory:
await ctx.send_msgs([{"cmd": "StatusUpdate", "status": ClientStatus.CLIENT_GOAL}])
ctx.finished_game = True
await asyncio.sleep(0.1)


def launch():
async def main(args):
ctx = KHRECOMContext(args.connect, args.password)
ctx.server_task = asyncio.create_task(server_loop(ctx), name="server loop")
if gui_enabled:
ctx.run_gui()
ctx.run_cli()
progression_watcher = asyncio.create_task(
game_watcher(ctx), name="KHRECOMProgressionWatcher")

await ctx.exit_event.wait()
ctx.server_address = None

await progression_watcher

await ctx.shutdown()

import colorama

parser = get_base_parser(description="KHRECOM Client, for text interfacing.")

args, rest = parser.parse_known_args()
colorama.init()
asyncio.run(main(args))
colorama.deinit()
Loading
Loading