player.py 2.05 KB
Newer Older
1
from util import *
Ralf's avatar
Ralf committed
2
3
from thing import Thing
from labyrinth import directions as directionOffsets
4

Ralf's avatar
Ralf committed
5
6
7
8
goVerbs = ['go', 'walk']
sayVerbs = ['say', 'talk', 'scream']

class Player(Thing):
Ralf's avatar
Ralf committed
9
	def __init__(self, game, conn):
Ralf's avatar
Ralf committed
10
		super().__init__(self)
Ralf's avatar
Ralf committed
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
		self.buffer = b""
		self.game = game
		self.conn = conn
	
	# low-level functions
	def send(self, data):
		assert type(data) == str
		send_async(self.conn, (data+"\n").encode('utf-8'))
	
	def close(self): # only to be called by Game - it has to remove us from its list
		self.conn.close()
	
	def read(self, conn, mask):
		assert self.conn == conn, "The player's connection changed?"
		data = conn.recv(1024)  # Should be ready
		if data:
			self.buffer += data
			pos = self.buffer.find(b'\n')
Ralf's avatar
Ralf committed
29
			while pos >= 0:
Ralf's avatar
Ralf committed
30
31
32
				cmd = self.buffer[:pos]
				self.buffer = self.buffer[pos+1:]
				self.readCmd(cmd.decode('utf-8'))
Ralf's avatar
Ralf committed
33
34
				# maybe we got several lines?
				pos = self.buffer.find(b'\n')
Ralf's avatar
Ralf committed
35
36
37
		else:
			self.game.removePlayer(self)
	
Ralf's avatar
Ralf committed
38
	def __str__(self):
Constantin's avatar
Constantin committed
39
40
		return "another player"
	
Ralf's avatar
Ralf committed
41
42
	# high(er)-level functions
	def readCmd(self, cmd):
Ralf's avatar
Ralf committed
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
		words = cmd.lower().split()
		if not words:
			self.send("What did you mean?")
			return
		verb = words[0]
		if verb in goVerbs:
			if len(words) >= 3 and words[1:3] == ["to", "the"]:
				direction = words[3:]
			else:
				direction = words[1:]
			if len(direction) != 1 or direction[0] not in directionOffsets:
				self.send("Where do you want to go?")
				return
			dy, dx = directionOffsets.get(direction[0])
			target = self.field.neighbor(dy=dy, dx=dx)
			if target is None or not target.isWalkable():
				self.send("Sorry, you cannot go there")
				return
			self.game.labyrinth.moveThing(self, target)
			return
		elif verb in sayVerbs:
			msg = " ".join(words[1:])
			for dx, dy in [(0, 0)]+directionOffsets.values():
				for thing in self.field.neighbor(dx=dx, dy=dy):
					if isinstance(thing, Player) and thing != self:
						thing.send("You hear someone saying: "+msg)
			self.send("You say: "+msg)
	
	def onMove(self, newField):
		desc = self.game.labyrinth.getDescription(newField)
		self.send(desc)
		return True