diff options
| -rw-r--r-- | asciifarm/client/gameclient.py | 22 | ||||
| -rw-r--r-- | asciifarm/client/inputhandler.py | 92 | ||||
| -rw-r--r-- | asciifarm/client/inputhandling.hy | 48 | ||||
| -rw-r--r-- | asciifarm/client/keymacros.hy | 25 | ||||
| -rwxr-xr-x | asciifarm/client/main.py | 7 | ||||
| -rw-r--r-- | asciifarm/keybindings/keybindings.hy | 57 | ||||
| -rw-r--r-- | asciifarm/keybindings/keybindings.json | 46 |
7 files changed, 151 insertions, 146 deletions
diff --git a/asciifarm/client/gameclient.py b/asciifarm/client/gameclient.py index 9903533..69380db 100644 --- a/asciifarm/client/gameclient.py +++ b/asciifarm/client/gameclient.py @@ -12,8 +12,8 @@ from .display.screen import Screen import string from .display.display import Display -import hy -from .inputhandling import InputHandler +from .inputhandler import InputHandler +from .keynames import nameFromKey class Client: @@ -26,9 +26,9 @@ class Client: self.logFile = logFile self.inputHandler = InputHandler(self, self.display, self.connection) - self.inputHandler.readCommands(keybindings) + self.keybindings = keybindings["actions"] - self.controlsString = self.inputHandler.getDocs() + self.controlsString = keybindings.get("help", "") self.display.showInfo(self.controlsString) @@ -106,26 +106,22 @@ class Client: self.display.update() def log(self, text): + if not isinstance(text, str): + text = str(text) self.display.addMessage(text) if self.logFile: with(open(self.logFile, 'a')) as f: f.write(text+'\n') - def nameFromKey(self, keynum): # this probably belongs in inputhandler... - prenamed = { - 10: "KEY_ENTER" - } - if keynum in prenamed: - return prenamed[keynum] - return str(curses.keyname(keynum), "utf-8") - def command_loop(self): while self.keepalive: key = self.stdscr.getch() if key == 27: self.keepalive = False return - self.inputHandler.onKey(key) + keyName = nameFromKey(key) + if keyName in self.keybindings: + self.inputHandler.execute(self.keybindings[keyName]) diff --git a/asciifarm/client/inputhandler.py b/asciifarm/client/inputhandler.py new file mode 100644 index 0000000..79209bd --- /dev/null +++ b/asciifarm/client/inputhandler.py @@ -0,0 +1,92 @@ + +import shlex + +class InvalidCommandException(Exception): + pass + + +class InputHandler: + + def __init__(self, client, display, connection): + self.client = client + self.display = display + self.connection = connection + + self.commands = { + "send": self.send, + "input": self.input, + "move": self.move, + "say": self.say, + "chat": self.chat, + "log": self.log, + "do": self.do, + "runinput": self.runInput, + "select": self.select, + "inputwithselected": self.actWithSelected, + "eval": self.eval, + "exec": self.exec + } + + def execute(self, action): + if isinstance(action[0], str): + command = action[0] + if command in self.commands: + self.commands[command](*action[1:]) + else: + raise InvalidCommandException("Invalid command '{}'".format(command)) + else: + raise Exception("Command should be a string") + + + + def send(self, data): + self.client.send(data) + + def input(self, action): + self.send(["input", action]) + + def move(self, direction): + self.input(["move", direction]) + + def say(self, text): + self.input(["say", text]) + + def chat(self, text): + self.send(["chat", text]) + + def log(self, text): + self.client.log(text) + + def do(self, actions): + for action in actions: + self.execute(action) + + def runInput(self): + message = self.display.getString() + if message: + if message[0] == '/': + if message[1] == '/': + self.chat(message[1:]) + else: + try: + self.execute(shlex.split(message[1:])) + except InvalidCommandException as e: + self.log(", ".join(e.args)) + else: + self.chat(message) + + def select(self, widget, value, relative=False, modular=False): + self.display.getWidget(widget).select(value, relative, modular) + + def actWithSelected(self, action, widget): + self.input([action, self.display.getWidget(widget).getSelected()]) + + def eval(self, *texts): + text = " ".join(texts) + self.log(eval(text, {"self": self, "client": self.client, "connection": self.connection, "display": self.display})) + + def exec(self, *texts): + text = " ".join(texts) + exec(text, {"self": self, "client": self.client, "connection": self.connection, "display": self.display}) + + diff --git a/asciifarm/client/inputhandling.hy b/asciifarm/client/inputhandling.hy deleted file mode 100644 index 9c3e254..0000000 --- a/asciifarm/client/inputhandling.hy +++ /dev/null @@ -1,48 +0,0 @@ - -(require [asciifarm.client.keymacros [*]]) -(import [asciifarm.client.keynames [nameFromKey]]) - -(defclass InputHandler [] - - (defn --init-- [self client display connection] - (setv self.client client) - (setv self.display display) - (setv self.connection connection) - (setv self.commands None)) - - (defn readCommands [self commandsstring] (do - (setv self.commands - (dict-comp - (str key) - ( - (eval `(do - (require [asciifarm.client.keymacros [*]]) - (fn [handler] - (fn [] ~value)))) - self) - [[key value] (.items (read-str commandsstring))])) - ((.get self.commands "init" (fn []))))) - - (defn runCommand [self commandstring] - (try - (eval (read-str (+ "(" commandstring ")"))) - (except [e Exception] - (self.client.log (repr e))))) - - (defn parseMessage [self message] - (if message - (if (= (first message) "/") - (do - (setv msg (.join "" (drop 1 message))) - (if (= (first msg) "/") - (send ["chat" msg]) - (self.runCommand msg))) - (send ["chat" message])))) - - (defn getDocs [self] - (if (in "help" self.commands) ((get self.commands "help")) "")) - - (defn onKey [self key] (do - (setv keyname (nameFromKey key)) - (if (in keyname self.commands) ((get self.commands keyname))))) -) diff --git a/asciifarm/client/keymacros.hy b/asciifarm/client/keymacros.hy deleted file mode 100644 index 2de89e4..0000000 --- a/asciifarm/client/keymacros.hy +++ /dev/null @@ -1,25 +0,0 @@ - - -(defmacro send [data] - `(self.client.send ~data)) - -(defmacro inp [action] - `(send ["input" ~action])) - -(defmacro move [dir] - `(inp ["move" ~dir])) - -(defmacro say [text] - `(inp ["say" ~text])) - -(defmacro log [text] - `(self.client.log ~text)) - -(defmacro chat [text] - `(send ["chat" ~text])) - -(defmacro doall [actions] - `(for [action ~actions] (action))) - -(defmacro log [text] - `(self.client.log ~text)) diff --git a/asciifarm/client/main.py b/asciifarm/client/main.py index 1a4ac51..ece3c5a 100755 --- a/asciifarm/client/main.py +++ b/asciifarm/client/main.py @@ -15,7 +15,7 @@ charMapPath = os.path.join(farmsPath, "charmaps") keybindingsPath = os.path.join(farmsPath, "keybindings") standardCharFiles = [name[:-5] for name in os.listdir(charMapPath) if name[-5:] == ".json"] -standardKeyFiles = [name[:-3] for name in os.listdir(keybindingsPath) if name[-3:] == ".hy"] +standardKeyFiles = [name[:-5] for name in os.listdir(keybindingsPath) if name[-5:] == ".json"] defaultAdresses = { @@ -54,9 +54,10 @@ def main(argv=None): keyFile = args.keybindings if keyFile in standardKeyFiles: - keyFile = os.path.join(keybindingsPath, keyFile + ".hy") + keyFile = os.path.join(keybindingsPath, keyFile + ".json") with open(keyFile, 'r') as kf: - keybindings = kf.read() + # todo: support yaml + keybindings = json.load(kf) address = args.address if address is None: diff --git a/asciifarm/keybindings/keybindings.hy b/asciifarm/keybindings/keybindings.hy deleted file mode 100644 index 2919d1d..0000000 --- a/asciifarm/keybindings/keybindings.hy +++ /dev/null @@ -1,57 +0,0 @@ -{ -w (inp ["move" "north"]) -s (inp ["move" "south"]) -d (inp ["move" "east"]) -a (inp ["move" "west"]) -KEY_UP (inp ["move" "north"]) -KEY_DOWN (inp ["move" "south"]) -KEY_RIGHT (inp ["move" "east"]) -KEY_LEFT (inp ["move" "west"]) -k (inp ["move" "north"]) -j (inp ["move" "south"]) -l (inp ["move" "east"]) -h (inp ["move" "west"]) -e (inp ["take" (.getSelected (self.display.getWidget "ground"))]) -q (inp ["drop" (.getSelected (self.display.getWidget "inventory"))]) -E (inp ["use" (.getSelected (self.display.getWidget "inventory"))]) -R (inp ["interact"]) -r (do [ - (inp ["interact"]) - (inp ["interact" "north"]) - (inp ["interact" "south"]) - (inp ["interact" "east"]) - (inp ["interact" "west"])]) -c (.select (self.display.getWidget "inventory") 1 True True) -x (.select (self.display.getWidget "ground") 1 True True) -v (.select (self.display.getWidget "equipment") 1 True True) -z (inp ["unequip" (.getSelected (self.display.getWidget "equipment"))]) -f (do [ - (inp ["attack"]) - (inp ["attack" "north"]) - (inp ["attack" "south"]) - (inp ["attack" "east"]) - (inp ["attack" "west"])]) -F (inp ["attack"]) -W (inp ["attack" "north"]) -S (inp ["attack" "south"]) -D (inp ["attack" "east"]) -A (inp ["attack" "west"]) -t (self.parseMessage (self.display.getString)) -NEWLINE (self.parseMessage (self.display.getString)) -KEY_PPAGE (self.display.scrollBack 1) -KEY_NPAGE (self.display.scrollBack -1) -help "\ -Controls: - wasd or arrows: - Move around - e: Grab - q: Drop - E: Use/Equip - r: Interact - f: Attack - t: Chat - z: Unequip - xcv: scroll - ctrl-c: close client" -;; init ((. (self.display.getWidget "inventory") setTitle) "Inventory (c)") -} diff --git a/asciifarm/keybindings/keybindings.json b/asciifarm/keybindings/keybindings.json new file mode 100644 index 0000000..20759bd --- /dev/null +++ b/asciifarm/keybindings/keybindings.json @@ -0,0 +1,46 @@ +{ +"actions": { +"w": ["move", "north"], +"s": ["move", "south"], +"d": ["move", "east"], +"a": ["move", "west"], +"KEY_UP": ["move", "north"], +"KEY_DOWN": ["move", "south"], +"KEY_RIGHT": ["move", "east"], +"KEY_LEFT": ["move", "west"], +"k": ["move", "north"], +"j": ["move", "south"], +"l": ["move", "east"], +"h": ["move", "west"], +"e": ["inputwithselected", "take", "ground"], +"q": ["inputwithselected", "drop", "inventory"], +"E": ["inputwithselected", "use", "inventory"], +"z": ["inputwithselected", "unequip", "equipment"], +"R": ["input", ["interact"]], +"r": ["do", [ + ["input", ["interact"]], + ["input", ["interact", "north"]], + ["input", ["interact", "south"]], + ["input", ["interact", "east"]], + ["input", ["interact", "west"]]]], +"c": ["select", "inventory", 1, true, true], +"x": ["select", "ground", 1, true, true], +"v": ["select", "equipment", 1, true, true], +"f": ["do", [ + ["input", ["attack"]], + ["input", ["attack", "north"]], + ["input", ["attack", "south"]], + ["input", ["attack", "east"]], + ["input", ["attack", "west"]]]], +"F": ["input", ["attack"]], +"W": ["input", ["attack", "north"]], +"S": ["input", ["attack", "south"]], +"D": ["input", ["attack", "east"]], +"A": ["input", ["attack", "west"]], +"t": ["runinput"], +"NEWLINE": ["runinput"], +"KEY_PPAGE": "(self.display.scrollBack 1]", +"KEY_NPAGE": "(self.display.scrollBack -1]" +}, +"help": "Controls:\n wasd or arrows:\n Move around\n e: Grab\n q: Drop\n E: Use/Equip\n r: Interact\n f: Attack\n t: Chat\n z: Unequip\n xcv: scroll\n ctrl-c: close client" +} |
