Mercurial > traipse_dev
changeset 212:13054be69834 beta
Traipse Beta 'OpenRPG' {100428-00}
Traipse is a distribution of OpenRPG that is designed to be easy to setup and go. Traipse also makes it easy for
developers to work on code without fear of sacrifice. 'Ornery-Orc' continues the trend of 'Grumpy' and adds fixes to
the code. 'Ornery-Orc's main goal is to offer more advanced features and enhance the productivity of the user.
Update Summary (Patch-2)
New Features:
New Namespace method with two new syntaxes
New Namespace Internal is context sensitive, always!
New Namespace External is 'as narrow as you make it'
New Namespace FutureCheck helps ensure you don't receive an incorrect node
New PluginDB access for URL2Link plugin
New to Forms, they now show their content in Design Mode
New to Update Manager, checks Repo for updates on software start
Fixes:
Fix to Server GUI startup errors
Fix to Server GUI Rooms tab updating
Fix to Chat and Settings if non existant die roller is picked
Fix to Dieroller and .open() used with .vs(). Successes are correctly calculated
Fix to Alias Lib's Export to Tree, Open, Save features
Fix to alias node, now works properly
Fix to Splitter node, minor GUI cleanup
Fix to Backgrounds not loading through remote loader
Fix to Node name errors
Fix to rolling dice in chat Whispers
Fix to Splitters Sizing issues
Fix to URL2Link plugin, modified regex compilation should remove memory leak
Fix to mapy.py, a roll back due to zoomed grid issues
Fix to whiteboard_handler, Circles work by you clicking the center of the circle
Fix to Servers parse_incoming_dom which was outdated and did not respect XML
Fix to a broken link in the server welcome message
Fix to InterParse and logger requiring traceback
Fix to Update Manager Status Bar
Fix to failed image and erroneous pop up
line wrap: on
line diff
--- a/orpg/chat/chatwnd.py Mon Feb 01 18:29:16 2010 -0600 +++ b/orpg/chat/chatwnd.py Wed Apr 28 08:08:09 2010 -0500 @@ -45,7 +45,7 @@ ## import os, time, re, sys, traceback, webbrowser, commands, chat_msg, chat_util -from orpg.orpg_version import VERSION +from orpg.orpg_version import VERSION, DISTRO, DIS_VER, BUILD from orpg.orpg_windows import * from orpg.player_list import WG_LIST from orpg.dirpath import dir_struct @@ -763,9 +763,11 @@ self.chatwnd = chat_html_window(self,-1) self.set_colors() wx.CallAfter(self.chatwnd.SetPage, self.chatwnd.Header()) + welcome = "<b>Welcome to <a href='http://www.knowledgearcana.com/traipse-openrpg/'>" + welcome += DISTRO +'</a> '+ DIS_VER +' {'+BUILD+'},' + welcome += ' built on OpenRPG '+ VERSION +'</b>' if (self.sendtarget == "all"): - wx.CallAfter(self.Post, self.colorize(self.syscolor, - "<b>Welcome to <a href='http://www.openrpg.com'>OpenRPG</a> version " + self.version + "... </b>")) + wx.CallAfter(self.Post, self.colorize(self.syscolor, welcome)) self.chattxt = orpg.tools.predTextCtrl.predTextCtrl(self, -1, "", style=wx.TE_PROCESS_ENTER |wx.TE_PROCESS_TAB|wx.TE_LINEWRAP, keyHook = self.myKeyHook, validator=None ) @@ -1030,7 +1032,7 @@ sound_file = self.settings.get_setting("SendSound") if sound_file != '': component.get('sound').play(sound_file) if s[0] != "/": ## it's not a slash command - s = self.ParsePost( s, True, True ) + s = Parse.Post(s, self, True, True) else: self.chat_cmds.docmd(s) # emote is in chatutils.py def on_chat_key_down(self, event): @@ -1169,7 +1171,7 @@ if len(dieMod) and dieMod[0] not in "*/-+": dieMod = "+" + dieMod dieText += dieMod dieText = "[" + dieText + "]" - self.ParsePost(dieText, 1, 1) + Parse.Post(dieText, self, 1, 1) self.chattxt.SetFocus() def on_chat_save(self, evt): @@ -1299,7 +1301,7 @@ return text def emote_message(self, text): - text = Parse.Normalize(text) + text = Parse.Normalize(text, self) text = self.colorize(self.emotecolor, text) if self.type == MAIN_TAB and self.sendtarget == 'all': self.send_chat_message(text,chat_msg.EMOTE_MESSAGE) elif self.type == MAIN_TAB and self.sendtarget == "gm": @@ -1317,7 +1319,7 @@ def whisper_to_players(self, text, player_ids): tabbed_whispers_p = self.settings.get_setting("tabbedwhispers") - text = Parse.Normalize(text) + text = Parse.Normalize(text, self) player_names = "" for m in player_ids: id = m.strip() @@ -1384,6 +1386,7 @@ if (strip_img == "0"): display_name = chat_util.strip_img_tags(display_name) recvSound = "RecvSound" # act on the type of messsage + if (type == chat_msg.CHAT_MESSAGE): text = "<b>" + display_name + "</b>: " + text self.Post(text) @@ -1589,11 +1592,6 @@ logger.general("EXCEPTION: " + str(e)) return "[ERROR]" - def ParsePost(self, s, send=False, myself=False): - s = Parse.Normalize(s) - self.set_colors() - self.Post(s,send,myself) - # This subroutine builds a chat display name. # def chat_display_name(self, player):
--- a/orpg/chat/commands.py Mon Feb 01 18:29:16 2010 -0600 +++ b/orpg/chat/commands.py Wed Apr 28 08:08:09 2010 -0500 @@ -214,14 +214,17 @@ def on_dieroller(self, cmdargs): args = string.split(cmdargs,None,-1) rm = component.get('DiceManager') + cur_die = rm.getRoller() try: rm.setRoller(args[0]) - self.chat.SystemPost("You have changed your die roller to the <b>\"" + args[0] + "\"</b> roller.") - self.settings.set_setting('dieroller',args[0]) + self.chat.SystemPost('You have changed your die roller to the <b>"' +rm.getRoller()+ '"</b> roller.') + self.settings.change('dieroller', rm.getRoller()) except Exception, e: - print e - self.chat.InfoPost("Available die rollers: " + str(rm.listRollers())) - self.chat.InfoPost("You are using the <b>\"" + rm.getRoller() + "\"</b> die roller.") + rm.setRoller(cur_die) + self.settings.change('dieroller', str(cur_die)) + if args[0] != '': self.chat.SystemPost(args[0]+ ' is an invalid roller.') + self.chat.InfoPost('Available die rollers: ' +str(rm.listRollers()) ) + self.chat.InfoPost('You are using the <b>"' +cur_die+ '"</b> die roller.') def on_ping(self, cmdargs): ct = time.clock()
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/orpg/dieroller/HOWTO.txt Wed Apr 28 08:08:09 2010 -0500 @@ -0,0 +1,72 @@ +HOW TO CREATE A NEW DIE ROLLER + +So you want a make a new roller or add a new option? here's a short guide. + + +Step 1: Create a new die roller sub class. + +You need to derive a new die roller class from an existing die roller class. +Most likely, this will be the std die roller class. + +The basics would look like this: + +class new_roller(std): + def __init__(self,source=[]): + std.__init__(self,source) + ..... + + .... + +Step 2: Implement new methods and/or override existing ones. + +Now, you just need to implement any new die options and override any +existing ones that you want to act differently. The most common options +to override are the sum and __str__ functions. Sum is used to determine +the result of the rolls and __str__ is used to display the results in +a user friendly string. + +For example: + +class new_roller(std): + def __init__(self,source=[]): + std.__init__(self,source) + ..... + + def myoption(self,param): + .... + + def sum(self): + .... + + def __str__(self): + .... + +REMEMBER! +Always return an instance of your die roller for each option expect str and sum. + + +Step 3: + +Modify Utils.py + +You need to make some minor modifications to utils.py to facilitate +your new roller. You need to a) add an import call for your roller, +and b) add your roller to the list of available rollers. + +For example: + +from die import * +# add addtional rollers here +from myroller import * +.... + +rollers = ['std','wod','d20','myroller'] + +Step 4: You're done! + +Test it and make sure it works. When you think its done, send it to +the openrpg developers and they might include it in future releases. + +-Chris Davis + +
--- a/orpg/dieroller/base.py Mon Feb 01 18:29:16 2010 -0600 +++ b/orpg/dieroller/base.py Wed Apr 28 08:08:09 2010 -0500 @@ -126,7 +126,6 @@ elif hasattr(other,"sum"): return cmp(self.sum(), other.sum()) else: return UserList.UserList.__cmp__(self,other) - def __rcmp__(self,other): return self.__cmp__(other) @@ -230,7 +229,7 @@ ### di class to handle actual dice class di: - def __init__(self,sides,min=1): + def __init__(self, sides, min=1): self.sides = sides self.history = None self.value = None @@ -264,7 +263,6 @@ def __int__(self): return self.value - def __lt__(self,other): if type(other) == type(3) or type(other) == type(3.0): return self.value < other elif hasattr(other,"value"): return self.value < other.value
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/orpg/dieroller/dieroller.txt Wed Apr 28 08:08:09 2010 -0500 @@ -0,0 +1,309 @@ +The New Dicing System: A Proposal for OpenRPG +---------------------------------------------- + +The current dice system for OpenRPG has several limitations. Foremost +among these are the fact that adding a new, non-standard dicing mechanism +requires editing of the basic dice code. There are several secondary +limitations, such as the fact that while the dice system can handle math, +it cannot be used as a calculator -- it will not allow expressions that do +not involve dice. + +This proposal is for a new dicing system to replace the current one in +OpenRPG. Since the dicing system is something that users will interact +with frequently, a new system needs to be considered carefully. This +document attempts to describe the new dicing system so that such +consideration can be given to it. It is expected that this document will +grow and change as it is scrutinized. + + +Design goals for this dicing system: + + 1. Should be easy for new users to get started with, based on knowing + standard RPG dice notation (NdX) and basic math. + + 2. Should, as far as practical, maintain compatibility with existing + character sheets, etc., that use the current dice system. + + 3. Should allow users to create new dice types and new ways of + counting dice. Ideally, this should not require programming, except + in exceptional cases. + + 4. The dice system should be usable for doing basic math that does + not involve dice. + + 5. The dice system should be able to handle most current RPG dicing + systems. + +Things this dicing system is designed to NOT do: + + 1. Be a programming language. There are no facilities in it for + user input, output formatting, loops, if-then-else, or similar + things. If these are desired for something involving dice, an + appropriate node and nodehandler can be created. + + 2. Handle all theoretically possible dicing systems without the + need for programming plugins. First off, this is impossible. + Second, even making an attempt to would require supporting + dicing methods that don't actually turn up in any real game. + + 3. Handle floating-point math. I don't know of any systems that + use it in their dice schemes right now. If there are some, + we might have to consider adding it. + + +Syntax Specification + +What follows is a BNF specification for the proposed dicing system, with +explanatory text interleaved. At the end of this document is a copy of +the BNF with no explanations, for those who would like to look at it "all +together". Note that BNF describes only syntax, and not semantics; thus, +while anything generated with this grammar should be syntactically correct, +that doesn't mean it will make sense or be allowed. + + +dice string ::= <expression> + <expression> of <comparison> | <comparison> + +This is the top level. The major thing of note here is that comparisons +only occur at this level. This is intentional; the result of a comparison +is a boolean true/false flag rather than a number. Thus, it makes no +sense to allow people to perform further numerical operations on the +result of a comparison. Systems where dice are triggered by the results +of other dice are left for the realm of plugins. + + +comparison ::= <expression> <relation> <expression> + +expression ::= <factor> | <factor> <low-op> <factor> + +The separation into "low-op" and "high-op" of the operators is to allow +order of operations to be handled more easily. Syntactically, it's not +really necessary, but it should be helpful in implementation. + + +factor :: = <term> | <term> <high-op> <term> | + <multi-dice> | <multi-dice> <high-op> <term> | + <term> <high-op> <multi-dice> + +Here we start to hit some complication. The intent of the different +entries for multi-dice is that we don't want to allow things like +[3d6 each * 2d6 each]. We are *not* doing vector multiplication! +The "expression" level doesn't have any such limitation on syntax; +things like [3d6 each + 2d6 each] we'll have to either think of a +logical way to handle, or disallow on a semantic level. (Well... I +suppose it could be handled in the BNF, but I think it would get +kind of messy.) + + +term ::= <dice> | <unit> + +unit ::= <number> | ( <expression> ) + +Dice are not considered a unit. This means that things like [3d6d10] can't +be done without using parentheses. I consider that to be a win for +clarity. + + +dice ::= <unit>d<unit> | <unit>d<name> | <dice> <flag> | lastroll + +The <name> entry here allows for user-created dice (in the syntax, at +least...). + + +multi-dice ::= ( <dice>, <dice>+ ) | # (1d6,1d8) + <dice> each | # 3d6 each + ( <expression> of <expression> ) | # (3 of 2d6) + lastroll | # lastroll + <multi-dice> <flag> # (3 of 2d6) best 2 + +"lastroll" by itself can be either dice or multi-dice. I'm thinking that it + +should be whatever type the last roll was. + + +flag ::= reroll <condition> | # repeats + reroll <slice> | # once only + grow <condition> | # reroll and add + shrink <condition> | # reroll and subtract + drop <condition> | + drop <slice> | + take <condition> | + take <slice> | + <slice> | # implied "take" + <name> <condition> | # user-created + <name> # user-created + +Technically, we don't need both "drop" and "take" -- one implies the +other. However, having both should make the language easier to use. + +"reroll" will work differently depending on whether a condition or a +slice is given. If a condition is given, it will reroll until none of +the dice in the set meet the reroll condition (or until it hits a maximum +allowed number of rerolls). If a slice is given, it will reroll those +dice once. IMHO, this behavior makes the most sense. + +The <name> entries here are to allow for user-created flags. Note that +as I've specified things right now, a user-created flag can have a + condition, +but not a slice. That's mostly because I couldn't think of a case where +a slice would be useful... should we add it anyways? + + +slice ::= highest | lowest | highest <number> | lowest <number> + +"highest" and "lowest" without a number are equivalent to doing them with +1 as the number. This is to simplify things like [4d6 drop lowest]. + + +condition ::= <relation> <unit> + +This is for conditions on flags. Note that it can take a unit, so you could + +use dice in a condition; however, I think the unit should only be evaluated + +once, to make things faster. Anyone for repetitive evaluation? + + +low-op ::= + | - | min | max + +"min" takes two values and returns the highest of them, and "max" +returns the lowest of them. This might seem counterintuitive, but +it's meant to be used with dice, like so: + + 3d6 min 8 - always returns 8 or higher + + 3d6 max 15 - always returns 15 or lower + +I decided to put min and max as having the same precedence as + and -, +because if they had higher precedence, then: + + 3d6+2 min 10 + +would be equivalent to 3d6+10. (It would take the max of 2 and 10, then +add that to 3d6). One problem that does arise here is with multiplication +and division: [1d6 min 5 * 2] will be equivalent to [1d6 min 10], since +multiplication has higher precedence. We may just want to warn people +that min and max can be screwy unless you parenthesize, unless someone can +think of a better way to handle them. + + +high-op ::= * | / | mod + +The / is integer division, of course, since we're doing integer math. + + +number ::= <digit>+ | -<digit>+ + +Positive and negative numbers are allowed. This means that, syntactically, +[-2d-4] is legal. Do we want to modify the BNF to disallow this, or handle +it on a semantic level? + + +name ::= <letter>[<letter>|<digit>]* + +We may want to expand to allow underscores and dashes in user-created names. + + + +letter ::= A-Z | a-z + +digit ::= 0-9 + +relation ::= < | > | <= | >= | => | =< | = | == + + + +Well, that's the BNF. Again, at the end is a copy without all the running +commentary. + + +Thoughts on Implementation: + +First, I think a sort of "dice library" of common functions needs to be +created. This would include rolling a set of dice, getting the highest +of a group of dice, growing and shrinking dice from a set based on +conditions, and so on. These functions should be available for use by +custom-written dice types. + +Next, that library should be used as a tool in implementing a dice-string +interpreter. That will require creating a parser for the dice-string +'language'. This could be either a custom-written parser, or possibly +one created with some of the Python parser generators. A custom-written +parser may take longer to do and be a bit more finicky to maintain, but +it would remove a dependency from the code. + +User-created flags and dice types could be supported in two ways: + + - First, by allowing users to specify strings in the dice language + that the flags/expressions would expand to -- basically, allowing + dice macros. + + - Second, by adding hooks for python modules to be associated with + user-created dice or flag types. This is likely to be the more + complicated of the two solutions, but it would also be more + flexible. + +Personally, I think both are desirable -- the first, so that +non-programming users can create simple die and flag types. The +second, because by design, there are some things this dice system +just won't do. + + +Further work needed: + + - specs for the "dice library" + + - specs on an interface for python modules meant to be dice and + flag types. + +---------------------------------------------------------------- + +start ::= <expression> | + <comparison> + +comparison ::= <expression> <condition> + +expression ::= <term> | <term> <low-op> <factor> + +term ::= <factor> | <factor> <high-op> <unit> + +factor ::= <atom> | <dice_set> + +atom ::= <number> | ( <expression> ) + +dice_set ::= <dice> <dice_set>, <dice> | <expr> of <dice> | <dice> each | + lastroll + +dice ::= <atom>d<atom> | <atom>d<name> | <dice> <flag> + +flag ::= reroll <condition> | + reroll <slice> | + grow <condition> | + shrink <condition> | + drop <condition> | + drop <slice> | + take <condition> | + take <slice> | + <slice> | + <name> <condition> | + <name> <slice> | + <name> + +slice ::= highest | lowest | highest <number> | lowest <number> + +condition ::= <relation> <unit> + +low-op ::= + | - + +high-op ::= * | / | mod| max | min + +number ::= <digit>+ | -<digit>+ + +name ::= <letter>[<letter>|<digit>]* + +letter ::= A-Z | a-z + +digit ::= 0-9 + +relation ::= < | > | <= | >= | => | =< | = | == +
--- a/orpg/dieroller/rollers/std.py Mon Feb 01 18:29:16 2010 -0600 +++ b/orpg/dieroller/rollers/std.py Wed Apr 28 08:08:09 2010 -0500 @@ -3,8 +3,8 @@ class std(die_base): name = "std" - def __init__(self,source=[]): - die_base.__init__(self,source) + def __init__(self, source=[]): + die_base.__init__(self, source) # Examples of adding member functions through inheritance. @@ -19,30 +19,27 @@ result.reverse() return result - def takeHighest(self,num_dice): + def takeHighest(self, num_dice): return self.descending()[:num_dice] def takeLowest(self,num_dice): return self.ascending()[:num_dice] - def extra(self,num): + def extra(self, num): for i in range(len(self.data)): if self.data[i].lastroll() >= num: self.data[i].extraroll() return self - def open(self,num): - if num <= 1: - self + def open(self, num): + if num <= 1: self done = 1 for i in range(len(self.data)): if self.data[i].lastroll() >= num: self.data[i].extraroll() done = 0 - if done: - return self - else: - return self.open(num) + if done: return self + else: return self.open(num) def minroll(self,min): for i in range(len(self.data)): @@ -50,13 +47,12 @@ self.data[i].roll(min) return self - def each(self,mod): + def each(self, mod): mod = int(mod) for i in range(len(self.data)): self.data[i].modify(mod) return self - def vs(self, target): for dn in self.data: dn.target = target @@ -72,12 +68,10 @@ for dn in self.data: setValue = reduce( lambda x, y : int(x)+int(y), dn.history ) if dn.target: - if setValue >= dn.target: - retValue += 1 - + for dv in dn.history: + if int(dv) >= dn.target: retValue += 1 else: retValue += setValue - return retValue die_rollers.register(std)
--- a/orpg/gametree/gametree.py Mon Feb 01 18:29:16 2010 -0600 +++ b/orpg/gametree/gametree.py Wed Apr 28 08:08:09 2010 -0500 @@ -21,11 +21,18 @@ # Author: Chris Davis # Maintainer: # Version: -# $Id: gametree.py,v Traipse 'Ornery-Orc' prof.ebral Exp $ +# $Id: gametree.py,v 1.68 2007/12/07 20:39:48 digitalxero Exp $ # # Description: The file contains code fore the game tree shell # -# Traipse EZ_Tree Reference System (TaS - Prof.Ebral): v Traipse 'Ornery-Orc' prof.ebral Exp +# Traipse EZ_Tree Reference System (TaS - Prof.Ebral): +# +# The new EZ_Tree Reference System being implemented takes full advantage of +# Python's OOP Language. The entire tree code is being reused, but a new ID is +# being created which 'shuts off' some of the features of the tree and adds new ones. +# This new feature will allow users to quickly add a Reference button to new node +# handlers. The button will show a faximile of the tree and users can then create a +# node reference with ease! # from __future__ import with_statement @@ -37,7 +44,7 @@ from orpg.orpgCore import component from orpg.dirpath import dir_struct from nodehandlers import core -import string, urllib, time, os, shutil +import string, urllib, time, os from orpg.orpg_xml import xml from orpg.tools.validate import validate @@ -82,12 +89,6 @@ TOP_FEATURES = wx.NewId() EZ_REF = wx.NewId() -def exists(path): - try: - os.stat(path) - return True - except: return False - class game_tree(wx.TreeCtrl): def __init__(self, parent, id): @@ -239,14 +240,11 @@ self.xml_root = None if not self.xml_root: - count = 1 - while exists(filename[:len(filename)-4]+'-bad-'+str(count)+'.xml'): count += 1 - shutil.copy(filename, filename[:len(filename)-4]+'-bad-'+str(count)+'.xml') - shutil.copyfile(dir_struct["template"]+'default_tree.xml', filename) + os.rename(filename,filename+".corrupt") emsg = "Your gametree is being regenerated.\n\n"\ "To salvage a recent version of your gametree\n"\ "exit OpenRPG and copy the lastgood.xml file in\n"\ - "your myfiles directory to "+filename[:len(filename)-4]+'-bad-'+str(count)+'.xml'+ "\n"\ + "your myfiles directory to "+filename+ "\n"\ "in your myfiles directory.\n\n"\ "lastgood.xml WILL BE OVERWRITTEN NEXT TIME YOU RUN OPENRPG.\n\n"\ "Would you like to select a different gametree file to use?\n"\ @@ -288,11 +286,8 @@ except Exception, e: logger.exception(traceback.format_exc()) - count = 1 - while exists(filename[:len(filename)-4]+'-bad-'+str(count)+'.xml'): count += 1 - shutil.copy(filename, filename[:len(filename)-4]+'-bad-'+str(count)+'.xml') - shutil.copyfile(dir_struct["template"]+'default_tree.xml', filename) wx.MessageBox("Corrupt Tree!\nYour game tree is being regenerated. To\nsalvage a recent version of your gametree\nexit OpenRPG and copy the lastgood.xml\nfile in your myfiles directory\nto "+filename+ "\nin your myfiles directory.\nlastgood.xml WILL BE OVERWRITTEN NEXT TIME YOU RUN OPENRPG.") + os.rename(filename,filename+".corrupt") validate.config_file("tree.xml","default_tree.xml") self.load_tree(error=1) @@ -809,7 +804,7 @@ self.rename_flag = 0 if txt != "": obj = self.GetPyData(item) - obj.xml_root.setAttribute('name',txt) + obj.xml_root.set('name',txt) else: evt.Veto() def on_label_begin(self, evt):
--- a/orpg/gametree/nodehandlers/chatmacro.py Mon Feb 01 18:29:16 2010 -0600 +++ b/orpg/gametree/nodehandlers/chatmacro.py Wed Apr 28 08:08:09 2010 -0500 @@ -98,6 +98,6 @@ txt = self.text[id].GetValue() if txt == "": return if id == P_TITLE: - self.handler.xml.setAttribute('name',txt) + self.handler.xml.set('name',txt) self.handler.rename(txt) elif id == P_BODY: self.handler.set_text(txt)
--- a/orpg/gametree/nodehandlers/containers.py Mon Feb 01 18:29:16 2010 -0600 +++ b/orpg/gametree/nodehandlers/containers.py Wed Apr 28 08:08:09 2010 -0500 @@ -245,7 +245,6 @@ parent.SetSize(self.GetBestSize()) self.Bind(wx.EVT_TEXT, self.on_text, id=1) - def on_text(self,evt): txt = self.title.GetValue() if txt != "": @@ -281,19 +280,19 @@ container_handler.on_drop(self,evt) def build_splitter_wnd(self, parent, mode): + self.parent = parent self.split = self.xml.get("horizontal") - self.pane = splitter_panel(parent, self) + self.pane = splitter_panel(parent, self, mode) + self.frame = self.pane.frame self.splitter = MultiSplitterWindow(self.pane, -1, style=wx.SP_LIVE_UPDATE|wx.SP_3DSASH|wx.SP_NO_XP_THEME) + self.splitter.parent = self if self.split == '1': self.splitter.SetOrientation(wx.VERTICAL) else: self.splitter.SetOrientation(wx.HORIZONTAL) - self.bestSizex = -1 - self.bestSizey = -1 self.tree.traverse(self.mytree_node, self.doSplit, mode, False) - self.pane.sizer.Add(self.splitter, 1, wx.EXPAND) - if mode != 1: self.pane.hozCheck.Hide() - self.pane.SetSize((self.bestSizex, self.bestSizey)) - self.pane.Layout() + self.pane.sizer.Add(self.splitter, -1, wx.EXPAND) + self.pane.SetAutoLayout(True) + self.pane.Fit() parent.SetSize(self.pane.GetSize()) return self.pane @@ -301,41 +300,40 @@ node = self.tree.GetPyData(treenode) if mode == 1: tmp = node.get_design_panel(self.splitter) else: tmp = node.get_use_panel(self.splitter) - if self.split == '1': - sash = tmp.GetBestSize()[1]+1 - self.bestSizey += sash+11 - if self.bestSizex < tmp.GetBestSize()[0]: self.bestSizex = tmp.GetBestSize()[0]+10 - else: - sash = tmp.GetBestSize()[0]+1 - self.bestSizex += sash - if self.bestSizey < tmp.GetBestSize()[1]: self.bestSizey = tmp.GetBestSize()[1]+31 + if self.split == '1': sash = self.frame.GetSize()[1]/len(self.xml.findall('nodehandler')) + else: sash = self.frame.GetSize()[0]/len(self.xml.findall('nodehandler')) self.splitter.AppendWindow(tmp, sash) + def get_size_constraint(self): return 1 class splitter_panel(wx.Panel): - def __init__(self, parent, handler): + def __init__(self, parent, handler, mode): wx.Panel.__init__(self, parent, -1) + self.parent = parent self.handler = handler - sizer = wx.BoxSizer(wx.VERTICAL) - self.title = wx.TextCtrl(self, 1, handler.xml.get('name')) - - self.hozCheck = wx.CheckBox(self, -1, "Horizontal Split") - hoz = self.handler.xml.get("horizontal") + self.sizer = wx.BoxSizer(wx.VERTICAL) + if mode == 0: self.title = wx.StaticText(self, 1, handler.xml.get('name')) + elif mode == 1: self.title = wx.TextCtrl(self, 1, handler.xml.get('name')) + self.frame = self.GetParent() + while self.frame.GetName() != 'frame': + self.frame = self.frame.GetParent() - if hoz == '1': self.hozCheck.SetValue(True) - else: self.hozCheck.SetValue(False) + if mode == 1: + self.hozCheck = wx.CheckBox(self, -1, "Horizontal Split") + hoz = self.handler.xml.get("horizontal") + if hoz == '1': self.hozCheck.SetValue(True) + else: self.hozCheck.SetValue(False) - sizer.Add(wx.StaticText(self, -1, "Title:"), 0, wx.EXPAND) - sizer.Add(self.title, 0) - sizer.Add(self.hozCheck, 0, wx.EXPAND) - sizer.Add(wx.Size(10,0)) + if mode == 1: self.sizer.Add(wx.StaticText(self, -1, "Title:"), 0, wx.EXPAND) + self.sizer.Add(self.title, 0) + if mode == 1: self.sizer.Add(self.hozCheck, 0, wx.EXPAND) + self.sizer.Add(wx.Size(10,0)) - self.sizer = sizer self.SetSizer(self.sizer) self.SetAutoLayout(True) self.Bind(wx.EVT_TEXT, self.on_text, id=1) - self.Bind(wx.EVT_CHECKBOX, self.on_check_box, id=self.hozCheck.GetId()) + if mode == 1: self.Bind(wx.EVT_CHECKBOX, self.on_check_box, id=self.hozCheck.GetId()) def on_check_box(self,evt): state = self.hozCheck.GetValue()
--- a/orpg/gametree/nodehandlers/forms.py Mon Feb 01 18:29:16 2010 -0600 +++ b/orpg/gametree/nodehandlers/forms.py Wed Apr 28 08:08:09 2010 -0500 @@ -109,11 +109,11 @@ F_HEIGHT = wx.NewId() F_WIDTH = wx.NewId() -class form_edit_panel(wx.Panel): +class form_edit_panel(ScrolledPanel): def __init__(self, parent, handler): - wx.Panel.__init__(self, parent, -1) + ScrolledPanel.__init__(self, parent, wx.ID_ANY, style=wx.NO_BORDER|wx.VSCROLL|wx.HSCROLL) self.handler = handler - sizer = wx.StaticBoxSizer(wx.StaticBox(self, -1, "Form Properties"), wx.VERTICAL) + self.main_sizer = wx.BoxSizer(wx.VERTICAL) wh_sizer = wx.BoxSizer(wx.HORIZONTAL) self.text = { P_TITLE : wx.TextCtrl(self, P_TITLE, handler.xml.get('name')), F_HEIGHT : wx.TextCtrl(self, F_HEIGHT, handler.xml.get('height')), @@ -128,15 +128,17 @@ wh_sizer.Add(wx.Size(10,10)) wh_sizer.Add(self.text[F_HEIGHT], 0, wx.EXPAND) - sizer.Add(wx.StaticText(self, -1, "Title:"), 0, wx.EXPAND) - sizer.Add(self.text[P_TITLE], 0, wx.EXPAND) - sizer.Add(wx.Size(10,10)) - sizer.Add(wh_sizer,0,wx.EXPAND) + self.main_sizer.Add(wx.StaticText(self, -1, "Title:"), 0, wx.EXPAND) + self.main_sizer.Add(self.text[P_TITLE], 0, wx.EXPAND) + self.main_sizer.Add(wx.Size(10,10)) + self.main_sizer.Add(wh_sizer,0,wx.EXPAND) + handler.tree.traverse(handler.mytree_node, self.create_child_wnd, None, False) - self.SetSizer(sizer) + self.SetSizer(self.main_sizer) self.SetAutoLayout(True) + self.SetupScrolling() + parent.SetSize(self.GetSize()) self.Fit() - parent.SetSize(self.GetBestSize()) self.Bind(wx.EVT_TEXT, self.on_text, id=P_TITLE) self.Bind(wx.EVT_TEXT, self.on_text, id=F_HEIGHT) @@ -155,6 +157,14 @@ if id == F_HEIGHT: self.handler.xml.set("height",txt) elif id == F_WIDTH: self.handler.xml.set("width",txt) + def create_child_wnd(self, treenode, evt): + node = self.handler.tree.GetPyData(treenode) + panel = node.get_design_panel(self) + size = node.get_size_constraint() + if panel: + self.main_sizer.Add(panel, size, wx.EXPAND) + self.main_sizer.Add(wx.Size(10,10)) + ########################## ## control handler ########################## @@ -263,16 +273,16 @@ def on_send(self, evt): txt = self.text.GetValue() - txt = Parse.NodeMap(txt, self.handler.xml) - txt = Parse.NodeParent(txt, self.handler.xml.get('map')) + txt = Parse.ParseLogic(txt, self.handler.xml) if not self.handler.is_raw_send(): - Parse.Post(self.handler.tohtml(), True, True) + Parse.Post(self.handler.tohtml(), self.chat, True, True) return 1 actionlist = txt.split("\n") for line in actionlist: + line = Parse.ParseLogic(line, self.handler.xml) if(line != ""): if line[0] != "/": ## it's not a slash command - Parse.Post(line, True, True) + Parse.Post(line, self.chat, True, True) else: action = line self.chat.chat_cmds.docmd(action) @@ -320,7 +330,7 @@ sizer_style=wx.EXPAND text_style = 0 multi = 0 - self.text = wx.TextCtrl(self, F_TEXT, handler.get_value(),style=text_style) + self.text = wx.TextCtrl(self, F_TEXT, handler.get_value() or '',style=text_style) sizer.Add(wx.Size(5,0)) sizer.Add(self.text, multi, sizer_style) self.SetSizer(sizer) @@ -596,18 +606,16 @@ def on_send_to_chat(self, evt): txt = self.get_selected_text() - txt = Parse.NodeMap(txt, self.xml) - txt = Parse.NodeParent(txt, self.xml.get('map')) + txt = Parse.ParseLogic(txt, self.xml) if not self.is_raw_send(): - Parse.Post(self.tohtml(), True, True) + Parse.Post(self.tohtml(), self.chat, True, True) return 1 actionlist = self.get_selections_text() for line in actionlist: - line = Parse.NodeMap(line, self.xml) - line = Parse.NodeParent(line, self.xml.get('map')) + line = Parse.ParseLogic(line, self.xml) if(line != ""): if line[0] != "/": ## it's not a slash command - Parse.Post(line, True, True) + Parse.Post(line, self.chat, True, True) else: action = line self.chat.chat_cmds.docmd(action) @@ -621,6 +629,7 @@ class listbox_panel(wx.Panel): def __init__(self, parent, handler): wx.Panel.__init__(self, parent, -1) + #ScrolledPanel.__init__(self, parent, wx.ID_ANY, style=wx.NO_BORDER|wx.VSCROLL|wx.HSCROLL) self.handler = handler self.chat = handler.chat opts = [] @@ -638,8 +647,8 @@ if self.list.GetSize()[0] > 200: self.list.Destroy() self.list = wx.ComboBox(self, F_LIST, cur_opt, size=(200, -1), choices=opts, style=wx.CB_READONLY) - elif type == L_LIST: self.list = wx.ListBox(self,F_LIST,choices=opts) - elif type == L_RADIO: self.list = wx.RadioBox(self,F_LIST,label,choices=opts,majorDimension=3) + elif type == L_LIST: self.list = wx.ListBox(self, F_LIST, choices=opts) + elif type == L_RADIO: self.list = wx.RadioBox(self, F_LIST, label, choices=opts, majorDimension=3) elif type == L_CHECK: self.list = wx.CheckListBox(self,F_LIST,choices=opts) self.set_checks() @@ -651,17 +660,17 @@ else: sizer = wx.BoxSizer(wx.VERTICAL) if type != L_RADIO: - sizer.Add(wx.StaticText(self, -1, label+": "), 0, wx.EXPAND) - sizer.Add(wx.Size(5,0)) - sizer.Add(self.list, 1, wx.EXPAND) + sizer.Add(wx.StaticText(self, -1, label+": "), 0, wx.EXPAND|wx.ALL) + sizer.Add(self.list, 1, wx.EXPAND|wx.ALL) if handler.has_send_button(): - sizer.Add(wx.Button(self, F_SEND, "Send"), 0, wx.EXPAND) + sizer.Add(wx.Button(self, F_SEND, "Send"), 0, wx.EXPAND|wx.ALL) self.Bind(wx.EVT_BUTTON, self.handler.on_send_to_chat, id=F_SEND) self.sizer = sizer self.SetSizer(sizer) self.SetAutoLayout(True) + #self.SetupScrolling() + #parent.SetSize(self.GetBestSize()) self.Fit() - parent.SetSize(self.GetBestSize()) if type == L_DROP: self.Bind(wx.EVT_COMBOBOX, self.on_change, id=F_LIST) elif type == L_LIST: self.Bind(wx.EVT_LISTBOX, self.on_change, id=F_LIST)
--- a/orpg/gametree/nodehandlers/rpg_grid.py Mon Feb 01 18:29:16 2010 -0600 +++ b/orpg/gametree/nodehandlers/rpg_grid.py Wed Apr 28 08:08:09 2010 -0500 @@ -89,7 +89,7 @@ html_str += "<td >" text = c.text if text == None or text == '': text = '<br />' - s = Parse.NodeMap(text, self.xml) + s = Parse.ParseLogic(text, self.xml) s = Parse.Normalize(s) try: text = str(eval(s)) except: text = s @@ -327,8 +327,7 @@ text = '' cells[i].text = text if self.mode == 0: - s = Parse.NodeMap(text, self.handler.xml) - s = Parse.NodeParent(s, self.handler.xml.get('map')) + s = Parse.ParseLogic(text, self.handler.xml) try: text = str(eval(s)) except: text = s self.SetCellValue(rowi,i,text)
--- a/orpg/main.py Mon Feb 01 18:29:16 2010 -0600 +++ b/orpg/main.py Wed Apr 28 08:08:09 2010 -0500 @@ -622,7 +622,7 @@ # Update Manager #self.manifest = manifest.ManifestChanges() self.updateMana = upmana.updatemana.updaterFrame(self, - "OpenRPG Update Manager 1.0", component, manifest, True) + "OpenRPG Update Manager 1.2", component, manifest, True) component.add('upmana-win', self.updateMana) logger.debug("Menu Created") h = int(xml_dom.get("height")) @@ -790,7 +790,7 @@ temp_wnd = orpg.chat.chatwnd.chat_notebook(parent_wnd, wx.DefaultSize) self.chattabs = temp_wnd self.chat = temp_wnd.MainChatPanel - component.add("chat",self.chat) + component.add("chat", self.chat) elif name == "player": temp_wnd = orpg.player_list.player_list(parent_wnd)
--- a/orpg/map/__init__.py Mon Feb 01 18:29:16 2010 -0600 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,269 +0,0 @@ -from threading import Lock -import mimetypes -import xml.dom.minidom as minidom - -import wx - -import orpg.dirpath -from orpg.orpgCore import * -from orpg.tools.rgbhex import RGBHex -import orpg.tools.ButtonPanel as BP - -from _canvas import MapCanvas - -class MapWnd(wx.Panel): - def __init__(self, parent, openrpg): - wx.Panel.__init__(self, parent, wx.ID_ANY) - self.openrpg = openrpg - self.log = self.openrpg.get_component("log") - self.xml = self.openrpg.get_component("xml") - self.dir_struct = self.openrpg.get_component("dir_struct") - self.validate = self.openrpg.get_component("validate") - self.settings = self.openrpg.get_component("settings") - - self.Freeze() - sizer = wx.GridBagSizer(hgap=1, vgap=1) - sizer.SetEmptyCellSize((0,0)) - - self.canvas = MapCanvas(self, self.openrpg) - sizer.Add(self.canvas, (0,0), flag=wx.EXPAND) - - self.gmToolBar = BP.ButtonPanel(self, wx.ID_ANY) - sizer.Add(self.gmToolBar, (1,0), flag=wx.EXPAND) - self.playerToolBar = BP.ButtonPanel(self, wx.ID_ANY) - sizer.Add(self.playerToolBar, (2,0), flag=wx.EXPAND) - - sizer.AddGrowableCol(0) - sizer.AddGrowableRow(0) - - self.SetSizer(sizer) - self.SetAutoLayout(True) - - self._CreateToolBar() - - self.Bind(wx.EVT_MOUSEWHEEL, self.canvas.OnZoom) - self.Bind(wx.EVT_KEY_DOWN, self.canvas.OnKey) - self.Bind(wx.EVT_KEY_UP, self.canvas.OnKey) - self.Layout() - self.Thaw() - - wx.CallAfter(self.PostLoad) - - #Public API - def PostLoad(self): - self.canvas.Clear() - #self.canvas.roleTimer.Start(100) - self.canvas.UpdateMap() - - #Events - - - #Private Methods - def _SetColorBtn(self, color, btn): - dc = wx.MemoryDC() - bmp = wx.EmptyBitmap(16, 16) - dc.SelectObject(bmp) - dc.SetBrush(wx.Brush(color)) - dc.DrawRectangle(0,0, 16, 16) - - del dc - - btn.SetBitmap(bmp) - - def _CreateToolBar(self): - self.exclusiveToolList = {} - - self.OpenBtn = BP.ButtonInfo(self.gmToolBar, wx.ID_ANY, wx.Bitmap(orpg.dirpath.dir_struct["icon"] + 'open.bmp', wx.BITMAP_TYPE_BMP), kind=wx.ITEM_NORMAL, shortHelp="Load New Map", longHelp="Load New Map") - self.gmToolBar.AddButton(self.OpenBtn) - - self.SaveBtn = BP.ButtonInfo(self.gmToolBar, wx.ID_ANY, wx.Bitmap(orpg.dirpath.dir_struct["icon"] + 'save.bmp', wx.BITMAP_TYPE_BMP), kind=wx.ITEM_NORMAL, shortHelp="Save Map", longHelp="Save Map") - self.gmToolBar.AddButton(self.SaveBtn) - - self.DefaultBtn = BP.ButtonInfo(self.gmToolBar, wx.ID_ANY, wx.Bitmap(orpg.dirpath.dir_struct["icon"] + 'defaultmap.png', wx.BITMAP_TYPE_PNG), kind=wx.ITEM_NORMAL, shortHelp="Load Default Map", longHelp="Load Default Map") - self.gmToolBar.AddButton(self.DefaultBtn) - self.Bind(wx.EVT_BUTTON, self.canvas.OnDefaultBtn, id=self.DefaultBtn.GetId()) - - self.MapPropsBtn = BP.ButtonInfo(self.gmToolBar, wx.ID_ANY, wx.Bitmap(orpg.dirpath.dir_struct["icon"] + 'compass.gif', wx.BITMAP_TYPE_GIF), kind=wx.ITEM_NORMAL, shortHelp="Map Properties", longHelp="Map Properties") - self.gmToolBar.AddButton(self.MapPropsBtn) - - - self.gmToolBar.AddSeparator() - - self.BGBtn = BP.ButtonInfo(self.gmToolBar, wx.ID_ANY, wx.Bitmap(orpg.dirpath.dir_struct["icon"] + 'img.gif', wx.BITMAP_TYPE_GIF), kind=wx.ITEM_NORMAL, shortHelp="Change Background", longHelp="Change Background") - self.gmToolBar.AddButton(self.BGBtn) - self.Bind(wx.EVT_BUTTON, self.canvas.OnBGBtn, id=self.BGBtn.GetId()) - - self.BGColorBtn = BP.ButtonInfo(self.gmToolBar, wx.ID_ANY, wx.EmptyBitmap(16,16), kind=wx.ITEM_NORMAL, shortHelp="Map Background Color", longHelp="Map Background Color") - self.gmToolBar.AddButton(self.BGColorBtn) - self._SetColorBtn(wx.GREEN, self.BGColorBtn) - self.Bind(wx.EVT_BUTTON, self.canvas.OnBGColorBtn, id=self.BGColorBtn.GetId()) - - self.TileAddBtn = BP.ButtonInfo(self.gmToolBar, wx.ID_ANY, wx.Bitmap(orpg.dirpath.dir_struct["icon"] + 'chess.gif', wx.BITMAP_TYPE_GIF), kind=wx.ITEM_NORMAL, shortHelp="Add Map Tile", longHelp="Add Map Tile") - self.gmToolBar.AddButton(self.TileAddBtn) - - self.TileMoveBtn = BP.ButtonInfo(self.gmToolBar, wx.ID_ANY, wx.Bitmap(orpg.dirpath.dir_struct["icon"] + 'crosshair.gif', wx.BITMAP_TYPE_GIF), kind=wx.ITEM_CHECK, shortHelp="Edit Tiles", longHelp="Edit Tiles") - self.gmToolBar.AddButton(self.TileMoveBtn) - self.exclusiveToolList[self.TileMoveBtn.GetId()] = self.TileMoveBtn - self.Bind(wx.EVT_BUTTON, self.canvas.OnExlusiveBtn, id=self.TileMoveBtn.GetId()) - - self.GridBtn = BP.ButtonInfo(self.gmToolBar, wx.ID_ANY, wx.Bitmap(orpg.dirpath.dir_struct["icon"] + 'grid.gif', wx.BITMAP_TYPE_GIF), kind=wx.ITEM_NORMAL, shortHelp="Set Grid", longHelp="Set Grid") - self.gmToolBar.AddButton(self.GridBtn) - - self.gmToolBar.AddSeparator() - - self.FogBtn = BP.ButtonInfo(self.gmToolBar, wx.ID_ANY, wx.Bitmap(orpg.dirpath.dir_struct["icon"] + 'fogon.png', wx.BITMAP_TYPE_PNG), kind=wx.ITEM_CHECK, shortHelp="Turn Fog On", longHelp="Turn Fog On") - self.gmToolBar.AddButton(self.FogBtn) - self.Bind(wx.EVT_BUTTON, self.canvas.OnFogBtn, id=self.FogBtn.GetId()) - - self.FogToolBtn = BP.ButtonInfo(self.gmToolBar, wx.ID_ANY, wx.Bitmap(orpg.dirpath.dir_struct["icon"] + 'showfog.png', wx.BITMAP_TYPE_PNG), kind=wx.ITEM_CHECK, shortHelp="Show Tool", longHelp="Show Tool") - self.gmToolBar.AddButton(self.FogToolBtn) - self.exclusiveToolList[self.FogToolBtn.GetId()] = self.FogToolBtn - self.Bind(wx.EVT_BUTTON, self.canvas.OnExlusiveBtn, id=self.FogToolBtn.GetId()) - menu = wx.Menu("Fog Tool") - item = wx.MenuItem(menu, 1, "Show", "Show") - self.Bind(wx.EVT_MENU, self.OnFogSelection, item) - menu.AppendItem(item) - item = wx.MenuItem(menu, 2, "Hide", "Hide") - self.Bind(wx.EVT_MENU, self.OnFogSelection, item) - menu.AppendItem(item) - self.currentFog = 'Show' - self.FogToolBtn.SetMenu(menu) - - self.FogColorBtn = BP.ButtonInfo(self.gmToolBar, wx.ID_ANY, wx.EmptyBitmap(16,16), kind=wx.ITEM_NORMAL, shortHelp="Fog Color", longHelp="Fog Color") - self.gmToolBar.AddButton(self.FogColorBtn) - self._SetColorBtn(wx.BLACK, self.FogColorBtn) - self.Bind(wx.EVT_BUTTON, self.canvas.OnFogColorBtn, id=self.FogColorBtn.GetId()) - - self.gmToolBar.AddSeparator() - - self.MiniPropsBtn = BP.ButtonInfo(self.playerToolBar, wx.ID_ANY, wx.Bitmap(orpg.dirpath.dir_struct["icon"] + 'questionhead.gif', wx.BITMAP_TYPE_GIF), kind=wx.ITEM_NORMAL, shortHelp="Miniture Properties", longHelp="Miniture Properties") - self.gmToolBar.AddButton(self.MiniPropsBtn) - - self.gmToolBar.DoLayout() - - self.SelectorBtn = BP.ButtonInfo(self.playerToolBar, wx.ID_ANY, wx.Bitmap(orpg.dirpath.dir_struct["icon"] + 'mouse.gif', wx.BITMAP_TYPE_GIF), kind=wx.ITEM_CHECK, shortHelp="Selection Tool", longHelp="Selection Tool") - self.playerToolBar.AddButton(self.SelectorBtn) - self.exclusiveToolList[self.SelectorBtn.GetId()] = self.SelectorBtn - self.Bind(wx.EVT_BUTTON, self.canvas.OnExlusiveBtn, id=self.SelectorBtn.GetId()) - - self.MeasureBtn = BP.ButtonInfo(self.playerToolBar, wx.ID_ANY, wx.Bitmap(orpg.dirpath.dir_struct["icon"] + 'tape.gif', wx.BITMAP_TYPE_GIF), kind=wx.ITEM_CHECK, shortHelp="Measure Tool", longHelp="Measure Tool") - self.playerToolBar.AddButton(self.MeasureBtn) - self.exclusiveToolList[self.MeasureBtn.GetId()] = self.MeasureBtn - self.Bind(wx.EVT_BUTTON, self.canvas.OnExlusiveBtn, id=self.MeasureBtn.GetId()) - - self.ColorBtn = BP.ButtonInfo(self.playerToolBar, wx.ID_ANY, wx.EmptyBitmap(16,16), kind=wx.ITEM_NORMAL, shortHelp="Select a Color", longHelp="Select a Color") - self.playerToolBar.AddButton(self.ColorBtn) - self._SetColorBtn(wx.BLACK, self.ColorBtn) - self.Bind(wx.EVT_BUTTON, self.canvas.OnColorBtn, id=self.ColorBtn.GetId()) - - self.DrawBtn = BP.ButtonInfo(self.playerToolBar, wx.ID_ANY, wx.Bitmap(orpg.dirpath.dir_struct["icon"] + 'draw.gif', wx.BITMAP_TYPE_GIF), kind=wx.ITEM_CHECK, shortHelp="Freehand Line Tool", longHelp="Freehand Line Tool") - self.playerToolBar.AddButton(self.DrawBtn) - self.exclusiveToolList[self.DrawBtn.GetId()] = self.DrawBtn - self.Bind(wx.EVT_BUTTON, self.canvas.OnExlusiveBtn, id=self.DrawBtn.GetId()) - menu = wx.Menu("Line Tool") - item = wx.MenuItem(menu, 3, "Free Draw", "Free Draw") - self.Bind(wx.EVT_MENU, self.OnLineSelection, item) - menu.AppendItem(item) - item = wx.MenuItem(menu, 4, "Poly Draw", "Poly Draw") - self.Bind(wx.EVT_MENU, self.OnLineSelection, item) - menu.AppendItem(item) - self.currentLine = 'Free' - self.DrawBtn.SetMenu(menu) - - self.AddTextBtn = BP.ButtonInfo(self.playerToolBar, wx.ID_ANY, wx.Bitmap(orpg.dirpath.dir_struct["icon"] + 'text.png', wx.BITMAP_TYPE_PNG), kind=wx.ITEM_CHECK, shortHelp="Add Text Tool", longHelp="Add Text Tool") - self.playerToolBar.AddButton(self.AddTextBtn) - self.exclusiveToolList[self.AddTextBtn.GetId()] = self.AddTextBtn - self.Bind(wx.EVT_BUTTON, self.canvas.OnExlusiveBtn, id=self.AddTextBtn.GetId()) - - self.AddShapeBtn = BP.ButtonInfo(self.playerToolBar, wx.ID_ANY, wx.Bitmap(orpg.dirpath.dir_struct["icon"] + 'circle.png', wx.BITMAP_TYPE_PNG), kind=wx.ITEM_CHECK, shortHelp="Add Shape Tool", longHelp="Add Shape Tool") - self.playerToolBar.AddButton(self.AddShapeBtn) - self.exclusiveToolList[self.AddShapeBtn.GetId()] = self.AddShapeBtn - self.Bind(wx.EVT_BUTTON, self.canvas.OnExlusiveBtn, id=self.AddShapeBtn.GetId()) - menu = wx.Menu("Shape Tool") - item = wx.MenuItem(menu, 5, "Circle", "Circle") - self.Bind(wx.EVT_MENU, self.OnShapeSelection, item) - menu.AppendItem(item) - item = wx.MenuItem(menu, 6, "Rectangle", "Rectangle") - self.Bind(wx.EVT_MENU, self.OnShapeSelection, item) - menu.AppendItem(item) - item = wx.MenuItem(menu, 7, "Arc", "Arc") - self.Bind(wx.EVT_MENU, self.OnShapeSelection, item) - menu.AppendItem(item) - self.currentShape = 'Circle' - self.AddShapeBtn.SetMenu(menu) - - self.LineWidth = wx.Choice(self.playerToolBar, wx.ID_ANY, choices=["1","2","3","4","5","6","7","8","9","10"]) - self.LineWidth.SetSelection(0) - self.playerToolBar.AddControl(self.LineWidth) - - self.playerToolBar.AddSeparator() - - self.MiniBtn = BP.ButtonInfo(self.playerToolBar, wx.ID_ANY, wx.Bitmap(orpg.dirpath.dir_struct["icon"] + 'player.gif', wx.BITMAP_TYPE_GIF), kind=wx.ITEM_NORMAL, shortHelp="Add Mini", longHelp="Add Mini") - self.playerToolBar.AddButton(self.MiniBtn) - - self.playerToolBar.DoLayout() - - def OnShapeSelection(self, event): - id = event.GetId() - if id == 5: - self.currentShape = 'Circle' - self.AddShapeBtn.Bitmap = wx.Bitmap(orpg.dirpath.dir_struct["icon"] + 'circle.png', wx.BITMAP_TYPE_PNG) - elif id == 6: - self.currentShape = 'Rectangle' - self.AddShapeBtn.Bitmap = wx.Bitmap(orpg.dirpath.dir_struct["icon"] + 'rectangle.png', wx.BITMAP_TYPE_PNG) - elif id == 7: - self.currentShape = 'Arc' - self.AddShapeBtn.Bitmap = wx.Bitmap(orpg.dirpath.dir_struct["icon"] + 'arc.png', wx.BITMAP_TYPE_PNG) - - def OnLineSelection(self, event): - id = event.GetId() - if id == 3: - self.currentLine = 'Free' - self.DrawBtn.Bitmap = wx.Bitmap(orpg.dirpath.dir_struct["icon"] + 'draw.gif', wx.BITMAP_TYPE_GIF) - self.DrawBtn.SetShortHelp("Freehand Line Tool") - self.DrawBtn.SetLongHelp("Freehand Line Tool") - elif id == 4: - self.currentLine = 'Poly' - self.DrawBtn.Bitmap = wx.Bitmap(orpg.dirpath.dir_struct["icon"] + 'dash.png', wx.BITMAP_TYPE_PNG) - self.DrawBtn.SetShortHelp("Poly Line Tool") - self.DrawBtn.SetLongHelp("Poly Line Tool") - - def OnFogSelection(self, event): - id = event.GetId() - if id == 1: - self.currentFog = 'Show' - self.FogToolBtn.Bitmap = wx.Bitmap(orpg.dirpath.dir_struct["icon"] + 'showfog.png', wx.BITMAP_TYPE_PNG) - self.FogToolBtn.SetShortHelp("Show Fog Tool") - self.FogToolBtn.SetLongHelp("Show Fog Tool") - elif id == 2: - self.currentFog = 'Hide' - self.FogToolBtn.Bitmap = wx.Bitmap(orpg.dirpath.dir_struct["icon"] + 'hidefog.png', wx.BITMAP_TYPE_PNG) - self.FogToolBtn.SetShortHelp("Hide Fog Tool") - self.FogToolBtn.SetLongHelp("Hide Fog Tool") - -### Test Stuff -class BlankFrame(wx.Frame): - def __init__(self, openrpg): - wx.Frame.__init__(self, None, title="New Map Test Window", size=(740,480)) - - self.map = MapWnd(self, openrpg) - self.basesizer = wx.BoxSizer(wx.VERTICAL) - self.basesizer.Add(self.map, 1, wx.EXPAND) - - self.SetSizer(self.basesizer) - self.SetAutoLayout(True) - #self.Fit() - - -class BlankApp(wx.App): - def OnInit(self): - self.frame = BlankFrame() - self.frame.Show() - self.SetTopWindow(self.frame) - - - return True - -if __name__ == "__main__": - app = BlankApp(0) - app.MainLoop() \ No newline at end of file
--- a/orpg/map/_canvas.py Mon Feb 01 18:29:16 2010 -0600 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,994 +0,0 @@ -from threading import Lock -import mimetypes -import xml.dom.minidom as minidom - -import wx - -import orpg.dirpath -from orpg.orpgCore import * -from orpg.tools.rgbhex import RGBHex - -from _object import * - -from _circles import MapCircle -from _text import MapText -from _lines import MapLine -from _grid import GridLayer -from _fog import FogLayer - -USE_BUFFER = True -if "wxMAC" in wx.PlatformInfo: - USE_BUFFER = False - -class MapCanvas(wx.ScrolledWindow): - def __init__(self, parent, openrpg): - wx.ScrolledWindow.__init__(self, parent, wx.ID_ANY, style=wx.HSCROLL | wx.VSCROLL | wx.NO_FULL_REPAINT_ON_RESIZE | wx.SUNKEN_BORDER) - - self.openrpg = openrpg - self.log = self.openrpg.get_component("log") - self.xml = self.openrpg.get_component("xml") - self.dir_struct = self.openrpg.get_component("dir_struct") - self.validate = self.openrpg.get_component("validate") - self.settings = self.openrpg.get_component("settings") - self.session = self.openrpg.get_component("session") - self.chat = self.openrpg.get_component("chat") - - self.lock = Lock() - - self.RGBHex = RGBHex() - - self.toolWnd = parent - - self.shift = False - self.ctrl = False - - self.selectedObjects = [] - self.overObjects = [] - self._objectId = 0 - - self.gridLayer = GridLayer(self) - self.circleLayer = MapCircle(self) - self.textLayer = MapText(self) - self.lineLayer = MapLine(self) - self.fogLayer = FogLayer(self) - - self.zOrder = {} - self.zOrder['tiles'] = [] - self.zOrder["back"] = [] - self.zOrder["front"] = [] - - self.bgImage = None - self.bgType = 'Image' - self.bgPath = None - self.backgroundColor = '#008040' - - self.gridType = 'Square' - self.gridLines = wx.SOLID - self.gridSnap = True - self.gridSize = 60 - self.gridColor = "#000000" - - self.whiteboardColor = "#000000" - - self.zoomScale = 1.0 - self.lastZoomTime = time.time() - self.lastZoomScale = 1.0 - - self.useFog = False - self.fogRegion = [] - self.fogColor = "#000000" - - self.zoomScale = 1.0 - self.lastZoomTime = time.time() - self.lastZoomScale = 1.0 - self.zoomTimer = wx.Timer(self) - self.Bind(wx.EVT_TIMER, self.OnZoomTimer, self.zoomTimer) - #self.zoomTimer.Start(1000) - - self.imageCache = {} - - self._SetSize((1000,1000)) - - self.Bind(wx.EVT_PAINT, self.OnPaint) - self.Bind(wx.EVT_SIZE, self.OnSize) - self.Bind(wx.EVT_MOUSEWHEEL, self.OnZoom) - self.Bind(wx.EVT_LEFT_DOWN, self.OnLeftDown) - self.Bind(wx.EVT_LEFT_DCLICK, self.OnLeftDClick) - self.Bind(wx.EVT_LEFT_UP, self.OnLeftUp) - self.Bind(wx.EVT_RIGHT_DOWN, self.OnRightDown) - self.Bind(wx.EVT_MOTION, self.OnMotion) - self.Bind(wx.EVT_SCROLLWIN, self.OnScroll) - self.Bind(wx.EVT_CLOSE, self.OnClose) - self.Bind(wx.EVT_ERASE_BACKGROUND, self.OnBackground) - self.Bind(wx.EVT_KEY_DOWN, self.OnKey) - self.Bind(wx.EVT_KEY_UP, self.OnKey) - - self.Bind(EVT_ENTER_OBJECT, self.EnterObject) - self.Bind(EVT_LEAVE_OBJECT, self.LeaveObject) - self.Bind(EVT_SELECT_OBJECT, self.ObjectSelected) - self.Bind(EVT_DESELECT_OBJECT, self.ObjectDeselected) - - self.roleTimer = wx.Timer(self) - self.Bind(wx.EVT_TIMER, self.OnRoleTimer, self.roleTimer) - - wx.CallAfter(self.OnSize, None) - - - #Public API - def UpdateMap(self, send=True): - cdc = wx.ClientDC(self) - self.PrepareDC(cdc) - cdc.SetBackgroundMode(wx.TRANSPARENT) - if USE_BUFFER: - bdc = wx.BufferedDC(cdc, self._buffer) - bdc.Clear() - dc = wx.GraphicsContext.Create(bdc) - else: - cdc.Clear() - dc = wx.GraphicsContext.Create(cdc) - - - dc.SetPen(wx.TRANSPARENT_PEN) - dc.SetBrush(wx.TRANSPARENT_BRUSH) - - #Draw BG Color - r,g,b = self.RGBHex.rgb_tuple(self.backgroundColor) - brush = wx.Brush(wx.Color(r,g,b,255)) - dc.SetBrush(brush) - - path = dc.CreatePath() - - dc.PushState() - path.AddRectangle(0, 0, self.size[0]+2, self.size[1]+2) - dc.DrawPath(path) - dc.PopState() - - dc.SetBrush(wx.NullBrush) - - #Set the Zoom - dc.Scale(self.zoomScale, self.zoomScale) - - #Draw BG Image - if self.bgImage != None: - if self.bgType == 'Image': - dc.DrawBitmap(self.bgImage, self.offset[0], self.offset[1], self.bgImage.GetWidth(), self.bgImage.GetHeight()) - else: - bmpW = self.bgImage.GetWidth() - bmpH = self.bgImage.GetHeight() - - pos = wx.Point(self.offset[0], self.offset[1]) - while pos.x < self.size[0]: - dc.DrawBitmap(self.bgImage, pos.x, pos.y, self.bgImage.GetWidth(), self.bgImage.GetHeight()) - while pos.y < self.size[1]: - pos.y += bmpH - dc.DrawBitmap(self.bgImage, pos.x, pos.y, self.bgImage.GetWidth(), self.bgImage.GetHeight()) - pos.y = 0 - pos.x += bmpW - - #Draw Tiles - for tile in self.zOrder['tiles']: - tile.Draw(dc) - - #Draw Grid - self.gridLayer.Draw(dc) - - #Draw Objects - for object in self.zOrder['back']: - object.Draw(dc) - - zl = self.zOrder.keys() - zl.remove('back') - zl.remove('front') - zl.remove('tiles') - zl.sort() - - for layer in zl: - for object in self.zOrder[layer]: - object.Draw(dc) - - for object in self.zOrder['front']: - object.Draw(dc) - - - #Draw Fog - if self.useFog: - self.fogLayer.Draw(dc) - - dc.SetBrush(wx.NullBrush) - - dc.Scale(1/self.zoomScale, 1/self.zoomScale) - - if self.zoomScale != 1.0: - pos = self.GetViewStart() - unit = self.GetScrollPixelsPerUnit() - pos = [pos[0]*unit[0],pos[1]*unit[1]] - font = wx.Font(8, wx.DEFAULT, wx.NORMAL, wx.NORMAL) - dc.SetFont(font, wx.BLACK) - - dc.DrawText("Zoom Factor: " + str(self.zoomScale), pos[0], pos[1], dc.CreateBrush(wx.WHITE_BRUSH)) - - def Clear(self): - self._SetSize((1000,1000)) - self.selectedObjects = [] - self.overObjects = [] - self._objectId = 0 - self.bgImage = None - self.bgType = 'Image' - self.bgPath = None - - self.backgroundColor = '#008040' - r, g, b = self.RGBHex.rgb_tuple(self.backgroundColor) - self.toolWnd._SetColorBtn(wx.Color(r, g, b, 255), self.toolWnd.BGColorBtn) - - self.gridType = 'Square' - self.gridLines = wx.SOLID - self.gridSnap = True - self.gridSize = 60 - self.gridColor = "#000000" - - self.whiteboardColor = "#000000" - r, g, b = self.RGBHex.rgb_tuple(self.whiteboardColor) - self.toolWnd._SetColorBtn(wx.Color(r, g, b, 255), self.toolWnd.ColorBtn) - - self.zoomScale = 1.0 - self.lastZoomTime = time.time() - self.lastZoomScale = 1.0 - - self.useFog = False - self.fogRegion = [] - self.fogColor = "#000000" - - self.OnRemoveAllObjects(None) - - self.toolWnd.Freeze() - for btn in self.toolWnd.exclusiveToolList: - self.toolWnd.exclusiveToolList[btn].SetToggled(False) - - self.toolWnd.FogBtn.SetToggled(False) - self.toolWnd.SelectorBtn.SetToggled(True) - self.toolWnd.Thaw() - - def GetNewObjectId(self): - return str(self._objectId+1) - - #Map Events - def OnBackground(self, event): - #Dont do it - pass - - def OnPaint(self, event): - if USE_BUFFER: - dc = wx.PaintDC(self) - self.PrepareDC(dc) - dc.DrawBitmap(self._buffer, 0, 0) - else: - event.Skip() - - - def OnSize(self, event): - self._buffer = wx.EmptyBitmap(self.size[0], self.size[1]) - self._FixScroll() - wx.CallAfter(self.UpdateMap) - - - def OnZoom(self, event): - if event.GetWheelRotation() < 0: - self.zoomScale -= .1 - if self.zoomScale < .5: - self.zoomScale = .5 - else: - self.lastZoomTime = time.time() - self._FixScroll() - self.UpdateMap() - else: - self.zoomScale += .1 - - if self.zoomScale > 1.5: - self.zoomScale = 1.5 - else: - self.lastZoomTime = time.time() - self._FixScroll() - self.UpdateMap() - - def OnKey(self, event): - self.shift = False - self.ctrl = False - if event.ShiftDown(): - self.shift = True - elif event.ControlDown(): - self.ctrl = True - - - def EnterObject(self, event): - obj = event.GetObject() - self.overObjects.append(obj) - obj.Highlight() - - def LeaveObject(self, event): - obj = event.GetObject() - try: - self.overObjects.remove(obj) - except: - pass - obj.UnHighlight() - - def ObjectSelected(self, event): - obj = event.GetObject() - self.selectedObjects.append(obj) - try: - self.overObjects.remove(obj) - except: - pass - obj.UnHighlight() - - def ObjectDeselected(self, event): - obj = event.GetObject() - try: - self.selectedObjects.remove(obj) - except: - pass - obj.Update() - - def OnLeftDown(self, event): - dc = wx.ClientDC(self) - self.PrepareDC(dc) - pos = event.GetLogicalPosition(dc) - pos.x /= self.zoomScale - pos.y /= self.zoomScale - - if self.toolWnd.AddShapeBtn.GetToggled() and self.toolWnd.currentShape == 'Circle': - self.circleLayer.OnLeftDown(pos) - - elif self.toolWnd.AddTextBtn.GetToggled(): - self.textLayer.OnLeftDown(pos) - - elif self.toolWnd.DrawBtn.GetToggled(): - self.lineLayer.OnLeftDown(pos) - - elif self.toolWnd.SelectorBtn.GetToggled() and (self.selectedObjects == [] or self.ctrl or self.shift) and not (self.useFog and self.fogLayer.region.Contains(pos.x, pos.y) and not self.toolWnd.gmToolBar.IsShown()): - self.initiatPos = pos - self.lxd = 0 - self.lyd = 0 - if len(self.overObjects) == 0: - return - elif len(self.overObjects) == 1: - self.overObjects[0].Select() - else: - if not self.shift: - menu = wx.Menu("Object Selection") - id = 0 - for obj in self.overObjects: - menu.Append(id, obj.GetName()) - id += 1 - - def selectmenu(event): - id = event.GetId() - self.overObjects[id].Select() - self.Unbind(wx.EVT_MENU) - - self.Bind(wx.EVT_MENU, selectmenu) - self.PopupMenu(menu) - else: - for i in xrange(len(self.overObjects)): - self.overObjects[0].Select() - - elif self.toolWnd.SelectorBtn.GetToggled() and not self.selectedObjects == []: - xd = (self.initiatPos.x+pos.x)*(self.initiatPos.x+pos.x) - yd = (self.initiatPos.y+pos.y)*(self.initiatPos.y+pos.y) - - for i in xrange(len(self.selectedObjects)): - self.selectedObjects[0].Deselect() - - elif self.toolWnd.FogToolBtn.GetToggled(): - self.fogLayer.OnLeftDown(pos) - - def OnLeftDClick(self, event): - dc = wx.ClientDC(self) - self.PrepareDC(dc) - pos = event.GetLogicalPosition(dc) - pos.x /= self.zoomScale - pos.y /= self.zoomScale - - if self.toolWnd.DrawBtn.GetToggled(): - self.lineLayer.OnLeftDClick(pos) - - def OnLeftUp(self, event): - dc = wx.ClientDC(self) - self.PrepareDC(dc) - pos = event.GetLogicalPosition(dc) - pos.x /= self.zoomScale - pos.y /= self.zoomScale - - if self.toolWnd.AddShapeBtn.GetToggled() and self.toolWnd.currentShape == 'Circle': - self.circleLayer.OnLeftUp(pos) - - elif self.toolWnd.FogToolBtn.GetToggled(): - self.fogLayer.OnLeftUp(pos) - - elif self.toolWnd.DrawBtn.GetToggled(): - self.lineLayer.OnLeftUp(pos) - - elif self.toolWnd.SelectorBtn.GetToggled() and self.selectedObjects == []: - rgn = wx.Region(self.initiatPos.x, self.initiatPos.y, self.lxd, self.lyd) - - for object in self.zOrder['back']: - if rgn.Contains(object.start.x, object.start.y): - object.Select() - - zl = self.zOrder.keys() - zl.remove('back') - zl.remove('front') - zl.remove('tiles') - zl.sort() - - for layer in zl: - for object in self.zOrder[layer]: - if rgn.Contains(object.start.x, object.start.y): - object.Select() - - for object in self.zOrder['front']: - if rgn.Contains(object.start.x, object.start.y): - object.Select() - - self.lxd = 0 - self.lyd = 0 - self.initiatPos = pos - self.Refresh() - - def OnMotion(self, event): - dc = wx.ClientDC(self) - self.PrepareDC(dc) - pos = event.GetLogicalPosition(dc) - pos.x /= self.zoomScale - pos.y /= self.zoomScale - - - #HitTest - for object in self.zOrder['back']: - object.HitTest(pos) - - zl = self.zOrder.keys() - zl.remove('back') - zl.remove('front') - zl.remove('tiles') - zl.sort() - - for layer in zl: - for object in self.zOrder[layer]: - object.HitTest(pos) - - for object in self.zOrder['front']: - object.HitTest(pos) - - if self.toolWnd.AddShapeBtn.GetToggled() and event.m_leftDown and self.toolWnd.currentShape == 'Circle': - self.circleLayer.OnMotion(pos) - - elif self.toolWnd.DrawBtn.GetToggled() and self.lineLayer.start != wx.Point(0,0): - self.lineLayer.OnMotion(pos) - - elif self.toolWnd.SelectorBtn.GetToggled() and self.selectedObjects != [] and not (self.ctrl or self.shift): - xd = (pos.x-self.initiatPos.x) - yd = (pos.y-self.initiatPos.y) - for obj in self.selectedObjects: - obj.start.x += xd - obj.start.y += yd - obj.Update() - self.initiatPos = pos - - - elif self.toolWnd.SelectorBtn.GetToggled() and self.selectedObjects == [] and event.m_leftDown: - dc.SetBrush(wx.TRANSPARENT_BRUSH) - pen = wx.Pen(wx.BLACK, 3, wx.DOT) - dc.SetPen(pen) - dc.SetLogicalFunction(wx.INVERT) - - xd = (pos.x-self.initiatPos.x) - yd = (pos.y-self.initiatPos.y) - - if self.lxd != 0 and self.lyd != 0: - r = wx.Rect(self.initiatPos.x, self.initiatPos.y, self.lxd, self.lyd) - dc.DrawRectangleRect(r) - - self.lxd = xd - self.lyd = yd - r = wx.Rect(self.initiatPos.x, self.initiatPos.y, self.lxd, self.lyd) - dc.DrawRectangleRect(r) - - elif (self.toolWnd.FogToolBtn.GetToggled()) and event.m_leftDown: - self.fogLayer.OnMotion(pos) - - def OnRightDown(self, event): - mapmenu = wx.Menu() - - item = wx.MenuItem(mapmenu, wx.ID_ANY, "Load Map", "Load Map") - #self.Bind(wx.EVT_MENU, self.OnOpenBtn, item) - mapmenu.AppendItem(item) - - item = wx.MenuItem(mapmenu, wx.ID_ANY, "Save Map", "Save Map") - #self.Bind(wx.EVT_MENU, self.OnSaveBtn, item) - mapmenu.AppendItem(item) - - item = wx.MenuItem(mapmenu, wx.ID_ANY, "Default Map", "Default Map") - self.Bind(wx.EVT_MENU, self.OnDefaultBtn, item) - mapmenu.AppendItem(item) - - item = wx.MenuItem(mapmenu, wx.ID_ANY, "Map Properties", "Map Properties") - #self.Bind(wx.EVT_MENU, OnMapPropsBtn, item) - mapmenu.AppendItem(item) - - bgmenu = wx.Menu() - - item = wx.MenuItem(bgmenu, wx.ID_ANY, "Change Background Image", "Change Background Image") - self.Bind(wx.EVT_MENU, self.OnBGBtn, item) - bgmenu.AppendItem(item) - - item = wx.MenuItem(bgmenu, wx.ID_ANY, "Change Background Color", "Change Background Color") - self.Bind(wx.EVT_MENU, self.OnBGColorBtn, item) - bgmenu.AppendItem(item) - - item = wx.MenuItem(bgmenu, wx.ID_ANY, "Grid Properties", "Grid Properties") - #self.Bind(wx.EVT_MENU, self.OnGridBtn, item) - bgmenu.AppendItem(item) - - fogmenu = wx.Menu() - - item = wx.MenuItem(fogmenu, wx.ID_ANY, "Toggle Fog", "Toggle Fog") - self.Bind(wx.EVT_MENU, self.OnFogBtn, item) - fogmenu.AppendItem(item) - - item = wx.MenuItem(fogmenu, wx.ID_ANY, "Fog Color", "Fog Color") - self.Bind(wx.EVT_MENU, self.OnFogColorBtn, item) - fogmenu.AppendItem(item) - - menu = wx.Menu() - - if self.toolWnd.gmToolBar.IsShown(): - menu.AppendMenu(wx.ID_ANY, "Map", mapmenu) - menu.AppendMenu(wx.ID_ANY, "Background", bgmenu) - menu.AppendMenu(wx.ID_ANY, "Fog", fogmenu) - menu.AppendSeparator() - item = wx.MenuItem(menu, wx.ID_ANY, "Miniture Properties", "Miniture Properties") - #self.Bind(wx.EVT_MENU, self.OnColorBtn, item) - menu.AppendItem(item) - menu.AppendSeparator() - - item = wx.MenuItem(menu, wx.ID_ANY, "Whiteboard Color", "Whiteboard Color") - self.Bind(wx.EVT_MENU, self.OnColorBtn, item) - menu.AppendItem(item) - - - def ObjectMenu(event): - id = event.GetId() - objid = int(menu.GetHelpString(id)) - menuname = menu.GetLabel(id) - obj = self.overObjects[objid] - - if menuname == "Move To Back": - self.MoveToBack(obj) - - elif menuname == "Move Back": - self.MoveBack(obj) - - elif menuname == "Move Forward": - self.MoveForward(obj) - - elif menuname == "Move To Front": - self.MoveToFront(obj) - - elif menuname == "Remove": - self.zOrder[obj.zOrder].remove(obj) - obj.Update() - - self.Unbind(wx.EVT_MENU) - self.overObjects.remove(obj) - - - if len(self.overObjects): - menu.AppendSeparator() - - id = 0 - for obj in self.overObjects: - if obj.IsShown() or self.toolWnd.gmToolBar.IsShown(): - objmenu = wx.Menu() - item = wx.MenuItem(objmenu, wx.ID_ANY, "Move To Back", str(id)) - self.Bind(wx.EVT_MENU, ObjectMenu, item) - objmenu.AppendItem(item) - item = wx.MenuItem(objmenu, wx.ID_ANY, "Move Back", str(id)) - self.Bind(wx.EVT_MENU, ObjectMenu, item) - objmenu.AppendItem(item) - item = wx.MenuItem(objmenu, wx.ID_ANY, "Move Forward", str(id)) - self.Bind(wx.EVT_MENU, ObjectMenu, item) - objmenu.AppendItem(item) - item = wx.MenuItem(objmenu, wx.ID_ANY, "Move To Front", str(id)) - self.Bind(wx.EVT_MENU, ObjectMenu, item) - objmenu.AppendItem(item) - objmenu.AppendSeparator() - if obj.IsShown(): - item = wx.MenuItem(objmenu, wx.ID_ANY, "Hide", str(id)) - self.Bind(wx.EVT_MENU, obj.Hide, item) - objmenu.AppendItem(item) - objmenu.AppendSeparator() - elif self.toolWnd.gmToolBar.IsShown(): - item = wx.MenuItem(objmenu, wx.ID_ANY, "Show", str(id)) - self.Bind(wx.EVT_MENU, obj.Show, item) - objmenu.AppendItem(item) - objmenu.AppendSeparator() - item = wx.MenuItem(objmenu, wx.ID_ANY, "Remove", str(id)) - self.Bind(wx.EVT_MENU, ObjectMenu, item) - objmenu.AppendItem(item) - item = wx.MenuItem(objmenu, wx.ID_ANY, "Properties", str(id)) - self.Bind(wx.EVT_MENU, obj.ShowProperties, item) - objmenu.AppendItem(item) - menu.AppendMenu(wx.ID_ANY, obj.GetName(), objmenu) - - menu.AppendSeparator() - item = wx.MenuItem(menu, wx.ID_ANY, "Remove All Objects", "Remove All Whiteboard Items") - self.Bind(wx.EVT_MENU, self.OnRemoveAllObjects, item) - menu.AppendItem(item) - - self.PopupMenu(menu) - - - def OnRemoveAllObjects(self, event): - for layer in self.zOrder: - for i in xrange(len(self.zOrder[layer])): - del self.zOrder[layer][0] - - self.zOrder = {} - self.zOrder['tiles'] = [] - self.zOrder["back"] = [] - self.zOrder["front"] = [] - if event != None: - self.UpdateMap() - - def MoveToBack(self, object): - self.zOrder[object.zOrder].remove(object) - self.zOrder['back'].append(object) - object.zOrder = 'back' - self.UpdateMap() - - def MoveToFront(self, object): - self.zOrder[object.zOrder].remove(object) - self.zOrder['front'].append(object) - object.zOrder = 'front' - self.UpdateMap() - - def MoveBack(self, object): - self.zOrder[object.zOrder].remove(object) - - zl = self.zOrder.keys() - zl.remove('back') - zl.remove('front') - zl.remove('tiles') - zl.sort() - lzo = 1 - if len(zl): - lzo = zl.pop() - - if object.zOrder == 'back' or object.zOrder == 1: - self.zOrder['back'].append(object) - object.zOrder = 'back' - elif object.zOrder == 'front': - if not self.zOrder.has_key(lzo): - self.zOrder[lzo] = [] - self.zOrder[lzo].append(object) - object.zOrder = lzo - else: - object.zOrder -= 1 - if not self.zOrder.has_key(object.zOrder): - self.zOrder[object.zOrder] = [] - self.zOrder[object.zOrder].append(object) - self.UpdateMap() - - def MoveForward(self, object): - self.zOrder[object.zOrder].remove(object) - - zl = self.zOrder.keys() - zl.remove('back') - zl.remove('front') - zl.remove('tiles') - zl.sort() - lzo = 1 - if len(zl): - lzo = zl.pop() - - if object.zOrder == 'back': - if not self.zOrder.has_key(1): - self.zOrder[1] = [] - self.zOrder[1].append(object) - object.zOrder = 1 - elif z == 'front': - self.zOrder['front'].append(object) - object.zOrder = 'front' - else: - object.zOrder += 1 - if not self.zOrder.has_key(object.zOrder): - self.zOrder[object.zOrder] = [] - self.zOrder[object.zOrder].append(object) - self.UpdateMap() - - def OnScroll(self, event): - event.Skip() - self.Refresh() - - def OnZoomTimer(self, event): - if (time.time() - self.lastZoomTime) >= 3 and self.lastZoomScale != self.zoomScale: - #Send Zoome Notice to other clients - self.lastZoomTime = time.time() - self.lastZoomScale = self.zoomScale - - def OnRoleTimer(self, event): - #Figure out the users role - if self.session.my_role() == self.session.ROLE_GM: - self.role = 'GM' - elif self.session.my_role() == self.session.ROLE_PLAYER: - self.role = 'Player' - else: - self.role = 'Lurker' - - if self.role == 'GM' and not self.toolWnd.gmToolBar.IsShown() and not (str(self.session.group_id) == '0' and str(self.session.status) == '1'): - self.toolWnd.Freeze() - self.toolWnd.gmToolBar.Show() - self.toolWnd.Thaw() - elif self.role == 'Player' and not (str(self.session.group_id) == '0' and str(self.session.status) == '1'): - if self.toolWnd.gmToolBar.IsShown(): - self.toolWnd.Freeze() - self.toolWnd.gmToolBar.Hide() - self.toolWnd.Thaw() - - if not self.toolWnd.playerToolBar.IsShown(): - self.toolWnd.Freeze() - self.toolWnd.playerToolBar.Show() - self.toolWnd.Thaw() - elif self.role == 'Lurker' or (str(self.session.group_id) == '0' and str(self.session.status) == '1'): - if self.toolWnd.playerToolBar.IsShown(): - self.toolWnd.Freeze() - self.toolWnd.gmToolBar.Hide() - self.toolWnd.playerToolBar.Hide() - self.toolWnd.Thaw() - - try: - self.toolWnd.Layout() - except: - pass - - def OnClose(self, event): - self.zoomTimer.Stop() - self.roleTimer.Stop() - event.Skip() - - #Toolbar Events - def OnDefaultBtn(self, event): - self.Clear() - wx.CallAfter(self.UpdateMap) - - def OnColorBtn(self, event): - newcolor = self.RGBHex.do_hex_color_dlg(self.toolWnd) - if newcolor == None: - return - - self.whiteboardColor = newcolor - r, g, b = self.RGBHex.rgb_tuple(self.whiteboardColor) - self.toolWnd._SetColorBtn(wx.Color(r, g, b, 255), self.toolWnd.ColorBtn) - - def OnBGColorBtn(self, event): - newcolor = self.RGBHex.do_hex_color_dlg(self.toolWnd) - if newcolor == None: - return - - self.backgroundColor = newcolor - r, g, b = self.RGBHex.rgb_tuple(self.backgroundColor) - self.toolWnd._SetColorBtn(wx.Color(r, g, b, 255), self.toolWnd.BGColorBtn) - self.UpdateMap() - - def OnFogColorBtn(self, event): - newcolor = self.RGBHex.do_hex_color_dlg(self.toolWnd) - if newcolor == None: - return - - self.fogColor = newcolor - r, g, b = self.RGBHex.rgb_tuple(self.fogColor) - self.toolWnd._SetColorBtn(wx.Color(r, g, b, 255), self.toolWnd.FogColorBtn) - self.UpdateMap() - - def OnExlusiveBtn(self, event): - id = event.GetId() - #This is backwards because the Toggle Switch does not get set until AFTER The mouse gets released - if not self.toolWnd.exclusiveToolList[id].GetToggled(): - self.toolWnd.Freeze() - #Disable all mutualy exclusive tools - for btn in self.toolWnd.exclusiveToolList: - if self.toolWnd.exclusiveToolList[btn].GetId() != id: - self.toolWnd.exclusiveToolList[btn].SetToggled(False) - self.toolWnd.Thaw() - else: - wx.CallAfter(self.toolWnd.SelectorBtn.SetToggled, True) - - def OnFogBtn(self, event): - if not self.toolWnd.FogBtn.GetToggled(): - self.useFog = True - else: - self.useFog = False - self.toolWnd.Freeze() - self.toolWnd.SelectorBtn.SetToggled(True) - self.toolWnd.FogToolBtn.SetToggled(False) - self.toolWnd.Thaw() - self.fogRegion = [] - self.UpdateMap() - - def OnBGBtn(self, event): - dlg = wx.Dialog(self.toolWnd, wx.ID_ANY, title="Background Properties") - sizer = wx.BoxSizer(wx.HORIZONTAL) - - filename = wx.TextCtrl(dlg, wx.ID_ANY) - filename.Hide() - - bgpath = wx.TextCtrl(dlg, wx.ID_ANY) - if self.bgPath != None: - bgpath.SetValue(self.bgPath) - - bgtype = wx.Choice(dlg, wx.ID_ANY, choices=['Image', 'Texture']) - bgtype.SetStringSelection(self.bgType) - - browsebtn = wx.Button(dlg, wx.ID_ANY, "Browse") - okbtn = wx.Button(dlg, wx.ID_OK) - cancelbtn = wx.Button(dlg, wx.ID_CANCEL) - - sizer.Add(wx.StaticText(dlg, wx.ID_ANY, "Image Path"), 0, wx.ALIGN_CENTER_VERTICAL|wx.ALL, 2) - sizer.Add(bgpath, 0, wx.EXPAND|wx.ALL, 3) - sizer.Add(wx.StaticText(dlg, wx.ID_ANY, "Image Type"), 0, wx.ALIGN_CENTER_VERTICAL|wx.ALL, 2) - sizer.Add(bgtype, 0, wx.ALIGN_CENTER_VERTICAL|wx.ALL, 3) - sizer.Add(browsebtn, 0, wx.EXPAND|wx.ALL, 2) - sizer.Add(okbtn, 0, wx.EXPAND|wx.ALL, 3) - sizer.Add(cancelbtn, 0, wx.EXPAND|wx.ALL, 2) - - dlg.SetSizer(sizer) - dlg.SetAutoLayout(True) - dlg.Fit() - - def OnBrowse(event): - filedlg = wx.FileDialog(self, "Select an Image File", self.dir_struct["user"], wildcard="Image files (*.bmp, *.gif, *.jpg, *.png)|*.bmp;*.gif;*.jpg;*.png", style=wx.HIDE_READONLY|wx.OPEN) - if filedlg.ShowModal() != wx.ID_OK: - filedlg.Destroy() - return - - bgpath.SetValue(filedlg.GetPath()) - filename.SetValue(filedlg.GetFilename()) - - dlg.Bind(wx.EVT_BUTTON, OnBrowse, browsebtn) - dlg.Show() - - if not dlg.ShowModal() == wx.ID_OK: - dlg.Destroy() - return - - self.bgType = bgtype.GetStringSelection() - - if bgpath.GetValue().lower().find('http:') == -1: - file = open(bgpath.GetValue(), "rb") - imgdata = file.read() - file.close() - - (imgtype,j) = mimetypes.guess_type(filename.GetValue()) - - postdata = urllib.urlencode({'filename':filename.GetValue(), 'imgdata':imgdata, 'imgtype':imgtype}) - - thread.start_new_thread(self.__Upload, (postdata, bgpath.GetValue(), "Background")) - else: - self.bgImage = self._LoadImage(bgpath.GetValue()) - self.UpdateMap() - - - #Private Methods - def _SetSize(self, size): - if size[0] == -1: - size[0] = self.size[0] - if size[1] == -1: - size[1] = self.size[1] - - if size[0] < 300: - size = (300, size[1]) - if size[1] < 300: - size = (size[0], 300) - - size1 = self.GetClientSizeTuple() - - if size[0] < size1[0]: - size = (size1[0], size[1]) - if size[1] < size1[1]: - size = (size[0], size1[1]) - - self.sizeChanged = 1 - self.size = size - self._FixScroll() - - def _FixScroll(self): - scale = self.zoomScale - pos = self.GetViewStart() - unit = self.GetScrollPixelsPerUnit() - pos = [pos[0]*unit[0],pos[1]*unit[1]] - size = self.GetClientSize() - unit = [10*scale,10*scale] - if (unit[0] == 0 or unit[1] == 0): - return - pos[0] /= unit[0] - pos[1] /= unit[1] - mx = [int(self.size[0]*scale/unit[0])+1, int(self.size[1]*scale/unit[1]+1)] - self.SetScrollbars(unit[0], unit[1], mx[0], mx[1], pos[0], pos[1]) - - def _LoadImage(self, path, miniId=None): - if self.imageCache.has_key(path): - return self.imageCache[path] - - while len(self.imageCache) > int(self.settings.get_setting("ImageCacheSize")): - keys = self.imageCache.keys() - del self.imageCache[keys[0]] - - - thread.start_new_thread(self.__DownloadImage, (path, miniId)) - - return wx.Bitmap(orpg.dirpath.dir_struct["icon"] + "fetching.png", wx.BITMAP_TYPE_PNG) - - def _ClearCache(self): - for key in self.imageCache: - del self.imageCache[key] - - #Threads - def __Upload(self, postdata, filename, type="Background"): - self.lock.acquire() - - url = self.settings.get_setting('ImageServerBaseURL') - file = urllib.urlopen(url, postdata) - recvdata = file.read() - file.close() - try: - xml_dom = minidom.parseString(recvdata)._get_documentElement() - - if xml_dom.nodeName == 'path': - path = xml_dom.getAttribute('url') - path = urllib.unquote(path) - - if type == 'Background': - self.bgImage = self._LoadImage(path) - self.bgPath = path - - else: - self.minis.append(self.mapLayer.AddMiniture(path)) - - self.UpdateMap() - - else: - self.chat.InfoPost(xml_dom.getAttribute('msg')) - except Exception, e: - print e - print recvdata - - self.lock.release() - - def __DownloadImage(self, path, miniId): - self.lock.acquire() - - uriPath = urllib.unquote(path) - try: - data = urllib.urlretrieve(uriPath) - - if data[0] and data[1].getmaintype() == "image": - imageType = data[1].gettype() - img = wx.ImageFromMime(data[0], imageType).ConvertToBitmap() - self.imageCache[path] = img - - if miniId == None: - self.bgImage = img - if self.bgType == 'Image': - self._SetSize((img.GetHeight(), img.GetWidth())) - - else: - mini = self.GetMiniById(miniId) - mini.image = img - - self.UpdateMap() - except Exception, e: - self.chat.InfoPost("Unable to resolve/open the specified URI; image was NOT laoded:" + path) - - urllib.urlcleanup() - self.lock.release() \ No newline at end of file
--- a/orpg/map/_circles.py Mon Feb 01 18:29:16 2010 -0600 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,168 +0,0 @@ -from math import sqrt - -import wx - -import orpg.dirpath -from orpg.orpgCore import * - -from _object import MapObject - -class MapCircle(MapObject): - def __init__(self, canvas, center=wx.Point(0,0), radius=0, color="#000000"): - MapObject.__init__(self, canvas=canvas) - self.start = center - self.radius = int(radius) - self.color = color - - r, g, b = self.RGBHex.rgb_tuple(self.color) - self.hcolor = self.RGBHex.hexstring(r^255, g^255, b^255) - - self.id = 'circle-' + self.canvas.GetNewObjectId() - - - def Draw(self, dc): - path = dc.CreatePath() - - if not self.highlighed: - c = self.color - else: - c = self.hcolor - r, g, b = self.RGBHex.rgb_tuple(c) - - pen = wx.TRANSPARENT_PEN - brush = wx.TRANSPARENT_BRUSH - if self.IsShown(): - brush = wx.Brush(wx.Color(r, g, b, 128)) - pen = wx.Pen(wx.Color(r, g, b, 128)) - elif self.canvas.toolWnd.gmToolBar.IsShown(): - brush = wx.Brush(wx.Color(r, g, b, 40)) - pen = wx.Pen(wx.Color(r, g, b, 40)) - font = wx.Font(12, wx.DEFAULT, wx.NORMAL, wx.NORMAL) - dc.SetFont(font, wx.RED) - w, h = dc.GetTextExtent("Hidden") - dc.DrawText("Hidden", self.start.x-(w/2), self.start.y-(h/2), dc.CreateBrush(wx.WHITE_BRUSH)) - - dc.SetBrush(brush) - dc.SetPen(pen) - - path.AddCircle(self.start.x, self.start.y, self.radius) - path.CloseSubpath() - dc.DrawPath(path) - - dc.SetBrush(wx.NullBrush) - dc.SetPen(wx.NullPen) - - if self.selected: - self.DrawSelection(dc) - - def DrawSelection(self, dc): - dc.SetBrush(wx.GREEN_BRUSH) - dc.SetPen(wx.GREEN_PEN) - path = dc.CreatePath() - - path.AddRectangle(self.start.x-self.radius, self.start.y-self.radius, 5, 5) - path.AddRectangle(self.start.x-self.radius, self.start.y+self.radius, 5, 5) - path.AddRectangle(self.start.x+self.radius, self.start.y-self.radius, 5, 5) - path.AddRectangle(self.start.x+self.radius, self.start.y+self.radius, 5, 5) - - path.MoveToPoint(self.start.x, self.start.y) - path.AddLineToPoint(self.start.x-10, self.start.y) - path.MoveToPoint(self.start.x, self.start.y) - path.AddLineToPoint(self.start.x, self.start.y+10) - path.MoveToPoint(self.start.x, self.start.y) - path.AddLineToPoint(self.start.x+10, self.start.y) - path.MoveToPoint(self.start.x, self.start.y) - path.AddLineToPoint(self.start.x, self.start.y-10) - - dc.DrawPath(path) - - dc.SetBrush(wx.NullBrush) - dc.SetPen(wx.NullPen) - - def InObject(self, pos): - xd = (self.start.x-pos.x)*(self.start.x-pos.x) - yd = (self.start.y-pos.y)*(self.start.y-pos.y) - distance = sqrt(xd+yd) - - if distance <= self.radius: - return True - - return False - - def GetName(self): - return 'Circle: ' + str(self.id) + ' Radius:' + str(self.radius) + ' Color:' + self.color - - def ShowProperties(self, event): - dlg = wx.Dialog(self.canvas, wx.ID_ANY, "Circle Properties") - sizer = wx.BoxSizer(wx.HORIZONTAL) - - radius = wx.TextCtrl(dlg, wx.ID_ANY) - radius.SetValue(str(self.radius)) - - colorbtn = wx.Button(dlg, wx.ID_ANY, "Color") - colorbtn.SetForegroundColour(self.hcolor) - - def ColorBtn(event): - newcolor = self.RGBHex.do_hex_color_dlg(self.canvas) - if newcolor == None: - return - - colorbtn.SetForegroundColour(newcolor) - dlg.Unbind(wx.EVT_BUTTON) - - dlg.Bind(wx.EVT_BUTTON, ColorBtn, colorbtn) - - sizer.Add(wx.StaticText(dlg, wx.ID_ANY, "Radius:"), 0, wx.ALIGN_CENTER_VERTICAL|wx.ALL, 2) - sizer.Add(radius, 0, wx.EXPAND|wx.ALL, 3) - sizer.Add(colorbtn, 0, wx.ALL, 2) - sizer.Add(wx.Button(dlg, wx.ID_OK), 0, wx.ALL, 3) - - dlg.SetSizer(sizer) - dlg.SetAutoLayout(True) - dlg.Fit() - dlg.Show() - - if dlg.ShowModal() == wx.ID_OK: - self.radius = int(radius.GetValue()) - r,g,b = colorbtn.GetForegroundColour().Get() - self.color = self.RGBHex.hexstring(r, g, b) - self.hcolor = self.RGBHex.hexstring(r^255, g^255, b^255) - self.Update(send=True, action="update") - - - def OnLeftDown(self, pos): - self.start = pos - self.lastRadius = 0 - self.radius = 0 - - def OnMotion(self, pos): - dc = wx.ClientDC(self.canvas) - self.canvas.PrepareDC(dc) - dc.SetLogicalFunction(wx.EQUIV) - dc.SetUserScale(self.canvas.zoomScale, self.canvas.zoomScale) - - - if self.radius > 0: - dc.DrawCircle(self.start.x, self.start.y, self.radius) - - xd = (self.start.x-pos.x)*(self.start.x-pos.x) - yd = (self.start.y-pos.y)*(self.start.y-pos.y) - self.radius = sqrt(xd+yd) - - #self.lastRadius = self.radius - dc.DrawCircle(self.start.x, self.start.y, self.radius) - - def OnLeftUp(self, pos): - xd = (self.start.x-pos.x)*(self.start.x-pos.x) - yd = (self.start.y-pos.y)*(self.start.y-pos.y) - radius = sqrt(xd+yd) - - if radius > 15: - self.canvas.zOrder['front'].append(MapCircle(self.canvas, self.start, radius, self.canvas.whiteboardColor)) - self.Update(send=True, action='new') - self.lastRadius = 0 - self.start = wx.Point(0,0) - self.radius = 0 - - def _toxml(self, action="update"): - return '' \ No newline at end of file
--- a/orpg/map/_fog.py Mon Feb 01 18:29:16 2010 -0600 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,92 +0,0 @@ -from math import sqrt - -import wx - -import orpg.dirpath -from orpg.orpgCore import * - -from _object import MapObject - -class FogLayer(MapObject): - def __init__(self, canvas): - MapObject.__init__(self, canvas=canvas) - - def Draw(self, dc): - path = dc.CreatePath() - r, g, b = self.RGBHex.rgb_tuple(self.canvas.fogColor) - if self.canvas.toolWnd.gmToolBar.IsShown(): - brush = wx.Brush(wx.Color(r, g, b, 128)) - else: - brush = wx.Brush(wx.Color(r, g, b, 255)) - dc.SetBrush(brush) - - self.region = wx.Region(0, 0, self.canvas.size[0]+2, self.canvas.size[1]+2) - - points = [] - lp = 's' - for point in self.canvas.fogRegion: - if point == 's' or point == 'h': - if lp == 's' and len(points) > 0: - self.region.XorRegion(wx.RegionFromPoints(points)) - self.region.SubtractRegion(wx.RegionFromPoints(points)) - elif len(points) > 0: - self.region.UnionRegion(wx.RegionFromPoints(points)) - lp = point - points = [] - else: - points.append((point.x, point.y)) - - if len(points) > 0: - if lp == 's': - self.region.XorRegion(wx.RegionFromPoints(points)) - self.region.SubtractRegion(wx.RegionFromPoints(points)) - else: - self.region.UnionRegion(wx.RegionFromPoints(points)) - - dc.ClipRegion(self.region) - - dc.DrawRectangle(0, 0, self.canvas.size[0]+2, self.canvas.size[1]+2) - - dc.SetBrush(wx.NullBrush) - - def OnLeftDown(self, pos): - self.start = pos - self.lastPoint = pos - if self.canvas.toolWnd.currentFog == 'Show': - self.canvas.fogRegion.append('s') - else: - self.canvas.fogRegion.append('h') - self.canvas.fogRegion.append(pos) - - def OnMotion(self, pos): - cdc = wx.ClientDC(self.canvas) - self.canvas.PrepareDC(cdc) - - dc = wx.GraphicsContext.Create(cdc) - dc.Scale(self.canvas.zoomScale, self.canvas.zoomScale) - - dc.SetPen(wx.WHITE_PEN) - - path = dc.CreatePath() - - xd = (self.lastPoint.x-pos.x)*(self.lastPoint.x-pos.x) - yd = (self.lastPoint.y-pos.y)*(self.lastPoint.y-pos.y) - distance = sqrt(xd+yd) - - if distance > 5: - path.MoveToPoint(self.lastPoint.x, self.lastPoint.y) - path.AddLineToPoint(pos.x, pos.y) - - self.canvas.fogRegion.append(pos) - self.lastPoint = pos - - path.CloseSubpath() - dc.StrokePath(path) - - dc.SetPen(wx.NullPen) - - def OnLeftUp(self, pos): - self.canvas.fogRegion.append(pos) - self.canvas.fogRegion.append(self.start) - self.canvas.UpdateMap() -
--- a/orpg/map/_grid.py Mon Feb 01 18:29:16 2010 -0600 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,39 +0,0 @@ -import wx - -import orpg.dirpath -from orpg.orpgCore import * -from orpg.tools.rgbhex import RGBHex - -class GridLayer: - def __init__(self, canvas): - self.canvas = canvas - self.RGBHex = RGBHex() - - def Draw(self, dc): - r, g, b = self.RGBHex.rgb_tuple(self.canvas.gridColor) - pen = wx.Pen(wx.Color(r, g, b, 255), 1, self.canvas.gridLines) - dc.SetPen(pen) - - path = dc.CreatePath() - - if self.canvas.gridType == 'Square': - self._DrawSquare(dc, path) - - dc.SetPen(wx.NullPen) - - def _DrawSquare(self, dc, path): - path.MoveToPoint(0, 0) - y = 0 - while y < self.canvas.size[1]: - path.AddLineToPoint(self.canvas.size[0], y) - y += self.canvas.gridSize - path.MoveToPoint(0, y) - - path.MoveToPoint(0, 0) - x = 0 - while x < self.canvas.size[0]: - path.AddLineToPoint(x, self.canvas.size[0]) - x += self.canvas.gridSize - path.MoveToPoint(x, 0) - - dc.StrokePath(path) \ No newline at end of file
--- a/orpg/map/_lines.py Mon Feb 01 18:29:16 2010 -0600 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,157 +0,0 @@ -from math import sqrt - -import wx - -import orpg.dirpath -from orpg.orpgCore import * - -from _object import MapObject - -class MapLine(MapObject): - def __init__(self, canvas, start=wx.Point(0,0), width=1, color="#000000", points=[]): - MapObject.__init__(self, canvas=canvas) - self.start = wx.Point(start[0], start[1]) - self.color = color - self.points = points - self.width = width - - r, g, b = self.RGBHex.rgb_tuple(self.color) - self.hcolor = self.RGBHex.hexstring(r^255, g^255, b^255) - - self.id = 'line-' + self.canvas.GetNewObjectId() - - - def Draw(self, dc): - path = dc.CreatePath() - - if not self.highlighed: - c = self.color - else: - c = self.hcolor - r, g, b = self.RGBHex.rgb_tuple(c) - - pen = wx.Pen(wx.Color(r, g, b, 0), self.width) - if self.IsShown(): - pen = wx.Pen(wx.Color(r, g, b, 255), self.width) - elif self.canvas.toolWnd.gmToolBar.IsShown(): - pen = wx.Pen(wx.Color(r, g, b, 40), self.width) - dc.SetPen(pen) - - dc.DrawLines(self.points) - - dc.SetBrush(wx.NullBrush) - dc.SetPen(wx.NullPen) - - if self.selected: - self.DrawSelection(dc) - - def DrawSelection(self, dc): - dc.SetBrush(wx.GREEN_BRUSH) - dc.SetPen(wx.GREEN_PEN) - path = dc.CreatePath() - - dc.DrawPath(path) - - dc.SetBrush(wx.NullBrush) - dc.SetPen(wx.NullPen) - - def InObject(self, pos): - for point in self.points: - xd = (point[0]-pos.x)*(point[0]-pos.x) - yd = (point[1]-pos.y)*(point[1]-pos.y) - distance = sqrt(xd+yd) - - if distance <= self.width+1: - return True - - return False - - def GetName(self): - return self.id + ' Color:' + self.color - - def ShowProperties(self, event): - dlg = wx.Dialog(self.canvas, wx.ID_ANY, "Circle Properties") - sizer = wx.BoxSizer(wx.HORIZONTAL) - - radius = wx.TextCtrl(dlg, wx.ID_ANY) - radius.SetValue(str(self.radius)) - - colorbtn = wx.Button(dlg, wx.ID_ANY, "Color") - colorbtn.SetForegroundColour(self.hcolor) - - def ColorBtn(event): - newcolor = self.RGBHex.do_hex_color_dlg(self.canvas) - if newcolor == None: - return - - colorbtn.SetForegroundColour(newcolor) - dlg.Unbind(wx.EVT_BUTTON) - - dlg.Bind(wx.EVT_BUTTON, ColorBtn, colorbtn) - - sizer.Add(wx.StaticText(dlg, wx.ID_ANY, "Radius:"), 0, wx.ALIGN_CENTER_VERTICAL|wx.ALL, 2) - sizer.Add(radius, 0, wx.EXPAND|wx.ALL, 3) - sizer.Add(colorbtn, 0, wx.ALL, 2) - sizer.Add(wx.Button(dlg, wx.ID_OK), 0, wx.ALL, 3) - - dlg.SetSizer(sizer) - dlg.SetAutoLayout(True) - dlg.Fit() - dlg.Show() - - if dlg.ShowModal() == wx.ID_OK: - self.radius = int(radius.GetValue()) - r,g,b = colorbtn.GetForegroundColour().Get() - self.color = self.RGBHex.hexstring(r, g, b) - self.hcolor = self.RGBHex.hexstring(r^255, g^255, b^255) - self.Update(send=True, action="update") - - - def OnLeftDown(self, pos): - self.lastPoint = pos - self.start = pos - self.points.append((pos.x, pos.y)) - - def OnMotion(self, pos): - dc = wx.ClientDC(self.canvas) - self.canvas.PrepareDC(dc) - - r,g,b = self.RGBHex.rgb_tuple(self.canvas.whiteboardColor) - pen = wx.Pen(wx.Color(r,g,b,255), int(self.canvas.toolWnd.LineWidth.GetStringSelection())) - dc.SetPen(pen) - - xd = (self.lastPoint.x-pos.x)*(self.lastPoint.x-pos.x) - yd = (self.lastPoint.y-pos.y)*(self.lastPoint.y-pos.y) - distance = sqrt(xd+yd) - - if distance > 5: - if self.canvas.toolWnd.currentLine == 'Free': - self.points.append((pos.x, pos.y)) - self.lastPoint = pos - dc.DrawLines(self.points) - else: - dc.SetLogicalFunction(wx.INVERT) - dc.DrawLine(self.start.x, self.start.y, self.lastPoint.x, self.lastPoint.y) - dc.DrawLine(self.start.x, self.start.y, pos.x, pos.y) - dc.SetLogicalFunction(wx.COPY) - dc.DrawLines(self.points) - self.lastPoint = pos - - dc.SetPen(wx.NullPen) - - def OnLeftUp(self, pos): - if self.canvas.toolWnd.currentLine == 'Free' and len(self.points) > 2: - self.points.append((pos.x, pos.y)) - self.canvas.zOrder['front'].append(MapLine(self.canvas, self.points[0], int(self.canvas.toolWnd.LineWidth.GetStringSelection()), self.canvas.whiteboardColor, self.points)) - self.start = wx.Point(0,0) - self.points = [] - - def OnLeftDClick(self, pos): - if self.canvas.toolWnd.currentLine == 'Poly' and len(self.points) > 2: - self.points.append((pos.x, pos.y)) - self.canvas.zOrder['front'].append(MapLine(self.canvas, self.points[0], int(self.canvas.toolWnd.LineWidth.GetStringSelection()), self.canvas.whiteboardColor, self.points)) - self.points = [] - self.start = wx.Point(0,0) - - def _toxml(self, action="update"): - return '' \ No newline at end of file
--- a/orpg/map/_object.py Mon Feb 01 18:29:16 2010 -0600 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,165 +0,0 @@ -from math import sqrt - -import wx - -import orpg.dirpath -from orpg.orpgCore import * -from orpg.tools.rgbhex import RGBHex - -wxEVT_ENTER_OBJECT = wx.NewEventType() -wxEVT_LEAVE_OBJECT = wx.NewEventType() -wxEVT_SELECT_OBJECT = wx.NewEventType() -wxEVT_DESELECT_OBJECT = wx.NewEventType() -EVT_ENTER_OBJECT = wx.PyEventBinder(wxEVT_ENTER_OBJECT) -EVT_LEAVE_OBJECT = wx.PyEventBinder(wxEVT_LEAVE_OBJECT) -EVT_SELECT_OBJECT = wx.PyEventBinder(wxEVT_SELECT_OBJECT) -EVT_DESELECT_OBJECT = wx.PyEventBinder(wxEVT_DESELECT_OBJECT) - -class ObjectEvent(wx.PyCommandEvent): - def __init__(self, eventType, object): - wx.PyCommandEvent.__init__(self, eventType) - - self._object = object - - self._eventType = eventType - self.notify = wx.NotifyEvent(eventType, -1) - - def GetNotifyEvent(self): - return self.notify - - def GetObject(self): - return self._object - - def GetId(self): - return self._object.GetId() - -class MapObject: - def __init__(self, **kwargs): - self.id = -1 - self.start = wx.Point(0,0) - self.color = "#000000" - self.hcolor = "#ffffff" - self.lineWidth = 1 - self.zOrder = 'front' - self.selected = False - self.inObject = False - self.highlighed = False - self.isshown = True - self.canvas = None - self.RGBHex = RGBHex() - self.trans = 1 - - for atter, value in kwargs.iteritems(): - setattr(self, atter, value) - - try: - if self.id == wx.ID_ANY: - self.id = wx.NewId() - except: - self.id = wx.NewId() - - #Public Methods - def HitTest(self, pos): - if self.InObject(pos) and not self.inObject and not self.selected: - self.inObject = True - evt = ObjectEvent(wxEVT_ENTER_OBJECT, self) - self.canvas.GetEventHandler().ProcessEvent(evt) - elif not self.InObject(pos) and self.inObject and not self.selected: - self.inObject = False - evt = ObjectEvent(wxEVT_LEAVE_OBJECT, self) - self.canvas.GetEventHandler().ProcessEvent(evt) - - def GetId(self): - return self.id - - def IsShown(self): - return self.isshown - - def Show(self, event=None, show=True): - self.isshown = show - self.Update(send=True, action="update") - - def Hide(self, event=None): - self.isshown = False - self.Update(send=True, action="update") - - def IsSelected(self): - return self.selected - - def Select(self, select=True): - self.selected = select - - if select: - evt = ObjectEvent(wxEVT_SELECT_OBJECT, self) - else: - evt = ObjectEvent(wxEVT_DESELECT_OBJECT, self) - - self.canvas.GetEventHandler().ProcessEvent(evt) - - def Deselect(self): - self.selected = False - evt = ObjectEvent(wxEVT_DESELECT_OBJECT, self) - self.canvas.GetEventHandler().ProcessEvent(evt) - - def Update(self, send=False, action="update"): - self.canvas.UpdateMap() - if send: - self.canvas.session.send(self._toxml(action)) - - def GetName(self): - return 'ID: ' + str(self.id) + ' Color: ' + self.color - - def InObject(self, pos): - pass - - def Draw(self, dc): - if self.selected: - self.DrawSelected(dc) - - def DrawSelected(self, dc): - pass - - def Highlight(self): - self.highlighed = True - self.Update() - - def UnHighlight(self): - self.highlighed = False - self.Update() - - def OnLeftDown(self, pos): - if self.inObject and self.selected: - self.start = pos - self.Deselect() - - elif self.inObject and not self.selected: - self.Select() - - else: - self.start = pos - - self.Update() - - def OnMotion(self, pos): - cdc = wx.ClientDC(self.canvas) - self.canvas.PrepareDC(cdc) - dc = wx.GraphicsContext.Create(cdc) - - if self.selected: - self.start = pos - self.Draw(dc) - - def OnLeftUp(self, pos): - pass - - def OnRightDown(self, pos): - pass - - def OnLeftDClick(self, pos): - pass - - def ShowProperties(self, event): - pass - - def _toxml(self, action="update"): - return '' \ No newline at end of file
--- a/orpg/map/_text.py Mon Feb 01 18:29:16 2010 -0600 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,161 +0,0 @@ -from math import sqrt - -import wx - -import orpg.dirpath -from orpg.orpgCore import * - -from _object import MapObject - -class MapText(MapObject): - def __init__(self, canvas, start=wx.Point(0,0), text='', size=12, weight=wx.NORMAL, style=wx.NORMAL, color="#000000"): - MapObject.__init__(self, canvas=canvas) - self.start = start - self.color = color - self.text = text - self.weight = weight - self.style = style - self.size = size - - r, g, b = self.RGBHex.rgb_tuple(self.color) - self.hcolor = self.RGBHex.hexstring(r^255, g^255, b^255) - - self.id = 'text-' + self.canvas.GetNewObjectId() - - - def Draw(self, dc): - if not self.highlighed: - c = self.color - else: - c = self.hcolor - - font = wx.Font(self.size, wx.DEFAULT, self.weight, self.style) - dc.SetFont(font, c) - w, h = dc.GetTextExtent(self.text) - - - if self.IsShown(): - dc.DrawText(self.text, self.start.x-(w/2), self.start.y-(h/2)) - elif self.canvas.toolWnd.gmToolBar.IsShown(): - r, g, b = self.RGBHex.rgb_tuple(c) - dc.SetFont(font, wx.Color(r, g, b, 40)) - dc.DrawText(self.text, self.start.x-(w/2), self.start.y-(h/2)) - - - if self.selected: - self.DrawSelection(dc) - - def DrawSelection(self, dc): - w, h = dc.GetTextExtent(self.text) - dc.SetBrush(wx.GREEN_BRUSH) - dc.SetPen(wx.GREEN_PEN) - path = dc.CreatePath() - - path.AddRectangle(self.start.x-((w/2)+1), self.start.y-((h/2)+1), 5, 5) - path.AddRectangle(self.start.x-((w/2)+1), self.start.y+((h/2)+1), 5, 5) - path.AddRectangle(self.start.x+((w/2)+1), self.start.y-((h/2)+1), 5, 5) - path.AddRectangle(self.start.x+((w/2)+1), self.start.y+((h/2)+1), 5, 5) - - dc.DrawPath(path) - - dc.SetBrush(wx.NullBrush) - dc.SetPen(wx.NullPen) - - def InObject(self, pos): - dc = wx.ClientDC(self.canvas) - self.canvas.PrepareDC(dc) - font = wx.Font(self.size, wx.DEFAULT, self.weight, self.style) - w, h = dc.GetTextExtent(self.text) - rgn = wx.RegionFromPoints([(self.start.x-(w/2), self.start.y-(h/2)), (self.start.x-(w/2), self.start.y+(h/2)), (self.start.x+(w/2), self.start.y-(h/2)), (self.start.x+(w/2), self.start.y+(h/2))]) - - if rgn.Contains(pos.x, pos.y): - return True - - return False - - def GetName(self): - return self.text + ' Color:' + self.color - - def ShowProperties(self, event): - dlg = wx.Dialog(self.canvas, wx.ID_ANY, "Circle Properties") - sizer = wx.BoxSizer(wx.HORIZONTAL) - - text = wx.TextCtrl(dlg, wx.ID_ANY) - text.SetValue(self.text) - - colorbtn = wx.Button(dlg, wx.ID_ANY, "Color") - colorbtn.SetForegroundColour(self.color) - - size = wx.SpinCtrl(dlg, wx.ID_ANY, value=str(self.size), min=7, initial=12, name="Font Size: ") - - weight = wx.Choice(dlg, wx.ID_ANY, choices=["Normal", "Bold"]) - if self.weight == wx.NORMAL: - weight.SetSelection(0) - else: - weight.SetSelection(1) - - style = wx.Choice(dlg, wx.ID_ANY, choices=["Normal", "Italic"]) - if self.weight == wx.NORMAL: - style.SetSelection(0) - else: - style.SetSelection(1) - - def ColorBtn(event): - newcolor = self.RGBHex.do_hex_color_dlg(self.canvas) - if newcolor == None: - return - - colorbtn.SetForegroundColour(newcolor) - dlg.Unbind(wx.EVT_BUTTON) - - dlg.Bind(wx.EVT_BUTTON, ColorBtn, colorbtn) - - sizer.Add(wx.StaticText(dlg, wx.ID_ANY, "Text:"), 0, wx.ALIGN_CENTER_VERTICAL|wx.ALL, 2) - sizer.Add(text, 0, wx.EXPAND|wx.ALL, 3) - sizer.Add(size, 0, wx.ALL, 2) - sizer.Add(weight, 0, wx.ALL, 3) - sizer.Add(style, 0, wx.ALL, 2) - sizer.Add(colorbtn, 0, wx.ALL, 3) - sizer.Add(wx.Button(dlg, wx.ID_OK), 0, wx.ALL, 2) - - dlg.SetSizer(sizer) - dlg.SetAutoLayout(True) - dlg.Fit() - dlg.Show() - - if dlg.ShowModal() == wx.ID_OK: - self.text = text.GetValue() - r,g,b = colorbtn.GetForegroundColour().Get() - self.color = self.RGBHex.hexstring(r, g, b) - self.hcolor = self.RGBHex.hexstring(r^255, g^255, b^255) - self.size = int(size.GetValue()) - if weight.GetSelection() == 0: - self.weight = wx.NORMAL - else: - self.weight = wx.BOLD - - if style.GetSelection() == 0: - self.style = wx.NORMAL - else: - self.style = wx.ITALIC - - if event != None: - self.Update(send=True, action="update") - - - def OnLeftDown(self, pos): - self.ShowProperties(None) - self.color = self.canvas.whiteboardColor - if self.text != '': - self.canvas.zOrder['front'].append(MapText(self.canvas, pos, self.text, self.size, self.weight, self.style, self.color)) - self.Update(send=True, action='new') - - self.text = '' - self.weight = wx.NORMAL - self.size = 12 - self.style = wx.NORMAL - self.color = self.canvas.whiteboardColor - self.hcolor = self.canvas.whiteboardColor - - def _toxml(self, action="update"): - return '' \ No newline at end of file
--- a/orpg/mapper/background.py Mon Feb 01 18:29:16 2010 -0600 +++ b/orpg/mapper/background.py Wed Apr 28 08:08:09 2010 -0500 @@ -34,6 +34,7 @@ from orpg.orpgCore import component from orpg.tools.orpg_log import logger from orpg.tools.orpg_settings import settings +from xml.etree.ElementTree import fromstring ##----------------------------- ## background layer @@ -244,22 +245,21 @@ def upload(self, postdata, filename, type): self.lock.acquire() if type == 'Image' or type == 'Texture': - url = component.get('settings').get_setting('ImageServerBaseURL') + url = settings.get_setting('ImageServerBaseURL') file = urllib.urlopen(url, postdata) recvdata = file.read() file.close() try: - xml_dom = minidom.parseString(recvdata)._get_documentElement() - if xml_dom.nodeName == 'path': - path = xml_dom.getAttribute('url') + xml_dom = fromstring(recvdata) + if xml_dom.tag == 'path': + path = xml_dom.get('url') path = urllib.unquote(path) if type == 'Image': self.set_image(path, 1) else: self.set_texture(path) self.localPath = filename self.local = True self.localTime = time.time() - else: - print xml_dom.getAttribute('msg') + else: print xml_dom.get('msg') except Exception, e: print e print recvdata
--- a/orpg/mapper/map.py Mon Feb 01 18:29:16 2010 -0600 +++ b/orpg/mapper/map.py Wed Apr 28 08:08:09 2010 -0500 @@ -156,7 +156,8 @@ else: pass if not ImageHandler.Queue.empty(): (path, image_type, imageId) = ImageHandler.Queue.get() - if path == 'failed': img = wx.Image(dir_struct["icon"] + "failed.png", wx.BITMAP_TYPE_PNG) + if (path == 'failed' or path == dir_struct["icon"] + "failed.png"): + img = wx.Image(dir_struct["icon"] + "failed.png", wx.BITMAP_TYPE_PNG) else: img = wx.ImageFromMime(path[1], path[2]) try: # Now, apply the image to the proper object @@ -250,8 +251,9 @@ topleft1 = self.GetViewStart() topleft = [topleft1[0]*scrollsize[0], topleft1[1]*scrollsize[1]] if (clientsize[0] > 1) and (clientsize[1] > 1): - self.SetBackgroundStyle(wx.BG_STYLE_CUSTOM) - dc = wx.AutoBufferedPaintDC(self) + dc = wx.MemoryDC() + bmp = wx.EmptyBitmap(clientsize[0]+1, clientsize[1]+1) + dc.SelectObject(bmp) dc.SetPen(wx.TRANSPARENT_PEN) dc.SetBrush(wx.Brush(self.GetBackgroundColour(), wx.SOLID)) dc.DrawRectangle(0,0,clientsize[0]+1,clientsize[1]+1) @@ -266,11 +268,22 @@ self.layers['fog'].layerDraw(dc, topleft, clientsize) dc.SetPen(wx.NullPen) dc.SetBrush(wx.NullBrush) + + dc.SelectObject(wx.NullBitmap) + del dc + wdc = self.preppaint() + wdc.DrawBitmap(bmp, topleft[0], topleft[1]) + if settings.get_setting("AlwaysShowMapScale") == "1": - self.showmapscale(dc) + self.showmapscale(wdc) try: evt.Skip() except: pass + def preppaint(self): + dc = wx.PaintDC(self) + self.PrepareDC(dc) + return (dc) + def showmapscale(self, dc): scalestring = "Scale x" + `self.layers['grid'].mapscale`[:3] (textWidth, textHeight) = dc.GetTextExtent(scalestring)
--- a/orpg/mapper/whiteboard_handler.py Mon Feb 01 18:29:16 2010 -0600 +++ b/orpg/mapper/whiteboard_handler.py Wed Apr 28 08:08:09 2010 -0500 @@ -754,9 +754,9 @@ pos = self.get_snapped_to_logical_pos(evt) size = self.canvas.layers['grid'].unit_size #60 radius = int(int(self.radius.GetValue())/5) - center = wx.Point(pos.x, pos.y+size*radius) + center = wx.Point(pos.x, pos.y) curve = self.calculate_circle(center, radius, size) - if(self.temp_circle): + if self.temp_circle: self.canvas.layers['whiteboard'].del_temp_line(self.temp_circle) self.selected = None self.temp_circle = self.canvas.layers['whiteboard'].add_temp_line(curve)
--- a/orpg/networking/meta_server_lib.py Mon Feb 01 18:29:16 2010 -0600 +++ b/orpg/networking/meta_server_lib.py Wed Apr 28 08:08:09 2010 -0500 @@ -312,7 +312,7 @@ def getMetaServerBaseURL(): # get meta server URL - url = "http://www.openrpg.com/openrpg_servers.php" + url = "http://orpgmeta.appspot.com/" try: component.get('validate').config_file("settings.xml","default_settings.xml") ini = open(dir_struct["user"]+"settings.xml","r") @@ -323,6 +323,7 @@ node_list = tree.getElementsByTagName("MetaServerBaseURL") if node_list: url = node_list[0].getAttribute("value") + print url # allow tree to be collected try: tree.unlink() except: pass
--- a/orpg/networking/mplay_server.py Mon Feb 01 18:29:16 2010 -0600 +++ b/orpg/networking/mplay_server.py Wed Apr 28 08:08:09 2010 -0500 @@ -64,7 +64,7 @@ from orpg.tools.decorators import debugging # Snag the version number -from orpg.orpg_version import VERSION, PROTOCOL_VERSION, CLIENT_STRING, SERVER_MIN_CLIENT_VERSION +from orpg.orpg_version import VERSION, DISTRO, DIS_VER, BUILD, PROTOCOL_VERSION, CLIENT_STRING, SERVER_MIN_CLIENT_VERSION #Plugins from server_plugins import ServerPlugins @@ -253,7 +253,7 @@ self.allowRemoteKill = False self.allowRemoteAdmin = True self.sendLobbySound = False - self.lobbySound = 'http://www.digitalxero.net/music/mus_tavern1.bmu' ##used? + #self.lobbySound = 'http://www.digitalxero.net/music/mus_tavern1.bmu' ##used? def initServer(self, **kwargs): for atter, value in kwargs.iteritems(): setattr(self, atter, value) @@ -1069,7 +1069,7 @@ msg = self.groups[group_id].game_map.get_all_xml() self.send(msg,id,group_id) - def new_request(self,newsock, xml_dom, LOBBY_ID='0'): + def new_request(self, newsock, xml_dom, LOBBY_ID='0'): #build client stub props = {} # Don't trust what the client tells us...trust what they connected as! @@ -1101,14 +1101,15 @@ # send confirmation data = self.recvMsg(newsock, new_stub.useCompression, new_stub.compressionType) - try: xml_dom = XML(data) + try: + xml_dom = XML(data) except Exception, e: print e (remote_host,remote_port) = newsock.getpeername() bad_xml_string = "Your client sent an illegal message to the server and will be disconnected. " bad_xml_string += "Please report this bug to the development team at:<br /> " - bad_xml_string += "<a href=\"http://sourceforge.net/tracker/?group_id=2237&atid=102237\">OpenRPG bugs " - bad_xml_string += "(http://sourceforge.net/tracker/?group_id=2237&atid=102237)</a><br />" + bad_xml_string += "<a href='http://www.assembla.com/spaces/traipse_dev/tickets/'>Traipse-Dev " + bad_xml_string += "(http://www.assembla.com/spaces/traipse_dev/tickets/)</a><br />" self.sendMsg( newsock, "<msg to='" + props['id'] + "' from='" + props['id'] + "' group_id='0' />" + bad_xml_string, new_stub.useCompression, new_stub.compressionType) @@ -1214,7 +1215,8 @@ newsock.close() # Display the lobby message - self.SendLobbyMessage(newsock,props['id']) + print 'lobby message' + self.SendLobbyMessage(newsock, props['id']) def checkClientVersion(self, clientversion): minv = self.minClientVersion.split('.') @@ -1234,8 +1236,9 @@ # prepend this server's version string to the the lobby message """ try: - lobbyMsg = "You have connected to an <a href=\"http://www.openrpg.com\">OpenRPG</a> " - lobbyMsg += "server, version '" + VERSION + "'" + lobbyMsg = "You have connected to a <a href='http://www.knowledgearcana.com/traipse-openrpg'>" + lobbyMsg += DISTRO +'</a> '+ DIS_VER +' {'+ BUILD+'}' + lobbyMsg += " server, built on OpenRPG version '" + VERSION + "'" # See if we have a server name to report! if len(self.serverName): lobbyMsg += ", named '" + self.serverName + "'." @@ -1250,7 +1253,6 @@ open_msg = open( self.userPath + "LobbyMessage.html", "r" ) lobbyMsg += open_msg.read() open_msg.close() - # Send the server's lobby message to the client no matter what self.sendMsg(socket, "<msg to='" + player_id + "' from='0' group_id='0' />" + lobbyMsg, self.players[player_id].useCompression, self.players[player_id].compressionType) @@ -1394,13 +1396,16 @@ self.incoming_event.set() def parse_incoming_dom(self, data): - end = data.find(">") #locate end of first element of message + end = data.find(">") head = data[:end+1] - xml_dom = None + msg = data[end+1:] + ### This if statement should help close invalid messages. ### + if head[end:] != '/': + if head[end:] != '>': head = head[:end] + '/>' try: - xml_dom = XML(head) + try: xml_dom = fromstring(head) + except: xml_dom = fromstring(head[:end] +'/>') self.message_action(xml_dom, data) - except Exception, e: print "Error in parse of inbound message. Ignoring message." print " Offending data(" + str(len(data)) + "bytes)=" + data @@ -1603,6 +1608,7 @@ #notify user about others in the room self.return_room_roles(from_id,group_id) self.log_msg(("join_group", (self.groups[group_id].name, group_id, from_id))) + self.log_msg(("update_group", (self.groups[old_group_id].name, old_group_id, len(self.groups[old_group_id].players) ))) self.log_msg(("update_group", (self.groups[group_id].name, group_id, len(self.groups[group_id].players) ))) self.handle_role("set", from_id, self.players[from_id].role, self.groups[group_id].boot_pwd, group_id) except Exception, e: @@ -1632,7 +1638,7 @@ if persist !=0: ins="Persistant " lmsg = "Creating " + ins + "Group... (" + str(group_id) + ") " + str(name) self.log_msg( lmsg ) - self.log_msg(("create_group", (str(name), int(group_id), pwd, 0) )) + self.log_msg(("create_group", (str(name), int(group_id), 0, 'No' if pwd == '' else 'Yes') )) def change_group_name(self, gid, name, pid): "Change the name of a group" @@ -2184,10 +2190,8 @@ def send_group_list(self, to_id, action="new"): try: - print self.groups for key in self.groups: xml = self.groups[key].toxml(action) - print xml, key self.players[to_id].outbox.put(xml) except Exception, e: self.log_msg("Exception: send_group_list(): (client #"+to_id+") : " + str(e))
--- a/orpg/networking/mplay_server_gui.py Mon Feb 01 18:29:16 2010 -0600 +++ b/orpg/networking/mplay_server_gui.py Wed Apr 28 08:08:09 2010 -0500 @@ -151,8 +151,8 @@ (room, room_id, players, passworded) = data i = self.InsertStringItem(0, str(room_id)) self.SetStringItem(i, 1, room) - self.SetStringItem(i, 2, players) - self.SetStringItem(i, 3, str(passworded)) + self.SetStringItem(i, 2, str(players)) + self.SetStringItem(i, 3, passworded) def DeleteGroup(self, data): i = self.FindItem(-1, str(data)) @@ -162,7 +162,7 @@ (room, room_id, players) = data i = self.FindItem( -1, str(room_id)) self.SetStringItem( i, 1, room ) - if players: self.SetStringItem(i, 2, str(players)) + self.SetStringItem(i, 2, str(players)) ### Need to add room for Password Updates ### class Connections(wx.ListCtrl): @@ -354,8 +354,8 @@ STATUS = SERVER_STOPPED def __init__(self, parent, id, title): wx.Frame.__init__(self, parent, id, title, size = (760, 560) ) - if wx.Platform == '__WXMSW__': icon = wx.Icon( dir_struct["icon"]+'WAmisc9.ico', wx.BITMAP_TYPE_ICO ) - else: icon = wx.Icon( dir_struct["icon"]+'connect.gif', wx.BITMAP_TYPE_GIF ) + if wx.Platform == '__WXMSW__': icon = wx.Icon(dir_struct["icon"]+'WAmisc9.ico', wx.BITMAP_TYPE_ICO) + else: icon = wx.Icon(dir_struct["icon"]+'connect.gif', wx.BITMAP_TYPE_GIF) self.SetIcon(icon) self.serverName = "Server Name" self.bootPwd = "" @@ -401,10 +401,10 @@ # File Menu menu = wx.Menu() - menu.Append( 1, 'Start', 'Start server.') - menu.Append( 2, 'Stop', 'Shutdown server.') + menu.Append(1, 'Start', 'Start server.') + menu.Append(2, 'Stop', 'Shutdown server.') menu.AppendSeparator() - menu.Append( 3, 'E&xit', 'Exit application.') + menu.Append(3, 'E&xit', 'Exit application.') self.Bind(wx.EVT_MENU, self.OnStart, id=1) self.Bind(wx.EVT_MENU, self.OnStop, id=2) self.Bind(wx.EVT_MENU, self.OnExit, id=3) @@ -412,23 +412,24 @@ # Registration Menu menu = wx.Menu() - menu.Append( 4, 'Register', 'Register with OpenRPG server directory.') - menu.Append( 5, 'Unregister', 'Unregister from OpenRPG server directory.') + menu.Append(4, 'Register', 'Register with OpenRPG server directory.') + menu.Append(5, 'Unregister', 'Unregister from OpenRPG server directory.') self.Bind(wx.EVT_MENU, self.OnRegister, id=4) self.Bind(wx.EVT_MENU, self.OnUnregister, id=5) self.mainMenu.Append( menu, '&Registration' ) # Server Configuration Menu menu = wx.Menu() - menu.Append( 6, 'Ban List', 'Modify Ban List.') + menu.Append(6, 'Ban List', 'Modify Ban List.') menu.Append(11, 'Zombies', 'Set auto-kick time for zombie clients') menu.Append(14, 'Send Size', 'Adjust the send size limit') menu.AppendSeparator() - menu.Append( 7, 'Start Ping', 'Ping players to validate remote connection.' ) - menu.Append( 8, 'Stop Ping', 'Stop validating player connections.' ) - menu.Append( 9, 'Ping Interval', 'Change the ping interval.' ) + menu.Append(7, 'Start Ping', 'Ping players to validate remote connection.' ) + menu.Append(8, 'Stop Ping', 'Stop validating player connections.' ) + menu.Append(9, 'Ping Interval', 'Change the ping interval.' ) menu.AppendSeparator() - menu.AppendCheckItem( 10, 'Server Logging', 'Turn on or off the Server GUI Log').Check(self.do_log) + menu.AppendCheckItem(10, 'Server Logging', + 'Turn on or off the Server GUI Log').Check(self.do_log) menu.AppendCheckItem(12, 'Room Passwords', 'Allow or Deny Room Passwords').Check(False) menu.AppendCheckItem(13, 'Remote Admin', 'Allow or Deny Remote Admin').Check(False) menu.AppendCheckItem(15, 'Remote Kill', 'Allow or Deny Remote Admin Server Kill').Check(False) @@ -437,37 +438,38 @@ self.Bind(wx.EVT_MENU, self.StopPingPlayers, id=8) self.Bind(wx.EVT_MENU, self.ConfigPingInterval, id=9) self.Bind(wx.EVT_MENU, self.LogToggle, id=10) - self.mainMenu.Append( menu, '&Configuration' ) - self.SetMenuBar( self.mainMenu ) + self.mainMenu.Append( menu, '&Configuration') + self.SetMenuBar(self.mainMenu) - self.mainMenu.Enable( 2, False ) - self.mainMenu.Enable( 4, False ) - self.mainMenu.Enable( 5, False ) + self.mainMenu.Enable(2, False) + self.mainMenu.Enable(4, False) + self.mainMenu.Enable(5, False) # Disable the ping menu items - self.mainMenu.Enable( 7, False ) - self.mainMenu.Enable( 8, False ) - self.mainMenu.Enable( 9, False ) + self.mainMenu.Enable(7, False) + self.mainMenu.Enable(8, False) + self.mainMenu.Enable(9, False) # Disable placeholders - self.mainMenu.Enable( 11, False ) - self.mainMenu.Enable( 14, False ) - self.mainMenu.Enable( 12, False ) - self.mainMenu.Enable( 13, False ) - self.mainMenu.Enable( 15, False ) + self.mainMenu.Enable(11, False) + self.mainMenu.Enable(14, False) + self.mainMenu.Enable(12, False) + self.mainMenu.Enable(13, False) + self.mainMenu.Enable(15, False) + def build_body(self): """ Create the ViewNotebook and logger. """ splitter = wx.SplitterWindow(self, -1, style=wx.NO_3D | wx.SP_3D) - nb = wx.Notebook( splitter, -1 ) + nb = wx.Notebook(splitter, -1) self.conns = Connections(nb, self) self.groups = Groups(nb, self) - self.msgWindow = HTMLMessageWindow( nb ) + self.msgWindow = HTMLMessageWindow(nb) nb.AddPage(self.conns, "Players") nb.AddPage(self.groups, 'Rooms') - nb.AddPage( self.msgWindow, "Messages" ) + nb.AddPage(self.msgWindow, "Messages") log = wx.TextCtrl(splitter, -1, style=wx.TE_MULTILINE | wx.TE_READONLY | wx.HSCROLL) - wx.Log.SetActiveTarget( wx.LogTextCtrl(log) ) + wx.Log.SetActiveTarget(wx.LogTextCtrl(log)) splitter.SplitHorizontally(nb, log, 400) splitter.SetMinimumPaneSize(40) self.nb = nb @@ -522,12 +524,14 @@ def OnDataSent(self, bytes): self.total_messages_sent += 1 self.total_data_sent += bytes - self.sb.SetStatusText("Sent: %s (%d)" % (format_bytes(self.total_data_sent), self.total_messages_sent), 1) + self.sb.SetStatusText("Sent: %s (%d)" % (format_bytes(self.total_data_sent), + self.total_messages_sent), 1) def OnDataRecv(self, bytes): self.total_messages_received += 1 self.total_data_received += bytes - self.sb.SetStatusText("Recv: %s (%d)" % (format_bytes(self.total_data_received), self.total_messages_received), 2) + self.sb.SetStatusText("Recv: %s (%d)" % (format_bytes(self.total_data_received), + self.total_messages_received), 2) def OnCreateGroup( self, data ): (room, room_id, player, pwd) = data @@ -545,7 +549,7 @@ self.conns.updateRoom(data) def OnUpdateGroup(self, data): - (room, room_id, players) = data + (room, room_id, players) = data; print 'update group', data self.groups.UpdateGroup(data) def OnSetRole( self, data ): @@ -569,13 +573,16 @@ except: pass if self.serverName == '': self.serverName = 'Server Name' - serverNameEntry = wx.TextEntryDialog(self, "Please Enter The Server Name You Wish To Use:", - "Server's Name", self.serverName, wx.OK|wx.CANCEL|wx.CENTRE ) + serverNameEntry = wx.TextEntryDialog(self, + "Please Enter The Server Name You Wish To Use:", + "Server's Name", + self.serverName, wx.OK|wx.CANCEL|wx.CENTRE) if serverNameEntry.ShowModal() == wx.ID_OK: self.serverName = serverNameEntry.GetValue() if self.bootPwd == '': serverPasswordEntry = wx.TextEntryDialog(self, - "Please Enter The Server Admin Password:", "Server's Password", - self.bootPwd, wx.OK|wx.CANCEL|wx.CENTRE) + "Please Enter The Server Admin Password:", + "Server's Password", + self.bootPwd, wx.OK|wx.CANCEL|wx.CENTRE) if serverPasswordEntry.ShowModal() == wx.ID_OK: self.bootPwd = serverPasswordEntry.GetValue() if len(self.serverName): wx.BeginBusyCursor() @@ -584,9 +591,9 @@ self.STATUS = SERVER_RUNNING self.sb.SetStatusText("Running", 3) self.SetTitle(__appname__ + "- (running) - (unregistered)") - self.mainMenu.Enable( 1, False ) - self.mainMenu.Enable( 2, True ) - self.mainMenu.Enable( 4, True ) + self.mainMenu.Enable(1, False) + self.mainMenu.Enable(2, True) + self.mainMenu.Enable(4, True) wx.EndBusyCursor() else: self.show_error("Server is already running.", "Error Starting Server") @@ -598,10 +605,10 @@ self.STATUS = SERVER_STOPPED self.sb.SetStatusText("Stopped", 3) self.SetTitle(__appname__ + "- (stopped) - (unregistered)") - self.mainMenu.Enable( 1, True ) - self.mainMenu.Enable( 2, False ) - self.mainMenu.Enable( 4, False ) - self.mainMenu.Enable( 5, False ) + self.mainMenu.Enable(1, True) + self.mainMenu.Enable(2, False) + self.mainMenu.Enable(4, False) + self.mainMenu.Enable(5, False) self.conns.DeleteAllItems() def OnRegister(self, event = None): @@ -613,8 +620,8 @@ wx.BeginBusyCursor() self.server.server.register(self.serverName) self.sb.SetStatusText( ("%s" % (self.serverName)), 4 ) - self.mainMenu.Enable( 4, False ) - self.mainMenu.Enable( 5, True ) + self.mainMenu.Enable(4, False) + self.mainMenu.Enable(5, True) #self.mainMenu.Enable( 2, False ) self.SetTitle(__appname__ + "- (running) - (registered)") wx.EndBusyCursor() @@ -627,9 +634,9 @@ """ wx.BeginBusyCursor() self.server.server.unregister() - self.sb.SetStatusText( "Unregistered", 4 ) - self.mainMenu.Enable( 5, False ) - self.mainMenu.Enable( 4, True ) + self.sb.SetStatusText("Unregistered", 4) + self.mainMenu.Enable(5, False) + self.mainMenu.Enable(4, True) #self.mainMenu.Enable( 2, True ) self.SetTitle(__appname__ + "- (running) - (unregistered)") wx.EndBusyCursor()
--- a/orpg/orpg_version.py Mon Feb 01 18:29:16 2010 -0600 +++ b/orpg/orpg_version.py Wed Apr 28 08:08:09 2010 -0500 @@ -2,9 +2,9 @@ SERVER_MIN_CLIENT_VERSION = "1.7.1" #BUILD NUMBER FORMAT: "YYMMDD-##" where ## is the incremental daily build index (if needed) -DISTRO = "Traipse Beta" +DISTRO = "Traipse Alpha" DIS_VER = "Ornery Orc" -BUILD = "100201-03" +BUILD = "100428-03" # This version is for network capability. PROTOCOL_VERSION = "1.2"
--- a/orpg/templates/default_settings.xml Mon Feb 01 18:29:16 2010 -0600 +++ b/orpg/templates/default_settings.xml Wed Apr 28 08:08:09 2010 -0500 @@ -2,9 +2,8 @@ <tab name="General" type="tab"> <tab name="Networking" type="grid"> <Heartbeat options="bool" value="1" help="This sends a message to the server to keep alive your connection when idle." /> - <MetaServerBaseURL help="This is the URL that contains the server list." options="URL" value="http://www.openrpg.com/openrpg_servers.php"/> + <MetaServerBaseURL help="This is the URL that contains the server list." options="URL" value="http://orpgmeta.appspot.com/"/> <ImageServerBaseURL help="This is the URL that contains the server list." options="URL" value="http://openrpg.digitalxero.net/imgupload/index.php"/> - <LocalImageBaseURL help="This is the URL that contains the server list." options="URL" value="http://127.0.0.1:6774/webfiles/"/> <LocalorRemote help="Decide to load files locally or remotely. CherryPy must be running for local files." options="Local | Remote" value="Local"/> </tab> <tab name="Sound" type="grid">
--- a/orpg/templates/metaservers.cache Mon Feb 01 18:29:16 2010 -0600 +++ b/orpg/templates/metaservers.cache Wed Apr 28 08:08:09 2010 -0500 @@ -1,1 +1,1 @@ -http://www.openrpg.com/openrpg_servers.php 1 2 +http://orpgmeta.appspot.com 1 2
--- a/orpg/templates/nodes/split.xml Mon Feb 01 18:29:16 2010 -0600 +++ b/orpg/templates/nodes/split.xml Wed Apr 28 08:08:09 2010 -0500 @@ -1,3 +1,2 @@ - <nodehandler class="splitter_handler" icon="divider" module="containers" name="Splitter" version="1.0"> - <splitter_atts horizontal="0"/> - </nodehandler> \ No newline at end of file + <nodehandler class="splitter_handler" icon="divider" module="containers" name="Splitter" version="1.0" horizontal="0"> + </nodehandler>
--- a/orpg/templates/nodes/textctrl.xml Mon Feb 01 18:29:16 2010 -0600 +++ b/orpg/templates/nodes/textctrl.xml Wed Apr 28 08:08:09 2010 -0500 @@ -1,4 +1,4 @@ <nodehandler class="textctrl_handler" icon="note" module="forms" name="Text" version="1.0"> - <text multiline="0" send_button="0">text</text> + <text multiline="1" send_button="0">text</text> </nodehandler>
--- a/orpg/tools/InterParse.py Mon Feb 01 18:29:16 2010 -0600 +++ b/orpg/tools/InterParse.py Wed Apr 28 08:08:09 2010 -0500 @@ -1,35 +1,75 @@ +#!/usr/bin/env python +# Copyright (C) 2000-2010 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: InterParse.py +# Author: +# Maintainer: Tyler Starke (Traipse) +# Version: +# $Id: InterParse.py,v Traipse 'Ornery-Orc' prof.ebral Exp $ +# +# Description: InterParse = Interpretor Parser. This class parses all of the node referencing. +# + from orpg.orpgCore import component import re from orpg.tools.orpg_log import logger from wx import TextEntryDialog, ID_OK +from xml.etree.ElementTree import iselement class InterParse(): def __init__(self): pass - def Post(self, s, send=False, myself=False): - s = self.Normalize(s) - component.get('chat').set_colors() - component.get('chat').Post(s, send, myself) + def Post(self, s, tab=False, send=False, myself=False): + if not tab: tab = component.get('chat') + s = self.Normalize(s, tab) + tab.set_colors() + tab.Post(s, send, myself) - def Normalize(self, s): - for plugin_fname in component.get('chat').activeplugins.keys(): - plugin = component.get('chat').activeplugins[plugin_fname] + def ParseLogic(self, s, node): + 'Nodes now parse through ParsLogic. Easily add new parse rules right here!!' + s = self.NameSpaceE(s) + s = self.NameSpaceI(s, node) + s = self.NodeMap(s, node) + s = self.NodeParent(s, node.get('map')) + return s + + def Normalize(self, s, tab): + for plugin_fname in tab.activeplugins.keys(): + plugin = tab.activeplugins[plugin_fname] try: s = plugin.pre_parse(s) except Exception, e: if str(e) != "'module' object has no attribute 'post_msg'": - logger.general(traceback.format_exc()) + #logger.general(traceback.format_exc()) logger.general("EXCEPTION: " + str(e)) - if component.get('chat').parsed == 0: + if tab.parsed == 0: + s = self.NameSpaceE(s) s = self.Node(s) s = self.Dice(s) - s = self.Filter(s) - component.get('chat').parsed = 1 + s = self.Filter(s, tab) + tab.parsed = 1 return s - def Filter(self, s): - s = component.get('chat').GetFilteredText(s) + def Filter(self, s, tab): + s = tab.GetFilteredText(s) return s def Node(self, s): @@ -77,7 +117,7 @@ lb = "Replace '?' with: " if len(matches[i][0]): lb = matches[i][1] + "?: " - dlg = TextEntryDialog(self, lb, "Missing Value?") + dlg = TextEntryDialog(component.get('chat'), lb, "Missing Value?") dlg.SetValue('') if matches[i][0] != '': dlg.SetTitle("Enter Value for " + matches[i][1]) @@ -87,6 +127,90 @@ dlg.Destroy() return s + def LocationCheck(self, node, tree_map, new_map, find): + if node == 'Invalid Reference!': return node + namespace = node.getiterator('nodehandler'); tr = tree_map.split('::') + newstr = '' + for name in namespace: + try: t = new_map.index(name.get('name'))-1 + except: t = 0 + if find[0] == name.get('name'): + s = '::'.join(new_map[:len(tr)-t])+'::'+'::'.join(find) + newstr = self.NameSpaceE('!&' +s+ '&!') + break + if newstr != '': return newstr + else: + del new_map[len(new_map)-1] + node = self.get_node(new_map) + newstr = self.LocationCheck(node, tree_map, new_map, find) + return newstr + + def FutureCheck(self, node, next): + future = node.getiterator('nodehandler') + for advance in future: + if next == advance.get('name'): return True + return False + + def NameSpaceI(self, s, node): + reg = re.compile("(!=(.*?)=!)") + matches = reg.findall(s) + tree_map = node.get('map') + for i in xrange(0,len(matches)): + ## Build the new tree_map + new_map = tree_map.split('::') + find = matches[i][1].split('::') + ## Backwards Reference the Parent Children + node = self.get_node(new_map) + newstr = self.LocationCheck(node, tree_map, new_map, find) + s = s.replace(matches[i][0], newstr, 1) + return s + + def NameSpaceE(self, s): + reg = re.compile("(!&(.*?)&!)") + matches = reg.findall(s) + newstr = False + nodeable = ['rpg_grid_handler', 'container_handler', + 'group_handler', 'tabber_handler', + 'splitter_handler', 'form_handler', 'textctrl_handler'] + for i in xrange(0,len(matches)): + find = matches[i][1].split('::') + node = component.get('tree').xml_root + if not iselement(node): + s = s.replace(matches[i][0], 'Invalid Reference!', 1); + s = self.NameSpaceE(s) + return s + for x in xrange(0, len(find)): + namespace = node.getiterator('nodehandler') + for node in namespace: + if find[x] == node.get('name'): + if node.get('class') not in nodeable: continue + if node.get('class') == 'rpg_grid_handler': + try: newstr = self.NameSpaceGrid(find[x+1], node); break + except: newstr = 'Invalid Grid Reference!' + try: + if self.FutureCheck(node, find[x+1]): break + else: continue + except: + if x == len(find)-1: + if node.find('text') != None: newstr = str(node.find('text').text) + else: newstr = 'Invalid Reference!' + break + else: break + if not newstr: newstr = 'Invalid Reference!' + s = s.replace(matches[i][0], newstr, 1) + s = self.ParseLogic(s, node) + return s + + def NameSpaceGrid(self, s, node): + cell = tuple(s.strip('(').strip(')').split(',')) + grid = node.find('grid') + rows = grid.findall('row') + try: + col = rows[int(self.Dice(cell[0]))-1].findall('cell') + s = self.ParseLogic(col[int(self.Dice(cell[1]))-1].text, node) or 'No Cell Data' + except: s = 'Invalid Grid Reference!' + return s + def NodeMap(self, s, node): """Parses player input for embedded nodes rolls""" cur_loc = 0 @@ -112,7 +236,7 @@ del new_map[len(new_map)-1] parent_map = matches[i][1].split('::') ## Backwards Reference the Parent Children - child_node = self.get_node('::'.join(new_map)) + child_node = self.get_node(new_map) newstr = self.get_root(child_node, tree_map, new_map, parent_map) s = s.replace(matches[i][0], newstr, 1) s = self.Node(s) @@ -130,14 +254,13 @@ if newstr != '': return newstr else: del new_map[len(new_map)-1] - child_node = self.get_node('::'.join(new_map)) + child_node = self.get_node(new_map) newstr = self.get_root(child_node, tree_map, new_map, parent_map) return newstr - def get_node(self, s): + def get_node(self, path): return_node = 'Invalid Reference!' value = "" - path = s.split('::') depth = len(path) try: node = component.get('tree').tree_map[path[0]]['node'] except Exception, e: return return_node @@ -147,7 +270,7 @@ def resolve_get_loop(self, node, path, step, depth): if step == depth: return node else: - child_list = node.findall('nodehandler') + child_list = node.getchildren() for child in child_list: if step == depth: break if child.get('name') == path[step]: @@ -195,10 +318,8 @@ if node.get('class') == 'textctrl_handler': s = str(node.find('text').text) else: s = 'Nodehandler for '+ node.get('class') + ' not done!' or 'Invalid Reference!' - else: - s = '' - s = self.NodeMap(s, node) - s = self.NodeParent(s, node.get('map')) + else: s = '' + s = self.ParseLogic(s, node) return s def resolve_grid(self, node, path, step, depth): @@ -208,7 +329,7 @@ grid = node.find('grid') rows = grid.findall('row') col = rows[int(self.Dice(cell[0]))-1].findall('cell') - try: s = self.NodeMap(col[int(self.Dice(cell[1]))-1].text, node) or 'No Cell Data' + try: s = self.ParseLogic(col[int(self.Dice(cell[1]))-1].text, node) or 'No Cell Data' except: s = 'Invalid Grid Reference!' return s
--- a/orpg/tools/aliaslib.py Mon Feb 01 18:29:16 2010 -0600 +++ b/orpg/tools/aliaslib.py Wed Apr 28 08:08:09 2010 -0500 @@ -35,6 +35,7 @@ from orpg.dirpath import dir_struct from orpg.tools.validate import validate from orpg.tools.orpg_settings import settings +from xml.etree.ElementTree import tostring, parse import re class AliasLib(wx.Frame): @@ -458,36 +459,30 @@ self.Fit() def loadFile(self): - f = open(dir_struct["user"] + self.filename, "r") - data = f.read() - f.close() - self.alias = -1 - self.filter = -1 - xml_dom = component.get('xml').parseXml(data) - del data - aliases = xml_dom.getElementsByTagName("alias") + data = parse(dir_struct["user"] + self.filename) + xml_dom = data.getroot() + aliases = xml_dom.findall("alias") alist = [] for alias in aliases: - if alias.hasAttribute("color"): color = alias.getAttribute("color") + if alias.get("color"): color = alias.get("color") else: color = 'Default' - aname = self.MakeSafeHTML(alias.getAttribute("name")) + aname = self.MakeSafeHTML(alias.get("name")) alist.append([aname, color]) alist.sort() self.aliasList = alist - filters = xml_dom.getElementsByTagName("filter") + filters = xml_dom.findall("filter") flist = [] self.regExList = [] for filter in filters: - flist.append(filter.getAttribute("name")) - rules = filter.getElementsByTagName("rule") + flist.append(filter.get("name")) + rules = filter.findall("rule") sub = [] - for rule in rules: sub.append([self.MakeSafeHTML(rule.getAttribute("match")), - self.MakeSafeHTML(rule.getAttribute("sub"))]) + for rule in rules: sub.append([self.MakeSafeHTML(rule.get("match")), + self.MakeSafeHTML(rule.get("sub"))]) self.regExList.append(sub) self.filterList = flist - xml_dom.unlink() - self.alias = -1 - self.filter = -1 + self.alias = 0 + self.filter = 0 def MakeSafeHTML(self, str): return str.replace("&", "&").replace("<", "<").replace(""", '"').replace(">", ">").replace("'", "'") @@ -495,7 +490,7 @@ return str.replace("&", "&").replace("<", "<").replace('"', """).replace(">", ">").replace("'", "'") def ImportFromTree(self, xml_dom): oldfilename = self.filename - if xml_dom.getAttribute('name') == 'Alias Library': + if xml_dom.get('name') == 'Alias Library': dlg = wx.TextEntryDialog(self, "Please Name This Alias Lib", "New Alias Lib") if dlg.ShowModal() == wx.ID_OK: self.filename = dlg.GetValue() + '.alias' @@ -503,11 +498,11 @@ else: dlg.Destroy() return - else: self.filename = xml_dom.getAttribute('name') + '.alias' + else: self.filename = xml_dom.get('name') + '.alias' settings.set_setting('aliasfile', self.filename[:-6]) if oldfilename != self.filename: self.OnMB_FileSave(None, oldfilename) f = open(dir_struct["user"] + self.filename, "w") - f.write(xml_dom.toxml().replace('nodehandler', 'aliaslib').replace('voxchat.', '')) + f.write(tostring(xml_dom).replace('nodehandler', 'aliaslib').replace('voxchat.', '')) f.close() wx.CallAfter(self.loadFile)
--- a/orpg/tools/orpg_log.py Mon Feb 01 18:29:16 2010 -0600 +++ b/orpg/tools/orpg_log.py Wed Apr 28 08:08:09 2010 -0500 @@ -62,7 +62,7 @@ def write(self, text): logger.stdout(text) wx.Yield() - #sys.__stdout__.write(text) + sys.__stdout__.write(text) class TrueDebug(object): """A simple debugger. Add debug() to a function and it prints the function name and any objects included. Add an object or a group of objects in ()'s.
--- a/orpg/tools/orpg_settings.py Mon Feb 01 18:29:16 2010 -0600 +++ b/orpg/tools/orpg_settings.py Wed Apr 28 08:08:09 2010 -0500 @@ -183,14 +183,17 @@ def dieroller_ok(self, changes): rm = component.get('DiceManager') + cur_die = rm.getRoller() try: rm.setRoller(changes) self.chat.SystemPost('You have changed your die roller to the <b>"' + rm.getRoller() + '"</b> roller.') except Exception, e: - print e rm.setRoller('std') - self.settings.change('dieroller', 'std') - self.chat.SystemPost('<b>"' + changes + '"</b> is an invalid roller. Setting roller to <b>"std"</b>') + rm.setRoller(cur_die) + self.settings.change('dieroller', cur_die) + self.chat.SystemPost('<b>"' + changes + '"</b> is an invalid roller.') + self.chat.InfoPost('Available die rollers: ' +str(rm.listRollers()) ) + self.chat.InfoPost('You are using the <b>"' +cur_die+ '"</b> die roller.') def colortree_ok(self, changes): top_frame = component.get('frame')
--- a/plugins/xxurl2link.py Mon Feb 01 18:29:16 2010 -0600 +++ b/plugins/xxurl2link.py Wed Apr 28 08:08:09 2010 -0500 @@ -9,36 +9,36 @@ def __init__(self, plugindb, parent): orpg.pluginhandler.PluginHandler.__init__(self, plugindb, parent) - # The Following code should be edited to contain the proper information self.name = 'URL to link conversion' self.author = 'tdb30 tbaleno@wrathof.com' self.help = "This plugin automaticaly wraps urls in link tags\n" self.help += "making them clickable." - self.url_regex = None - self.mailto_regex = None - def plugin_menu(self): self.menu = wx.Menu() self.toggle = self.menu.AppendCheckItem(wx.ID_ANY, 'On') self.topframe.Bind(wx.EVT_MENU, self.plugin_toggle, self.toggle) - self.toggle.Check(True) def plugin_toggle(self, evt): + if self.toggle.IsChecked() == True: self.plugindb.SetString('xxurl2link', 'url2link', 'True') + if self.toggle.IsChecked() == False: self.plugindb.SetString('xxurl2link', 'url2link', 'False') pass def plugin_enabled(self): - #This is where you set any variables that need to be initalized when your plugin starts - self.url_regex = re.compile("(?<![\[=\"a-z0-9:/.])((?:http|ftp|gopher)://)?(?<![@a-z])((?:[a-z0-9\-]+[-.]?[a-z0-9]+)*\.(?:[a-z]{2,4})(?:[a-z0-9_=\?\#\&~\%\.\-/\:\+;]*))", re.I) - - self.mailto_regex = re.compile("(?<![=\"a-z0-9:/.])((?:[a-z0-9]+[_]?[a-z0-9]*)+@{1}(?:[a-z0-9]+[-.]?[a-z0-9]+)*\.(?:[a-z]{2,4}))", re.I) + self.url_regex = re.compile( #from Paul Hayman of geekzilla + "((https?|ftp|gopher|telnet|file|notes|ms-help):((//)|(\\\\))+[\w\d:#@%/;$()~_?\+-=\\\.&]*)", re.I) + self.mailto_regex = re.compile( #Taken from Django + r"(^[-!#$%&'*+/=?^_`{}|~0-9A-Z]+(\.[-!#$%&'*+/=?^_`{}|~0-9A-Z]+)*" # dot-atom + r'|^"([\001-\010\013\014\016-\037!#-\[\]-\177]|\\[\001-011\013\014\016-\177])*"' # quoted-string + r')@(?:[A-Z0-9](?:[A-Z0-9-]{0,61}[A-Z0-9])?\.)+[A-Z]{2,6}\.?$', re.IGNORECASE) + self.link = self.plugindb.GetString('xxurl2link', 'url2link', '') or 'False' + self.toggle.Check(True) if self.link == 'True' else self.toggle.Check(False) def plugin_disabled(self): - #Here you need to remove any commands you added, and anything else you want to happen when you disable the plugin - #such as closing windows created by the plugin pass def pre_parse(self, text): + text2 = text if self.toggle.IsChecked() == True: text = self.mailto_regex.sub(self.regmailsub, text) text = self.url_regex.sub(self.regurlsub, text) @@ -56,7 +56,5 @@ def regurlsub(self, m): link = m.group(2) - if m.group(1) != None: - return '<a href="' + m.group(1).lower() + link + '">' + m.group(0) + '</a>' - else: - return '<a href="http://' + link + '">' + link + '</a>' + if m.group(1) != None: return '<a href="' + m.group(1).lower() + '">' + m.group(0) + '</a>' + else: return '<a href="http://' + link + '">' + link + '</a>'
--- a/readme.txt Mon Feb 01 18:29:16 2010 -0600 +++ b/readme.txt Wed Apr 28 08:08:09 2010 -0500 @@ -1,9 +1,18 @@ -How to use OpenRPG version 1.7.x -Make sure you have installed python 2.5+ and wxPython 2.8+! +Welcome to Traipse 'OpenRPG' Ornery Orc +Traipse is a fork of the original OpenRPG software. Traipse +provides the best stability of any OpenRPG fork, and the best +features of any OpenRPG version + +How to use Traipse 'OpenRPG': -Launching OpenRPG: -OpenRPG can be launch by executing the OpenRPG.pyw script -located in the openrpg folder. On windows, Macs, and +Minimum software requirements +* Python 2.5.2 +* wx.Python 2.8.1.9 + +Launching Traipse 'OpenRPG': + +OpenRPG can be launch by executing the Traipse.pyw script +located in the folder you ran setup.py. On windows, Macs, and Unix with a GUI, this can be accomplished by double clicking OpenRPG.pyw. From a shell, type: python OpenRPG.pyw @@ -11,8 +20,8 @@ You want to launch your own server execute the Server.py. -For more info on how to use OpenRPG, -visit http://www.openrpg.com +For more info on how to use Traipse 'OpenRPG', +visit http://www.knowledgearcana.com/traipse-openrpg -OpenRPG Team
--- a/rollback.py Mon Feb 01 18:29:16 2010 -0600 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,17 +0,0 @@ -#!/usr/bin/env python - -import sys -import os - -HG = os.environ["HG"] - -os.system(HG + " rollback") -os.system(HG + " revert --all") -print "Since you reverted, I am guessing there are issues with the last update" -print "PLEASE notify me on either the openrpg.com boards, or by email" -print "digitalxero@gmail.com" -print "You can continue using your rolled back version by launching openrpg from" -print "the command line with the command: OpenRPG*.py -n" -print "the -n tells the system not to update, it will still run the downloader" -print "but it will not change your files" -raw_input("press <enter> key to terminate program") \ No newline at end of file
--- a/start_developer.py Mon Feb 01 18:29:16 2010 -0600 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,20 +0,0 @@ -#!/usr/bin/env python - -import pyver -pyver.checkPyVersion() - -#Update Manager -from orpg.orpg_wx import * -import upmana.updatemana -app = upmana.updatemana.updateApp(0) -app.MainLoop() - -#Main Program -from orpg.orpg_wx import * -import orpg.main - -if WXLOADED: - mainapp = orpg.main.orpgApp(0) - mainapp.MainLoop() -else: - print "You really really need wx!"
--- a/start_noupdate.py Mon Feb 01 18:29:16 2010 -0600 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,20 +0,0 @@ -#!/usr/bin/env python - -import pyver -pyver.checkPyVersion() - -#Update Manager -from orpg.orpg_wx import * -import upmana.updatemana -app = upmana.updatemana.updateApp(0) -app.MainLoop() - -#Main Program -from orpg.orpg_wx import * -import orpg.main - -if WXLOADED: - mainapp = orpg.main.orpgApp(0) - mainapp.MainLoop() -else: - print "You really really need wx!"
--- a/start_tester.py Mon Feb 01 18:29:16 2010 -0600 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,26 +0,0 @@ -#!/usr/bin/env python - -import sys -import os - -HG = os.environ["HG"] - -import pyver -pyver.checkPyVersion() - -from orpg.orpg_wx import * -import upmana.updatemana -app = upmana.updatemana.updateApp(0) -app.MainLoop() -for key in sys.modules.keys(): - if 'orpg' in key: - del sys.modules[key] - -from orpg.orpg_wx import * -import orpg.main - -if WXLOADED: - mainapp = orpg.main.orpgApp(0) - mainapp.MainLoop() -else: - print "You really really need wx!"
--- a/upmana/updatemana.py Mon Feb 01 18:29:16 2010 -0600 +++ b/upmana/updatemana.py Wed Apr 28 08:08:09 2010 -0500 @@ -12,8 +12,9 @@ class Term2Win(object): # A stdout redirector. Allows the messages from Mercurial to be seen in the Install Window def write(self, text): - statbar.SetStatusText(text) - wx.Yield() + self.closed = sys.__stdout__.closed + self.flush = sys.__stdout__.flush + statbar.SetStatusText(text.replace('\n', '')) sys.__stdout__.write(text) class Updater(wx.Panel): @@ -21,7 +22,10 @@ wx.Panel.__init__(self, parent) ### Status Bar ### #statbar.SetStatusText('Select a Package and Update') - statbar.SetStatusText('New Status Bar') + #statbar.SetStatusText('New Status Bar') + + self.timer = wx.Timer(self, 1) + self.count = 0 ### Update Manager self.ui = ui.ui() @@ -44,7 +48,7 @@ self.buttons['update'] = wx.Button(self, wx.ID_ANY, "Update Now") self.buttons['finish'] = wx.Button(self, wx.ID_ANY, "Finish") - self.sizer.Add(self.changelog, (0,0), span=(4,1), flag=wx.EXPAND) + self.sizer.Add(self.changelog, (0,0), span=(5,1), flag=wx.EXPAND) self.sizer.Add(self.filelist, (0,1), span=(1,3), flag=wx.EXPAND) self.sizer.Add(self.buttons['progress_bar'], (1,1), span=(1,3), flag=wx.EXPAND) @@ -55,7 +59,7 @@ self.sizer.Add(self.buttons['advanced'], (2,3), flag=wx.EXPAND) self.sizer.Add(self.buttons['update'], (3,3), flag=wx.EXPAND) self.sizer.Add(self.buttons['finish'], (4,3), flag=wx.EXPAND) - #self.buttons['finish'].Disable() + self.buttons['progress_bar'].SetValue(100) self.sizer.AddGrowableCol(0) self.sizer.AddGrowableRow(0) self.SetSizer(self.sizer) @@ -76,6 +80,29 @@ self.Bind(wx.EVT_BUTTON, self.ChooseBranch, self.buttons['advanced']) self.Bind(wx.EVT_CHECKBOX, self.ToggleAutoUpdate, self.buttons['auto_check']) self.Bind(wx.EVT_CHECKBOX, self.ToggleNoUpdate, self.buttons['no_check']) + self.Bind(wx.EVT_TIMER, self.OnTimer, self.timer) + + def OnTimer(self, event): + self.count = self.count + 1 + self.buttons['progress_bar'].SetValue(self.count) + if self.count == 100: + self.timer.Stop() + statbar.SetStatusText('Checking For Updates') + + def UpdateCheck(self): + self.timer.Start(100) + self.count = 3 + self.buttons['progress_bar'].SetValue(3) + doUpdate = commands.incoming(self.ui, self.repo, + manifest.GetString('default', 'repo', ''), force=True, bundle=False) + if doUpdate: + statbar.SetStatusText('No Updates Available') + self.buttons['progress_bar'].SetValue(100) + self.timer.Stop() + else: + statbar.SetStatusText('Refresh Repo For Updated Source') + self.buttons['progress_bar'].SetValue(100) + self.timer.Stop() def ToggleAutoUpdate(self, event): if self.buttons['auto_check'].GetValue() == True: @@ -687,17 +714,18 @@ global statbar statbar = self.CreateStatusBar() + sys.stdout = Term2Win() self.Centre() # create the page windows as children of the notebook - page1 = Updater(nb, openrpg) + self.page1 = Updater(nb, openrpg) page2 = Repos(nb, openrpg) page3 = Manifest(nb) page4 = Control(nb) page5 = Help(nb) # add the pages to the notebook with the label to show on the tab - nb.AddPage(page1, "Updater") + nb.AddPage(self.page1, "Updater") nb.AddPage(page2, "Repos") nb.AddPage(page3, "Manifest") nb.AddPage(page4, "Control") @@ -720,11 +748,11 @@ class updateApp(wx.App): def OnInit(self): self.main = False - sys.stdout = Term2Win() + logger._set_log_to_console(False) logger.note("Updater Start") component.add('validate', validate) - self.updater = updaterFrame(self, "OpenRPG Update Manager 1.0", + self.updater = updaterFrame(self, "OpenRPG Update Manager 1.2", component, manifest, self.main) if manifest.GetString("updatemana", "auto_update", "") == 'on' and self.main == False: self.AutoUpdate(); self.OnExit() @@ -736,6 +764,7 @@ self.updater.Show() self.updater.Fit() except: pass + if not self.main: self.updater.page1.UpdateCheck() return True def AutoUpdate(self):