1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
|
import curses
from asciifarm.common.utils import clamp
from .window import Window
import signal
class Screen:
def __init__(self, display, stdscr, colours):
self.display = display
try:
curses.curs_set(0)
self.cursorSet = False
except curses.error:
# Not all terminals support this functionality.
# When the error is ignored the screen will look a little uglier,
# A cursor will move around, but that's not terrible
# So in order to keep the game as accesible as possible to everyone, it should be safe to ignore the error.
self.cursorSet = True
# It is probably possible to make sure the cursor is only in a corner of the screen
# but I can't figure out how.
# it seems to ignore all my move commands unless I press a key
# I give up
self.stdscr = stdscr
self.colours = colours
self.setWins()
signal.signal(signal.SIGWINCH, self.updateSize)
def _limitHeight(self, h, y):
return min(h + y, self.height) - y
def setWins(self):
height, width = self.height, self.width = self.stdscr.getmaxyx()
sideW = 20
sideX = width-sideW
msgH = clamp(height // 5, 3, 5)
msgY = height - msgH-1
inputH = 1
inputY = msgY + msgH
healthY = 0
healthH = self._limitHeight(2, healthY)
groundY = healthY + healthH
groundH = self._limitHeight(6, groundY)
invY = groundY + groundH
invH = self._limitHeight(9, invY)
eqY = invY + invH
eqH = self._limitHeight(5, eqY)
infoY = eqY + eqH
infoH = self._limitHeight(20, infoY)
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, invH),
"inventory": self.makeWin(sideX, groundY, sideW, invH),
"equipment": self.makeWin(sideX, eqY, sideW, eqH),
"info": self.makeWin(sideX, infoY, sideW, infoH)
}
def makeWin(self, x, y, width, height):
if width < 1 or height < 1:
win = None
else:
win = curses.newwin(height, width, y, x)
return Window(win, self.colours)
def getWin(self, name):
return self.windows.get(name, None)
def updateSize(self, *args):
curses.endwin()
curses.initscr()
self.setWins()
self.stdscr.clear()
self.display.forceUpdate()
def update(self):
curses.doupdate()
def getWidth(self):
return self.width
def getHeight(self):
return self.height
|