Mercurial > traipse_dev
view orpg/mapper/fog.py @ 21:fdd70f11bc7e traipse_dev
One too many deletes last time. This run tested on Linux and working
author | sirebral |
---|---|
date | Sat, 25 Jul 2009 19:28:21 -0500 |
parents | 072ffc1d466f |
children | 449a8900f9ac |
line wrap: on
line source
# Copyright (C) 2000-2001 The OpenRPG Project # # openrpg-dev@lists.sourceforge.net # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. # -- # # File: mapper/fog.py # Author: OpenRPG Team # # Description: Maintenance of data structures required for FoW # import sys from base import * from random import Random from region import * from orpg.minidom import Element import traceback COURSE = 10 class FogArea: def __init__(self, outline, log): self.log = log self.log.log("Enter FogArea", ORPG_DEBUG) self.outline = outline self.log.log("Exit FogArea", ORPG_DEBUG) def set_fog_props(self, str): self.log.log("Enter FogArea->set_fog_props(self, str)", ORPG_DEBUG) self.outline = str self.log.log("Exit FogArea->set_fog_props(self, str)", ORPG_DEBUG) def points_to_elements(self, points=None): self.log.log("Enter FogArea->points_to_elements(self, points)", ORPG_DEBUG) result = [] if points == None: self.log.log("Exit FogArea->points_to_elements(self, points)", ORPG_DEBUG) return result for pairs in string.split( points, ';' ): pair = string.split( pairs, ',' ) p = Element( "point" ) p.setAttribute( "x", pair[0] ) p.setAttribute( "y", pair[1] ) result.append( p ) self.log.log("Exit FogArea->points_to_elements(self, points)", ORPG_DEBUG) return result def toxml(self, action="update"): self.log.log("Enter FogArea->toxml(self, " + action + ")", ORPG_DEBUG) xml_str = "" localOutline = self.outline if localOutline != None and localOutline != "all" and localOutline != "none": localOutline = "points" elem = Element( "poly" ) if action == "del": elem.setAttribute( "action", action ) elem.setAttribute( "outline", localOutline ) if localOutline == 'points': list = self.points_to_elements( self.outline ) for p in list: elem.appendChild( p ) str = elem.toxml() elem.unlink() self.log.log(str, ORPG_DEBUG) self.log.log("Exit FogArea->toxml(self, " + action + ")", ORPG_DEBUG) return str elem.setAttribute( "action", action ) if localOutline != None: elem.setAttribute( "outline", localOutline ) if localOutline == 'points': list = self.points_to_elements( self.outline ) for p in list: elem.appendChild( p ) xml_str = elem.toxml() elem.unlink() self.log.log(xml_str, ORPG_DEBUG) self.log.log("Exit FogArea->toxml(self, " + action + ")", ORPG_DEBUG) return xml_str class fog_layer(layer_base): def __init__(self, canvas): self.canvas = canvas self.log = self.canvas.log self.log.log("Enter fog_layer", ORPG_DEBUG) layer_base.__init__(self) self.color = wx.Color(128,128,128) if "__WXGTK__" not in wx.PlatformInfo: self.color = wx.Color(128,128,128, 128) self.fogregion = wx.Region() self.fogregion.Clear() self.fog_bmp = None self.width = 0 self.height = 0 self.use_fog = False self.last_role = "" self.log.log("Exit fog_layer", ORPG_DEBUG) def clear(self): self.log.log("Enter fog_layer->clear(self)", ORPG_DEBUG) self.fogregion.Clear() self.use_fog = True self.del_area("all") self.recompute_fog() self.log.log("Exit fog_layer->clear(self)", ORPG_DEBUG) def remove_fog(self): self.log.log("Enter fog_layer->remove_fog(self)", ORPG_DEBUG) self.fogregion.Clear() self.use_fog = False self.del_area("all") self.add_area("none") self.fog_bmp = None self.log.log("Exit fog_layer->remove_fog(self)", ORPG_DEBUG) def resize(self, size): self.log.log("Enter fog_layer->resize(self, size)", ORPG_DEBUG) try: if self.width == size[0] and self.height == size[1]: self.log.log("Exit fog_layer->resize(self, size)", ORPG_DEBUG) return self.recompute_fog() except: pass self.log.log("Exit fog_layer->resize(self, size)", ORPG_DEBUG) def recompute_fog(self): self.log.log("Enter fog_layer->recompute_fog(self)", ORPG_DEBUG) if not self.use_fog: self.log.log("Exit fog_layer->recompute_fog(self)", ORPG_DEBUG) return size = self.canvas.size self.width = size[0]/COURSE+1 self.height = size[1]/COURSE+1 self.fog_bmp = wx.EmptyBitmap(self.width+2,self.height+2) self.fill_fog() self.log.log("Exit fog_layer->recompute_fog(self)", ORPG_DEBUG) def fill_fog(self): self.log.log("Enter fog_layer->fill_fog(self)", ORPG_DEBUG) if not self.use_fog: self.log.log("Exit fog_layer->fill_fog(self)", ORPG_DEBUG) return if "__WXGTK__" in wx.PlatformInfo: mdc = wx.MemoryDC() mdc.SelectObject(self.fog_bmp) mdc.SetPen(wx.TRANSPARENT_PEN) if (self.canvas.frame.session.role == "GM"): color = self.color else: color = wx.BLACK self.last_role = self.canvas.frame.session.role mdc.SetBrush(wx.Brush(color,wx.SOLID)) mdc.DestroyClippingRegion() mdc.DrawRectangle(0, 0, self.width+2, self.height+2) mdc.SetBrush(wx.Brush(wx.WHITE, wx.SOLID)) if self.fogregion.GetBox().GetWidth()>0: mdc.SetClippingRegionAsRegion(self.fogregion) mdc.DrawRectangle(0, 0, self.width+2, self.height+2) mdc.SelectObject(wx.NullBitmap) del mdc self.log.log("Exit fog_layer->fill_fog(self)", ORPG_DEBUG) def layerDraw(self, dc, topleft, size): self.log.log("Enter fog_layer->layerDraw(self, dc, topleft, size)", ORPG_DEBUG) if self.fog_bmp == None or not self.fog_bmp.Ok() or not self.use_fog: self.log.log("Exit fog_layer->layerDraw(self, dc, topleft, size)", ORPG_DEBUG) return if self.last_role != self.canvas.frame.session.role: self.fill_fog() if "__WXGTK__" not in wx.PlatformInfo: gc = wx.GraphicsContext.Create(dc) gc.SetBrush(wx.Brush(wx.BLACK)) if (self.canvas.frame.session.role == "GM"): gc.SetBrush(wx.Brush(self.color)) rgn = wx.Region(0, 0, self.canvas.size[0]+2, self.canvas.size[1]+2) if not self.fogregion.IsEmpty(): rgn.SubtractRegion(self.fogregion) gc.ClipRegion(rgn) gc.DrawRectangle(0, 0, self.canvas.size[0]+2, self.canvas.size[1]+2) else: sc = dc.GetUserScale() bmp = wx.EmptyBitmap(size[0],size[1]) mdc = wx.MemoryDC() mdc.BeginDrawing() mdc.SelectObject(bmp) mdc.SetPen(wx.TRANSPARENT_PEN) mdc.SetBrush(wx.Brush(wx.WHITE, wx.SOLID)) mdc.DrawRectangle(0,0,size[0],size[1]) srct = [int(topleft[0]/(sc[0]*COURSE)), int(topleft[1]/(sc[1]*COURSE))] srcsz = [int((int(size[0]/COURSE+1)*COURSE)/(sc[0]*COURSE))+2, int((int(size[1]/COURSE+1)*COURSE)/(sc[1]*COURSE))+2] if (srct[0]+srcsz[0] > self.width): srcsz[0] = self.width-srct[0] if (srct[1]+srcsz[1] > self.height): srcsz[1] = self.height-srct[1] img = wx.ImageFromBitmap(self.fog_bmp).GetSubImage(wx.Rect(srct[0], srct[1], srcsz[0], srcsz[1])) img.Rescale(srcsz[0]*COURSE*sc[0], srcsz[1]*COURSE*sc[1]) fog = wx.BitmapFromImage(img) mdc.SetDeviceOrigin(-topleft[0], -topleft[1]) mdc.DrawBitmap(fog, srct[0]*COURSE*sc[0], srct[1]*COURSE*sc[1]) mdc.SetDeviceOrigin(0,0) mdc.SetUserScale(1,1) mdc.EndDrawing() dc.SetUserScale(1,1) dc.Blit(topleft[0], topleft[1], size[0], size[1], mdc,0,0,wx.AND) dc.SetUserScale(sc[0],sc[1]) mdc.SelectObject(wx.NullBitmap) del mdc self.log.log("Exit fog_layer->layerDraw(self, dc, topleft, size)", ORPG_DEBUG) def createregn2(self, polyline, mode, show): self.log.log("Enter fog_layer->createregn2(self, polyline, mode, show)", ORPG_DEBUG) regn = self.scanConvert(polyline) area = "" for i in polyline: if (area != ""): area += ";" area += str(i.X) + "," + str(i.Y) if mode == 'new': if self.fogregion.IsEmpty(): self.fogregion = regn else: self.fogregion.UnionRegion(regn) self.add_area(area, show) else: if not self.fogregion.IsEmpty(): self.fogregion.SubtractRegion(regn) else: self.fogregion = wx.Region(0, 0, self.canvas.size[0]+2, self.canvas.size[1]+2) self.fogregion.SubtractRegion(regn) self.del_area(area, show) self.log.log("Exit fog_layer->createregn2(self, polyline, mode, show)", ORPG_DEBUG) def createregn(self, polyline, mode, show="Yes"): self.log.log("Enter fog_layer->createregn(self, polyline, mode, show)", ORPG_DEBUG) if not self.use_fog and mode == 'del': self.clear() self.canvas.Refresh(False) if self.use_fog: self.createregn2(polyline, mode, show) self.fill_fog() self.log.log("Exit fog_layer->createregn(self, polyline, mode, show)", ORPG_DEBUG) def scanConvert(self, polypt): self.log.log("Enter fog_layer->scanConvert(self, polypt)", ORPG_DEBUG) regn = wx.Region() regn.Clear() list = IRegion().scan_Convert(polypt) for i in list: if regn.IsEmpty(): if "__WXGTK__" not in wx.PlatformInfo: regn = wx.Region(i.left*COURSE, i.y*COURSE, i.right*COURSE+1-i.left*COURSE, 1*COURSE) else: regn = wx.Region(i.left, i.y, i.right+1-i.left, 1) else: if "__WXGTK__" not in wx.PlatformInfo: regn.Union(i.left*COURSE, i.y*COURSE, i.right*COURSE+1-i.left*COURSE, 1*COURSE) else: regn.Union(i.left, i.y, i.right+1-i.left, 1) self.log.log("Exit fog_layer->scanConvert(self, polypt)", ORPG_DEBUG) return regn def add_area(self, area="", show="Yes"): self.log.log("Enter fog_layer->add_area(self, area, show)", ORPG_DEBUG) poly = FogArea(area, self.log) xml_str = "<map><fog>" xml_str += poly.toxml("new") xml_str += "</fog></map>" if show == "Yes": self.canvas.frame.session.send(xml_str) self.log.log(xml_str, ORPG_DEBUG) self.log.log("Exit fog_layer->add_area(self, area, show)", ORPG_DEBUG) def del_area(self, area="", show="Yes"): self.log.log("Enter fog_layer->del_area(self, area, show)", ORPG_DEBUG) poly = FogArea(area, self.log) xml_str = "<map><fog>" xml_str += poly.toxml("del") xml_str += "</fog></map>" if show == "Yes": self.canvas.frame.session.send(xml_str) self.log.log(xml_str, ORPG_DEBUG) self.log.log("Exit fog_layer->del_area(self, area, show)", ORPG_DEBUG) def layerToXML(self, action="update"): self.log.log("Enter fog_layer->layerToXML(self, " + action + ")", ORPG_DEBUG) if not self.use_fog: self.log.log("Exit fog_layer->layerToXML(self, " + action + ") return None", ORPG_DEBUG) return "" fog_string = "" ri = wx.RegionIterator(self.fogregion) if not (ri.HaveRects()): fog_string = FogArea("all", self.log).toxml("del") while ri.HaveRects(): if "__WXGTK__" not in wx.PlatformInfo: x1 = ri.GetX()/COURSE x2 = x1+(ri.GetW()/COURSE)-1 y1 = ri.GetY()/COURSE y2 = y1+(ri.GetH()/COURSE)-1 else: x1 = ri.GetX() x2 = x1+ri.GetW()-1 y1 = ri.GetY() y2 = y1+ri.GetH()-1 poly = FogArea(str(x1) + "," + str(y1) + ";" + str(x2) + "," + str(y1) + ";" + str(x2) + "," + str(y2) + ";" + str(x1) + "," + str(y2), self.log) fog_string += poly.toxml(action) ri.Next() if fog_string: s = "<fog" s += ">" s += fog_string s += "</fog>" self.log.log(s, ORPG_DEBUG) self.log.log("Exit fog_layer->layerToXML(self, " + action + ")", ORPG_DEBUG) return s else: self.log.log("Exit fog_layer->layerToXML(self, " + action + ") return None", ORPG_DEBUG) return "" def layerTakeDOM(self, xml_dom): self.log.log("Enter fog_layer->layerTakeDOM(self, xml_dom)", ORPG_DEBUG) try: if not self.use_fog: self.use_fog = True self.recompute_fog() if xml_dom.hasAttribute('serial'): self.serial_number = int(xml_dom.getAttribute('serial')) children = xml_dom._get_childNodes() for l in children: action = l.getAttribute("action") outline = l.getAttribute("outline") if (outline == "all"): polyline = [IPoint().make(0,0), IPoint().make(self.width-1, 0), IPoint().make(self.width-1, self.height-1), IPoint().make(0, self.height-1)] elif (outline == "none"): polyline = [] self.use_fog = 0 self.fog_bmp = None else: polyline = [] lastx = None lasty = None list = l._get_childNodes() for point in list: x = point.getAttribute( "x" ) y = point.getAttribute( "y" ) if (x != lastx or y != lasty): polyline.append(IPoint().make(int(x), int(y))) lastx = x lasty = y if (len(polyline) > 1): self.createregn2(polyline, action, "No") self.fill_fog() except: self.log.log(traceback.format_exc(), ORPG_GENERAL) self.log.log("Exit fog_layer->layerTakeDOM(self, xml_dom)", ORPG_DEBUG)