diff options
| author | troido <troido@hotmail.com> | 2017-12-28 22:47:36 +0100 |
|---|---|---|
| committer | troido <troido@hotmail.com> | 2017-12-28 22:47:36 +0100 |
| commit | 8c8c410f0eb7b6995c6e8db613228d91191f4e23 (patch) | |
| tree | 8a0ff8bf95e20963a40332bc5fb2588fd9eb6ba6 | |
| parent | d983e275f3f4ba156e33d00e5deaa2f730695cae (diff) | |
chat now works!
| -rw-r--r-- | asciifarm/client/display/__init__.py | 91 | ||||
| -rw-r--r-- | asciifarm/client/display/display.py | 121 | ||||
| -rw-r--r-- | asciifarm/client/display/fieldpad.py | 10 | ||||
| -rw-r--r-- | asciifarm/client/display/healthpad.py | 9 | ||||
| -rw-r--r-- | asciifarm/client/display/infopad.py | 9 | ||||
| -rw-r--r-- | asciifarm/client/display/inventorypad.py | 9 | ||||
| -rw-r--r-- | asciifarm/client/display/messagepad.py | 9 | ||||
| -rw-r--r-- | asciifarm/client/display/screen.py | 21 | ||||
| -rw-r--r-- | asciifarm/client/display/textinput.py | 29 | ||||
| -rw-r--r-- | asciifarm/client/display/window.py | 40 | ||||
| -rw-r--r-- | asciifarm/client/gameclient.py | 43 | ||||
| -rw-r--r-- | asciifarm/client/start.py | 2 | ||||
| -rw-r--r-- | asciifarm/keybindings/default.json | 6 |
13 files changed, 273 insertions, 126 deletions
diff --git a/asciifarm/client/display/__init__.py b/asciifarm/client/display/__init__.py index d806889..e69de29 100644 --- a/asciifarm/client/display/__init__.py +++ b/asciifarm/client/display/__init__.py @@ -1,91 +0,0 @@ - - -import curses -from .fieldpad import FieldPad -from .infopad import InfoPad -from .healthpad import HealthPad -from .inventorypad import InventoryPad -from .screen import Screen -from .colours import Colours -from .messagepad import MessagePad - - -SIDEWIDTH = 20 - - -class Display: - - def __init__(self, stdscr, charMap, colours=False): - - if colours: - self.colours = Colours() - else: - self.colours = None - self.screen = Screen(self, stdscr) - self.fieldPad = FieldPad((1, 1), charMap.get("charwidth", 1), self.colours) - self.characters = charMap["mapping"] - self.defaultChar = charMap.get("default", "?") - self.infoPad = InfoPad() - self.healthPad = HealthPad( - charMap.get("healthfull", ("@",7, 2)), - charMap.get("healthempty", ("-",7, 1)), - self.colours) - self.inventoryPad = InventoryPad("Inventory") - self.groundPad = InventoryPad("Ground") - self.lastinfostring = None - self.changed = False - self.messagePad = messagepad.MessagePad() - - self.screen.update(True) - - - def resizeField(self, size): - self.fieldPad.resize(*size) - - def drawFieldCells(self, cells): - for cell in cells: - (x, y), spriteName = cell - sprite = self.getChar(spriteName) - self.fieldPad.changeCell(x, y, *sprite) - self.change() - - def setFieldCenter(self, pos): - self.fieldPad.setCenter(pos) - - def setHealth(self, health, maxHealth): - self.healthPad.setHealth(health, maxHealth) - self.change() - - def showInfo(self, infostring): - if infostring != self.lastinfostring: - self.infoPad.showString(infostring) - self.change() - self.lastinfostring = infostring - - def setInventory(self, items): - self.inventoryPad.setInventory(items) - self.change() - - def setGround(self, items): - self.groundPad.setInventory(items) - self.change() - - def addMessage(self, message): - self.messagePad.addMessage(message) - self.change() - - def getChar(self, sprite): - char = self.characters.get(sprite, self.defaultChar) - if isinstance(char, str): - return [char] - return char - - def change(self): - self.changed = True - - def update(self): - if self.changed: - self.screen.update() - - self.changed = False - diff --git a/asciifarm/client/display/display.py b/asciifarm/client/display/display.py new file mode 100644 index 0000000..a3dbb2e --- /dev/null +++ b/asciifarm/client/display/display.py @@ -0,0 +1,121 @@ + + +import curses +from .fieldpad import FieldPad +from .infopad import InfoPad +from .healthpad import HealthPad +from .inventorypad import InventoryPad +from .screen import Screen +from .colours import Colours +from .messagepad import MessagePad +from .textinput import TextInput + + +SIDEWIDTH = 20 + + +class Display: + + def __init__(self, stdscr, charMap, colours=False): + + if colours: + self.colours = Colours() + else: + self.colours = None + self.characters = charMap["mapping"] + self.defaultChar = charMap.get("default", "?") + self.screen = Screen(self, stdscr) + + def setwin(pad, winname): + pad.setWin(self.screen.getWin(winname)) + + self.fieldPad = FieldPad((1, 1), charMap.get("charwidth", 1), self.colours) + setwin(self.fieldPad, "field") + self.infoPad = InfoPad() + setwin(self.infoPad, "info") + self.healthPad = HealthPad( + charMap.get("healthfull", ("@",7, 2)), + charMap.get("healthempty", ("-",7, 1)), + self.colours) + setwin(self.healthPad, "health") + self.inventoryPad = InventoryPad("Inventory") + setwin(self.inventoryPad, "inventory") + self.groundPad = InventoryPad("Ground") + setwin(self.groundPad, "ground") + self.messagePad = MessagePad() + setwin(self.messagePad, "msg") + self.textInput = TextInput() + setwin(self.textInput, "textinput") + + self.lastinfostring = None + self.changed = False + + self.update(True) + + + def resizeField(self, size): + self.fieldPad.resize(*size) + + def drawFieldCells(self, cells): + for cell in cells: + (x, y), spriteName = cell + sprite = self.getChar(spriteName) + self.fieldPad.changeCell(x, y, *sprite) + self.change() + + def setFieldCenter(self, pos): + self.fieldPad.setCenter(pos) + + def setHealth(self, health, maxHealth): + self.healthPad.setHealth(health, maxHealth) + self.change() + + def showInfo(self, infostring): + if infostring != self.lastinfostring: + self.infoPad.showString(infostring) + self.change() + self.lastinfostring = infostring + + def setInventory(self, items): + self.inventoryPad.setInventory(items) + self.change() + + def setGround(self, items): + self.groundPad.setInventory(items) + self.change() + + def addMessage(self, message): + self.messagePad.addMessage(message) + self.change() + + def getChar(self, sprite): + """This returns the character belonging to some spritename. This does not read a character""" + char = self.characters.get(sprite, self.defaultChar) + if isinstance(char, str): + return [char] + return char + + def getString(self): + """This does actually read input""" + return self.textInput.getString() + + def change(self): + self.changed = True + + def update(self, force=False): + if not self.changed and not force: + return + + self.fieldPad.update(force) + self.messagePad.update(force) + self.healthPad.update(force) + self.groundPad.update(force) + self.inventoryPad.update(force) + self.infoPad.update(force) + + self.textInput.update(force) + + self.screen.update() + + self.changed = False + diff --git a/asciifarm/client/display/fieldpad.py b/asciifarm/client/display/fieldpad.py index 4445aba..cb20285 100644 --- a/asciifarm/client/display/fieldpad.py +++ b/asciifarm/client/display/fieldpad.py @@ -5,7 +5,6 @@ import curses class FieldPad: - def __init__(self, size=(1,1), charSize=1, colours=False): self.pad = curses.newpad(size[1]+1, (size[0]+1)*charSize) self.size = size @@ -13,6 +12,10 @@ class FieldPad: self.center = (0, 0) self.colours = colours self.changed = False + self.win = None + + def setWin(self, win): + self.win = win def resize(self, width, height): self.size = (width, height) @@ -37,9 +40,10 @@ class FieldPad: def _roundWidth(self, x): return x // self.charSize * self.charSize - def update(self, win, force): - if not self.changed and not force or not win: + def update(self, force): + if not self.changed and not force or not self.win: return + win = self.win height, width = win.getmaxyx() y, x = win.getparyx() xmax = x + width diff --git a/asciifarm/client/display/healthpad.py b/asciifarm/client/display/healthpad.py index f5a9cc4..968ed1c 100644 --- a/asciifarm/client/display/healthpad.py +++ b/asciifarm/client/display/healthpad.py @@ -10,6 +10,10 @@ class HealthPad: self.colours = colours self.health = 0 self.maxHealth = 0 + self.win = None + + def setWin(self, win): + self.win = win def setHealth(self, health, maxHealth): self.health = health @@ -17,9 +21,10 @@ class HealthPad: self.changed = True - def update(self, win, force): - if not self.changed and not force or not win: + def update(self, force): + if not self.changed and not force or not self.win: return + win = self.win self.changed = False height, width = win.getmaxyx() width -= 1 diff --git a/asciifarm/client/display/infopad.py b/asciifarm/client/display/infopad.py index c98b7cd..b630013 100644 --- a/asciifarm/client/display/infopad.py +++ b/asciifarm/client/display/infopad.py @@ -10,14 +10,19 @@ class InfoPad: def __init__(self): self.changed = False self.lines = [] + self.win = None + + def setWin(self, win): + self.win = win def showString(self, string): self.lines = string.split('\n') self.changed = True - def update(self, win, force): - if not self.changed and not force or not win: + def update(self, force): + if not self.changed and not force or not self.win: return + win = self.win height, width = win.getmaxyx() lines = [line[:width-1] for line in self.lines][:height] text = '\n'.join(lines) diff --git a/asciifarm/client/display/inventorypad.py b/asciifarm/client/display/inventorypad.py index 6f12127..0cb0b01 100644 --- a/asciifarm/client/display/inventorypad.py +++ b/asciifarm/client/display/inventorypad.py @@ -7,6 +7,10 @@ class InventoryPad: self.title = title self.setInventory([]) self.changed = False + self.win = None + + def setWin(self, win): + self.win = win def setInventory(self, items): self.items = items @@ -15,9 +19,10 @@ class InventoryPad: def getHeight(self): return self.maxItems+2 - def update(self, win, force): - if not self.changed and not force or not win: + def update(self, force): + if not self.changed and not force or not self.win: return + win = self.win self.changed = False height, width = win.getmaxyx() win.erase() diff --git a/asciifarm/client/display/messagepad.py b/asciifarm/client/display/messagepad.py index 095e53a..d5de5a9 100644 --- a/asciifarm/client/display/messagepad.py +++ b/asciifarm/client/display/messagepad.py @@ -7,14 +7,19 @@ class MessagePad(): def __init__(self): self.changed = False self.messages = [] + self.win = None + + def setWin(self, win): + self.win = win def addMessage(self, message): self.messages.append(message) self.changed = True - def update(self, win, force): - if not self.changed and not force or not win: + def update(self, force): + if not self.changed and not force or not self.win: return + win = self.win height, width = win.getmaxyx() if height < 1: return diff --git a/asciifarm/client/display/screen.py b/asciifarm/client/display/screen.py index 41b7e12..588310e 100644 --- a/asciifarm/client/display/screen.py +++ b/asciifarm/client/display/screen.py @@ -22,8 +22,10 @@ class Screen: sideW = 20 sideX = width-sideW - msgH = max(3, min(height // 5, 6)) - msgY = height - msgH + msgH = max(3, min(height // 5, 5)) + msgY = height - msgH-1 + inputH = 1 + inputY = msgY + msgH healthY = 0 healthH = self._limitHeight(2, healthY) groundY = healthY + healthH @@ -36,6 +38,7 @@ class Screen: self.windows = { "field": self.makeWin(0, 0, sideX - 1, msgY), "msg": self.makeWin(0, msgY, sideX - 1, msgH), + "textinput": self.makeWin(0, inputY, sideX - 1, inputH), "health": self.makeWin(sideX, healthY, sideW, healthH), "ground": self.makeWin(sideX, groundY, sideW, groundH), "inventory": self.makeWin(sideX, invY, sideW, invH), @@ -47,22 +50,18 @@ class Screen: return None return curses.newwin(height, width, y, x) + def getWin(self, name): + return self.windows[name] + def updateSize(self, *args): curses.endwin() curses.initscr() self.setWins() self.stdscr.clear() - self.update(True) + self.display.update(True) - def update(self, force=False): - d = self.display - d.fieldPad.update(self.windows["field"], force) - d.messagePad.update(self.windows["msg"], force) - d.healthPad.update(self.windows["health"], force) - d.groundPad.update(self.windows["ground"], force) - d.inventoryPad.update(self.windows["inventory"], force) - d.infoPad.update(self.windows["info"], force) + def update(self): curses.doupdate() diff --git a/asciifarm/client/display/textinput.py b/asciifarm/client/display/textinput.py new file mode 100644 index 0000000..ca5f4af --- /dev/null +++ b/asciifarm/client/display/textinput.py @@ -0,0 +1,29 @@ + +import curses + +class TextInput: + + def __init__(self): + self.reading = False + self.win = None + + def setWin(self, win): + self.win = win + + def getString(self): + if not self.win: + return None + self.reading = True + curses.echo() + curses.nocbreak() + self.win.addstr(0, 0, ">") + string = self.win.getstr(0,2) + curses.noecho() + curses.cbreak() + self.reading = False + self.win.erase() + self.win.noutrefresh() + return string + + def update(self, force=False): + pass diff --git a/asciifarm/client/display/window.py b/asciifarm/client/display/window.py new file mode 100644 index 0000000..bae7797 --- /dev/null +++ b/asciifarm/client/display/window.py @@ -0,0 +1,40 @@ + + + +class Window: + """ Small wrapper around curses windows """ + + def __init__(self, win, colours=False): + + self.setWin(win) + self.colours = colours + + + + def setWin(self, win): + self.win = win + + def getSize(self): + if not self.win: + return (0, 0) + height, width = self.win.getmaxyx() + return (width, height) + + def getPos(self): + if not self.win: + return (0, 0) + y, x = win.getparyx() + return (x, y) + + def addString(self, pos, string, colour=(0,0)): + x, y = pos + if self.colours: + self.win.addstr(y, x, string, self.colours.get(colour)) + else: + self.win.addstr(y, x, string) + + def erase(self): + self.win.erase() + + + diff --git a/asciifarm/client/gameclient.py b/asciifarm/client/gameclient.py index ca6d53a..b4cd259 100644 --- a/asciifarm/client/gameclient.py +++ b/asciifarm/client/gameclient.py @@ -10,7 +10,7 @@ import getpass import argparse from .display.screen import Screen import string -from .display import Display +from .display.display import Display class Client: @@ -24,20 +24,42 @@ class Client: self.logFile = logFile self.commands = {} - for key, commands in keybindings["input"].items(): - if isinstance(commands[0], str): - commands = [commands] - self.commands[key] = [["input", command] for command in commands] + if "input" in keybindings: + for key, commands in keybindings["input"].items(): + if isinstance(commands[0], str): + commands = [commands] + self.commands[key] = [("send", ["input", command]) for command in commands] + if "control" in keybindings: + for key, commands in keybindings["control"].items(): + if isinstance(commands[0], str): + commands = [commands] + self.commands[key] = commands - self.controlsString = "Controls:\n"+'\n'.join( - key + ": " + ', '.join(' '.join(action[1]) for action in actions) - for key, actions in self.commands.items() - if key in string.printable) + self.controlsString = """\ +Default Controls: + wasd or arrows: + Move around + e: Grab + q: Drop + E: Use + r: Interact + f: Attack + t: Chat""" self.display.showInfo(self.controlsString) + self.actions = { + "send": (lambda data: self.connection.send(json.dumps(data))), + "text": (lambda: self.readString()) + } + def readString(self): + text = self.display.getString() + string = str(text, "utf-8") + if string: + self.connection.send(json.dumps(["input", ["say", string]])) + def start(self): threading.Thread(target=self.listen, daemon=True).start() self.connection.send(json.dumps(["name", self.name])) @@ -117,7 +139,8 @@ class Client: except ValueError: continue if keyname in self.commands: - self.connection.send(json.dumps(self.commands[keyname])) + for command, *data in self.commands[keyname]: + self.actions[command](*data) diff --git a/asciifarm/client/start.py b/asciifarm/client/start.py index e9d3ce7..0a6cfa4 100644 --- a/asciifarm/client/start.py +++ b/asciifarm/client/start.py @@ -6,7 +6,7 @@ import getpass import sys from .connection import Connection from .gameclient import Client -from .display import Display +from .display.display import Display defaultAdresses = { "abstract": "asciifarm", diff --git a/asciifarm/keybindings/default.json b/asciifarm/keybindings/default.json index 9f1d02a..2af12bf 100644 --- a/asciifarm/keybindings/default.json +++ b/asciifarm/keybindings/default.json @@ -17,7 +17,9 @@ "KEY_UP": ["move", "north"], "KEY_DOWN": ["move", "south"], "KEY_RIGHT": ["move", "east"], - "KEY_LEFT": ["move", "west"], - "t": ["say", "hey everybody"] + "KEY_LEFT": ["move", "west"] + }, + "control": { + "t": ["text"] } } |
