Mercurial > traipse
comparison orpg/mapper/fog.py @ 0:4385a7d0efd1 grumpy-goblin
Deleted and repushed it with the 'grumpy-goblin' branch. I forgot a y
author | sirebral |
---|---|
date | Tue, 14 Jul 2009 16:41:58 -0500 |
parents | |
children | 211ac836b6a0 |
comparison
equal
deleted
inserted
replaced
-1:000000000000 | 0:4385a7d0efd1 |
---|---|
1 # Copyright (C) 2000-2001 The OpenRPG Project | |
2 # | |
3 # openrpg-dev@lists.sourceforge.net | |
4 # | |
5 # This program is free software; you can redistribute it and/or modify | |
6 # it under the terms of the GNU General Public License as published by | |
7 # the Free Software Foundation; either version 2 of the License, or | |
8 # (at your option) any later version. | |
9 # | |
10 # This program is distributed in the hope that it will be useful, | |
11 # but WITHOUT ANY WARRANTY; without even the implied warranty of | |
12 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
13 # GNU General Public License for more details. | |
14 # | |
15 # You should have received a copy of the GNU General Public License | |
16 # along with this program; if not, write to the Free Software | |
17 # Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | |
18 # -- | |
19 # | |
20 # File: mapper/fog.py | |
21 # Author: OpenRPG Team | |
22 # | |
23 # Description: Maintenance of data structures required for FoW | |
24 # | |
25 | |
26 import sys | |
27 from base import * | |
28 from random import Random | |
29 from region import * | |
30 from orpg.minidom import Element | |
31 import traceback | |
32 COURSE = 10 | |
33 | |
34 class FogArea: | |
35 def __init__(self, outline, log): | |
36 self.log = log | |
37 self.log.log("Enter FogArea", ORPG_DEBUG) | |
38 self.outline = outline | |
39 self.log.log("Exit FogArea", ORPG_DEBUG) | |
40 | |
41 def set_fog_props(self, str): | |
42 self.log.log("Enter FogArea->set_fog_props(self, str)", ORPG_DEBUG) | |
43 self.outline = str | |
44 self.log.log("Exit FogArea->set_fog_props(self, str)", ORPG_DEBUG) | |
45 | |
46 def points_to_elements(self, points=None): | |
47 self.log.log("Enter FogArea->points_to_elements(self, points)", ORPG_DEBUG) | |
48 result = [] | |
49 if points == None: | |
50 self.log.log("Exit FogArea->points_to_elements(self, points)", ORPG_DEBUG) | |
51 return result | |
52 for pairs in string.split( points, ';' ): | |
53 pair = string.split( pairs, ',' ) | |
54 p = Element( "point" ) | |
55 p.setAttribute( "x", pair[0] ) | |
56 p.setAttribute( "y", pair[1] ) | |
57 result.append( p ) | |
58 self.log.log("Exit FogArea->points_to_elements(self, points)", ORPG_DEBUG) | |
59 return result | |
60 | |
61 def toxml(self, action="update"): | |
62 self.log.log("Enter FogArea->toxml(self, " + action + ")", ORPG_DEBUG) | |
63 xml_str = "" | |
64 localOutline = self.outline | |
65 if localOutline != None and localOutline != "all" and localOutline != "none": | |
66 localOutline = "points" | |
67 elem = Element( "poly" ) | |
68 if action == "del": | |
69 elem.setAttribute( "action", action ) | |
70 elem.setAttribute( "outline", localOutline ) | |
71 if localOutline == 'points': | |
72 list = self.points_to_elements( self.outline ) | |
73 for p in list: | |
74 elem.appendChild( p ) | |
75 str = elem.toxml() | |
76 elem.unlink() | |
77 self.log.log(str, ORPG_DEBUG) | |
78 self.log.log("Exit FogArea->toxml(self, " + action + ")", ORPG_DEBUG) | |
79 return str | |
80 elem.setAttribute( "action", action ) | |
81 if localOutline != None: | |
82 elem.setAttribute( "outline", localOutline ) | |
83 if localOutline == 'points': | |
84 list = self.points_to_elements( self.outline ) | |
85 for p in list: | |
86 elem.appendChild( p ) | |
87 xml_str = elem.toxml() | |
88 elem.unlink() | |
89 self.log.log(xml_str, ORPG_DEBUG) | |
90 self.log.log("Exit FogArea->toxml(self, " + action + ")", ORPG_DEBUG) | |
91 return xml_str | |
92 | |
93 class fog_layer(layer_base): | |
94 def __init__(self, canvas): | |
95 self.canvas = canvas | |
96 self.log = self.canvas.log | |
97 self.log.log("Enter fog_layer", ORPG_DEBUG) | |
98 layer_base.__init__(self) | |
99 self.color = wx.Color(128,128,128) | |
100 if "__WXGTK__" not in wx.PlatformInfo: | |
101 self.color = wx.Color(128,128,128, 128) | |
102 self.fogregion = wx.Region() | |
103 self.fogregion.Clear() | |
104 self.fog_bmp = None | |
105 self.width = 0 | |
106 self.height = 0 | |
107 self.use_fog = False | |
108 self.last_role = "" | |
109 self.log.log("Exit fog_layer", ORPG_DEBUG) | |
110 | |
111 def clear(self): | |
112 self.log.log("Enter fog_layer->clear(self)", ORPG_DEBUG) | |
113 self.fogregion.Clear() | |
114 self.use_fog = True | |
115 self.del_area("all") | |
116 self.recompute_fog() | |
117 self.log.log("Exit fog_layer->clear(self)", ORPG_DEBUG) | |
118 | |
119 def remove_fog(self): | |
120 self.log.log("Enter fog_layer->remove_fog(self)", ORPG_DEBUG) | |
121 self.fogregion.Clear() | |
122 self.use_fog = False | |
123 self.del_area("all") | |
124 self.add_area("none") | |
125 self.fog_bmp = None | |
126 self.log.log("Exit fog_layer->remove_fog(self)", ORPG_DEBUG) | |
127 | |
128 def resize(self, size): | |
129 self.log.log("Enter fog_layer->resize(self, size)", ORPG_DEBUG) | |
130 try: | |
131 if self.width == size[0] and self.height == size[1]: | |
132 self.log.log("Exit fog_layer->resize(self, size)", ORPG_DEBUG) | |
133 return | |
134 self.recompute_fog() | |
135 except: | |
136 pass | |
137 self.log.log("Exit fog_layer->resize(self, size)", ORPG_DEBUG) | |
138 | |
139 def recompute_fog(self): | |
140 self.log.log("Enter fog_layer->recompute_fog(self)", ORPG_DEBUG) | |
141 if not self.use_fog: | |
142 self.log.log("Exit fog_layer->recompute_fog(self)", ORPG_DEBUG) | |
143 return | |
144 size = self.canvas.size | |
145 self.width = size[0]/COURSE+1 | |
146 self.height = size[1]/COURSE+1 | |
147 self.fog_bmp = wx.EmptyBitmap(self.width+2,self.height+2) | |
148 self.fill_fog() | |
149 self.log.log("Exit fog_layer->recompute_fog(self)", ORPG_DEBUG) | |
150 | |
151 def fill_fog(self): | |
152 self.log.log("Enter fog_layer->fill_fog(self)", ORPG_DEBUG) | |
153 if not self.use_fog: | |
154 self.log.log("Exit fog_layer->fill_fog(self)", ORPG_DEBUG) | |
155 return | |
156 if "__WXGTK__" in wx.PlatformInfo: | |
157 mdc = wx.MemoryDC() | |
158 mdc.SelectObject(self.fog_bmp) | |
159 mdc.SetPen(wx.TRANSPARENT_PEN) | |
160 if (self.canvas.frame.session.role == "GM"): | |
161 color = self.color | |
162 else: | |
163 color = wx.BLACK | |
164 self.last_role = self.canvas.frame.session.role | |
165 mdc.SetBrush(wx.Brush(color,wx.SOLID)) | |
166 mdc.DestroyClippingRegion() | |
167 mdc.DrawRectangle(0, 0, self.width+2, self.height+2) | |
168 mdc.SetBrush(wx.Brush(wx.WHITE, wx.SOLID)) | |
169 if self.fogregion.GetBox().GetWidth()>0: | |
170 mdc.SetClippingRegionAsRegion(self.fogregion) | |
171 mdc.DrawRectangle(0, 0, self.width+2, self.height+2) | |
172 mdc.SelectObject(wx.NullBitmap) | |
173 del mdc | |
174 self.log.log("Exit fog_layer->fill_fog(self)", ORPG_DEBUG) | |
175 | |
176 def layerDraw(self, dc, topleft, size): | |
177 self.log.log("Enter fog_layer->layerDraw(self, dc, topleft, size)", ORPG_DEBUG) | |
178 if self.fog_bmp == None or not self.fog_bmp.Ok() or not self.use_fog: | |
179 self.log.log("Exit fog_layer->layerDraw(self, dc, topleft, size)", ORPG_DEBUG) | |
180 return | |
181 if self.last_role != self.canvas.frame.session.role: | |
182 self.fill_fog() | |
183 if "__WXGTK__" not in wx.PlatformInfo: | |
184 gc = wx.GraphicsContext.Create(dc) | |
185 gc.SetBrush(wx.Brush(wx.BLACK)) | |
186 if (self.canvas.frame.session.role == "GM"): | |
187 gc.SetBrush(wx.Brush(self.color)) | |
188 rgn = wx.Region(0, 0, self.canvas.size[0]+2, self.canvas.size[1]+2) | |
189 if not self.fogregion.IsEmpty(): | |
190 rgn.SubtractRegion(self.fogregion) | |
191 gc.ClipRegion(rgn) | |
192 gc.DrawRectangle(0, 0, self.canvas.size[0]+2, self.canvas.size[1]+2) | |
193 else: | |
194 sc = dc.GetUserScale() | |
195 bmp = wx.EmptyBitmap(size[0],size[1]) | |
196 mdc = wx.MemoryDC() | |
197 mdc.BeginDrawing() | |
198 mdc.SelectObject(bmp) | |
199 mdc.SetPen(wx.TRANSPARENT_PEN) | |
200 mdc.SetBrush(wx.Brush(wx.WHITE, wx.SOLID)) | |
201 mdc.DrawRectangle(0,0,size[0],size[1]) | |
202 srct = [int(topleft[0]/(sc[0]*COURSE)), int(topleft[1]/(sc[1]*COURSE))] | |
203 srcsz = [int((int(size[0]/COURSE+1)*COURSE)/(sc[0]*COURSE))+2, int((int(size[1]/COURSE+1)*COURSE)/(sc[1]*COURSE))+2] | |
204 if (srct[0]+srcsz[0] > self.width): | |
205 srcsz[0] = self.width-srct[0] | |
206 if (srct[1]+srcsz[1] > self.height): | |
207 srcsz[1] = self.height-srct[1] | |
208 img = wx.ImageFromBitmap(self.fog_bmp).GetSubImage(wx.Rect(srct[0], srct[1], srcsz[0], srcsz[1])) | |
209 img.Rescale(srcsz[0]*COURSE*sc[0], srcsz[1]*COURSE*sc[1]) | |
210 fog = wx.BitmapFromImage(img) | |
211 mdc.SetDeviceOrigin(-topleft[0], -topleft[1]) | |
212 mdc.DrawBitmap(fog, srct[0]*COURSE*sc[0], srct[1]*COURSE*sc[1]) | |
213 mdc.SetDeviceOrigin(0,0) | |
214 mdc.SetUserScale(1,1) | |
215 mdc.EndDrawing() | |
216 dc.SetUserScale(1,1) | |
217 dc.Blit(topleft[0], topleft[1], size[0], size[1], mdc,0,0,wx.AND) | |
218 dc.SetUserScale(sc[0],sc[1]) | |
219 mdc.SelectObject(wx.NullBitmap) | |
220 del mdc | |
221 self.log.log("Exit fog_layer->layerDraw(self, dc, topleft, size)", ORPG_DEBUG) | |
222 | |
223 def createregn2(self, polyline, mode, show): | |
224 self.log.log("Enter fog_layer->createregn2(self, polyline, mode, show)", ORPG_DEBUG) | |
225 regn = self.scanConvert(polyline) | |
226 area = "" | |
227 for i in polyline: | |
228 if (area != ""): | |
229 area += ";" | |
230 area += str(i.X) + "," + str(i.Y) | |
231 if mode == 'new': | |
232 if self.fogregion.IsEmpty(): | |
233 self.fogregion = regn | |
234 else: | |
235 self.fogregion.UnionRegion(regn) | |
236 self.add_area(area, show) | |
237 else: | |
238 if not self.fogregion.IsEmpty(): | |
239 self.fogregion.SubtractRegion(regn) | |
240 else: | |
241 self.fogregion = wx.Region(0, 0, self.canvas.size[0]+2, self.canvas.size[1]+2) | |
242 self.fogregion.SubtractRegion(regn) | |
243 self.del_area(area, show) | |
244 self.log.log("Exit fog_layer->createregn2(self, polyline, mode, show)", ORPG_DEBUG) | |
245 | |
246 def createregn(self, polyline, mode, show="Yes"): | |
247 self.log.log("Enter fog_layer->createregn(self, polyline, mode, show)", ORPG_DEBUG) | |
248 if not self.use_fog and mode == 'del': | |
249 self.clear() | |
250 self.canvas.Refresh(False) | |
251 if self.use_fog: | |
252 self.createregn2(polyline, mode, show) | |
253 self.fill_fog() | |
254 self.log.log("Exit fog_layer->createregn(self, polyline, mode, show)", ORPG_DEBUG) | |
255 | |
256 def scanConvert(self, polypt): | |
257 self.log.log("Enter fog_layer->scanConvert(self, polypt)", ORPG_DEBUG) | |
258 regn = wx.Region() | |
259 regn.Clear() | |
260 list = IRegion().scan_Convert(polypt) | |
261 for i in list: | |
262 if regn.IsEmpty(): | |
263 if "__WXGTK__" not in wx.PlatformInfo: | |
264 regn = wx.Region(i.left*COURSE, i.y*COURSE, i.right*COURSE+1-i.left*COURSE, 1*COURSE) | |
265 else: | |
266 regn = wx.Region(i.left, i.y, i.right+1-i.left, 1) | |
267 else: | |
268 if "__WXGTK__" not in wx.PlatformInfo: | |
269 regn.Union(i.left*COURSE, i.y*COURSE, i.right*COURSE+1-i.left*COURSE, 1*COURSE) | |
270 else: | |
271 regn.Union(i.left, i.y, i.right+1-i.left, 1) | |
272 self.log.log("Exit fog_layer->scanConvert(self, polypt)", ORPG_DEBUG) | |
273 return regn | |
274 | |
275 def add_area(self, area="", show="Yes"): | |
276 self.log.log("Enter fog_layer->add_area(self, area, show)", ORPG_DEBUG) | |
277 poly = FogArea(area, self.log) | |
278 xml_str = "<map><fog>" | |
279 xml_str += poly.toxml("new") | |
280 xml_str += "</fog></map>" | |
281 if show == "Yes": | |
282 self.canvas.frame.session.send(xml_str) | |
283 self.log.log(xml_str, ORPG_DEBUG) | |
284 self.log.log("Exit fog_layer->add_area(self, area, show)", ORPG_DEBUG) | |
285 | |
286 def del_area(self, area="", show="Yes"): | |
287 self.log.log("Enter fog_layer->del_area(self, area, show)", ORPG_DEBUG) | |
288 poly = FogArea(area, self.log) | |
289 xml_str = "<map><fog>" | |
290 xml_str += poly.toxml("del") | |
291 xml_str += "</fog></map>" | |
292 if show == "Yes": | |
293 self.canvas.frame.session.send(xml_str) | |
294 self.log.log(xml_str, ORPG_DEBUG) | |
295 self.log.log("Exit fog_layer->del_area(self, area, show)", ORPG_DEBUG) | |
296 | |
297 def layerToXML(self, action="update"): | |
298 self.log.log("Enter fog_layer->layerToXML(self, " + action + ")", ORPG_DEBUG) | |
299 if not self.use_fog: | |
300 self.log.log("Exit fog_layer->layerToXML(self, " + action + ") return None", ORPG_DEBUG) | |
301 return "" | |
302 fog_string = "" | |
303 ri = wx.RegionIterator(self.fogregion) | |
304 if not (ri.HaveRects()): | |
305 fog_string = FogArea("all", self.log).toxml("del") | |
306 while ri.HaveRects(): | |
307 if "__WXGTK__" not in wx.PlatformInfo: | |
308 x1 = ri.GetX()/COURSE | |
309 x2 = x1+(ri.GetW()/COURSE)-1 | |
310 y1 = ri.GetY()/COURSE | |
311 y2 = y1+(ri.GetH()/COURSE)-1 | |
312 else: | |
313 x1 = ri.GetX() | |
314 x2 = x1+ri.GetW()-1 | |
315 y1 = ri.GetY() | |
316 y2 = y1+ri.GetH()-1 | |
317 poly = FogArea(str(x1) + "," + str(y1) + ";" + | |
318 str(x2) + "," + str(y1) + ";" + | |
319 str(x2) + "," + str(y2) + ";" + | |
320 str(x1) + "," + str(y2), self.log) | |
321 fog_string += poly.toxml(action) | |
322 ri.Next() | |
323 if fog_string: | |
324 s = "<fog" | |
325 s += ">" | |
326 s += fog_string | |
327 s += "</fog>" | |
328 self.log.log(s, ORPG_DEBUG) | |
329 self.log.log("Exit fog_layer->layerToXML(self, " + action + ")", ORPG_DEBUG) | |
330 return s | |
331 else: | |
332 self.log.log("Exit fog_layer->layerToXML(self, " + action + ") return None", ORPG_DEBUG) | |
333 return "" | |
334 | |
335 def layerTakeDOM(self, xml_dom): | |
336 self.log.log("Enter fog_layer->layerTakeDOM(self, xml_dom)", ORPG_DEBUG) | |
337 try: | |
338 if not self.use_fog: | |
339 self.use_fog = True | |
340 self.recompute_fog() | |
341 if xml_dom.hasAttribute('serial'): | |
342 self.serial_number = int(xml_dom.getAttribute('serial')) | |
343 children = xml_dom._get_childNodes() | |
344 for l in children: | |
345 action = l.getAttribute("action") | |
346 outline = l.getAttribute("outline") | |
347 if (outline == "all"): | |
348 polyline = [IPoint().make(0,0), IPoint().make(self.width-1, 0), | |
349 IPoint().make(self.width-1, self.height-1), | |
350 IPoint().make(0, self.height-1)] | |
351 elif (outline == "none"): | |
352 polyline = [] | |
353 self.use_fog = 0 | |
354 self.fog_bmp = None | |
355 else: | |
356 polyline = [] | |
357 lastx = None | |
358 lasty = None | |
359 list = l._get_childNodes() | |
360 for point in list: | |
361 x = point.getAttribute( "x" ) | |
362 y = point.getAttribute( "y" ) | |
363 if (x != lastx or y != lasty): | |
364 polyline.append(IPoint().make(int(x), int(y))) | |
365 lastx = x | |
366 lasty = y | |
367 if (len(polyline) > 1): | |
368 self.createregn2(polyline, action, "No") | |
369 self.fill_fog() | |
370 except: | |
371 self.log.log(traceback.format_exc(), ORPG_GENERAL) | |
372 self.log.log("Exit fog_layer->layerTakeDOM(self, xml_dom)", ORPG_DEBUG) |