git.fiddlerwoaroof.com
Browse code

added terrain

edwlan authored on 26/07/2013 18:32:05
Showing 2 changed files
... ...
@@ -11,7 +11,9 @@ from src import map
11 11
 class Application(object):
12 12
 	def __init__(self):
13 13
 		self.screen = console.Screen(200,125)
14
-		self.map = map.Map(200,125)
14
+		self.terrain_registry = map.TerrainRegistry()
15
+		self.terrain_registry.load_from_file('data/terrain.yml')
16
+		self.map = map.Map(200,125, self.terrain_registry)
15 17
 		self.player = player.Player(4,5, self.map)
16 18
 		self.events = events.EventHandler()
17 19
 		player.ArrowHandler(self.player, self.events)
... ...
@@ -1,22 +1,45 @@
1 1
 import numpy as np
2 2
 import libtcodpy as tc
3
+import yaml
3 4
 
4 5
 def squeeze(val, low, high):
5 6
 	return min(max(val, low), high)
6 7
 
8
+class TerrainGen(object):
9
+	def __init__(self, map):
10
+		self.width, self.height = map.dim
11
+		self.terrain_registry = map.terrain_registry
12
+
13
+	def generate(self):
14
+		w,h = self.width, self.height
15
+		map = np.random.choice(self.terrain_registry.get_terrain_types(), (w,h))
16
+		print self.terrain_registry.get_terrain_types()
17
+		print map[map>4]
18
+		chars = np.zeros((w,h)).astype('int')
19
+		fgcolors = np.zeros((w,h,3))
20
+		bgcolors = np.zeros((w,h,3))
21
+
22
+		for x, row in enumerate(map):
23
+			for y, cell in enumerate(row):
24
+				char, bgcolor, fgcolor = self.terrain_registry.get_display(cell)
25
+				chars[x,y] = char
26
+				fgcolors[x,y] = fgcolor
27
+				bgcolors[x,y] = bgcolor
28
+		return map, chars, fgcolors, bgcolors
29
+
30
+
7 31
 class Map(object):
8
-	def __init__(self, w, h):
32
+	def __init__(self, w, h, terrain_registry):
33
+		self.pov = None
9 34
 		self.width = w
10 35
 		self.height = h
11
-		self.map = np.random.random_integers(ord('a'), ord('z'), (w,h) )
12
-		self.map[3,5] = ord('*')
13
-		self.map[::10, ::10] = ord('#')
14
-		self.fgcolors = np.random.random_integers(100,255, (w,h,3) )
15
-		self.fgcolors[::10,::10] = (0,0,0)
16
-		self.bgcolors = np.random.random_integers(0,100, (w,h,3) )
17
-		self.bgcolors[::10,::10] = (255,255,255)
36
+		self.terrain_registry = terrain_registry
18 37
 		self.overlays = {} # (x,y): { set( object, ... ) }
19 38
 
39
+		self.ids, self.map, self.fgcolors, self.bgcolors = TerrainGen(self).generate()
40
+
41
+		self.fov = FovCache(self, self.terrain_registry)
42
+
20 43
 	def add(self, object):
21 44
 		self.overlays.setdefault(object.pos,[]).append(object)
22 45
 
... ...
@@ -59,3 +82,102 @@ class Map(object):
59 82
 				tc.console_set_char_foreground(con.con, screen_x,screen_y, tc.black)
60 83
 				tc.console_set_char_background(con.con, screen_x,screen_y, tc.white)
61 84
 		tc.console_fill_char(con.con, chars.transpose())
85
+
86
+	def coord_iter(self):
87
+		return ( (x,y) for x in range(self.width) for y in range(self.height) )
88
+
89
+	@property
90
+	def dim(self):
91
+		return self.width, self.height
92
+
93
+
94
+class FovCache(object):
95
+	# TODO: get allow updates to base_map
96
+	def __init__(self, map, terrain_registry):
97
+		self.base_map = tc.map_new(*map.dim)
98
+
99
+		for x,y in map.coord_iter():
100
+			if (x,y) in map.overlays:
101
+				object = map.overlays[x,y]
102
+				pssble,trnsprnt = object.passable, object.transparent
103
+			else:
104
+				pssble,trnsprnt = terrain_registry.get_props(map.ids[x,y])
105
+			tc.map_set_properties(self.base_map, x,y, trnsprnt,pssble)
106
+
107
+		self.fovmaps = {}
108
+
109
+	def get_fovmap(self, terrain_registry, origin, radius):
110
+		key = origin,radius
111
+
112
+		if key in self.fovmaps: fovmap = self.fovmaps[key]
113
+		else:
114
+			fovmap = tc.map_new(self.width, self.height)
115
+			tc.map_copy(self.base_map, fovmap)
116
+			self.fovmaps[key] = fovmap
117
+
118
+			x,y = origin
119
+			tc.map_compute_fov(fovmap, x,y, radius)
120
+
121
+		return fovmap
122
+
123
+	def is_transparent(self, coord):
124
+		return tc.map_is_transparent(self.base_map, *coord)
125
+	def is_passable(self, coord):
126
+		return tc.map_is_walkable(self.base_map, *coord)
127
+
128
+
129
+class TerrainInfo(object):
130
+	passable = False
131
+	transparent = False
132
+	char = ord(' ')
133
+	fg = (255,255,255)
134
+	bg = (0,0,0)
135
+
136
+	@classmethod
137
+	def make_terrain(cls, name, char, passable, transparent,fg,bg):
138
+		if hasattr(char, 'upper'): char = ord(char)
139
+		passable = bool(passable)
140
+		transparent = bool(transparent)
141
+		return type(name, (cls,), dict(char=char, passable=passable, transparent=transparent,fg=fg,bg=bg))
142
+
143
+class TerrainRegistry(object):
144
+	def __init__(self):
145
+		self.id = 0
146
+		self.registry = {}
147
+		self.names = {}
148
+
149
+	def get_terrain(self, id):
150
+		ter = self.registry[id]
151
+		return ter
152
+
153
+	def get_props(self, id):
154
+		ter = self.get_terrain(id)
155
+		return ter.passable, ter.transparent
156
+
157
+	def get_display(self, char):
158
+		ter = self.get_terrain(char)
159
+		return ter.char, ter.fg, ter.bg
160
+
161
+	def get_terrain_types(self):
162
+		return list(self.registry)
163
+
164
+
165
+	def register(self, ter):
166
+		self.id += 1
167
+		self.registry[self.id] = ter
168
+		self.names[ter.__name__] = ter
169
+		return ter
170
+
171
+	def new_terrain(self, name, char,
172
+		passable=False, transparent=False, fg=(255,255,255), bg=(0,0,0)
173
+	):
174
+		ter = TerrainInfo.make_terrain(name, char, passable, transparent, fg,bg)
175
+		return self.register(ter)
176
+
177
+	def load_from_file(self, fn, loader=yaml.safe_load):
178
+		with open(fn) as f:
179
+			values = loader(f)
180
+		for name, terrain in values.viewitems():
181
+			self.new_terrain(name, **terrain)
182
+
183
+