# HG changeset patch # User sirebral # Date 1276332637 18000 # Node ID 81d0bfd5e80069add7dd3219129212e2d84c6969 # Parent 4b2884f29a7264ad6abe185662d279f11a2c1523 Traipse Alpha 'OpenRPG' {100612-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 (Preparing to close updates) New Features: New to Map, can re-order Grid, Miniatures, and Whiteboard layer draw order Fixes: Fix to InterParse that was causing an Infernal Loop with Namespace Internal Fix to XML data, removed old Minidom and switched to Element Tree Fix to Server that was causing eternal attempt to find a Server ID, in Register Rooms thread Fix to metaservers.xml file not being created diff -r 4b2884f29a72 -r 81d0bfd5e800 orpg/chat/chat_msg.py --- a/orpg/chat/chat_msg.py Fri Jan 15 22:45:51 2010 -0600 +++ b/orpg/chat/chat_msg.py Sat Jun 12 03:50:37 2010 -0500 @@ -21,13 +21,13 @@ # Author: Ted Berg # Maintainer: # Version: -# $Id: chat_msg.py,v 1.15 2006/11/04 21:24:19 digitalxero Exp $ +# $Id: chat_msg.py,v Traipse 'Ornery-Orc' prof.ebral Exp $ # # Description: Contains class definitions for manipulating messages # # -__version__ = "$Id: chat_msg.py,v 1.15 2006/11/04 21:24:19 digitalxero Exp $" +__version__ = "$Id: chat_msg.py,v Traipse 'Ornery-Orc' prof.ebral Exp $" from orpg.orpgCore import * from chat_version import CHAT_VERSION @@ -48,8 +48,7 @@ self.takexml(xml_text) def __del__(self): - if self.chat_dom: - self.chat_dom.unlink() + if self.chat_dom: self.chat_dom.unlink() def toxml(self): return tostring(self.chat_dom) diff -r 4b2884f29a72 -r 81d0bfd5e800 orpg/chat/chatwnd.py --- a/orpg/chat/chatwnd.py Fri Jan 15 22:45:51 2010 -0600 +++ b/orpg/chat/chatwnd.py Sat Jun 12 03:50:37 2010 -0500 @@ -21,7 +21,7 @@ # Author: Chris Davis # Maintainer: # Version: -# $Id: chatwnd.py,v 1.177 2007/12/07 20:39:48 digitalxero Exp $ +# $Id: chatwnd.py,v Traipse 'Ornery-Orc' prof.ebral Exp $ # # Description: This file contains some of the basic definitions for the chat # utilities in the orpg project. @@ -37,7 +37,7 @@ # + Added simple_html_repair() to post() to fix malformed html in the chat window # -__version__ = "$Id: chatwnd.py,v 1.177 2007/12/07 20:39:48 digitalxero Exp $" +__version__ = "$Id: chatwnd.py,v Traipse 'Ornery-Orc' prof.ebral Exp $" ## @@ -45,11 +45,10 @@ ## 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 -#from orpg.tools.metamenus import MenuEx #Needed? from string import * import cStringIO # for reading inline imagedata as a stream @@ -62,11 +61,11 @@ from orpg.tools.orpg_settings import settings import orpg.tools.predTextCtrl from orpg.tools.orpg_log import logger, debug +from orpg.tools.InterParse import Parse from orpg.orpgCore import component from xml.etree.ElementTree import tostring -from orpg.networking.mplay_client import MPLAY_CONNECTED # needed to only send typing/not_typing messages while connected - +from orpg.networking.mplay_client import MPLAY_CONNECTED NEWCHAT = False try: import wx.webview @@ -83,10 +82,10 @@ self.accum = "" self.special_tags = ['hr', 'br', 'img'] - def handle_data(self, data): # quote cdata literally + def handle_data(self, data): self.accum += data - def handle_entityref(self, name): # entities must be preserved exactly + def handle_entityref(self, name): self.accum += "&" + name + ";" def handle_starttag(self, tag, attrs): @@ -95,11 +94,10 @@ for attrib in attrs: self.accum += ' ' + attrib[0] + '="' + attrib[1] + '"' self.accum += '>' - def handle_charref(self, name): # charrefs too + def handle_charref(self, name): self.accum += "&#" + name + ";" htmlstripper = HTMLStripper() -# utility function; see Post(). def strip_html(string): "Return string tripped of html tags." @@ -114,7 +112,6 @@ filename = settings.get_setting('GameLogPrefix') if filename > '' and filename[0] != commands.ANTI_LOG_CHAR: filename = filename + time.strftime( '-%Y-%m-%d.html', time.localtime( time.time() ) ) - #filename = time.strftime( filename, time.localtime( time.time() ) ) timestamp = time.ctime(time.time()) header = '[%s] : ' % ( timestamp ); if settings.get_setting('TimeStampGameLog') != '1': header = '' @@ -122,8 +119,9 @@ f = open( dir_struct["user"] + filename, 'a' ) f.write( '
%s%s
\n' % ( header, text ) ) f.close() - except: + except Exception, e: print "could not open " + dir_struct["user"] + filename + ", ignoring..." + print 'Error given', e pass # This class displayes the chat information in html? @@ -136,12 +134,7 @@ # class chat_html_window(wx.html.HtmlWindow): """ a wxHTMLwindow that will load links """ - # initialization subroutine - # - # !self : instance of self - # !parent : - # !id : - + def __init__(self, parent, id): wx.html.HtmlWindow.__init__(self, parent, id, style=wx.SUNKEN_BORDER|wx.html.HW_SCROLLBAR_AUTO|wx.NO_FULL_REPAINT_ON_RESIZE) @@ -150,18 +143,14 @@ self.Bind(wx.EVT_LEFT_UP, self.LeftUp) self.Bind(wx.EVT_RIGHT_DOWN, self.onPopup) if "gtk2" in wx.PlatformInfo: self.SetStandardFonts() - # def __init__ - end - def onPopup(self, evt): self.PopupMenu(self.menu) - def LeftUp(self, event): event.Skip() wx.CallAfter(self.parent.set_chat_text_focus, None) - def build_menu(self): self.menu = wx.Menu() item = wx.MenuItem(self.menu, wx.ID_ANY, "Copy", "Copy") @@ -174,13 +163,11 @@ wx.TheClipboard.SetData(wx.TextDataObject(self.SelectionToText())) wx.TheClipboard.Close() - def scroll_down(self): maxrange = self.GetScrollRange(wx.VERTICAL) pagesize = self.GetScrollPageSize(wx.VERTICAL) self.Scroll(-1, maxrange-pagesize) - def mouse_wheel(self, event): amt = event.GetWheelRotation() units = amt/(-(event.GetWheelDelta())) @@ -197,19 +184,12 @@ def GetPageSource(self): return self.GetParser().GetSource() - - # This subroutine fires up the webbrowser when a link is clicked. - # - # !self : instance of self - # !linkinfo : instance of a class that contains the link information def OnLinkClicked(self, linkinfo): href = linkinfo.GetHref() wb = webbrowser.get() wb.open(href) - # def OnLinkClicked - end - def CalculateAllFonts(self, defaultsize): return [int(defaultsize * 0.4), int(defaultsize * 0.7), @@ -219,7 +199,6 @@ int(defaultsize * 2), int(defaultsize * 2.5)] - def SetDefaultFontAndSize(self, fontname, fontsize): """Set 'fontname' to the default chat font. Returns current font settings in a (fontname, fontsize) tuple.""" @@ -239,7 +218,6 @@ self.Bind(wx.EVT_RIGHT_DOWN, self.onPopup) self.Bind(wx.webview.EVT_WEBVIEW_BEFORE_LOAD, self.OnLinkClicked) - #Wrapers so I dont have to add special Code def SetPage(self, htmlstring): self.SetPageSource(htmlstring) @@ -366,7 +344,6 @@ def get_tab_index(self, chatpanel): "Return the index of a chatpanel in the wxNotebook." - for i in xrange(self.GetPageCount()): if (self.GetPage(i) == chatpanel): return i @@ -450,7 +427,6 @@ selected_idx = event.GetSelection() self.SetPageImage(selected_idx, 1) page = self.GetPage(selected_idx) - #wx.CallAfter(page.set_chat_text_focus, 0) event.Skip() """ @@ -505,10 +481,6 @@ # who receives outbound messages, either "all" or "playerid" string self.sendtarget = sendtarget self.type = tab_type - #self.sound_player = component.get('sound') #Removing! - # create die roller manager - #self.DiceManager = component.get('DiceManager') #Removing! - # create rpghex tool self.r_h = orpg.tools.rgbhex.RGBHex() self.h = 0 self.set_colors() @@ -530,13 +502,13 @@ wx.WXK_F9: 'event.GetKeyCode() == wx.WXK_F9', wx.WXK_F10: 'event.GetKeyCode() == wx.WXK_F10', wx.WXK_F11: 'event.GetKeyCode() == wx.WXK_F11', wx.WXK_F12: 'event.GetKeyCode() == wx.WXK_F12'} #Alias Lib stuff - self.defaultAliasName = 'Use Real Name' + self.defaultAliasName = 'Real Name' self.defaultFilterName = 'No Filter' self.advancedFilter = False self.lastSend = 0 # this is used to help implement the player typing indicator self.lastPress = 0 # this is used to help implement the player typing indicator self.Bind(wx.EVT_SIZE, self.OnSize) - self.Bind(EVT_ETC_LAYOUT_NEEDED, self.OnSize) #require to keep text at bottom of chat when text entry expands --SD + self.Bind(EVT_ETC_LAYOUT_NEEDED, self.OnSize) self.build_ctrls() StartupFont = self.settings.get_setting("defaultfont") StartupFontSize = self.settings.get_setting("defaultfontsize") @@ -778,7 +750,6 @@ self.build_menu() entries = [] entries.append((wx.ACCEL_CTRL, ord('H'), self.setChatFocusMenu.GetId())) - #entries.append((wx.ACCEL_CTRL, wx.WXK_TAB, SWAP_TABS)) return entries @@ -788,18 +759,15 @@ def back_tabs(self, evt): self.parent.AdvanceSelection(False) - # This subroutine builds the controls for the chat frame - # - # !self : instance of self - def build_ctrls(self): self.chatwnd = chat_html_window(self,-1) self.set_colors() wx.CallAfter(self.chatwnd.SetPage, self.chatwnd.Header()) + welcome = "Welcome to " + welcome += DISTRO +' '+ DIS_VER +' {'+BUILD+'},' + welcome += ' built on OpenRPG '+ VERSION +'' if (self.sendtarget == "all"): - wx.CallAfter(self.Post, self.colorize(self.syscolor, - "Welcome to OpenRPG version " + self.version + "... ")) - #self.chat_cmds.on_help() + 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 ) @@ -838,7 +806,6 @@ self.chattxt.Bind(wx.EVT_CHAR, self.chattxt.OnChar) self.chattxt.Bind(wx.EVT_KEY_DOWN, self.on_chat_key_down) self.chattxt.Bind(wx.EVT_TEXT_COPY, self.chatwnd.OnM_EditCopy) - # def build_ctrls - end def build_bar(self): self.toolbar_sizer = wx.BoxSizer(wx.HORIZONTAL) @@ -855,14 +822,12 @@ self.build_formating() self.build_colorbutton() - def build_scroll(self): self.scroll_lock = wx.Button( self, wx.ID_ANY, "Scroll ON",size= wx.Size(80,25)) - def build_alias(self): self.aliasSizer = wx.BoxSizer(wx.HORIZONTAL) - self.aliasList = wx.Choice(self, wx.ID_ANY, size=(100, 25), choices=[self.defaultAliasName]) + self.aliasList = wx.Choice(self, wx.ID_ANY, size=(120, 25), choices=[self.defaultAliasName]) self.aliasButton = createMaskedButton( self, dir_struct["icon"] + 'player.gif', 'Refresh list of aliases from Game Tree', wx.ID_ANY, '#bdbdbd' ) @@ -949,8 +914,6 @@ else: self.toolbar_sizer.Show(self.formatSizer, True) self.toolbar_sizer.Layout() - # Heroman - Ideally, we would use static labels... - def build_colorbutton(self): self.color_button = createMaskedButton(self, dir_struct["icon"]+'textcolor.gif', 'Text Color', wx.ID_ANY, '#bdbdbd', @@ -983,13 +946,6 @@ else: logger.general("Error, self.chatwnd.GetInternalRepresentation() return None") evt.Skip() - # This subroutine is registered with predTextCtrl to be run for every OnChar event - # It checks if we need to send a typing message - - # - # self: duh - # event: raw KeyEvent from OnChar() - def myKeyHook(self, event): if self.session.get_status() == MPLAY_CONNECTED: # only do if we're connected thisPress = time.time() # thisPress is local temp variable @@ -1005,11 +961,6 @@ logger.debug("Exit chat_panel->myKeyHook(self, event) return 0") return 0 - # This subroutine gets called once a second by the typing Timer - # It checks if we need to send a not_typing message - # - # self: duh - def typingTimerFunc(self, event): #following added by mDuo13 ##############refresh_counter()############## @@ -1027,12 +978,7 @@ # If we're not already typing, then self.lastSend will be 0 self.sendTyping(0) # send a typing event here (0 for False) - # This subroutine actually takes care of sending the messages for typing/not_typing events - # - # self: duh - # typing: boolean - def sendTyping(self, typing): if typing: self.lastSend = time.time() # remember our send time for use in myKeyHook() @@ -1047,11 +993,6 @@ if status_text == "" or status_text == None: status_text = "Idle" self.session.set_text_status(status_text) - # This subroutine sets the colors of the chat based on the settings in the - # self instance. - # - # !self : instance of self - def set_colors(self): # chat window backround color self.bgcolor = self.settings.get_setting('bgcolor') @@ -1067,18 +1008,11 @@ self.emotecolor = self.settings.get_setting('emotecolor') # color of whispers self.whispercolor = self.settings.get_setting('whispercolor') - # def set_colors - end - - # This subroutine will insert text into the chat window - # - # !self : instance of self - # !txt : text to be inserted into the chat window def set_chat_text(self, txt): self.chattxt.SetValue(txt) self.chattxt.SetFocus() self.chattxt.SetInsertionPointEnd() - # def set_chat_text - end def get_chat_text(self): @@ -1088,28 +1022,17 @@ def set_chat_text_focus(self, event): wx.CallAfter(self.chattxt.SetFocus) - # def set_chat_text_focus - end - - # This subrtouine grabs the user input and make the special keys and - # modifiers work. - # - # !self : instance of self - # !event : - # - # Note: self.chattxt now handles it's own Key events. It does, however still - # call it's parent's (self) OnChar to handle "default" behavior. def submit_chat_text(self, s): self.histidx = -1 self.temptext = "" self.history = [s] + self.history - #if not len(macroText): self.chattxt.SetValue("") # play sound 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): @@ -1144,17 +1067,12 @@ elif event.GetKeyCode() == wx.WXK_UP: logger.debug("event.GetKeyCode() == wx.WXK_UP") if self.histidx < len(self.history)-1: - #text that's not in history but also hasn't been sent to chat gets stored in self.temptext - #this way if someone presses the up key, they don't lose their current message permanently - #(unless they also press enter at the time) if self.histidx is -1: self.temptext = self.chattxt.GetValue() self.histidx += 1 self.chattxt.SetValue(self.history[self.histidx]) self.chattxt.SetInsertionPointEnd() else: - self.histidx = len(self.history) -1#in case it got too high somehow, this should fix it - #self.InfoPost("**Going up? I don't think so.**") - #print self.histidx, "in",self.history + self.histidx = len(self.history) -1 ## DOWN KEY elif event.GetKeyCode() == wx.WXK_DOWN: @@ -1166,9 +1084,7 @@ self.chattxt.SetValue(self.temptext) else: self.chattxt.SetValue(self.history[self.histidx]) self.chattxt.SetInsertionPointEnd() - else: self.histidx = -1 #just in case it somehow got below -1, this should fix it - #self.InfoPost("**Going down? I don't think so.**") - #print self.histidx, "in",self.history + else: self.histidx = -1 ## TAB KEY elif event.GetKeyCode() == wx.WXK_TAB: @@ -1242,8 +1158,6 @@ ## NOTHING else: event.Skip() logger.debug("Exit chat_panel->OnChar(self, event)") - # def OnChar - end - def onDieRoll(self, evt): """Roll the dice based on the button pressed and the die modifiers entered, if any.""" @@ -1257,15 +1171,9 @@ 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() - # This subroutine saves a chat buffer as html to a file chosen via a - # FileDialog. - # - # !self : instance of self - # !evt : - def on_chat_save(self, evt): f = wx.FileDialog(self,"Save Chat Buffer",".","","HTM* (*.htm*)|*.htm*|HTML (*.html)|*.html|HTM (*.htm)|*.htm",wx.SAVE) if f.ShowModal() == wx.ID_OK: @@ -1274,9 +1182,7 @@ file.close() f.Destroy() os.chdir(dir_struct["home"]) - # def on_chat_save - end - def ResetPage(self): self.set_colors() buffertext = self.chatwnd.Header() + "\n" @@ -1286,9 +1192,6 @@ "
\n").replace("\n\n", '') return buffertext - # This subroutine sets the color of selected text, or base text color if - # nothing is selected - def on_text_color(self, event): hexcolor = self.r_h.do_hex_color_dlg(self) if hexcolor != None: @@ -1305,25 +1208,11 @@ self.settings.set_setting('mytextcolor',hexcolor) self.set_colors() self.Post() - # def on_text_color - end - # This subroutine take a color and a text string and formats it into html. - # - # !self : instance of self - # !color : color for the text to be set - # !text : text string to be included in the html. - def colorize(self, color, text): """Puts font tags of 'color' around 'text' value, and returns the string""" return "" + text + "" - # def colorize - end - # This subroutine takes and event and inserts text with the basic format - # tags included. - # - # !self : instance of self - # !event : - def on_text_format(self, event): id = event.GetId() txt = self.chattxt.GetValue() @@ -1338,9 +1227,7 @@ self.chattxt.SetValue(txt) self.chattxt.SetInsertionPointEnd() self.chattxt.SetFocus() - # def on_text_format - end - def lock_scroll(self, event): if self.lockscroll: self.lockscroll = False @@ -1353,28 +1240,16 @@ self.lockscroll = True self.scroll_lock.SetLabel("Scroll OFF") - # This subroutine will popup a text window with the chatbuffer contents - # - # !self : instance of self - # !event : - def pop_textpop(self, event): """searchable popup text view of chatbuffer""" h_buffertext = self.ResetPage() h_dlg = orpgScrolledMessageFrameEditor(self, h_buffertext, "Text View of Chat Window", None, (500,300)) h_dlg.Show(True) - # This subroutine will change the dimension of the window - # - # !self : instance of self - # !event : - def OnSize(self, event=None): event.Skip() wx.CallAfter(self.scroll_down) - # def OnSize - end - def scroll_down(self): self.Freeze() self.chatwnd.scroll_down() @@ -1386,17 +1261,14 @@ self.set_colors() self.chatwnd.SetPage(self.chatwnd.Header()) - def system_message(self, text): self.send_chat_message(text,chat_msg.SYSTEM_MESSAGE) self.SystemPost(text) - def info_message(self, text): self.send_chat_message(text,chat_msg.INFO_MESSAGE) self.InfoPost(text) - def get_gms(self): the_gms = [] for playerid in self.session.players: @@ -1404,7 +1276,6 @@ if self.session.players[playerid][7]=="GM" and self.session.group_id != '0': the_gms += [playerid] return the_gms - def GetName(self): self.AliasLib = component.get('alias') player = self.session.get_my_info() @@ -1415,7 +1286,6 @@ return [self.chat_display_name([self.AliasLib.alias[0], player[1], player[2]]), self.AliasLib.alias[1]] return [self.chat_display_name(player), "Default"] - def GetFilteredText(self, text): advregex = re.compile('\"(.*?)\"', re.I) self.AliasLib = component.get('alias') @@ -1430,11 +1300,9 @@ text = text.replace(match, newmatch) return text - def emote_message(self, text): - text = self.NormalizeParse(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": msg_type = chat_msg.WHISPER_EMOTE_MESSAGE @@ -1449,13 +1317,10 @@ text = "** " + name + " " + text + " **" self.EmotePost(text) - def whisper_to_players(self, text, player_ids): tabbed_whispers_p = self.settings.get_setting("tabbedwhispers") - # Heroman - apply any filtering selected - text = self.NormalizeParse(text) + text = Parse.Normalize(text, self) player_names = "" - # post to our chat before we colorize for m in player_ids: id = m.strip() if self.session.is_valid_id(id): @@ -1469,7 +1334,6 @@ comma.join(player_ids) if (self.sendtarget == "all"): self.InfoPost("whispering to "+ player_names + " " + text + " ") - # colorize and loop, sending whisper messages to all valid clients text = self.colorize(self.mytextcolor, text) for id in player_ids: id = id.strip() @@ -1501,18 +1365,13 @@ if send: self.session.send(msg.toxml(),player_id) del msg - #### incoming chat message handler ##### - def post_incoming_msg(self, msg, player): - - # pull data type = msg.get_type() text = msg.get_text() alias = msg.get_alias() # who sent us the message? if alias: display_name = self.chat_display_name([alias, player[1], player[2]]) - elif player: display_name = self.chat_display_name(player) - else: display_name = "Server Administrator" + else: display_name = self.chat_display_name(player) ######### START plugin_incoming_msg() ########### for plugin_fname in self.activeplugins.keys(): @@ -1522,14 +1381,11 @@ if str(e) != "'module' object has no attribute 'receive_msg'": logger.general(traceback.format_exc()) logger.general("EXCEPTION: " + str(e)) - #end mDuo13 added code - #image stripping for players' names strip_img = self.settings.get_setting("Show_Images_In_Chat") if (strip_img == "0"): display_name = chat_util.strip_img_tags(display_name) - #end image stripping. --mDuo13, July 11th, 2005 - # default sound recvSound = "RecvSound" # act on the type of messsage + if (type == chat_msg.CHAT_MESSAGE): text = "" + display_name + ": " + text self.Post(text) @@ -1624,17 +1480,15 @@ sound_file = self.settings.get_setting(recvSound) if sound_file != '': component.get('sound').play(sound_file) + #### Posting helpers ##### - def InfoPost(self, s): self.Post(self.colorize(self.infocolor, s), c='info') - def SystemPost(self, s): self.Post(self.colorize(self.syscolor, s), c='system') - def EmotePost(self, s): self.Post(self.colorize(self.emotecolor, s), c='emote') @@ -1675,15 +1529,9 @@ if aliasInfo[1] != 'Default': self.settings.set_setting("mytextcolor", defaultcolor) self.set_colors() - #following line based on sourceforge patch #880403 from mDuo - # EDIT: Had to rework blank line check to handle malformed HTML throwing error. - # this limits the effectiveness of this check -SD lineHasText = 1 try: lineHasText = strip_html(s).replace(" ","").replace(" ","").strip()!="" except: - # HTML parser has errored out (most likely). Being as all we are doing is - # scanning for empty/blank lines anyway there is no harm in letting a - # troublesome message though. Worst case is a blank line to chat. lineHasText = 1 if lineHasText: #following added by mDuo13 @@ -1731,12 +1579,6 @@ else: self.InfoPost("Failed to send message, unknown send type for this tab") self.parsed=0 - # - # TimeIndexString() - # - # time indexing for chat display only (don't log time indexing) - # added by Snowdog 4/04 - def TimeIndexString(self): try: mtime = "" @@ -1749,94 +1591,13 @@ logger.general("EXCEPTION: " + str(e)) return "[ERROR]" - #### Post with parsing dice #### - - def ParsePost(self, s, send=False, myself=False): - s = self.NormalizeParse(s) - self.set_colors() - self.Post(s,send,myself) - - def NormalizeParse(self, s): - for plugin_fname in self.activeplugins.keys(): - plugin = self.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("EXCEPTION: " + str(e)) - if self.parsed == 0: - s = self.ParseNode(s) - s = self.ParseDice(s) - s = self.ParseFilter(s) - self.parsed = 1 - return s - - def ParseFilter(self, s): - s = self.GetFilteredText(s) - return s - - def ParseNode(self, s): - """Parses player input for embedded nodes rolls""" - cur_loc = 0 - #[a-zA-Z0-9 _\-\.] - reg = re.compile("(!@(.*?)@!)") - matches = reg.findall(s) - for i in xrange(0,len(matches)): - newstr = self.ParseNode(self.resolve_nodes(matches[i][1])) - s = s.replace(matches[i][0], newstr, 1) - return s - - def ParseDice(self, s): - """Parses player input for embedded dice rolls""" - reg = re.compile("\[([^]]*?)\]") - matches = reg.findall(s) - for i in xrange(0,len(matches)): - newstr = self.PraseUnknowns(matches[i]) - qmode = 0 - newstr1 = newstr - if newstr[0].lower() == 'q': - newstr = newstr[1:] - qmode = 1 - if newstr[0].lower() == '#': - newstr = newstr[1:] - qmode = 2 - try: newstr = component.get('DiceManager').proccessRoll(newstr) - except: pass - if qmode == 1: - s = s.replace("[" + matches[i] + "]", - "" + newstr, 1) - elif qmode == 2: - s = s.replace("[" + matches[i] + "]", newstr[len(newstr)-2:-1], 1) - else: s = s.replace("[" + matches[i] + "]", - "[" + newstr1 + "] => " + newstr, 1) - return s - - def PraseUnknowns(self, s): - # Uses a tuple. Usage: ?Label}dY. If no Label is assigned then use ?}DY - newstr = "0" - reg = re.compile("(\?\{*)([a-zA-Z ]*)(\}*)") - matches = reg.findall(s) - for i in xrange(0,len(matches)): - lb = "Replace '?' with: " - if len(matches[i][0]): - lb = matches[i][1] + "?: " - dlg = wx.TextEntryDialog(self, lb, "Missing Value?") - dlg.SetValue('') - if matches[i][0] != '': - dlg.SetTitle("Enter Value for " + matches[i][1]) - if dlg.ShowModal() == wx.ID_OK: newstr = dlg.GetValue() - if newstr == '': newstr = '0' - s = s.replace(matches[i][0], newstr, 1).replace(matches[i][1], '', 1).replace(matches[i][2], '', 1) - dlg.Destroy() - return s - # This subroutine builds a chat display name. # def chat_display_name(self, player): - if self.settings.get_setting("ShowIDInChat") == "0": - display_name = player[0] - else: - display_name = "("+player[2]+") " + player[0] + if player == None: + player = ['Server Administrator-> ', '127.0.0.1', '0'] + if self.settings.get_setting("ShowIDInChat") == "0": display_name = player[0] + else: display_name = "("+player[2]+") " + player[0] return display_name # This subroutine will get a hex color and return it, or return nothing @@ -1854,8 +1615,8 @@ else: dlg.Destroy() return None + # def get_color - end - def replace_quotes(self, s): in_tag = 0 i = 0 @@ -1869,179 +1630,3 @@ i += 1 return rs - def resolve_loop(self, node, path, step, depth): - if step == depth: - return self.resolution(node) - else: - child_list = node.findall('nodehandler') - for child in child_list: - if step == depth: break - if child.get('name') == path[step]: - node = child - step += 1 - if node.get('class') in ('dnd35char_handler', - "SWd20char_handler", - "d20char_handler", - "dnd3echar_handler"): self.resolve_cust_loop(node, path, step, depth) - elif node.get('class') == 'rpg_grid_handler': self.resolve_grid(node, path, step, depth) - else: self.resolve_loop(node, path, step, depth) - - def resolve_grid(self, node, path, step, depth): - if step == depth: - self.data = 'Invalid Grid Reference!' - return - cell = tuple(path[step].strip('(').strip(')').split(',')) - grid = node.find('grid') - rows = grid.findall('row') - col = rows[int(self.ParseDice(cell[0]))-1].findall('cell') - try: self.data = self.ParseMap(col[int(self.ParseDice(cell[1]))-1].text, node) or 'No Cell Data' - except: self.data = 'Invalid Grid Reference!' - return - - def resolution(self, node): - if self.passed == False: - self.passed = True - 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.ParseMap(s, node) - s = self.ParseParent(s, node.get('map')) - self.data = s - - def ParseMap(self, s, node): - """Parses player input for embedded nodes rolls""" - cur_loc = 0 - reg = re.compile("(!!(.*?)!!)") - matches = reg.findall(s) - for i in xrange(0,len(matches)): - tree_map = node.get('map') - tree_map = tree_map + '::' + matches[i][1] - newstr = '!@'+ tree_map +'@!' - s = s.replace(matches[i][0], newstr, 1) - s = self.ParseNode(s) - s = self.ParseParent(s, tree_map) - return s - - def ParseParent(self, s, tree_map): - """Parses player input for embedded nodes rolls""" - cur_loc = 0 - reg = re.compile("(!#(.*?)#!)") - matches = reg.findall(s) - for i in xrange(0,len(matches)): - ## Build the new tree_map - new_map = tree_map.split('::') - del new_map[len(new_map)-1] - parent_map = matches[i][1].split('::') - ## Find an index or use 1 for ease of use. - try: index = new_map.index(parent_map[0]) - except: index = 1 - ## Just replace the old tree_map from the index. - new_map[index:len(new_map)] = parent_map - newstr = '::'.join(new_map) - newstr = '!@'+ newstr +'@!' - s = s.replace(matches[i][0], newstr, 1) - #s = self.ParseMap(s, node) ## Needs to be added - s = self.ParseNode(s) - return s - - def resolve_nodes(self, s): - self.passed = False - self.data = 'Invalid Reference!' - value = "" - path = s.split('::') - depth = len(path) - self.gametree = component.get('tree') - try: node = self.gametree.tree_map[path[0]]['node'] - except Exception, e: return self.data - if node.get('class') in ('dnd35char_handler', - "SWd20char_handler", - "d20char_handler", - "dnd3echar_handler"): self.resolve_cust_loop(node, path, 1, depth) - elif node.get('class') == 'rpg_grid_handler': self.resolve_grid(node, path, 1, depth) - else: self.resolve_loop(node, path, 1, depth) - return self.data - - def resolve_cust_loop(self, node, path, step, depth): - node_class = node.get('class') - ## Code needs clean up. Either choose .lower() or .title(), then reset the path list's content ## - if step == depth: self.resolution(node) - ##Build Abilities dictionary## - if node_class not in ('d20char_handler', "SWd20char_handler"): ab = node.find('character').find('abilities') - else: ab = node.find('abilities') - ab_list = ab.findall('stat'); pc_stats = {} - - for ability in ab_list: - pc_stats[ability.get('name')] = ( - str(ability.get('base')), - str((int(ability.get('base'))-10)/2) ) - pc_stats[ability.get('abbr')] = ( - str(ability.get('base')), - str((int(ability.get('base'))-10)/2) ) - - if node_class not in ('d20char_handler', "SWd20char_handler"): ab = node.find('character').find('saves') - else: ab = node.find('saves') - ab_list = ab.findall('save') - for save in ab_list: - pc_stats[save.get('name')] = (str(save.get('base')), str(int(save.get('magmod')) + int(save.get('miscmod')) + int(pc_stats[save.get('stat')][1]) ) ) - if save.get('name') == 'Fortitude': abbr = 'Fort' - if save.get('name') == 'Reflex': abbr = 'Ref' - if save.get('name') == 'Will': abbr = 'Will' - pc_stats[abbr] = ( str(save.get('base')), str(int(save.get('magmod')) + int(save.get('miscmod')) + int(pc_stats[save.get('stat')][1]) ) ) - - if path[step].lower() == 'skill': - if node_class not in ('d20char_handler', "SWd20char_handler"): node = node.find('snf') - node = node.find('skills') - child_list = node.findall('skill') - for child in child_list: - if path[step+1].lower() == child.get('name').lower(): - if step+2 == depth: self.data = child.get('rank') - elif path[step+2].lower() == 'check': - self.data = 'Skill Check: ' + child.get('name') + ' [1d20+'+str( int(child.get('rank')) + int(pc_stats[child.get('stat')][1]) )+']' - return - - if path[step].lower() == 'feat': - if node_class not in ('d20char_handler', "SWd20char_handler"): node = node.find('snf') - node = node.find('feats') - child_list = node.findall('feat') - for child in child_list: - if path[step+1].lower() == child.get('name').lower(): - if step+2 == depth: self.data = ''+child.get('name')+''+': '+child.get('desc') - return - if path[step].lower() == 'cast': - if node_class not in ('d20char_handler', "SWd20char_handler"): node = node.find('snp') - node = node.find('spells') - child_list = node.findall('spell') - for child in child_list: - if path[step+1].lower() == child.get('name').lower(): - if step+2 == depth: self.data = ''+child.get('name')+''+': '+child.get('desc') - return - if path[step].lower() == 'attack': - if node_class not in ('d20char_handler', "SWd20char_handler"): node = node.find('combat') - if path[step+1].lower() == 'melee' or path[step+1].lower() == 'm': - bonus_text = '(Melee)' - bonus = node.find('attacks') - bonus = bonus.find('melee') - bonus = bonus.attrib; d = int(pc_stats['Str'][1]) - elif path[step+1].lower() == 'ranged' or path[step+1].lower() == 'r': - bonus_text = '(Ranged)' - bonus = node.find('attacks') - bonus = bonus.find('ranged') - bonus = bonus.attrib; d = int(pc_stats['Dex'][1]) - for b in bonus: - d += int(bonus[b]) - bonus = str(d) - if path[step+2] == None: self.data = bonus - else: - weapons = node.find('attacks') - weapons = weapons.findall('weapon') - for child in weapons: - if path[step+2].lower() == child.get('name').lower(): - self.data = 'Attack: '+bonus_text+' '+child.get('name')+' [1d20+'+bonus+'] ' + 'Damage: ['+child.get('damage')+']' - return - elif pc_stats.has_key(path[step].title()): - if step+1 == depth: self.data = pc_stats[path[step].title()][0] + ' +('+pc_stats[path[step].title()][1]+')' - elif path[step+1].title() == 'Mod': self.data = pc_stats[path[step].title()][1] - elif path[step+1].title() == 'Check': self.data = ''+path[step].title()+' Check: [1d20+'+str(pc_stats[path[step].title()][1])+']' - return diff -r 4b2884f29a72 -r 81d0bfd5e800 orpg/chat/commands.py --- a/orpg/chat/commands.py Fri Jan 15 22:45:51 2010 -0600 +++ b/orpg/chat/commands.py Sat Jun 12 03:50:37 2010 -0500 @@ -7,7 +7,6 @@ # on_whisper(self,text) # - import string, time import orpg.orpg_version import orpg.orpg_windows @@ -26,63 +25,41 @@ try: import cmd_ext print "Importing Developer Extended Command Set" -except: - pass +except: pass ##---------------------------------------------------------------- ANTI_LOG_CHAR = '!' class chat_commands: - # Initialization subroutine. - # - # !self : instance of self - # !chat : instance of the chat window to write to - def __init__(self,chat): self.post = chat.Post self.colorize = chat.colorize self.session = chat.session - #self.send = chat.session.send self.settings = chat.settings self.chat = chat self.cmdlist = {} self.shortcmdlist = {} self.defaultcmds() self.defaultcmdalias() - # def __init__ - end self.previous_whisper = [] - - # This subroutine will take a text string and attempt to match to a series - # of implemented emotions. - # - # !self : instance of self - # !text : string of text matching an implemented emotion - def addcommand(self, cmd, function, helpmsg): if not self.cmdlist.has_key(cmd) and not self.shortcmdlist.has_key(cmd): self.cmdlist[cmd] = {} self.cmdlist[cmd]['function'] = function self.cmdlist[cmd]['help'] = helpmsg - #print 'Command Added: ' + cmd - def addshortcmd(self, shortcmd, longcmd): if not self.shortcmdlist.has_key(shortcmd) and not self.cmdlist.has_key(shortcmd): self.shortcmdlist[shortcmd] = longcmd - def removecmd(self, cmd): if self.cmdlist.has_key(cmd): del self.cmdlist[cmd] elif self.shortcmdlist.has_key(cmd): del self.shortcmdlist[cmd] - #print 'Command Removed: ' + cmd - - - def defaultcmds(self): self.addcommand('/help', self.on_help, '- Displays this help message') self.addcommand('/version', self.on_version, ' - Displays current version of OpenRPG.') @@ -112,7 +89,6 @@ self.addcommand('/purge', self.on_purge, 'This will clear the entire chat window') self.addcommand('/advfilter', self.on_filter, 'This will toggle the Advanced Filter') - def defaultcmdalias(self): self.addshortcmd('/?', '/help') self.addshortcmd('/he', '/me') @@ -123,18 +99,14 @@ self.addshortcmd('/date', '/time') self.addshortcmd('/desc', '/description') self.addshortcmd('/d', '/description') - - #This is just an example or a differant way the shorcmd can be used self.addshortcmd('/sleep', '/me falls asleep') - def docmd(self,text): cmdsearch = string.split(text,None,1) cmd = string.lower(cmdsearch[0]) start = len(cmd) end = len(text) cmdargs = text[start+1:end] - if self.cmdlist.has_key(cmd): self.cmdlist[cmd]['function'](cmdargs) elif self.shortcmdlist.has_key(cmd): @@ -143,37 +115,26 @@ msg = "Sorry I don't know what %s is!" % (cmd) self.chat.InfoPost(msg) - def on_filter(self, cmdargs): - #print self.chat.advancedFilter test = not self.chat.advancedFilter - #print test - for tab in self.chat.parent.whisper_tabs: tab.advancedFilter = not self.chat.advancedFilter - for tab in self.chat.parent.null_tabs: tab.advancedFilter = not self.chat.advancedFilter - for tab in self.chat.parent.group_tabs: tab.advancedFilter = not self.chat.advancedFilter - if self.chat.parent.GMChatPanel != None: self.chat.parent.GMChatPanel.advancedFilter = not self.chat.advancedFilter - self.chat.advancedFilter = not self.chat.advancedFilter - if self.chat.advancedFilter: self.chat.InfoPost("Advanced Filtering has been turned On") else: self.chat.InfoPost("Advanced Filtering has been turned Off") - def on_purge(self, cmdargs): self.chat.PurgeChat() self.chat.InfoPost('Chat Buffer has been Purged!') - def on_sound(self, cmdargs): if len(cmdargs) < 8: self.chat.InfoPost("You must provide a URL for the file name, it does not work for just local sound files") @@ -186,9 +147,7 @@ else: snd = cmdargs.replace('&', '&') loop = '' - type = 'remote' - (name, ip, id, text_status, version, protocol_version, client_string, role) = self.session.get_my_info() group_id = self.session.group_id if (role != 'Lurker' and group_id != '0') or self.session.get_status() != 1: @@ -207,11 +166,9 @@ else: self.chat.InfoPost("Something dun fuckered up Frank!") - def on_version(self, cmdargs=""): self.chat.InfoPost("Version is OpenRPG " + self.chat.version) - def on_load(self, cmdargs): args = string.split(cmdargs,None,-1) try: @@ -222,14 +179,12 @@ print e self.chat.InfoPost("ERROR Loading settings") - def on_font(self, cmdargs): try: fontsettings = self.chat.set_default_font(fontname=cmdargs, fontsize=None) except: self.chat.InfoPost("ERROR setting default font") - def on_fontsize(self, cmdargs): args = string.split(cmdargs,None,-1) try: @@ -238,7 +193,6 @@ print e self.chat.InfoPost("ERROR setting default font size") - def on_close(self, cmdargs): try: chatpanel = self.chat @@ -250,7 +204,6 @@ except: self.chat.InfoPost("Error: cannot close private chat tab.") - def on_time(self, cmdargs): local_time = time.localtime() gmt_time = time.gmtime() @@ -258,30 +211,30 @@ self.chat.InfoPost("
Local: " + time.strftime(format_string)+\ "
GMT: "+time.strftime(format_string,gmt_time)) - def on_dieroller(self, cmdargs): args = string.split(cmdargs,None,-1) rm = component.get('DiceManager') + cur_die = rm.getRoller() + if len(args) == 0: self.chat.InfoPost('You are using the "' +cur_die+ '" die roller.'); return try: rm.setRoller(args[0]) - self.chat.SystemPost("You have changed your die roller to the \"" + args[0] + "\" roller.") - self.settings.set_setting('dieroller',args[0]) + self.chat.SystemPost('You have changed your die roller to the "' +rm.getRoller()+ '" 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 \"" + rm.getRoller() + "\" 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 "' +cur_die+ '" die roller.') - def on_ping(self, cmdargs): ct = time.clock() msg = "" self.session.outbox.put(msg) - def on_log(self,cmdargs): args = string.split(cmdargs,None,-1) logfile = self.settings.get_setting( 'GameLogPrefix' ) - if len( args ) == 0: self.postLoggingState() elif args[0] == "on" and logfile != '': @@ -309,7 +262,6 @@ else: self.chat.InfoPost("Unknown logging command, use 'on' or 'off'" ) - def postLoggingState( self ): logfile = self.settings.get_setting( 'GameLogPrefix' ) try: @@ -319,39 +271,23 @@ suffix = time.strftime( '-%d-%m-%y.html', time.localtime( time.time() ) ) self.chat.InfoPost('Log filename is "%s%s", system is %s logging.' % (logfile, suffix, comment) ) - # This subroutine will set the players netork status. - # - #!self : instance of self - - def on_name(self, cmdargs): - #only 20 chars no more! :) if cmdargs == "": self.chat.InfoPost("**Incorrect syntax for name.") else: - #txt = txt[:50] self.settings.set_setting('player', cmdargs) self.session.set_name(str(cmdargs)) - # def on_status - end - # This subroutine will set the players netork status. - # - # !self : instance of self - def on_status(self, cmdargs): if cmdargs == "": self.chat.InfoPost("Incorrect synatx for status.") else: - #only 20 chars no more! :) txt = cmdargs[:20] self.session.set_text_status(str(txt)) - # def on_status - end - def on_set(self, cmdargs): args = string.split(cmdargs,None,-1) keys = self.settings.get_setting_keys() - #print keys if len(args) == 0: line = "" for m in keys: @@ -378,11 +314,6 @@ self.chat.set_colors() self.chat.set_buffersize() - # This subroutine will display the correct usage of the different emotions. - # - #!self : instance of self - - def on_help(self, cmdargs=""): cmds = self.cmdlist.keys() cmds.sort() @@ -400,11 +331,6 @@ msg += ' %s' % (self.cmdlist[cmd]['help']) self.chat.InfoPost(msg) - # This subroutine will either show the list of currently ignored users - # !self : instance of self - # !text : string that is comprised of a list of users to toggle the ignore flag - - def on_ignore(self, cmdargs): args = string.split(cmdargs,None,-1) (ignore_list, ignore_name) = self.session.get_ignore_list() @@ -431,7 +357,6 @@ self.chat.InfoPost(m + " was ignored because it is an invalid player ID") traceback.print_exc() - def on_role(self, cmdargs): if cmdargs == "": self.session.display_roles() @@ -453,16 +378,7 @@ for m in player_ids: self.session.set_role(m.strip(),role,role_pwd) except: traceback.print_exc() -# return - # This subroutine implements the whisper functionality that enables a user - # to whisper to another user. - # - # !self : instance of self - # !text : string that is comprised of a list of users and the message to - #whisper. - - def on_whisper(self, cmdargs): delim = cmdargs.find("=") @@ -476,10 +392,6 @@ mesg = string.strip(cmdargs[delim+1:]) self.chat.whisper_to_players(mesg,player_ids) -#--------------------------------------------------------- -# [START] Digitalxero Multi Whisper Group 1/1/05 -#--------------------------------------------------------- - def on_groupwhisper(self, cmdargs): args = string.split(cmdargs,None,-1) delim = cmdargs.find("=") @@ -533,11 +445,6 @@ else: idList = str(n) + ", " + idList self.on_whisper(idList + "=" + self.settings.get_setting("gwtext") + msg) -#--------------------------------------------------------- -# [END] Digitalxero Multi Whisper Group 1/1/05 -#--------------------------------------------------------- - - def on_gmwhisper(self, cmdargs): if cmdargs == "": self.chat.InfoPost("**Incorrect syntax for GM Whisper.") @@ -551,7 +458,6 @@ self.on_whisper(gmstring + "=" + cmdargs) else: self.chat.InfoPost("**No GMs to Whisper to.") - def on_moderate(self, cmdargs): if cmdargs != "": pos = cmdargs.find("=") @@ -584,11 +490,9 @@ self.session.outbox.put(msg) self.session.update() - def on_update(self, cmdargs): self.chat.InfoPost("This command is no longer valid") - def on_description(self, cmdargs): if len(cmdargs) <= 0: self.chat.InfoPost("**No description text to display." + str(delim)) @@ -599,13 +503,10 @@ self.chat.Post(mesg) self.chat.send_chat_message(mesg) - def invoke_tab(self, cmdargs): - ######START mDuo13's Tab Initiator######## try: int(cmdargs) playerid = cmdargs.strip() - # Check to see if parent notebook already has a private tab for player for panel in self.chat.parent.whisper_tabs: if (panel.sendtarget == playerid): self.chat.Post("Cannot invoke tab: Tab already exists.") @@ -622,30 +523,22 @@ nidx = self.chat.parent.get_tab_index(displaypanel) self.chat.parent.newMsg(nidx) return - #######END mDuo13's Tab Initiator######### - - def on_remote_admin(self, cmdargs): args = string.split(cmdargs,None,-1) - #handles remote administration commands try: pass_state = 0 pwd = self.session.orpgFrame_callback.password_manager.GetSilentPassword("server") if pwd != None: pass_state = 1 else: pwd = "[NONE]" - if len( args ) == 0: - #raw command return state info msg = "
Remote Administrator Config:" if pass_state != 1 : msg += " Password not set. Remote admin functions disabled
" else: msg += " Enabled. Using password '"+pwd+"'
" self.chat.SystemPost(msg) return - if pass_state != 1 and args[0] != "set": - #no commands under this point will execute unless an admin password has been previously set self.chat.SystemPost("Command ignored. No remote administrator password set!!") return msgbase = "' self.session.outbox.put(msg) elif args[0] == "createroom": - #request creation of a (temporary) persistant room if len(args) < 2: self.chat.SystemPost( "You must supply a name and boot password at least.
/admin createroom <name> <boot password> [password]" ) return @@ -709,7 +600,6 @@ self.session.outbox.put(msg) else: self.chat.InfoPost("Unknown administrator command" ) - #command_function = {'banip': self.admin.r_admin_banip, 'createroom': self.r_admin_createroom,} except: self.chat.InfoPost("An error has occured while processing a Remote Administrator command!") traceback.print_exc() diff -r 4b2884f29a72 -r 81d0bfd5e800 orpg/dieroller/base.py --- a/orpg/dieroller/base.py Fri Jan 15 22:45:51 2010 -0600 +++ b/orpg/dieroller/base.py Sat Jun 12 03:50:37 2010 -0500 @@ -22,18 +22,16 @@ # Author: Andrew Bennett # Maintainer: # Version: -# $Id: die.py,v 1.13 2007/03/13 17:53:42 digitalxero Exp $ +# $Id: die.py,v Traipse 'Ornery-Orc' prof.ebral Exp $ # # Description: This class is used to make working with dice easier # -__version__ = "$Id: die.py,v 1.13 2007/03/13 17:53:42 digitalxero Exp $" - +__version__ = "$Id: die.py,v Traipse 'Ornery-Orc' prof.ebral Exp Exp $" import random import UserList import copy -#import string class die_base(UserList.UserList): name = None @@ -42,11 +40,9 @@ if isinstance(source, (int, float, basestring)): s = [] s.append(di(source)) - else: - s = source + else: s = source UserList.UserList.__init__(self,s) - def sum(self): s = 0 for a in self.data: @@ -58,28 +54,19 @@ o = other elif hasattr(other,"sum"): o = other.sum() - else: - return None - + else: return None result = [] for die in self: - if die < o: - result.append(die) + if die < o: result.append(die) return self.__class__(result) def __rshift__(self,other): - - if type(other) == type(3) or type(other) == type(3.0): - o = other - elif hasattr(other,"sum"): - o = other.sum() - else: - return None - + if type(other) == type(3) or type(other) == type(3.0): o = other + elif hasattr(other,"sum"): o = other.sum() + else: return None result = [] for die in self: - if die > o: - result.append(die) + if die > o: result.append(die) return self.__class__(result) def __rlshift__(self,other): @@ -88,77 +75,58 @@ def __rrshift__(self,other): return self.__lshift__(other) - def __str__(self): + try: print "MY STRING", myStr + except: pass if len(self.data) > 0: myStr = "[" + str(self.data[0]) for a in self.data[1:]: myStr += "," myStr += str(a) myStr += "] = (" + str(self.sum()) + ")" - else: - myStr = "[] = (0)" + else: myStr = "[] = (0)" return myStr def __lt__(self,other): if type(other) == type(3) or type(other) == type(3.0): return (self.sum() < other) - elif hasattr(other,"sum"): - return (self.sum() < other.sum()) - else: - return UserList.UserList.__lt__(self,other) + elif hasattr(other,"sum"): return (self.sum() < other.sum()) + else: return UserList.UserList.__lt__(self,other) def __le__(self,other): if type(other) == type(3) or type(other) == type(3.0): return (self.sum() <= other) - elif hasattr(other,"sum"): - return (self.sum() <= other.sum()) - else: - return UserList.UserList.__le__(self,other) + elif hasattr(other,"sum"): return (self.sum() <= other.sum()) + else: return UserList.UserList.__le__(self,other) def __eq__(self,other): if type(other) == type(3) or type(other) == type(3.0): return (self.sum() == other) - elif hasattr(other,"sum"): - return (self.sum() == other.sum()) - else: - return UserList.UserList.__eq__(self,other) + elif hasattr(other,"sum"): return (self.sum() == other.sum()) + else: return UserList.UserList.__eq__(self,other) def __ne__(self,other): - if type(other) == type(3) or type(other) == type(3.0): - return (self.sum() != other) - elif hasattr(other,"sum"): - return (self.sum() != other.sum()) - else: - return UserList.UserList.__ne__(self,other) + if type(other) == type(3) or type(other) == type(3.0): return (self.sum() != other) + elif hasattr(other,"sum"): return (self.sum() != other.sum()) + else: return UserList.UserList.__ne__(self,other) def __gt__(self,other): - if type(other) == type(3) or type(other) == type(3.0): - return (self.sum() > other) - elif hasattr(other,"sum"): - return (self.sum() > other.sum()) - else: - return UserList.UserList.__gt__(self,other) + if type(other) == type(3) or type(other) == type(3.0): return (self.sum() > other) + elif hasattr(other,"sum"): return (self.sum() > other.sum()) + else: return UserList.UserList.__gt__(self,other) def __ge__(self,other): - if type(other) == type(3) or type(other) == type(3.0): - return (self.sum() >= other) - elif hasattr(other,"sum"): - return (self.sum() >= other.sum()) - else: - return UserList.UserList.__ge__(self,other) + if type(other) == type(3) or type(other) == type(3.0): return (self.sum() >= other) + elif hasattr(other,"sum"): return (self.sum() >= other.sum()) + else: return UserList.UserList.__ge__(self,other) def __cmp__(self,other): # this function included for backwards compatibility # As of 2.1, lists implement the "rich comparison" # methods overloaded above. - if type(other) == type(3) or type(other) == type(3.0): - return cmp(self.sum(), other) - elif hasattr(other,"sum"): - return cmp(self.sum(), other.sum()) - else: - return UserList.UserList.__cmp__(self,other) - + if type(other) == type(3) or type(other) == type(3.0): return cmp(self.sum(), other) + 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) @@ -166,16 +134,9 @@ def __add__(self,other): mycopy = copy.deepcopy(self) if type(other) == type(3) or type(other) == type(3.0): - #if other < 0: - # return self.__sub__(-other) - #other = [di(other,other)] other = [static_di(other)] - #return self.sum() + other - - elif type(other) == type("test"): - return self + elif type(other) == type("test"): return self mycopy.extend(other) - #result = UserList.UserList.__add__(mycopy,other) return mycopy def __iadd__(self,other): @@ -197,17 +158,13 @@ mycopy = copy.deepcopy(self) if type(other) == type(3) or type(other) == type(3.0): neg_die = static_di(-other) - #neg_die.set_value(-other) other = [neg_die] - #return self.sum() - other - else: - other = -other + else: other = -other mycopy.extend(other) return mycopy def __rsub__(self,other): mycopy = -copy.deepcopy(self) - #print type(other) if type(other) == type(3) or type(other) == type(3.0): new_die = di(0) new_die.set_value(other) @@ -219,89 +176,62 @@ return self.__sub__(other) def __mul__(self,other): - if type(other) == type(3) or type(other) == type(3.0): - return self.sum() * other - elif hasattr(other,"sum"): - return other.sum() * self.sum() - else: - return UserList.UserList.__mul__(self,other) + if type(other) == type(3) or type(other) == type(3.0): return self.sum() * other + elif hasattr(other,"sum"): return other.sum() * self.sum() + else: return UserList.UserList.__mul__(self,other) def __rmul__(self,other): return self.__mul__(other) def __div__(self,other): - if type(other) == type(3) or type(other) == type(3.0): - return float(self.sum()) / other - elif hasattr(other,"sum"): - return float(self.sum()) / other.sum() - else: - return UserList.UserList.__div__(self,other) + if type(other) == type(3) or type(other) == type(3.0): return float(self.sum()) / other + elif hasattr(other,"sum"): return float(self.sum()) / other.sum() + else: return UserList.UserList.__div__(self,other) def __rdiv__(self,other): - if type(other) == type(3) or type(other) == type(3.0): - return other / float(self.sum()) - elif hasattr(other,"sum"): - return other.sum() / float(self.sum()) - else: - return UserList.UserList.__rdiv__(self,other) + if type(other) == type(3) or type(other) == type(3.0): return other / float(self.sum()) + elif hasattr(other,"sum"): return other.sum() / float(self.sum()) + else: return UserList.UserList.__rdiv__(self,other) def __mod__(self,other): - if type(other) == type(3) or type(other) == type(3.0): - return self.sum()%other - elif hasattr(other,"sum"): - return self.sum() % other.sum() - else: - return UserList.UserList.__mod__(self,other) + if type(other) == type(3) or type(other) == type(3.0): return self.sum()%other + elif hasattr(other,"sum"): return self.sum() % other.sum() + else: return UserList.UserList.__mod__(self,other) def __rmod__(self,other): - if type(other) == type(3) or type(other) == type(3.0): - return other % self.sum() - elif hasattr(other,"sum"): - return other.sum() % self.sum() - else: - return UserList.UserList.__rmod__(self,other) + if type(other) == type(3) or type(other) == type(3.0): return other % self.sum() + elif hasattr(other,"sum"): return other.sum() % self.sum() + else: return UserList.UserList.__rmod__(self,other) def __neg__(self): - for i in range(len(self.data)): - self.data[i] = -self.data[i] + for i in range(len(self.data)): self.data[i] = -self.data[i] return self def __pos__(self): - for i in range(len(self.data)): - self.data[i] = +self.data[i] + for i in range(len(self.data)): self.data[i] = +self.data[i] return self def __abs__(self): - for i in range(len(self.data)): - self.data[i] = abs(self.data[i]) + for i in range(len(self.data)): self.data[i] = abs(self.data[i]) return self - #return abs(self.sum()) def __pow__(self,other): - if type(other) == type(3) or type(other) == type(3.0): - return self.sum() ** other - elif hasattr(other,"sum"): - return self.sum() ** other.sum() - else: - return UserList.UserList.__pow__(self,other) - + if type(other) == type(3) or type(other) == type(3.0): return self.sum() ** other + elif hasattr(other,"sum"): return self.sum() ** other.sum() + else: return UserList.UserList.__pow__(self,other) def __rpow__(self,other): # We're overloading exponentiation of ints to create "other" number of dice - if other >= 1: result = self.__class__(self[0].sides) - for t in range(other-1): - result+=self.__class__(self[0].sides) - else: - result = None - + for t in range(other-1): result+=self.__class__(self[0].sides) + else: result = None return result ### 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 @@ -309,21 +239,17 @@ self.roll(min) def __str__(self): - if len(self.history) > 1: - return str(self.history) - else: - return str(self.value) + if len(self.history) > 1: return str(self.history) + else: return str(self.value) def __neg__(self): self.value = -self.value - for i in range(len(self.history)): - self.history[i] = -self.history[i] + for i in range(len(self.history)): self.history[i] = -self.history[i] return self def __pos__(self): self.value = +self.value - for i in range(len(self.history)): - self.history[i] = +self.history[i] + for i in range(len(self.history)): self.history[i] = +self.history[i] return self def __abs__(self): @@ -333,90 +259,59 @@ return self def __repr__(self): - if len(self.history) > 1: - return str(self.history) - else: - return str(self.value) + if len(self.history) > 1: return str(self.history) + else: return str(self.value) 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 - else: - return 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 + else: return self < other def __le__(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 - else: - return 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 + else: return self <= other def __eq__(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 - else: - return 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 + else: return self == other def __ne__(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 - else: - return 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 + else: return self != other def __gt__(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 - else: - return 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 + else: return self > other def __ge__(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 - else: - return 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 + else: return self >= other def __cmp__(self,other): # this function included for backwards compatibility # As of 2.1, lists implement the "rich comparison" # methods overloaded above. - if type(other) == type(3) or type(other) == type(3.0): - return cmp(self.value, other) - elif hasattr(other,"value"): - return cmp(self.value, other.value) - else: - return cmp(self,other) + if type(other) == type(3) or type(other) == type(3.0): return cmp(self.value, other) + elif hasattr(other,"value"): return cmp(self.value, other.value) + else: return cmp(self,other) def roll(self,min=1): - if isinstance(self.sides, basestring) and self.sides.lower() == 'f': - self.value = random.randint(-1, 1) - else: - #self.value = random.randint(min, self.sides) - self.value = int(random.uniform(min, self.sides+1)) + if isinstance(self.sides, basestring) and self.sides.lower() == 'f': self.value = random.randint(-1, 1) + else: self.value = int(random.uniform(min, self.sides+1)) self.history = [] self.history.append(self.value) def extraroll(self): - if isinstance(self.sides, basestring) and self.sides.lower() == 'f': - result = random.randint(-1, 1) - else: - #result = random.randint(1, self.sides) - result = int(random.uniform(1,self.sides+1)) - + if isinstance(self.sides, basestring) and self.sides.lower() == 'f': result = random.randint(-1, 1) + else: result = int(random.uniform(1,self.sides+1)) self.value += result self.history.append(result) @@ -444,8 +339,7 @@ _rollers = {} def __new__(cls): it = cls.__dict__.get("__it__") - if it is not None: - return it + if it is not None: return it cls.__it__ = it = object.__new__(cls) return it diff -r 4b2884f29a72 -r 81d0bfd5e800 orpg/dieroller/rollers/7sea.py --- a/orpg/dieroller/rollers/7sea.py Fri Jan 15 22:45:51 2010 -0600 +++ b/orpg/dieroller/rollers/7sea.py Sat Jun 12 03:50:37 2010 -0500 @@ -23,7 +23,7 @@ # Author: OpenRPG Dev Team # Maintainer: # Version: -# $Id: wod.py,v 1.14 2007/05/09 19:57:00 digitalxero Exp $ +# $Id: wod.py,v Traipse 'Ornery-Orc' prof.ebral Exp $ # # Description: WOD die roller # @@ -31,7 +31,7 @@ # for compatibility with Mage die rolls. # Threshhold addition by robert t childers -__version__ = "$Id: wod.py,v 1.14 2007/05/09 19:57:00 digitalxero Exp $" +__version__ = "$Id: wod.py,v Traipse 'Ornery-Orc' prof.ebral Exp $" from std import std from orpg.dieroller.base import * diff -r 4b2884f29a72 -r 81d0bfd5e800 orpg/dieroller/rollers/__init__.py --- a/orpg/dieroller/rollers/__init__.py Fri Jan 15 22:45:51 2010 -0600 +++ b/orpg/dieroller/rollers/__init__.py Sat Jun 12 03:50:37 2010 -0500 @@ -5,4 +5,4 @@ for roller in os.listdir(os.path.abspath(os.path.dirname(__file__))): if roller.endswith('.py') and not roller.startswith('__'): - __import__("%s.%s" % (rollers, roller.split('.')[0])) \ No newline at end of file + __import__("%s.%s" % (rollers, roller.split('.')[0])) diff -r 4b2884f29a72 -r 81d0bfd5e800 orpg/dieroller/rollers/alternity.py --- a/orpg/dieroller/rollers/alternity.py Fri Jan 15 22:45:51 2010 -0600 +++ b/orpg/dieroller/rollers/alternity.py Sat Jun 12 03:50:37 2010 -0500 @@ -18,20 +18,49 @@ # # Changelog: # -# v.1 original release JEC -# -# Traipse Release: -# The changes made in the Traipe release are intended to create a more direct connection -# between the source and the intrepretor. IF, ELIF statements have been replaced with dictionaries, +# v.1 original release JEC +# +# Traipse Release: +# The changes made in the Traipe release are intended to create a more direct connection +# between the source and the intrepretor. IF, ELIF statements have been replaced with dictionaries, # unused objects have been replace with re-usable objects, and the code has been condensed. - +# +# SEG: JAN 24 2010 - v.1.4 O'Flux Release: +# Edits & Additions: fixed a few minor bugs; Damage roll & Display Issues. +# Added Secondary Damage Calculation and Display. Fix all errors. +# Added proper results for Critcal Successes with failure ==> final Result Ordinary Success +# Removed reduntent Method to make parent class true with all others working as child. +# Made all special output same colour codes font size. Cleaned out old commented lines. +# Tested for Traipse on Win 7 +# +# Skill Check Example: +# [1d20.sk(12,-2)] +# OUTPUT Example: +# => [6,-3] = (3) AMAZING Success +# +# Pistol, Laser; 0 step -- Attack Example: +# [1d20.at(12,0,(1d4+1,"w"),(1d6+1,"w"),(1d4,"m"))] +# OUTPUT Example: +# => [1,0] = (1) CRITICAL SUCCESS AMAZING HIT +# ===> Damage [4] = (4) mortal ======> Secondary Damage (2) stun / (2) wound +# +# Action Check Example: +# [1d20.ac(14,-1)] +# OUTPUT Example: +# => ACTION CHECK : [18,-3] = (15) Marginal failure +# -1 Step make up bonus next Action Check +# +# import re - + from std import std from time import time, clock from orpg.dieroller.base import di, die_base, die_rollers +##from orpg.tools.orpg_log import debug + + __version__ = "$Id: alternity.py,v 0.1 2003/01/02 12:00:00 cchriss Exp $" # Alternity stands for "Alternity system" 20 sided die plus mods @@ -49,6 +78,9 @@ def at(self,score,mod,dmgo,dmgg,dmga): return at(self,score,mod,dmgo,dmgg,dmga) + def ac(self,score,mod): + return ac(self,score,mod) + die_rollers.register(alternity) class sk(std): @@ -59,25 +91,29 @@ self.mod = mod def getMod(self,mod=0): - m=0 - mods = { -4: -di(12), -3: -di(8), -2: -di(6), -1: -di(4), 1: -di(4), - 2: di(6), 3: di(8), 4: di(12), 5: di(20)} - if mod in mods.keys(): m = mods[mod].value + m=0 + mods = { -4: -di(12), -3: -di(8), -2: -di(6), -1: -di(4), 1: di(4), + 2: di(6), 3: di(8), 4: di(12), 5: di(20)} # SEG fix 1: di(4) # + if mod in mods.keys(): m = mods[mod].value elif mod <= -5: m=-di(20).value elif mod == 6: m=di(20).value + di(20).value elif mod >= 7: m=di(20).value + di(20).value + di(20).value return m def getRolLStr(self): - myStr = "[" + str(self.data[0]) + myStr = "[" + str(self.data[0]) self.d20 = self.sum() - amod = self.getMod(self.mod) - self.dieRoll = self.d20 + amod + self.amod = self.getMod(self.mod) + +## varN = "self.amod" +## debug(varN) +## debug(self.amod) ## seg added debug output + + self.dieRoll = self.d20 + self.amod for a in self.data[1:]: myStr += "," myStr += str(a) - myStr += "," + str(amod) + "] = (" + str(self.dieRoll) + ")" - if ( self.d20 == 1 ): self.success = 'CS' + myStr += "," + str(self.amod) + "] = (" + str(self.dieRoll) + ")" if ( self.dieRoll <= self.score / 4 ): self.success = 'A' elif ( self.dieRoll <= self.score / 2 ): self.success = 'G' elif ( self.dieRoll <= self.score ): self.success = 'O' @@ -86,51 +122,127 @@ return myStr def __str__(self): - myStr = self.getRolLStr() - successes = {'CS': " CRITICAL SUCCESS", - 'CF': " CRITICAL FAILURE", - 'A': " AMAZING Success", - 'G': " Good Success", - 'O': " Ordinary Success", - 'F': " failure"} + myStr = self.getRolLStr() + +## varN = "myStr" +## debug(varN) +## debug(myStr) ## seg added debug output + + successes = {'CS': " CRITICAL SUCCESS", + 'CF': " CRITICAL FAILURE", + 'A': " AMAZING Success", + 'G': " Good Success", + 'O': " Ordinary Success", + 'F': " failure"} + + if ( self.d20 == 1 ): myStr += successes['CS'] # SEG Dec 19 2009 myStr += successes[self.success] + if ( self.d20 == 1 ) and (self.success == 'F') : + myStr += " final result ==> " + myStr += successes['O'] # SEG JAN 23 2010 return myStr -class at(sk): - ## Traipse Usage: The source I received had the damage rolls like this 1d6s, with the damage type a - ## letter that could be sliced from the roll. However, the roll is parsed before the letter can be - ## sliced from it, and with the letter attached it created an error. - ## - ## The Traipse method puts the damage type and the damage roll into a Tuple, ie (1d6, 's'). - ## When uing this method you must include single or double quoutes around the damage type or the +class at(sk): + ## Traipse Usage: The source I received had the damage rolls like this 1d6s, with the damage type a + ## letter that could be sliced from the roll. However, the roll is parsed before the letter can be + ## sliced from it, and with the letter attached it created an error. + ## + ## The Traipse method puts the damage type and the damage roll into a Tuple, ie (1d6, 's'). + ## When using this method you must include single or double quoutes around the damage type or the ## software will treat it as an object. + def __init__(self,source=[],sc=10, mod=0, dmgo="(1d6, 's')",dmgg="(1d6, 'w')",dmga="(1d6, 'm')"): sk.__init__(self,source,sc,mod) self.dmgo = dmgo self.dmgg = dmgg self.dmga = dmga - def getdmg(self,dmgroll): - astr = "===> Damage " + def getdmg(self,dmgroll): + astr = "===> Damage " droll = str(dmgroll[0]) + xyz = droll.split('(') + secD = (int(xyz[1][:-1])/2) ## SEG* Calculate Secondary Damage + +## varN = "secD" +## debug(varN) +## debug(secD) ## seg added debug output + dtype = dmgroll[1] astr += droll - if dtype=="s": astr += " stun" - elif dtype=="w": astr += " wound" - elif dtype=="m":astr += " mortal" + if dtype=="s": astr += " stun
" + elif dtype=="w": + astr += " wound"+" ======> Secondary Damage ("+str(secD) \ + +") stun
" # SEG* Display Secondary Damage + elif dtype=="m": + astr += " mortal"+" ======> Secondary Damage ("+str(secD) \ + +") stun"+" / ("+str(secD)+") wound
" # SEG* Display Secondary Damage return astr def __str__(self): - myStr = self.getRolLStr() - successes = {'CS': " CRITICAL SUCCESS", - 'CF': " CRITICAL FAILURE", - 'A': " AMAZING HIT ", - 'G': " Good HIT ", - 'O': " Ordinary HIT ", - 'F': " miss"} - myStr += successes[self.success] - if self.success == 'A': myStr += self.getdmg(self.dmga) - elif self.success == 'G': myStr += self.getdmg(self.dmgg) - elif self.success == 'O': myStr += self.getdmg(self.dmgo) + myStr = self.getRolLStr() + +## varN = "myStr" +## debug(varN) +## debug(myStr) ## seg added debug output + + successes = {'CS': " CRITICAL SUCCESS", + 'CF': " CRITICAL FAILURE", + 'A': " AMAZING HIT
", + 'G': " Good HIT
", + 'O': " Ordinary HIT
", + 'F': " miss"} + if ( self.d20 == 1 ): + myStr += successes['CS'] # SEG Dec 19 2009 + + if ( self.d20 == 1 ) and (self.success == 'F') : + myStr += successes['F'] # SEG JAN 23 2010 + myStr += " final result ==> " + self.success = 'O' + + myStr += successes[self.success] + if self.success == 'A': myStr += self.getdmg(self.dmga) + elif self.success == 'G': myStr += self.getdmg(self.dmgg) + elif self.success == 'O': myStr += self.getdmg(self.dmgo) return myStr - + +class ac(sk): + def __init__(self,source=[],sc=10,mod=0): + sk.__init__(self,source,sc,mod) + + def __str__(self): + myStr = self.getRolLStr() + +## varN = "myStr" +## debug(varN) +## debug(myStr) ## seg added debug output + + myStr = " ACTION CHECK : "+myStr + successes = {'CS': " CRITICAL SUCCESS", + 'CF': " CRITICAL FAILURE
-2 Step make up bonus next Action Check", + 'A': " AMAZING Success", + 'G': " Good Success", + 'O': " Ordinary Success", + 'F': " Marginal failure"} + if ( self.d20 == 1 ): myStr += successes['CS'] # SEG Dec 19 2009 + myStr += successes[self.success] + if ( self.d20 == 1 ) and (self.success == 'F') : + myStr += " final result ==> " + myStr += successes['O'] # SEG JAN 23 2010 + if ( self.d20 != 1 ) and (self.success == 'F') : + myStr += "
-1 Step make up bonus next Action Check" + + return myStr + + + + + + + + + + + + + + diff -r 4b2884f29a72 -r 81d0bfd5e800 orpg/dieroller/rollers/d20.py --- a/orpg/dieroller/rollers/d20.py Fri Jan 15 22:45:51 2010 -0600 +++ b/orpg/dieroller/rollers/d20.py Sat Jun 12 03:50:37 2010 -0500 @@ -14,10 +14,10 @@ # Author: OpenRPG Dev Team # Maintainer: # Version: -# $Id: d20.py,v 1.9 2006/11/04 21:24:19 digitalxero Exp $ +# $Id: d20.py,v Traipse 'Ornery-Orc' prof.ebral Exp $ # # Description: d20 die roller -__version__ = "$Id: d20.py,v 1.9 2006/11/04 21:24:19 digitalxero Exp $" +__version__ = "$Id: d20.py,v Traipse 'Ornery-Orc' prof.ebral Exp $" # d20 stands for "d20 system" not 20 sided die :) @@ -30,8 +30,6 @@ def __init__(self,source=[]): std.__init__(self,source) -# these methods return new die objects for specific options - def attack(self,AC,mod,critical): return d20attack(self,AC,mod,critical) @@ -43,27 +41,23 @@ class d20dc(std): def __init__(self,source=[],DC=10,mod=0): std.__init__(self,source) + print "Source", source self.DC = DC self.mod = mod - self.append(static_di(mod)) + #self.append(static_di(mod)) def is_success(self): - return ((self.sum() >= self.DC or self.data[0] == 20) and self.data[0] != 1) + return ((self.sum()+self.mod >= self.DC or self.data[0] == 20) and self.data[0] != 1) def __str__(self): myStr = "[" + str(self.data[0]) for a in self.data[1:]: - myStr += "," + myStr += ", " myStr += str(a) - myStr += "] = (" + str(self.sum()) + ")" - + myStr += ", "+str(self.mod)+ "] = (" + str(self.sum()+self.mod) + ")" myStr += " vs DC " + str(self.DC) - - if self.is_success(): - myStr += " Success!" - else: - myStr += " Failure!" - + if self.is_success(): myStr += " Success!" + else: myStr += " Failure!" return myStr @@ -86,8 +80,7 @@ self.critical_roll = 0 if self.data[0] >= self.critical and self.is_hit(): self.critical_roll = die_base(20) + self.mod - if self.critical_roll.sum() >= self.AC: - self.critical_result = 1 + if self.critical_roll.sum() >= self.AC: self.critical_result = 1 def is_critical(self): return self.critical_result @@ -101,15 +94,9 @@ myStr += "," myStr += str(a) myStr += "] = (" + str(self.sum()) + ")" - myStr += " vs AC " + str(self.AC) - - if self.is_critical(): - myStr += " Critical" + if self.is_critical(): myStr += " Critical" + if self.is_hit(): myStr += " Hit!" + else: myStr += " Miss!" + return myStr - if self.is_hit(): - myStr += " Hit!" - else: - myStr += " Miss!" - - return myStr diff -r 4b2884f29a72 -r 81d0bfd5e800 orpg/dieroller/rollers/gurps.py --- a/orpg/dieroller/rollers/gurps.py Fri Jan 15 22:45:51 2010 -0600 +++ b/orpg/dieroller/rollers/gurps.py Sat Jun 12 03:50:37 2010 -0500 @@ -51,11 +51,9 @@ from time import time, clock import random - from std import std from orpg.dieroller.base import * - __version__ = "$Id: gurps.py,v 1.5 2007/05/06 16:42:55 digitalxero Exp $" # gurps @@ -66,9 +64,6 @@ def __init__(self,source=[]): std.__init__(self,source) -# these methods return new die objects for specific options - -# Original msk roll renamed to be easier to understand/remember def skill(self,skill,mod): return gurpsskill(self,skill,mod) @@ -133,8 +128,6 @@ else: if self.sum() == 18: myStr += " or less Critical Failure! [B556]" -# elif self.sum() == 17 and (self.skill+self.mod < 16): -# myStr += " or less Critical Failure! [B556]" elif self.sum() == 17: if (self.skill+self.mod) < 16: myStr += " or less Critical Failure! [B556]" @@ -279,13 +272,12 @@ std.__init__(self,source) def __str__(self): - myStr = "[" + str(self.data[0]) #Variable myStr holds text and first we put a [ into it and then adds the first die rolled - for a in self.data[1:]: #This is a for loop. It will do the next two lines of code for every die (except the first die which we handled in the line above) in the roll. - myStr += "," #Adds a comma after each die - myStr += str(a) #Adds the value of each die. - myStr += "] = " #Adds ] = to the end of the string (note the += means append to whatever is already stored in the variable - myStr += str(self.sum()) #Finally we add the actual result of the roll and myStr contains something like [3,2,1] = 6 - + myStr = "[" + str(self.data[0]) + for a in self.data[1:]: + myStr += "," + myStr += str(a) + myStr += "] = " + myStr += str(self.sum()) if self.sum() > 8 and self.sum() < 12: myStr += " The blow inflicts normal damage. [B556]" elif self.sum() == 12: @@ -310,13 +302,12 @@ std.__init__(self,source) def __str__(self): - myStr = "[" + str(self.data[0]) #Variable myStr holds text and first we put a [ into it and then adds the first die rolled - for a in self.data[1:]: #This is a for loop. It will do the next two lines of code for every die (except the first die which we handled in the line above) in the roll. - myStr += "," #Adds a comma after each die - myStr += str(a) #Adds the value of each die. - myStr += "] = " #Adds ] = to the end of the string (note the += means append to whatever is already stored in the variable - myStr += str(self.sum()) #Finally we add the actual result of the roll and myStr contains something like [3,2,1] = 6 - + myStr = "[" + str(self.data[0]) + for a in self.data[1:]: + myStr += "," + myStr += str(a) + myStr += "] = " + myStr += str(self.sum()) if self.sum() > 8 and self.sum() < 12: myStr += " The blow inflicts normal damage. [B556]" elif self.sum() == 12 or self.sum() == 13: @@ -347,13 +338,12 @@ std.__init__(self,source) def __str__(self): - myStr = "[" + str(self.data[0]) #Variable myStr holds text and first we put a [ into it and then adds the first die rolled - for a in self.data[1:]: #This is a for loop. It will do the next two lines of code for every die (except the first die which we handled in the line above) in the roll. - myStr += "," #Adds a comma after each die - myStr += str(a) #Adds the value of each die. - myStr += "] = " #Adds ] = to the end of the string (note the += means append to whatever is already stored in the variable - myStr += str(self.sum()) #Finally we add the actual result of the roll and myStr contains something like [3,2,1] = 6 - + myStr = "[" + str(self.data[0]) + for a in self.data[1:]: + myStr += "," + myStr += str(a) + myStr += "] = " + myStr += str(self.sum()) if self.sum() > 8 and self.sum() < 12: myStr += " You drop your weapon (& a cheap weapon breaks). [B556]" elif self.sum() == 12 or self.sum() == 8: @@ -386,13 +376,12 @@ std.__init__(self,source) def __str__(self): - myStr = "[" + str(self.data[0]) #Variable myStr holds text and first we put a [ into it and then adds the first die rolled - for a in self.data[1:]: #This is a for loop. It will do the next two lines of code for every die (except the first die which we handled in the line above) in the roll. - myStr += "," #Adds a comma after each die - myStr += str(a) #Adds the value of each die. - myStr += "] = " #Adds ] = to the end of the string (note the += means append to whatever is already stored in the variable - myStr += str(self.sum()) #Finally we add the actual result of the roll and myStr contains something like [3,2,1] = 6 - + myStr = "[" + str(self.data[0]) + for a in self.data[1:]: + myStr += "," + myStr += str(a) + myStr += "] = " + myStr += str(self.sum()) if self.sum() > 8 and self.sum() < 12: myStr += " You lose your balance; you can do nothing else (not even free actions) until next turn, and all defenses -2 until next turn. [B557]" elif self.sum() == 12: diff -r 4b2884f29a72 -r 81d0bfd5e800 orpg/dieroller/rollers/hackmaster.py --- a/orpg/dieroller/rollers/hackmaster.py Fri Jan 15 22:45:51 2010 -0600 +++ b/orpg/dieroller/rollers/hackmaster.py Sat Jun 12 03:50:37 2010 -0500 @@ -22,7 +22,7 @@ # Author: Ric Soard # Maintainer: # Version: -# $Id: hackmaster.py,v 0.4 2003/08/12 +# $Id: hackmaster.py,v Traipse 'Ornery-Orc' prof.ebral Exp # # Description: special die roller for HackMaster(C)(TM) RPG # has penetration damage - .damage(bonus,honor) @@ -32,7 +32,7 @@ # # -__version__ = "$Id: hackmaster.py,v 1.8 2006/11/15 12:11:22 digitalxero Exp $" +__version__ = "$Id: hackmaster.py,v Traipse 'Ornery-Orc' prof.ebral Exp $" import random from std import std @@ -120,7 +120,6 @@ #this is a static die that adds honor, we want high rolls so it's +1 self.append(static_di(self.hon)) - def check_crit(self): if self.data[0] == self.data[0].sides: self.crit = 1 @@ -170,7 +169,6 @@ myStr += " Example [1d8.severity(1)]
" myStr += " .help() :
" myStr += " displays this message
" - return myStr # the severity roll is for critical resolution. The die is rerolled and added @@ -185,7 +183,6 @@ self.CheckReroll() self.append(static_di(self.hon)) - def __str__(self): myStr = "[Severity Dice, Honor]" + " [" + str(self.data[0]) for a in self.data[1:]: @@ -205,7 +202,6 @@ result = int(random.uniform(1,self.data[num].sides+1)) self.data[num].value += (((result - 1) * neg) + self.hon) self.data[num].history.append(((result - 1) * neg) + self.hon) - if result >= self.data[num].sides: - self.crit_chain(num,1) - if result == 1: - self.crit_chain(num,-1) + if result >= self.data[num].sides: self.crit_chain(num,1) + if result == 1: self.crit_chain(num,-1) + diff -r 4b2884f29a72 -r 81d0bfd5e800 orpg/dieroller/rollers/hero.py --- a/orpg/dieroller/rollers/hero.py Fri Jan 15 22:45:51 2010 -0600 +++ b/orpg/dieroller/rollers/hero.py Sat Jun 12 03:50:37 2010 -0500 @@ -29,11 +29,10 @@ # # v.1 original release DJM -__version__ = "$Id: hero.py,v 1.15 2006/11/04 21:24:19 digitalxero Exp $" +__version__ = "$Id: hero.py,v Traipse 'Ornery-Orc' prof.ebral Exp $" from time import time, clock import random - from std import std from orpg.dieroller.base import * @@ -45,7 +44,6 @@ def __init__(self,source=[]): std.__init__(self,source) -# these methods return new die objects for specific options def k(self,mod): return herok(self,mod) @@ -73,7 +71,6 @@ self.cv = cv self.mod = mod - def __str__(self): myStr = "[" + str(self.data[0]) for a in self.data[1:]: @@ -110,15 +107,10 @@ modSum = self.sum()-self.mod myStr += " = (" + str(modSum) + ")" myStr += " vs " + str(self.sk) - - if self.is_success(): - myStr += " or less Success!" - else: - myStr += " or less Failure!" - + if self.is_success(): myStr += " or less Success!" + else: myStr += " or less Failure!" Diff = self.sk - modSum myStr += " by " + str(Diff) +" " - return myStr class herok(std): @@ -230,3 +222,4 @@ myStr += " Body and " myStr += "(" + str(int(round(self.sum()))) + ") Stun" return myStr + diff -r 4b2884f29a72 -r 81d0bfd5e800 orpg/dieroller/rollers/mythos.py --- a/orpg/dieroller/rollers/mythos.py Fri Jan 15 22:45:51 2010 -0600 +++ b/orpg/dieroller/rollers/mythos.py Sat Jun 12 03:50:37 2010 -0500 @@ -23,9 +23,9 @@ # Author: OpenRPG Dev Team # Maintainer: # Version: -# $Id: wod.py,v 1.14 2007/05/09 19:57:00 digitalxero Exp $ +# $Id: wod.py,v Traipse 'Ornery-Orc' prof.ebral Exp $ # -# Description: WOD die roller +# Description: Mythos die roller # # Targetthr is the Threshhold target # for compatibility with Mage die rolls. @@ -34,7 +34,7 @@ from std import std from orpg.dieroller.base import * -__version__ = "$Id: wod.py,v 1.14 2007/05/09 19:57:00 digitalxero Exp $" +__version__ = "$Id: wod.py,v Traipse 'Ornery-Orc' prof.ebral Exp $" class mythos(std): @@ -85,7 +85,7 @@ else: myStr += "] vs " +str(self.target)+" result of (" + str(self.sum()) + ")" return myStr - def non_stdDie(self, s): ## Puu-san + def non_stdDie(self, s): num_sides = s.split('v') if len(num_sides) > 1: num_sides; num = num_sides[0]; sides = num_sides[1] diff -r 4b2884f29a72 -r 81d0bfd5e800 orpg/dieroller/rollers/runequest.py --- a/orpg/dieroller/rollers/runequest.py Fri Jan 15 22:45:51 2010 -0600 +++ b/orpg/dieroller/rollers/runequest.py Sat Jun 12 03:50:37 2010 -0500 @@ -52,7 +52,7 @@ # o Added Sorcery Fumble table to sorcery spell roller # -__version__ = "$Id: runequest.py,v 1.4 2006/11/15 12:11:22 digitalxero Exp $" +__version__ = "$Id: runequest.py,v Traipse 'Ornery-Orc' prof.ebral Exp $" from time import time, clock import random @@ -68,8 +68,6 @@ def __init__(self,source=[]): std.__init__(self,source) -# these methods return new die objects for specific options - def skill(self,sk,mod,ma): return rqskill(self,sk,mod,ma) @@ -112,24 +110,20 @@ def __str__(self): myStr = "Unrestricted Training" - if self.s == 0: myStr = "Initial training completed for Cost(50) Time(20) Skill(1 + modifier)" else: cost = 0 time = 0 myStr = "Training: " - while self.s < self.f and self.s < 75: cost += self.s * 5 time += self.s * 1 self.s += random.uniform(1,4) + 1 - myStr = "Training completed:\n" myStr += "\tCost(" + str(int(cost)) + ")\n" myStr += "\tTime(" + str(int(time)) + ")\n" myStr += "\tSkill(" + str(int(self.s)) + ")" - return myStr @@ -150,30 +144,24 @@ def __str__(self): myStr = "" - if self.sk == 0 and self.cost >= 50: myStr = "Initial training completed for Cost(50), Time(50), Skill(1 + modifier)" else: cost = 0 time = 0 icost = self.sk * 5 - myStr = "Training: " - while (cost + icost) < self.cost: if self.sk >= 75: break - cost += icost time += self.sk * 1 self.sk += random.uniform(1,4) + 1 icost = self.sk * 5 - myStr = "Training completed: " myStr += "Cost(" + str(int(cost)) + ") " myStr += "Time(" + str(int(time)) + ") " myStr += "Skill(" + str(int(self.sk)) + ")" - return myStr @@ -194,30 +182,24 @@ def __str__(self): myStr = "" - if self.sk == 0 and self.time >= 20: myStr = "Initial training completed for Cost(50), Time(50), Skill(1 + modifier)" else: cost = 0 time = 0 itime = self.sk * 1 - myStr = "Trainingsss: " - while (time + itime) < self.time: if self.sk >= 75: break - cost += self.sk * 5 time += itime self.sk += random.uniform(1,4) + 1 itime = self.sk * 5 - myStr = "Training completed: " myStr += "Cost(" + str(int(cost)) + ") " myStr += "Time(" + str(int(time)) + ") " myStr += "Skill(" + str(int(self.sk)) + ")" - return myStr # RQ Skill Roll @@ -281,7 +263,6 @@ # build output string myStr = " (" + str(modSum) + ")" myStr += " vs [" + str(self.sk) + strAdd + str(swapmod) + "]" - if self.is_fumble(): myStr += " Fumble!" elif self.is_critical(): @@ -294,10 +275,8 @@ myStr += " Success!" else: myStr += " Failure!" - Diff = self.sk - modSum myStr += " " - return myStr # @@ -341,7 +320,6 @@ return ( self.sum() >= final_fum ) def __str__(self): - # get fumble roll result in case needed fum_roll = random.randint(1,100) @@ -359,7 +337,6 @@ # build output string myStr = " (" + str(modSum) + ")" myStr += " vs [" + str(self.sk) + strAdd + str(swapmod) + "]" - if self.is_fumble(): myStr += " Fumble! See Fumble Chart [" + str(fum_roll) + "]" elif self.is_critical() and self.is_riposte(): @@ -378,10 +355,8 @@ myStr += " Success! Weapon/Shield AP [" + str(self.AP) + "]" else: myStr += " Failure!" - Diff = self.sk - modSum myStr += " " - return myStr # RQ Dodge Roll @@ -424,7 +399,6 @@ return ( self.sum() >= final_fum ) def __str__(self): - # get fumble roll result in case needed fum_roll = random.randint(1,100) @@ -442,7 +416,6 @@ # build output string myStr = " (" + str(modSum) + ")" myStr += " vs [" + str(self.sk) + strAdd + str(swapmod) + "]" - if self.is_fumble(): myStr += " Fumble! See Fumble Chart [" + str(fum_roll) + "]" elif self.is_critical() and self.is_riposte(): @@ -461,14 +434,11 @@ myStr += " Success! Damage dodged" else: myStr += " Failure!" - Diff = self.sk - modSum myStr += " " - return myStr - # # RQ Attack Roll # @@ -535,7 +505,6 @@ myStr += "Head" hit_loc = myStr - # get normal damage in case needed norm_damage = random.randint(self.mindam*(self.trueswd+1),self.maxdam*(self.trueswd+1)) + self.bondam norm_damage_string = "{" + str( self.mindam*(self.trueswd+1) ) + "-" @@ -563,7 +532,6 @@ # build output string myStr = " (" + str(modSum) + ")" myStr += " vs [" + str(self.sk) + strAdd + str(swapmod) + "]" - if self.is_fumble(): myStr += " Fumble! See Fumble Chart [" + str(fum_roll) + "]" elif (self.is_supercritical() and self.is_success()): @@ -578,7 +546,6 @@ myStr += " Success! Damage: " + str(norm_damage_string) + str(hit_loc) else: myStr += " Failure!" - return myStr # @@ -691,6 +658,5 @@ myStr += "Intensity(-3):[" + str( self.int ) + "], " myStr += "Accelerate(-5):[" + str( self.acc ) + "], " myStr += "Multispell(-10):[" + str( self.mlt ) + "] ---" - return myStr diff -r 4b2884f29a72 -r 81d0bfd5e800 orpg/dieroller/rollers/savage.py --- a/orpg/dieroller/rollers/savage.py Fri Jan 15 22:45:51 2010 -0600 +++ b/orpg/dieroller/rollers/savage.py Sat Jun 12 03:50:37 2010 -0500 @@ -19,7 +19,7 @@ # Permission was granted by Pinnacle to reprint the result descriptions from their tables on Apr 20, 2006 by Simon Lucas # -__version__ = "$Id: savage.py,v 1.2 2007/05/06 16:42:55 digitalxero Exp $" +__version__ = "$Id: savage.py,v Traipse 'Ornery-Orc' prof.ebral Exp $" import string from random import * diff -r 4b2884f29a72 -r 81d0bfd5e800 orpg/dieroller/rollers/std.py --- a/orpg/dieroller/rollers/std.py Fri Jan 15 22:45:51 2010 -0600 +++ b/orpg/dieroller/rollers/std.py Sat Jun 12 03:50:37 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: print self; 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) \ No newline at end of file +die_rollers.register(std) diff -r 4b2884f29a72 -r 81d0bfd5e800 orpg/dieroller/rollers/trinity.py --- a/orpg/dieroller/rollers/trinity.py Fri Jan 15 22:45:51 2010 -0600 +++ b/orpg/dieroller/rollers/trinity.py Sat Jun 12 03:50:37 2010 -0500 @@ -23,7 +23,7 @@ # Author: Jacob Matthew, Talisan Creations # Maintainer: # Version: -# $Id: trinity.py,v 1.2 2007/05/05 05:30:10 digitalxero Exp $ +# $Id: trinity.py,v Traipse 'Ornery-Orc' prof.ebral Exp $ # # Description: Aeon Trinity die roller # Modified from the WoD dieroller "$Id: trinity.py,v 1.2 2007/05/05 05:30:10 digitalxero Exp $" @@ -32,7 +32,7 @@ # Threshhold addition by robert t childers # Threshhold functionality removed, some tags remain in code. -__version__ = "$Id: trinity.py,v 1.2 2007/05/05 05:30:10 digitalxero Exp $" +__version__ = "$Id: trinity.py,v Traipse 'Ornery-Orc' prof.ebral Exp $" from std import std from orpg.dieroller.base import * @@ -85,4 +85,4 @@ return myStr -die_rollers.register(trinity) \ No newline at end of file +die_rollers.register(trinity) diff -r 4b2884f29a72 -r 81d0bfd5e800 orpg/dieroller/rollers/wfrpg.py --- a/orpg/dieroller/rollers/wfrpg.py Fri Jan 15 22:45:51 2010 -0600 +++ b/orpg/dieroller/rollers/wfrpg.py Sat Jun 12 03:50:37 2010 -0500 @@ -23,13 +23,13 @@ # Author: Prof. Ebral, TaS (Traipse) # Maintainer: # Version: -# $Id: wfrpg.py,v 1.00 Jan/13/2010 prof.ebral Exp $ +# $Id: wfrpg.py,v Traipse 'Ornery-Orc' prof.ebral Exp $ # # Description: Warhammer Fantasy Roleplay Dice Roller die roller # Comissioned by Puu-san # -__version__ = "$Id: wfrpg.py,v 1.00 Jan/13/2010 prof.ebral Exp $" +__version__ = "$Id: wfrpg.py,v Traipse 'Ornery-Orc' prof.ebral Exp $" from std import std import random diff -r 4b2884f29a72 -r 81d0bfd5e800 orpg/dieroller/rollers/wod.py --- a/orpg/dieroller/rollers/wod.py Fri Jan 15 22:45:51 2010 -0600 +++ b/orpg/dieroller/rollers/wod.py Sat Jun 12 03:50:37 2010 -0500 @@ -23,7 +23,7 @@ # Author: OpenRPG Dev Team # Maintainer: # Version: -# $Id: wod.py,v 1.14 2007/05/09 19:57:00 digitalxero Exp $ +# $Id: wod.py,v Traipse 'Ornery-Orc' prof.ebral Exp $ # # Description: WOD die roller # @@ -31,7 +31,7 @@ # for compatibility with Mage die rolls. # Threshhold addition by robert t childers -__version__ = "$Id: wod.py,v 1.14 2007/05/09 19:57:00 digitalxero Exp $" +__version__ = "$Id: wod.py,v Traipse 'Ornery-Orc' prof.ebral Exp $" from std import std from orpg.dieroller.base import * diff -r 4b2884f29a72 -r 81d0bfd5e800 orpg/dieroller/rollers/wodex.py --- a/orpg/dieroller/rollers/wodex.py Fri Jan 15 22:45:51 2010 -0600 +++ b/orpg/dieroller/rollers/wodex.py Sat Jun 12 03:50:37 2010 -0500 @@ -34,7 +34,7 @@ from std import std from orpg.dieroller.base import * -__version__ = "$Id: wodex.py,v 1.9 2007/05/06 16:42:55 digitalxero Exp $" +__version__ = "$Id: wodex.py,v Traipse 'Ornery-Orc' prof.ebral Exp $" class wodex(std): name = "wodex" diff -r 4b2884f29a72 -r 81d0bfd5e800 orpg/dieroller/utils.py --- a/orpg/dieroller/utils.py Fri Jan 15 22:45:51 2010 -0600 +++ b/orpg/dieroller/utils.py Sat Jun 12 03:50:37 2010 -0500 @@ -22,12 +22,12 @@ # Author: OpenRPG Team # Maintainer: # Version: -# $Id: utils.py,v 1.22 2007/05/05 05:30:10 digitalxero Exp $ +# $Id: utils.py,v Traipse 'Ornery-Orc' prof.ebral Exp $ # # Description: Classes to help manage the die roller # -__version__ = "$Id: utils.py,v 1.22 2007/05/05 05:30:10 digitalxero Exp $" +__version__ = "$Id: utils.py,v Traipse 'Ornery-Orc' prof.ebral Exp Exp $" import re @@ -56,8 +56,7 @@ return die_rollers.keys() def stdDieToDClass(self, match): - s = match.group(0) - self.mod = str(match.string[len(s):]) + s = match.group(0); self.eval = str(match.string) num_sides = s.split('d') if len(num_sides) > 1: num_sides; num = num_sides[0]; sides = num_sides[1] @@ -66,13 +65,17 @@ if int(num) > 100 or int(sides) > 10000: return None except: pass ret = ['(', num.strip(), "**die_rollers['", self.getRoller(), "'](", - sides.strip(), '))'+self.mod] - s = ''.join(ret); s = str(eval(s)); return s ## Moved eval here for portability. + sides.strip(), '))'] + s = ''.join(ret) + self.eval = s + return s + ## Portable Non Standard Die Characters #Prof-Ebral - else: s = die_rollers._rollers[self.getRoller()]().non_stdDie(s); self.mod = ''; return s + else: s = die_rollers._rollers[self.getRoller()]().non_stdDie(s); return s # Use this to convert ndm-style (3d6) dice to d_base format def convertTheDieString(self,s): + self.result = '' reg = re.compile("(?:\d+|\([0-9\*/\-\+]+\))\s*[a-zA-Z]+\s*[\dFf]+") (result, num_matches) = reg.subn(self.stdDieToDClass, s) if num_matches == 0 or result is None: @@ -83,15 +86,19 @@ test = eval(s2) return s2 except Exception, e: print e; pass""" + self.result = result try: return self.do_math(s) except: pass return result def do_math(self, s): - self.mod = '' return str(eval(s)) def proccessRoll(self, s): - v = str(self.convertTheDieString(s)) - return v[:len(v)-len(self.mod)] + v = self.convertTheDieString(s) + try: b = str(eval(v)) + except: + if v == self.eval: b = s + else: b = str(v) ##Fail safe for non standard dice. + return b diff -r 4b2884f29a72 -r 81d0bfd5e800 orpg/gametree/gametree.py --- a/orpg/gametree/gametree.py Fri Jan 15 22:45:51 2010 -0600 +++ b/orpg/gametree/gametree.py Sat Jun 12 03:50:37 2010 -0500 @@ -45,8 +45,9 @@ from orpg.dirpath import dir_struct from nodehandlers import core import string, urllib, time, os +from shutil import copytree, copystat, copy, copyfile -from orpg.orpg_xml import xml +#from orpg.orpg_xml import xml from orpg.tools.validate import validate from orpg.tools.orpg_log import logger, debug from orpg.tools.orpg_settings import settings @@ -60,6 +61,12 @@ from xml.etree.ElementTree import fromstring, tostring, XML, iselement from xml.parsers.expat import ExpatError +def exists(path): + try: + os.stat(path) + return True + except: return False + STD_MENU_DELETE = wx.NewId() STD_MENU_DESIGN = wx.NewId() STD_MENU_USE = wx.NewId() @@ -206,9 +213,9 @@ self.EditLabel(curSelection) evt.Skip() - def locate_valid_tree(self, error, msg): ## --Snowdog 3/05 + def locate_valid_tree(self, error, msg, filename): ## --Snowdog 3/05 """prompts the user to locate a new tree file or create a new one""" - response = wx.MessageDialog(self, msg, error, wx.YES|wx.NO|wx.ICON_ERROR) + response = wx.MessageBox(msg, error, wx.YES|wx.NO|wx.ICON_ERROR) if response == wx.YES: file = None dlg = wx.FileDialog(self, "Locate Gametree file", dir_struct["user"], @@ -221,6 +228,7 @@ else: self.load_tree(file) return else: + copyfile(dir_struct['template']+'default_tree.xml', filename) validate.config_file("tree.xml","default_tree.xml") self.load_tree(error=1) return @@ -234,24 +242,25 @@ self.locate_valid_tree("Gametree Error", emsg) return try: + self.xml_root = False tree = parse(filename) self.xml_root = tree.getroot() - except: - self.xml_root = None - + except: self.xml_root = False if not self.xml_root: - os.rename(filename,filename+".corrupt") + count = 1 + while exists(filename[:len(filename)-4]+'-'+str(count)+'.xml'): count += 1 + corrupt_tree = filename[:len(filename)-4]+'-'+str(count)+'.xml' + copyfile(filename, corrupt_tree) 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"\ + "exit OpenRPG and copy the one of the tree-# files in\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"\ "(Selecting 'No' will cause a new default gametree to be generated)" - self.locate_valid_tree("Corrupt Gametree!", emsg) + self.locate_valid_tree("Corrupt Gametree!", emsg, filename) return - if self.xml_root.tag != "gametree": emsg = filename+" does not appear to be a valid gametree file.\n\n"\ "Would you like to select a different gametree file to use?\n"\ @@ -286,8 +295,22 @@ except Exception, e: logger.exception(traceback.format_exc()) - 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") + + count = 1 + while exists(filename[:len(filename)-4]+'-'+str(count)+'.xml'): count += 1 + corrupt_tree = filename[:len(filename)-4]+'-'+str(count)+'.xml' + copyfile(filename, corrupt_tree) + wx.MessageBox("Your gametree is being regenerated.\n\n"\ + "To salvage a recent version of your gametree\n"\ + "exit OpenRPG and copy the one of the tree-# files in\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") + + count = 1 + while exists(filename[:len(filename)-4]+'-'+str(count)+'.xml'): count += 1 + corrupt_tree = filename[:len(filename)-4]+'-'+str(count)+'.xml' + copyfile(filename, corrupt_tree) validate.config_file("tree.xml","default_tree.xml") self.load_tree(error=1) @@ -675,7 +698,7 @@ family_tree.append(parent) return family_tree - def load_xml(self, xml_element, parent_node, prev_node=None): + def load_xml(self, xml_element, parent_node, prev_node=None, drag_drop=False): if parent_node == self.root: self.tree_map[xml_element.get('name')] = {} self.tree_map[xml_element.get('name')]['node'] = xml_element @@ -698,6 +721,8 @@ if prev_node: if prev_node == parent_node: new_tree_node = self.PrependItem(parent_node, name, i, i) else: new_tree_node = self.InsertItem(parent_node, prev_node, name, i, i) + elif drag_drop: + new_tree_node = self.InsertItemBefore(parent_node, 0, name, i) else: new_tree_node = self.AppendItem(parent_node, name, i, i) logger.debug("Node Added to tree") @@ -804,7 +829,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): diff -r 4b2884f29a72 -r 81d0bfd5e800 orpg/gametree/nodehandlers/StarWarsd20.py --- a/orpg/gametree/nodehandlers/StarWarsd20.py Fri Jan 15 22:45:51 2010 -0600 +++ b/orpg/gametree/nodehandlers/StarWarsd20.py Sat Jun 12 03:50:37 2010 -0500 @@ -21,12 +21,12 @@ # Author: Chris Davis; Mark Twombley # Maintainer: Mark Twombley # Version: -# $Id: StarWarsd20.py,v 1.18 2006/11/15 12:11:23 digitalxero Exp $ +# $Id: StarWarsd20.py,v Traipse 'Ornery-Orc' prof.ebral Exp $ # # Description: The file contains code for the StarWarsd20 nodehanlers # -__version__ = "$Id: StarWarsd20.py,v 1.18 2006/11/15 12:11:23 digitalxero Exp $" +__version__ = "$Id: StarWarsd20.py,v Traipse 'Ornery-Orc' prof.ebral Exp $" from core import * from containers import * diff -r 4b2884f29a72 -r 81d0bfd5e800 orpg/gametree/nodehandlers/chatmacro.py --- a/orpg/gametree/nodehandlers/chatmacro.py Fri Jan 15 22:45:51 2010 -0600 +++ b/orpg/gametree/nodehandlers/chatmacro.py Sat Jun 12 03:50:37 2010 -0500 @@ -21,12 +21,12 @@ # Author: Chris Davis # Maintainer: # Version: -# $Id: chatmacro.py,v 1.15 2006/11/15 12:11:23 digitalxero Exp $ +# $Id: chatmacro.py,v Traipse 'Ornery-Orc' prof.ebral Exp $ # # Description: The file contains code for the form based nodehanlers # -__version__ = "$Id: chatmacro.py,v 1.15 2006/11/15 12:11:23 digitalxero Exp $" +__version__ = "$Id: chatmacro.py,v Traipse 'Ornery-Orc' prof.ebral Exp $" from core import * @@ -42,15 +42,12 @@ def __init__(self,xml,tree_node): node_handler.__init__(self,xml,tree_node) self.xml = xml - self.text_elem = self.xml.find('text') - self.text = self.text_elem.text - def set_text(self,txt): - self.text = txt + def set_text(self, txt): + self.xml.find('text').text = txt def on_use(self,evt): - txt = self.text - actionlist = txt.split("\n") + actionlist = self.xml.find('text').text.split("\n") for line in actionlist: if(line != ""): if line[0] != "/": ## it's not a slash command @@ -65,8 +62,7 @@ def tohtml(self): title = self.xml.get("name") - txt = self.text - txt = string.replace(txt,'\n',"
") + txt = string.replace(self.xml.find('text').text,'\n',"
") return "

"+title+":
"+txt P_TITLE = wx.NewId() @@ -80,7 +76,7 @@ sizer = wx.StaticBoxSizer(wx.StaticBox(self, -1, "Chat Macro"), wx.VERTICAL) self.text = {} self.text[P_TITLE] = wx.TextCtrl(self, P_TITLE, handler.xml.get('name')) - self.text[P_BODY] = wx.TextCtrl(self, P_BODY, handler.text, style=wx.TE_MULTILINE) + self.text[P_BODY] = wx.TextCtrl(self, P_BODY, handler.xml.find('text').text, style=wx.TE_MULTILINE) sizer.Add(wx.StaticText(self, -1, "Title:"), 0, wx.EXPAND) sizer.Add(self.text[P_TITLE], 0, wx.EXPAND) sizer.Add(wx.StaticText(self, -1, "Text Body:"), 0, wx.EXPAND) @@ -98,6 +94,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) diff -r 4b2884f29a72 -r 81d0bfd5e800 orpg/gametree/nodehandlers/containers.py --- a/orpg/gametree/nodehandlers/containers.py Fri Jan 15 22:45:51 2010 -0600 +++ b/orpg/gametree/nodehandlers/containers.py Sat Jun 12 03:50:37 2010 -0500 @@ -21,7 +21,7 @@ # Author: Chris Davis # Maintainer: # Version: -# $Id: containers.py,v 1.43 2007/08/08 19:17:17 digitalxero Exp $ +# $Id: containers.py,v Traipse 'Ornery-Orc' prof.ebral Exp $ # # Description: The file contains code for the container nodehandlers # @@ -67,11 +67,11 @@ drag_obj = self.tree.drag_obj if drag_obj == self or self.tree.is_parent_node(self.mytree_node,drag_obj.mytree_node): return opt = wx.MessageBox("Add node as child?","Container Node",wx.YES_NO|wx.CANCEL) + prev_sib = self.tree.GetPrevSibling(drag_obj.mytree_node) if opt == wx.YES: drop_xml = self.tree.drag_obj.delete() self.xml.insert(0, drop_xml) - self.tree.load_xml(drop_xml, self.mytree_node) - self.tree.Expand(self.mytree_node) + self.tree.load_xml(drop_xml, self.mytree_node, drag_drop=True) elif opt == wx.NO: node_handler.on_drop(self,evt) def gen_html(self, treenode, evt): @@ -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() diff -r 4b2884f29a72 -r 81d0bfd5e800 orpg/gametree/nodehandlers/core.py --- a/orpg/gametree/nodehandlers/core.py Fri Jan 15 22:45:51 2010 -0600 +++ b/orpg/gametree/nodehandlers/core.py Sat Jun 12 03:50:37 2010 -0500 @@ -21,14 +21,15 @@ # Author: Chris Davis # Maintainer: # Version: -# $Id: core.py,v 1.49 2007/12/07 20:39:48 digitalxero Exp $ +# $Id: core.py,v Traipse 'Ornery-Orc' prof.ebral Exp $ # # Description: The file contains code for the core nodehanlers # -__version__ = "$Id: core.py,v 1.49 2007/12/07 20:39:48 digitalxero Exp $" +__version__ = "$Id: core.py,v Traipse 'Ornery-Orc' prof.ebral Exp $" from nodehandler_version import NODEHANDLER_VERSION +from orpg.tools.InterParse import Parse try: from orpg.orpg_windows import * @@ -54,7 +55,6 @@ self.xml = xml self.mytree_node = tree_node self.tree = component.get('tree') - #self.tree = component.get('tree_fs') self.frame = component.get('frame') self.chat = component.get('chat') self.drag = True @@ -282,7 +282,7 @@ def get_html_panel(self,parent): html_str = ""+self.tohtml()+"" wnd = wx.html.HtmlWindow(parent,-1) - html_str = self.chat.ParseDice(html_str) + html_str = Parse.Dice(html_str) wnd.SetPage(html_str) return wnd @@ -345,6 +345,7 @@ if bad_txt_found: wx.MessageBox("Some non 7-bit ASCII characters found and stripped","Warning!") txt = u_txt + print txt, self.handler, self.handler.xml self.handler.text._set_nodeValue(txt) @@ -386,7 +387,8 @@ def on_ldclick(self,evt): file_name = self.file_node.get("name") - self.tree.insert_xml(open(orpg.dirpath.dir_struct["nodes"] + file_name,"r").read()) + try: self.tree.insert_xml(open(orpg.dirpath.dir_struct["nodes"] + file_name,"r").read()) + except: wx.MessageBox('Invalid File', 'Error') return 1 def on_design(self,evt): diff -r 4b2884f29a72 -r 81d0bfd5e800 orpg/gametree/nodehandlers/d20.py --- a/orpg/gametree/nodehandlers/d20.py Fri Jan 15 22:45:51 2010 -0600 +++ b/orpg/gametree/nodehandlers/d20.py Sat Jun 12 03:50:37 2010 -0500 @@ -21,12 +21,12 @@ # Author: Chris Davis # Maintainer: # Version: -# $Id: d20.py,v 1.30 2007/05/22 00:50:57 digitalxero Exp $ +# $Id: d20.py,v Traipse 'Ornery-Orc' prof.ebral Exp $ # # Description: The file contains code for the d20 nodehanlers # -__version__ = "$Id: d20.py,v 1.30 2007/05/22 00:50:57 digitalxero Exp $" +__version__ = "$Id: d20.py,v Traipse 'Ornery-Orc' prof.ebral Exp $" from core import * from containers import * @@ -34,6 +34,7 @@ from xml.etree.ElementTree import ElementTree, Element, iselement from xml.etree.ElementTree import fromstring, tostring, parse, XML from orpg.tools.orpg_log import debug +from orpg.tools.InterParse import Parse D20_EXPORT = wx.NewId() ############################ @@ -991,9 +992,9 @@ for i in range( 0, len( bab ) ): if bab[i] > 0 or i == 0: attack_roll_str = '[1d20%+d]' % (bab[i] + attack_mod) - attack_roll_parsed = self.chat.ParseDice( attack_roll_str ) + attack_roll_parsed = Parse.Dice( attack_roll_str ) damage_roll_str = '[%dd%d%+d%s]' % (num_damage_dice, damage_die, damage_mod, extra_damage) - damage_roll_parsed = self.chat.ParseDice( damage_roll_str ) + damage_roll_parsed = Parse.Dice( damage_roll_str ) txt = '%s (%s): %s ===> Damage: %s' \ % (name, bab_attributes[i], attack_roll_parsed, damage_roll_parsed) self.chat.Post( txt, True, True ) diff -r 4b2884f29a72 -r 81d0bfd5e800 orpg/gametree/nodehandlers/dnd3e.py --- a/orpg/gametree/nodehandlers/dnd3e.py Fri Jan 15 22:45:51 2010 -0600 +++ b/orpg/gametree/nodehandlers/dnd3e.py Sat Jun 12 03:50:37 2010 -0500 @@ -21,7 +21,7 @@ # Author: Chris Davis & Digitalxero # Maintainer: leadb # Version: -# $Id: dnd3e.py,v 1.33 2006/11/04 21:24:21 digitalxero Exp $ +# $Id: dnd3e.py,v Traipse 'Ornery-Orc' prof.ebral Exp $ # # Description: The file contains code for the dnd3e nodehanlers # @@ -261,7 +261,6 @@ n_list = self.xml.getchildren() html_str = "

General Information
" for n in n_list: - debug(n) html_str += ""+n.tag.capitalize() +": " html_str += n.text + ", " html_str = html_str[:len(html_str)-2] + "
" @@ -377,12 +376,10 @@ value = self.lang.GetValue() for node in self.n_list: if node.tag == nodeName: - debug(node) node.text = value def saveMoney(self, row, col): value = self.grid.GetCellValue(row, col) - debug(self.n_list[row]) self.n_list[row].text = value def on_cell_change(self, evt): @@ -2271,12 +2268,10 @@ self.xml.remove(self.n_list[i]) def on_add(self,evt): - debug() if not self.temp_dom: tree = parse(dir_struct["dnd3e"]+"dnd3espells.xml") xml_dom = tree.getroot() self.temp_dom = xml_dom - debug(self.temp_dom) f_list = self.temp_dom.findall('spell') opts = [] #lvl = int(dnd3e_char_child.get_char_lvl('level')) @@ -2667,12 +2662,10 @@ self.xml.remove(self.n_list[i]) def on_add(self,evt): - debug() if not self.temp_dom: tree = parse(dir_struct["dnd3e"]+"dnd3epowers.xml") xml_dom = tree.getroot() self.temp_dom = xml_dom - debug(self.temp) f_list = self.temp_dom.findall('power') opts = [] for f in f_list: diff -r 4b2884f29a72 -r 81d0bfd5e800 orpg/gametree/nodehandlers/forms.py --- a/orpg/gametree/nodehandlers/forms.py Fri Jan 15 22:45:51 2010 -0600 +++ b/orpg/gametree/nodehandlers/forms.py Sat Jun 12 03:50:37 2010 -0500 @@ -21,18 +21,19 @@ # Author: Chris Davis # Maintainer: # Version: -# $Id: forms.py,v 1.53 2007/04/21 23:00:51 digitalxero Exp $ +# $Id: forms.py,v Traipse 'Ornery-Orc' prof.ebral Exp $ # # Description: The file contains code for the form based nodehanlers # -__version__ = "$Id: forms.py,v 1.53 2007/04/21 23:00:51 digitalxero Exp $" +__version__ = "$Id: forms.py,v Traipse 'Ornery-Orc' prof.ebral Exp $" from containers import * import orpg.minidom as minidom -from orpg.orpg_xml import xml +#from orpg.orpg_xml import xml from wx.lib.scrolledpanel import ScrolledPanel from orpg.tools.settings import settings +from orpg.tools.InterParse import Parse def bool2int(b): #in wxPython 2.5+, evt.Checked() returns True or False instead of 1.0 or 0. @@ -108,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')), @@ -127,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) @@ -154,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 ########################## @@ -262,16 +273,16 @@ def on_send(self, evt): txt = self.text.GetValue() - txt = self.chat.ParseMap(txt, self.handler.xml) - txt = self.chat.ParseParent(txt, self.handler.xml.get('map')) + txt = Parse.ParseLogic(txt, self.handler.xml) if not self.handler.is_raw_send(): - self.chat.ParsePost(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 - self.chat.ParsePost(line, True, True) + Parse.Post(line, self.chat, True, True) else: action = line self.chat.chat_cmds.docmd(action) @@ -319,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) @@ -595,18 +606,16 @@ def on_send_to_chat(self, evt): txt = self.get_selected_text() - txt = self.chat.ParseMap(txt, self.xml) - txt = self.chat.ParseParent(txt, self.xml.get('map')) + txt = Parse.ParseLogic(txt, self.xml) if not self.is_raw_send(): - self.chat.ParsePost(self.tohtml(), True, True) + Parse.Post(self.tohtml(), self.chat, True, True) return 1 actionlist = self.get_selections_text() for line in actionlist: - line = self.chat.ParseMap(line, self.xml) - line = self.chat.ParseParent(line, self.xml.get('map')) + line = Parse.ParseLogic(line, self.xml) if(line != ""): if line[0] != "/": ## it's not a slash command - self.chat.ParsePost(line, True, True) + Parse.Post(line, self.chat, True, True) else: action = line self.chat.chat_cmds.docmd(action) @@ -620,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 = [] @@ -637,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() @@ -650,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) @@ -754,7 +764,7 @@ def on_add(self,evt): self.dlg = wx.Frame(self, -1, 'Text', size=(300,150)) edit_panel = wx.Panel(self.dlg, -1) - sizer = wx.GridBagSizer(1, 2) + sizer = wx.GridBagSizer(1, 1) edit_panel.SetSizer(sizer) caption_text = wx.StaticText(edit_panel, -1, 'Caption') self.caption_entry = wx.TextCtrl(edit_panel, -1, '') @@ -764,12 +774,17 @@ button_cancel = wx.Button(edit_panel, wx.ID_CANCEL) button_ref = wx.Button(edit_panel, BUT_REF, "Reference") sizer.Add(caption_text, (0,0)) - sizer.Add(self.caption_entry, (0,1), span=(1,3), flag=wx.EXPAND) + sizer.Add(self.caption_entry, (0,1), span=(1,4), flag=wx.EXPAND) sizer.Add(value_text, (1,0)) - sizer.Add(self.value_entry, (1,1), span=(1,3), flag=wx.EXPAND) + sizer.Add(self.value_entry, (1,1), span=(1,4), flag=wx.EXPAND) sizer.Add(button_ok, (3,0)) sizer.Add(button_cancel, (3,1)) sizer.Add(button_ref, (3,2), flag=wx.EXPAND) + sizer.AddGrowableCol(3) + sizer.AddGrowableRow(2) + self.dlg.SetSize((275, 125)) + self.dlg.SetMinSize((275, 125)) + self.dlg.Layout() self.Bind(wx.EVT_BUTTON, self.on_reference, id=BUT_REF) self.Bind(wx.EVT_BUTTON, self.on_add_option, id=wx.ID_OK) self.Bind(wx.EVT_BUTTON, self.on_edit_cancel, id=wx.ID_CANCEL) @@ -883,12 +898,17 @@ button_cancel = wx.Button(edit_panel, wx.ID_CANCEL) button_ref = wx.Button(edit_panel, BUT_REF, "Reference") sizer.Add(caption_text, (0,0)) - sizer.Add(self.caption_entry, (0,1), span=(1,3), flag=wx.EXPAND) + sizer.Add(self.caption_entry, (0,1), span=(1,4), flag=wx.EXPAND) sizer.Add(value_text, (1,0)) - sizer.Add(self.value_entry, (1,1), span=(1,3), flag=wx.EXPAND) + sizer.Add(self.value_entry, (1,1), span=(1,4), flag=wx.EXPAND) sizer.Add(button_ok, (3,0)) sizer.Add(button_cancel, (3,1)) sizer.Add(button_ref, (3,2), flag=wx.EXPAND) + sizer.AddGrowableCol(3) + sizer.AddGrowableRow(2) + self.dlg.SetSize((275, 125)) + self.dlg.SetMinSize((275, 125)) + self.dlg.Layout() self.Bind(wx.EVT_BUTTON, self.on_reference, id=BUT_REF) self.Bind(wx.EVT_BUTTON, self.on_edit_ok, id=wx.ID_OK) self.Bind(wx.EVT_BUTTON, self.on_edit_cancel, id=wx.ID_CANCEL) diff -r 4b2884f29a72 -r 81d0bfd5e800 orpg/gametree/nodehandlers/map_miniature_nodehandler.py --- a/orpg/gametree/nodehandlers/map_miniature_nodehandler.py Fri Jan 15 22:45:51 2010 -0600 +++ b/orpg/gametree/nodehandlers/map_miniature_nodehandler.py Sat Jun 12 03:50:37 2010 -0500 @@ -21,7 +21,7 @@ # Author: Andrew Bennett # Maintainer: # Version: -# $Id: map_miniature_nodehandler.py,v 1.17 2007/12/07 20:39:48 digitalxero Exp $ +# $Id: map_miniature_nodehandler.py,v Traipse 'Ornery-Orc' prof.ebral Exp $ # # Description: nodehandler for miniature images # diff -r 4b2884f29a72 -r 81d0bfd5e800 orpg/gametree/nodehandlers/minilib.py --- a/orpg/gametree/nodehandlers/minilib.py Fri Jan 15 22:45:51 2010 -0600 +++ b/orpg/gametree/nodehandlers/minilib.py Sat Jun 12 03:50:37 2010 -0500 @@ -21,12 +21,12 @@ # Author: Ted Berg # Maintainer: # Version: -# $Id: minilib.py,v 1.28 2007/04/22 22:00:18 digitalxero Exp $ +# $Id: minilib.py,v Traipse 'Ornery-Orc' prof.ebral Exp $ # # Description: nodehandler for a collection of miniatures. # -__version__ = "$Id: minilib.py,v 1.28 2007/04/22 22:00:18 digitalxero Exp $" +__version__ = "$Id: minilib.py,v Traipse 'Ornery-Orc' prof.ebral Exp $" """Nodehandler for collections of miniatures. User can add, delete, edit miniatures as sending them to the map singly or in batches. @@ -37,6 +37,7 @@ import map_miniature_nodehandler import orpg.mapper.map_msg import orpg.minidom as minidom +from orpg.tools.InterParse import Parse # import scriptkit # Constants @@ -44,17 +45,6 @@ FROM_MINILIB_MAP = {'url':'path', 'name':'label', 'unique':None} CORE_ATTRIBUTES = ['name', 'url', 'unique', 'posy', 'posx', 'hide', 'face', 'heading', 'align', 'locked', 'width', 'height'] -ATTRIBUTE_NAME = 'name' -ATTRIBUTE_URL = 'url' -ATTRIBUTE_UNIQUE = 'unique' -ATTRIBUTE_ID = 'id' -ATTRIBUTE_POSX = 'posx' -ATTRIBUTE_POSY = 'posy' - -TAG_MINIATURE = 'miniature' - -COMPONENT_MAP = 'map' -COMPONENT_SESSION = 'session' # # # @@ -100,11 +90,11 @@ """ str = '' str += "" - for mini in self.xml.findall(TAG_MINIATURE): - url = mini.get(ATTRIBUTE_URL) - label = mini.get(ATTRIBUTE_NAME) + for mini in self.xml.findall('miniature'): + url = mini.get('url') + label = mini.get('name') flag = 0 - try: flag = eval( mini.get(ATTRIBUTE_UNIQUE) ) + try: flag = eval( mini.get('unique') ) except: pass show = 'yes' if flag: show = 'no' @@ -133,16 +123,16 @@ for attrib in obj.keys(): key = TO_MINILIB_MAP.get( attrib, attrib ) if key != None: dict[ key ] = obj.get( attrib ) - dict[ ATTRIBUTE_UNIQUE ] = unique + dict[ 'unique' ] = unique self.new_mini( dict ) else: node_handler.on_drop(self, evt) def new_mini( self, data={}, add=1 ): - mini = Element( TAG_MINIATURE ) + mini = Element( 'miniature' ) for key in data.keys(): mini.set( key, data[ key ] ) for key in CORE_ATTRIBUTES: - if mini.get( key ) == '': mini.set( key, '0' ) + if mini.get( key ) == ('' or None): mini.set( key, '0' ) if add: self.add_mini( mini ) self.add_leaf( mini ) @@ -154,37 +144,39 @@ def add_leaf( self, mini, icon='gear' ): tree = self.tree icons = tree.icons - key = mini.get( ATTRIBUTE_NAME ) + key = mini.get( 'name' ) self.mydata.append( mini ) def update_leaves( self ): self.mydata = [] - for n in self.xml.findall(TAG_MINIATURE): self.add_leaf( n ) + for n in self.xml.findall('miniature'): self.add_leaf( n ) def on_drag( self, evt ): print 'drag event caught' def send_mini_to_map( self, mini, count=1, addName=True ): if mini == None: return - if mini.get( ATTRIBUTE_URL ) == '' or mini.get( ATTRIBUTE_URL ) == 'http://': - self.chat.ParsePost( self.chat.colorize(self.chat.syscolor, '"%s" is not a valid URL, the mini "%s" will not be added to the map' % ( mini.get( ATTRIBUTE_URL ), mini.get( ATTRIBUTE_NAME ) )) ) + if mini.get( 'url' ) == '' or mini.get( 'url' ) == 'http://': + Parse.Post( self.chat.colorize(self.chat.syscolor, + '"%s" is not a valid URL, the mini "%s" will not be added to the map' % ( + mini.get( 'url' ), mini.get( 'name' ) )) ) return - session = component.get( COMPONENT_SESSION ) + session = component.get( 'session' ) if (session.my_role() != session.ROLE_GM) and (session.my_role() != session.ROLE_PLAYER): component.get("chat").InfoPost("You must be either a player or GM to use the miniature Layer") return - map = component.get(COMPONENT_MAP) + canvas = component.get('map') for loop in range( count ): msg = self.get_miniature_XML( mini, addName) msg = str("" + msg + "") - map.new_data( msg ) + canvas.new_data( msg ) session.send( msg ) def get_miniature_XML( self, mini_xml, addName = True ): msg = orpg.mapper.map_msg.mini_msg() - map = component.get( COMPONENT_MAP ) - session = component.get( COMPONENT_SESSION ) - msg.init_prop( ATTRIBUTE_ID, session.get_next_id() ) + canvas = component.get( 'map' ) + session = component.get( 'session' ) + msg.init_prop( 'id', session.get_next_id() ) msg.init_prop('selected', '1')# this will make the mini initially selected for k in mini_xml.keys(): # translate our attributes to map attributes @@ -193,24 +185,24 @@ if not addName and k == 'name': pass else: msg.init_prop( key, mini_xml.get( k ) ) unique = self.is_unique( mini_xml ) - if addName: label = mini_xml.get( ATTRIBUTE_NAME ) + if addName: label = mini_xml.get( 'name' ) else: label = '' return msg.get_all_xml() def is_unique( self, mini ): - unique = mini.get( ATTRIBUTE_UNIQUE ) + unique = mini.get( 'unique' ) val = 0 try: val = eval( unique ) except: val = len( unique ) return val def sanity_check_nodes( self ): - for node in self.xml.findall(TAG_MINIATURE): - if node.get( ATTRIBUTE_POSX ) == '': node.set( ATTRIBUTE_POSX, '0' ) - if node.get( ATTRIBUTE_POSY ) == '': node.set( ATTRIBUTE_POSY, '0' ) + for node in self.xml.findall('miniature'): + if node.get( 'posx' ) == '': node.set( 'posx', '0' ) + if node.get( 'posy' ) == '': node.set( 'posy', '0' ) def get_mini( self, index ): - try: return self.xml.findall(TAG_MINIATURE)[index] + try: return self.xml.findall('miniature')[index] except: return None class mini_handler( node_handler ): @@ -279,7 +271,7 @@ """Returns a dictionary of label => game tree miniature DOM node mappings. """ self.list = [] - for mini in self.handler.xml.findall(TAG_MINIATURE): self.list.append( mini.get( ATTRIBUTE_NAME ) ) + for mini in self.handler.xml.findall('miniature'): self.list.append( mini.get( 'name' ) ) return self.list def on_close(self, evt): @@ -314,6 +306,11 @@ self.frame = frame self.sizer = wx.BoxSizer( wx.VERTICAL ) + + self.text = wx.TextCtrl(self, 3, handler.xml.get('name')) + self.sizer.Add(wx.StaticText(self, -1, "Title:"), 0, wx.EXPAND) + self.sizer.Add(self.text, 0, wx.EXPAND) + self.grid = minilib_grid( self, handler ) bbox = wx.BoxSizer( wx.HORIZONTAL ) @@ -333,6 +330,7 @@ self.SetAutoLayout(True) self.Fit() + self.Bind(wx.EVT_TEXT, self.on_text, id=3) self.Bind(wx.EVT_BUTTON, self.add_mini, newMiniBtn) self.Bind(wx.EVT_BUTTON, self.del_mini, delMiniBtn) self.Bind(wx.EVT_BUTTON, self.send_to_map, addMiniBtn) @@ -354,7 +352,7 @@ """Event handler for the 'Add 1' button. Sends the miniature defined by the currently selected row to the map, once. """ - index = self.grid.GetGridCursorRow() + index = self.grid.GetSelectedRows()[0] if len(self.grid.GetSelectedRows()) > 0 else 0 self.handler.send_mini_to_map( self.handler.get_mini( index ) ) def send_group_to_map( self, evt=None ): @@ -370,10 +368,16 @@ try: value = eval( dlg.GetValue() ) except: value = 0 print 'getting selected index for batch send' - index = self.grid.GetGridCursorRow() + index = self.grid.GetSelectedRows()[0] if len(self.grid.GetSelectedRows()) > 0 else 0 print 'sending batch to map' self.handler.send_mini_to_map( self.handler.get_mini( index ), value ) + def on_text(self, evt): + txt = self.text.GetValue() + if txt != "": + self.handler.xml.set('name',txt) + self.handler.rename(txt) + class minilib_grid(wx.grid.Grid): """A wxGrid subclass designed for editing game tree miniature library nodes. @@ -392,9 +396,10 @@ self.AutoSizeColumns() self.Bind(wx.grid.EVT_GRID_CELL_CHANGE, self.on_cell_change) self.Bind(wx.grid.EVT_GRID_SELECT_CELL, self.select_cell) + self.Bind(wx.grid.EVT_GRID_LABEL_LEFT_CLICK, self.select_cell) def update_cols( self ): - for n in self.handler.xml.findall(TAG_MINIATURE): + for n in self.handler.xml.findall('miniature'): for k in n.keys(): if k not in self.keys: self.keys.append( k ) @@ -413,7 +418,7 @@ """Returns the list of 'miniature' DOM elements associated with this miniature library. """ - return self.handler.xml.findall( TAG_MINIATURE ) + return self.handler.xml.findall( 'miniature' ) def add_row( self, count = 1 ): """creates a new miniature node, and then adds it to the current @@ -421,8 +426,8 @@ """ self.AppendRows( count ) node = self.handler.new_mini( { - ATTRIBUTE_NAME :' ', - ATTRIBUTE_URL :'http://'} )# minidom.Element( TAG_MINIATURE ) + 'name' :' ', + 'url' :'http://'} )# minidom.Element( 'miniature' ) self.update_all() #self.handler.xml.append( node ) @@ -433,11 +438,9 @@ """ if self.selectedRow > -1: pos = self.selectedRow - list = self.handler.xml.findall(TAG_MINIATURE) + list = self.handler.xml.findall('miniature') self.handler.xml.remove( list[pos] ) self.DeleteRows( pos, 1 ) - list = self.getList() - del list[ pos ] def on_cell_change( self, evt ): """Event handler for cell selection changes. selected row is used @@ -481,7 +484,7 @@ return self.GetTable().GetValue( self.selectedRow, 1 ) def getSelectedSerial( self ): - """Returns the ATTRIBUTE_UNIQUE value for the selected row + """Returns the 'unique' value for the selected row """ return self.GetTable().GetValue( self.selectedRow, 2 ) diff -r 4b2884f29a72 -r 81d0bfd5e800 orpg/gametree/nodehandlers/rpg_grid.py --- a/orpg/gametree/nodehandlers/rpg_grid.py Fri Jan 15 22:45:51 2010 -0600 +++ b/orpg/gametree/nodehandlers/rpg_grid.py Sat Jun 12 03:50:37 2010 -0500 @@ -21,15 +21,17 @@ # Author: Chris Davis # Maintainer: # Version: -# $Id: rpg_grid.py,v 1.20 2006/11/15 12:11:24 digitalxero Exp $ +# $Id: rpg_grid.py,v Traipse 'Ornery-Orc' prof.ebral Exp $ # # Description: The file contains code for the grid nodehanlers # -__version__ = "$Id: rpg_grid.py,v 1.20 2006/11/15 12:11:24 digitalxero Exp $" +__version__ = "$Id: rpg_grid.py,v Traipse 'Ornery-Orc' prof.ebral Exp $" from core import * from forms import * +from orpg.tools.orpg_log import debug +from orpg.tools.InterParse import Parse class rpg_grid_handler(node_handler): """ Node handler for rpg grid tool @@ -87,16 +89,20 @@ html_str += "" html_str += "" html_str += "
LabelImageURLUnique
" text = c.text if text == None or text == '': text = '
' + s = Parse.ParseLogic(text, self.xml) + s = Parse.Normalize(s) + try: text = str(eval(s)) + except: text = s html_str += text + "
" return html_str def get_design_panel(self,parent): - return rpg_grid_edit_panel(parent,self) + return rpg_grid_edit_panel(parent, self) def get_use_panel(self,parent): - return rpg_grid_panel(parent,self) + return rpg_grid_panel(parent, self) def get_size_constraint(self): return 1 @@ -194,7 +200,8 @@ to begin editing. Set the focus to the edit control. *Must Override* """ - self.startValue = grid.GetTable().GetValue(row, col) + #self.startValue = grid.GetTable().GetValue(row, col) + self.startValue = grid.get_value(row, col) self._tc.SetValue(self.startValue) self._tc.SetInsertionPointEnd() self._tc.SetFocus() @@ -213,7 +220,6 @@ if val != self.startValue: changed = True grid.GetTable().SetValue(row, col, val) # update the table - self.startValue = '' self._tc.SetValue('') return changed @@ -265,11 +271,11 @@ class rpg_grid(wx.grid.Grid): """grid for attacks""" - def __init__(self, parent, handler): + def __init__(self, parent, handler, mode): wx.grid.Grid.__init__(self, parent, -1, style=wx.SUNKEN_BORDER | wx.WANTS_CHARS) self.parent = parent self.handler = handler - + self.mode = mode self.RegisterDataType(wx.grid.GRID_VALUE_STRING, wx.grid.GridCellStringRenderer(),MyCellEditor()) self.rows = handler.grid.findall('row') @@ -286,7 +292,6 @@ self.Bind(wx.grid.EVT_GRID_COL_SIZE, self.on_col_size) self.Bind(wx.grid.EVT_GRID_CELL_LEFT_DCLICK, self.on_leftdclick) - def on_leftdclick(self,evt): if self.CanEnableCellControl(): self.EnableCellEditControl() @@ -304,6 +309,7 @@ cells = self.rows[row].findall('cell') cells[col].text = value if col == 0: self.handler.refresh_rows() + for i in range(0,len(self.rows)): self.refresh_row(i) def set_col_widths(self): cells = self.rows[0].findall('cell') @@ -313,13 +319,17 @@ self.SetColSize(i,size) except: continue - def refresh_row(self,rowi): + def refresh_row(self, rowi): cells = self.rows[rowi].findall('cell') for i in range(0,len(cells)): text = cells[i].text if text == None or text == '': text = '' cells[i].text = text + if self.mode == 0: + s = Parse.ParseLogic(text, self.handler.xml) + try: text = str(eval(s)) + except: text = s self.SetCellValue(rowi,i,text) def add_row(self,evt=None): @@ -359,6 +369,10 @@ self.DeleteCols(num-1,1) self.set_col_widths() + def get_value(self, row, col): + cells = self.rows[row].findall('cell') + return cells[col].text + G_TITLE = wx.NewId() GRID_BOR = wx.NewId() @@ -366,7 +380,7 @@ def __init__(self, parent, handler): wx.Panel.__init__(self, parent, -1) self.handler = handler - self.grid = rpg_grid(self, handler) + self.grid = rpg_grid(self, handler, mode=0) label = handler.xml.get('name') self.main_sizer = wx.BoxSizer(wx.VERTICAL) self.main_sizer.Add(wx.StaticText(self, -1, label+": "), 0, wx.EXPAND) @@ -388,7 +402,7 @@ wx.Panel.__init__(self, parent, -1) self.handler = handler self.parent = parent - self.grid = rpg_grid(self,handler) + self.grid = rpg_grid(self,handler, mode=1) self.main_sizer = wx.StaticBoxSizer(wx.StaticBox(self, -1, "Grid"), wx.VERTICAL) self.title = wx.TextCtrl(self, G_TITLE, handler.xml.get('name')) @@ -462,6 +476,8 @@ complete = complete[:len(complete)-2] + '::'+'('+row+','+col+')'+complete[len(complete)-2:] col = self.grid.GetGridCursorCol() row = self.grid.GetGridCursorRow() + temp_value = self.grid.GetCellValue(row, col) + complete = temp_value + complete self.grid.SetCellValue(row, col, complete) cells = self.grid.rows[row].findall('cell') cells[col].text = complete @@ -505,6 +521,8 @@ else: col = self.grid.GetGridCursorCol() row = self.grid.GetGridCursorRow() + temp_value = self.grid.GetCellValue(row, col) + complete = temp_value + complete self.grid.SetCellValue(row, col, complete) cells = self.grid.rows[row].findall('cell') cells[col].text = complete @@ -527,3 +545,15 @@ if txt != "": self.handler.xml.set('name',txt) self.handler.rename(txt) + + def refresh_row(self,rowi): + cells = self.rows[rowi].findall('cell') + for i in range(0,len(cells)): + text = cells[i].text + #s = component.get('chat').ParseMap(s, self.handler.xml) + #try: text = str(eval(s)) + #except: text = s + if text == None or text == '': + text = '' + cells[i].text = text + self.SetCellValue(rowi,i,text) diff -r 4b2884f29a72 -r 81d0bfd5e800 orpg/gametree/nodehandlers/voxchat.py --- a/orpg/gametree/nodehandlers/voxchat.py Fri Jan 15 22:45:51 2010 -0600 +++ b/orpg/gametree/nodehandlers/voxchat.py Sat Jun 12 03:50:37 2010 -0500 @@ -21,17 +21,16 @@ # Author: Ted Berg # Maintainer: # Version: -# $Id: voxchat.py,v 1.37 2007/05/06 16:42:55 digitalxero Exp $ +# $Id: voxchat.py,v Traipse 'Ornery-Orc' prof.ebral Exp $ # # Description: nodehandler for alias. # -__version__ = "$Id: voxchat.py,v 1.37 2007/05/06 16:42:55 digitalxero Exp $" +__version__ = "$Id: voxchat.py,v Traipse 'Ornery-Orc' prof.ebral Exp $" import re, os, string, core from orpg.orpg_windows import * -import core import orpg.tools.scriptkit import orpg.tools.predTextCtrl import orpg.tools.rgbhex @@ -53,7 +52,7 @@ def __init__(self, xml_dom, tree_node): core.node_handler.__init__( self, xml_dom, tree_node) self.node = xml_dom - self.xml = component.get('xml') + #self.xml = component.get('xml') def get_design_panel( self, parent ): aliasLib = component.get('alias') diff -r 4b2884f29a72 -r 81d0bfd5e800 orpg/main.py --- a/orpg/main.py Fri Jan 15 22:45:51 2010 -0600 +++ b/orpg/main.py Sat Jun 12 03:50:37 2010 -0500 @@ -21,13 +21,13 @@ # File: main.py # Author: Chris Davis # Maintainer: -# Version: -# $Id: main.py,v 1.153 2008/01/24 03:52:03 digitalxero Exp $ +# Version: Traipse 'Ornery-Orc' +# $Id: main.py,v Traipse 'Ornery-Orc' prof.ebral Exp $ # # Description: This is the main entry point of the oprg application # -__version__ = "$Id: main.py,v 1.154 2009/07/19 03:52:03 madmathlabs Exp $" +__version__ = "$Id: main.py,v Traipse 'Ornery-Orc' prof.ebral Exp $" from orpg.orpg_wx import * from orpg.orpgCore import * @@ -50,25 +50,20 @@ import orpg.mapper.images import orpg.dieroller.utils - -#Update Manager# Un remark if you have Mercurial installed import upmana.updatemana -import upmana.manifest as manifest +from upmana.manifest import manifest from orpg.dirpath import dir_struct -#from orpg.dieroller.utils import DiceManager from orpg.tools.settings import settings from orpg.tools.validate import validate from orpg.tools.passtool import PassTool from orpg.tools.orpg_log import logger, crash, debug from orpg.tools.metamenus import MenuBarEx +from orpg.tools.InterParse import Parse from xml.etree.ElementTree import ElementTree, Element, parse from xml.etree.ElementTree import fromstring, tostring -## Element Tree usage will require users to convert to and from string data quite often until users of older versions update. -## This is a problem that users of older versions will need to cross as it is both Core and Traipse that will make the change. -## Older versions have a problem with correct XML. -from orpg.orpg_xml import xml #to be replaced by etree +#from orpg.orpg_xml import xml #to be replaced by etree #################################### @@ -77,7 +72,7 @@ class orpgFrame(wx.Frame): - + def __init__(self, parent, id, title): wx.Frame.__init__(self, parent, id, title, wx.Point(100, 100), wx.Size(600,420), style=wx.DEFAULT_FRAME_STYLE) self.validate = component.get("validate") @@ -167,6 +162,11 @@ settings.add('Tip of the Day', 'tipotday_enabled', '1', '0|1', 'Show Tip of the Day on startup') logger.info('New Settings added', True) self.TraipseSuiteWarn('debug') + if setting == 'Meta Servers': + settings.add('Networking', 'MetaServers', 'metaservers.xml', '.xml file', 'Contains a list of Meta Servers') + logger.info('New Settings added', True) + self.validate.config_file("metaservers.xml","default_metaservers.xml") + self.TraipseSuiteWarn('debug') def get_activeplugins(self): try: tmp = self.pluginsFrame.get_activeplugins() @@ -207,7 +207,7 @@ [' -'], [' Tab Styles'], [' Slanted'], - [' Colorful', "check"], + #[' Colorful', "check"], [' Black and White', "check"], [' Aqua', "check"], [' Custom', "check"], @@ -257,7 +257,8 @@ self.mainmenu.SetMenuState('ToolsPasswordManager', True if settings.get('PWMannager') == 'On' else False) tabtheme = settings.get('TabTheme') #This change is stable. TaS. - self.mainmenu.SetMenuState("OpenRPGTabStylesSlantedColorful", tabtheme == 'slanted&colorful') + if tabtheme == 'slanted&colorful': tabtheme = 'customflat'; settings.change('TabTheme', 'customflat') + #self.mainmenu.SetMenuState("OpenRPGTabStylesSlantedColorful", tabtheme == 'slanted&colorful') self.mainmenu.SetMenuState("OpenRPGTabStylesSlantedBlackandWhite", tabtheme == 'slanted&bw') self.mainmenu.SetMenuState("OpenRPGTabStylesSlantedAqua", tabtheme == 'slanted&aqua') self.mainmenu.SetMenuState("OpenRPGTabStylesFlatBlackandWhite", tabtheme == 'flat&bw') @@ -299,7 +300,8 @@ self.mainmenu.Insert(8, self.traipseSuite, "&Traipse Suite!") if menuitem == 'debug': if self.debugger.IsShown() == True: - self.mainmenu.Replace(8, self.traipseSuite, '&Traipse Suite') + self.mainmenu.Remove(8) + self.mainmenu.Insert(8, self.traipseSuite, "&Traipse Suite") else: self.debugConsole.SetBitmap(wx.Bitmap(dir_struct["icon"] + 'spotlight.png')) self.traipseSuite.RemoveItem(self.debugConsole) @@ -322,9 +324,8 @@ #Tab Styles Menus def SetTabStyles(self, *args, **kwargs): - tabtheme = settings.get('TabTheme') #This change is stable. TaS. - self.mainmenu.SetMenuState("OpenRPGTabStylesSlantedColorful", tabtheme == 'slanted&colorful') + #self.mainmenu.SetMenuState("OpenRPGTabStylesSlantedColorful", tabtheme == 'slanted&colorful') self.mainmenu.SetMenuState("OpenRPGTabStylesSlantedBlackandWhite", tabtheme == 'slanted&bw') self.mainmenu.SetMenuState("OpenRPGTabStylesSlantedAqua", tabtheme == 'slanted&aqua') self.mainmenu.SetMenuState("OpenRPGTabStylesFlatBlackandWhite", tabtheme == 'flat&bw') @@ -340,7 +341,6 @@ else: try: menu = args[0] except: logger.general('Invalid Syntax for orpgFrame->SetTabStyles(self, *args, **kwargs)'); return - if kwargs.has_key('graidentTo'): graidentTo = kwargs['graidentTo'] else: graidentTo = None if kwargs.has_key('graidentFrom'): graidentFrom = kwargs['graidentFrom'] @@ -364,7 +364,7 @@ for wnd in tabbedwindows: style = wnd.GetWindowStyleFlag() # remove old tabs style - mirror = ~(FNB.FNB_VC71 | FNB.FNB_VC8 | FNB.FNB_FANCY_TABS | FNB.FNB_COLORFUL_TABS) + mirror = ~(FNB.FNB_VC71 | FNB.FNB_VC8 | FNB.FNB_FANCY_TABS ) style &= mirror style |= newstyle wnd.SetWindowStyleFlag(style) @@ -374,18 +374,15 @@ if textColor != None: wnd.SetNonActiveTabTextColour(textColor) wnd.Refresh() - def OnMB_OpenRPGNewMap(self): pass #Not Implemented yet! - def OnMB_OpenRPGTabStylesSlantedColorful(self): if self.mainmenu.GetMenuState("OpenRPGTabStylesSlantedColorful"): settings.change('TabTheme', 'slanted&colorful') self.SetTabStyles("OpenRPGTabStylesSlantedColorful", FNB.FNB_VC8|FNB.FNB_COLORFUL_TABS) else: self.mainmenu.SetMenuState("OpenRPGTabStylesSlantedColorful", True) - def OnMB_OpenRPGTabStylesSlantedBlackandWhite(self): if self.mainmenu.GetMenuState("OpenRPGTabStylesSlantedBlackandWhite"): settings.change('TabTheme', 'slanted&bw') @@ -393,7 +390,6 @@ FNB.FNB_VC8, graidentTo=wx.WHITE, graidentFrom=wx.WHITE, textColor=wx.BLACK) else: self.mainmenu.SetMenuState("OpenRPGTabStylesSlantedBlackandWhite", True) - def OnMB_OpenRPGTabStylesSlantedAqua(self): if self.mainmenu.GetMenuState("OpenRPGTabStylesSlantedAqua"): settings.change('TabTheme', 'slanted&aqua') @@ -505,7 +501,7 @@ else: self.updateMana.Show() def OnMB_DebugConsole(self, evt): - self.TraipseSuiteWarnCleanup('debug') ### Beta ### + self.TraipseSuiteWarnCleanup('debug') if self.debugger.IsShown() == True: self.debugger.Hide() else: self.debugger.Show() @@ -514,28 +510,28 @@ if self.mainmenu.GetMenuState("ToolsLoggingLevelDebug"): lvl |= ORPG_DEBUG else: lvl &= ~ORPG_DEBUG logger.log_level = lvl - settings.set('LoggingLevel', lvl) + settings.change('LoggingLevel', lvl) def OnMB_ToolsLoggingLevelNote(self): lvl = logger.log_level if self.mainmenu.GetMenuState("ToolsLoggingLevelNote"): lvl |= ORPG_DEBUG else: lvl &= ~ORPG_DEBUG logger.log_level = lvl - settings.set('LoggingLevel', lvl) + settings.change('LoggingLevel', lvl) def OnMB_ToolsLoggingLevelInfo(self): lvl = logger.log_level if self.mainmenu.GetMenuState("ToolsLoggingLevelInfo"): lvl |= ORPG_INFO else: lvl &= ~ORPG_INFO logger.log_level = lvl - settings.set('LoggingLevel', lvl) + settings.change('LoggingLevel', lvl) def OnMB_ToolsLoggingLevelGeneral(self): lvl = logger.log_level if self.mainmenu.GetMenuState("ToolsLoggingLevelGeneral"): lvl |= ORPG_GENERAL else: lvl &= ~ORPG_GENERAL logger.log_level = lvl - settings.set('LoggingLevel', lvl) + settings.change('LoggingLevel', lvl) def OnMB_ToolsPasswordManager(self): if self.mainmenu.GetMenuState("ToolsPasswordManager"): self.password_manager.Enable() @@ -630,10 +626,8 @@ # Update Manager #self.manifest = manifest.ManifestChanges() self.updateMana = upmana.updatemana.updaterFrame(self, - "OpenRPG Update Manager 1.0", component, manifest, True) - print component.get('upmana-win') + "OpenRPG Update Manager 1.2", component, manifest, True) component.add('upmana-win', self.updateMana) - print component.get('upmana-win') logger.debug("Menu Created") h = int(xml_dom.get("height")) w = int(xml_dom.get("width")) @@ -685,7 +679,7 @@ logger.debug("Status Window Created") # Create and show the floating dice toolbar - self.dieToolBar = orpg.tools.toolBars.DiceToolBar(self, callBack = self.chat.ParsePost) + self.dieToolBar = orpg.tools.toolBars.DiceToolBar(self, callBack = Parse.Post) wndinfo = AUI.AuiPaneInfo() menuid = wx.NewId() self.mainwindows[menuid] = "Dice Tool Bar" @@ -757,11 +751,11 @@ def do_tab_window(self, xml_dom, parent_wnd): # if container window loop through childern and do a recursive call - temp_wnd = orpgTabberWnd(parent_wnd, style=FNB.FNB_ALLOW_FOREIGN_DND) + temp_wnd = orpgTabberWnd(parent_wnd) children = xml_dom.getchildren() for c in children: - wnd = self.build_window(c,temp_wnd) + wnd = self.build_window(c, temp_wnd) name = c.get("name") temp_wnd.AddPage(wnd, name, False) return temp_wnd @@ -800,7 +794,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) @@ -939,10 +933,9 @@ etreeEl = Element('msg') try: etreeEl.append(fromstring(data)) except: etreeEl.text = data - if player: display_name = self.chat.chat_display_name(player) - else: display_name = "Server Administrator" - if etreeEl.text: self.chat.Post(etreeEl.text) + display_name = self.chat.chat_display_name(player) + if etreeEl.text:self.chat.Post(display_name+etreeEl.text) for child in etreeEl.getchildren(): if child.tag == 'tree': @@ -950,7 +943,6 @@ wx.YES_NO | wx.NO_DEFAULT | wx.ICON_QUESTION) if dlg.ShowModal() == wx.ID_YES: dlg.Destroy() - debug(child) self.tree.on_receive_data(tostring(child)) self.chat.InfoPost(display_name + " has sent you a tree node...") elif child.tag == 'map': @@ -1112,7 +1104,8 @@ 'Bernhard Bergbauer', 'Chris Blocher', 'David Byron', 'Ben Collins-Sussman', 'Robin Cook', 'Greg Copeland', 'Chris Davis', 'Michael Edwards', 'Andrew Ettinger', 'Todd Faris', 'Dj Gilcrease', 'Christopher Hickman', 'Paul Hosking', 'Brian Manning', 'Scott Mackay', 'Jesse McConnell', - 'Brian Osman', 'Rome Reginelli', 'Christopher Rouse', 'Dave Sanders', 'Tyler Starke', 'Mark Tarrabain'] + 'Brian Osman', 'Rome Reginelli', 'Christopher Rouse', 'Dave Sanders', 'Tyler Starke', 'Mark Tarrabain', + 'David Vrabel'] for dev in orpg_devs: self.About.AppendText(dev+'\n') @@ -1135,7 +1128,7 @@ def OnInit(self): component.add('log', logger) - component.add('xml', xml) + #component.add('xml', xml) component.add('settings', settings) component.add('validate', validate) component.add("tabbedWindows", []) diff -r 4b2884f29a72 -r 81d0bfd5e800 orpg/mapper/background.py --- a/orpg/mapper/background.py Fri Jan 15 22:45:51 2010 -0600 +++ b/orpg/mapper/background.py Sat Jun 12 03:50:37 2010 -0500 @@ -21,12 +21,12 @@ # Author: Chris Davis # Maintainer: # Version: -# $Id: background.py,v 1.29 2007/03/09 14:11:55 digitalxero Exp $ +# $Id: background.py,v Traipse 'Ornery-Orc' prof.ebral Exp $ # # Description: This file contains some of the basic definitions for the chat # utilities in the orpg project. # -__version__ = "$Id: background.py,v 1.29 2007/03/09 14:11:55 digitalxero Exp $" +__version__ = "$Id: background.py,v Traipse 'Ornery-Orc' prof.ebral Exp $" from base import * import thread, urllib, os.path, time, mimetypes @@ -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 @@ -210,28 +211,31 @@ else: return '' def layerTakeDOM(self, xml_dom): - type = BG_COLOR - color = xml_dom.getAttribute("color") - logger.debug("color=" + color) - path = urllib.unquote(xml_dom.getAttribute("path")) - logger.debug("path=" + path) - # Begin ted's map changes - if xml_dom.hasAttribute("color"): - r,g,b = self.r_h.rgb_tuple(xml_dom.getAttribute("color")) + bg_type = xml_dom.get("type") + urlpath = xml_dom.get('path') + color = xml_dom.get("color") + + if urlpath != None: + path = urllib.unquote(xml_dom.get("path")) + logger.debug("path=" + path) + + if color != None: + logger.debug("color=" + color) + r,g,b = self.r_h.rgb_tuple(color) self.set_color(cmpColour(r,g,b)) - # End ted's map changes - if xml_dom.hasAttribute("type"): - type = int(xml_dom.getAttribute("type")) - logger.debug("type=" + str(type)) - if type == BG_TEXTURE: + + if bg_type != None: + logger.debug("type=" + bg_type) + bg_type = int(xml_dom.get("type")) + if bg_type == BG_TEXTURE: if path != "": self.set_texture(path) - elif type == BG_IMAGE: + elif bg_type == BG_IMAGE: if path != "": self.set_image(path, 1) - elif type == BG_NONE: self.clear() - if xml_dom.hasAttribute('local') and xml_dom.getAttribute('local') == 'True' and os.path.exists(urllib.unquote(xml_dom.getAttribute('localPath'))): - self.localPath = urllib.unquote(xml_dom.getAttribute('localPath')) + elif bg_type == BG_NONE: self.clear() + if xml_dom.get('local') == 'True' and os.path.exists(urllib.unquote(xml_dom.get('localPath'))): + self.localPath = urllib.unquote(xml_dom.get('localPath')) self.local = True - self.localTime = int(xml_dom.getAttribute('localTime')) + self.localTime = int(xml_dom.get('localTime')) if self.localTime-time.time() <= 144000: file = open(self.localPath, "rb") imgdata = file.read() @@ -244,22 +248,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 diff -r 4b2884f29a72 -r 81d0bfd5e800 orpg/mapper/background_handler.py --- a/orpg/mapper/background_handler.py Fri Jan 15 22:45:51 2010 -0600 +++ b/orpg/mapper/background_handler.py Sat Jun 12 03:50:37 2010 -0500 @@ -21,11 +21,11 @@ # Author: OpenRPG Team # Maintainer: # Version: -# $Id: background_handler.py,v 1.23 2007/03/09 14:17:15 digitalxero Exp $ +# $Id: background_handler.py,v Traipse 'Ornery-Orc' prof.ebral Exp $ # # Description: Background layer handler # -__version__ = "$Id: background_handler.py,v 1.23 2007/03/09 14:17:15 digitalxero Exp $" +__version__ = "$Id: background_handler.py,v Traipse 'Ornery-Orc' prof.ebral Exp $" import thread, mimetypes, os from threading import Lock diff -r 4b2884f29a72 -r 81d0bfd5e800 orpg/mapper/background_msg.py --- a/orpg/mapper/background_msg.py Fri Jan 15 22:45:51 2010 -0600 +++ b/orpg/mapper/background_msg.py Sat Jun 12 03:50:37 2010 -0500 @@ -21,11 +21,11 @@ # Author: Chris Davis # Maintainer: # Version: -# $Id: background_msg.py,v 1.8 2006/11/04 21:24:21 digitalxero Exp $ +# $Id: background_msg.py,v Traipse 'Ornery-Orc' prof.ebral Exp $ # # Description: # -__version__ = "$Id: background_msg.py,v 1.8 2006/11/04 21:24:21 digitalxero Exp $" +__version__ = "$Id: background_msg.py,v Traipse 'Ornery-Orc' prof.ebral Exp $" from base_msg import * diff -r 4b2884f29a72 -r 81d0bfd5e800 orpg/mapper/base.py --- a/orpg/mapper/base.py Fri Jan 15 22:45:51 2010 -0600 +++ b/orpg/mapper/base.py Sat Jun 12 03:50:37 2010 -0500 @@ -21,11 +21,11 @@ # Author: Chris Davis # Maintainer: # Version: -# $Id: base.py,v 1.18 2007/02/12 02:29:08 digitalxero Exp $ +# $Id: base.py,v Traipse 'Ornery-Orc' prof.ebral Exp $ # # Description: # -__version__ = "$Id: base.py,v 1.18 2007/02/12 02:29:08 digitalxero Exp $" +__version__ = "$Id: base.py,v Traipse 'Ornery-Orc' prof.ebral Exp $" from images import ImageHandler from orpg.tools.rgbhex import * diff -r 4b2884f29a72 -r 81d0bfd5e800 orpg/mapper/base_handler.py --- a/orpg/mapper/base_handler.py Fri Jan 15 22:45:51 2010 -0600 +++ b/orpg/mapper/base_handler.py Sat Jun 12 03:50:37 2010 -0500 @@ -21,12 +21,12 @@ # Author: OpenRPG Team # Maintainer: # Version: -# $Id: base_handler.py,v 1.20 2007/11/04 17:32:25 digitalxero Exp $ +# $Id: base_handler.py,v Traipse 'Ornery-Orc' prof.ebral Exp $ # # Description: base layer handler. # layer handlers are responsible for the GUI elements of the layer # -__version__ = "$Id: base_handler.py,v 1.20 2007/11/04 17:32:25 digitalxero Exp $" +__version__ = "$Id: base_handler.py,v Traipse 'Ornery-Orc' prof.ebral Exp $" from orpg.orpg_windows import * @@ -42,14 +42,12 @@ self.chat = component.get("chat") self.build_ctrls() self.build_menu() - #self.Bind(wx.EVT_SIZE, self.on_size) self.Bind(wx.EVT_LEFT_DCLICK, self.on_left_dclick) def build_ctrls(self): self.basesizer = wx.BoxSizer(wx.HORIZONTAL) self.sizer = wx.BoxSizer(wx.HORIZONTAL) self.buttonsizer = wx.BoxSizer(wx.HORIZONTAL) - self.zoom_in_button = createMaskedButton( self, dir_struct["icon"]+'zoom_in.gif', "Zoom in from x1.0", wx.ID_ANY ) self.zoom_out_button = createMaskedButton( self, diff -r 4b2884f29a72 -r 81d0bfd5e800 orpg/mapper/base_msg.py --- a/orpg/mapper/base_msg.py Fri Jan 15 22:45:51 2010 -0600 +++ b/orpg/mapper/base_msg.py Sat Jun 12 03:50:37 2010 -0500 @@ -21,15 +21,15 @@ # Author: Chris Davis # Maintainer: # Version: -# $Id: base_msg.py,v 1.9 2007/03/09 14:11:55 digitalxero Exp $ +# $Id: base_msg.py,v Traipse 'Ornery-Orc' prof.ebral Exp $ # # Description: # -__version__ = "$Id: base_msg.py,v 1.9 2007/03/09 14:11:55 digitalxero Exp $" +__version__ = "$Id: base_msg.py,v Traipse 'Ornery-Orc' prof.ebral Exp $" from threading import RLock from orpg.networking.mplay_client import * -from xml.etree.ElementTree import ElementTree, Element +from xml.etree.ElementTree import ElementTree, Element, fromstring class map_element_msg_base: # This is a base class @@ -38,7 +38,6 @@ if not hasattr(self,"tagname"): raise Exception, "This is a virtual class that cannot be directly instantiated. Set self.tagname in derived class." - self._props = {} # This is a dictionary that holds (value,changed) 2-tuples, indexed by attribute # Avoid manipulating these values directly. Instead, use the provided accessor methods. @@ -217,20 +216,24 @@ self._from_dom(xml_dom,self.set_prop) def init_from_xml(self,xml): - xml_dom = parseXml(xml) - node_list = xml_dom.getElementsByTagName(self.tagname) + #xml_dom = parseXml(xml) + xml_dom = fromstring(xml) + #node_list = xml_dom.getElementsByTagName(self.tagname) + node_list = xml_dom.findall(self.tagname) if len(node_list) < 1: print "Warning: no <" + self.tagname + "/> elements found in DOM." else: while len(node_list): self.init_from_dom(node_list.pop()) - if xml_dom: xml_dom.unlink() + #if xml_dom: xml_dom.unlink() def set_from_xml(self,xml): - xml_dom = parseXml(xml) - node_list = xml_dom.getElementsByTagName(self.tagname) + #xml_dom = parseXml(xml) + xml_dom = fromstring(xml) + #node_list = xml_dom.getElementsByTagName(self.tagname) + node_list = xml_dom.findall(self.tagname) if len(node_list) < 1: print "Warning: no <" + self.tagname + "/> elements found in DOM." else: while len(node_list): self.set_from_dom(node_list.pop()) - if xml_dom: xml_dom.unlink() + #if xml_dom: xml_dom.unlink() # XML importers end ######################################### diff -r 4b2884f29a72 -r 81d0bfd5e800 orpg/mapper/fog.py --- a/orpg/mapper/fog.py Fri Jan 15 22:45:51 2010 -0600 +++ b/orpg/mapper/fog.py Sat Jun 12 03:50:37 2010 -0500 @@ -27,7 +27,7 @@ from base import * from random import Random from region import * -from orpg.minidom import Element +from xml.etree.ElementTree import Element, tostring import traceback COURSE = 10 @@ -47,8 +47,8 @@ for pairs in string.split( points, ';' ): pair = string.split( pairs, ',' ) p = Element( "point" ) - p.setAttribute( "x", pair[0] ) - p.setAttribute( "y", pair[1] ) + p.set( "x", pair[0] ) + p.set( "y", pair[1] ) result.append( p ) return result @@ -59,23 +59,20 @@ localOutline = "points" elem = Element( "poly" ) if action == "del": - elem.setAttribute( "action", action ) - elem.setAttribute( "outline", localOutline ) + elem.set( "action", action ) + elem.set( "outline", localOutline ) if localOutline == 'points': - list = self.points_to_elements( self.outline ) - for p in list: elem.appendChild( p ) - str = elem.toxml() - elem.unlink() - return str - elem.setAttribute( "action", action ) + foglist = self.points_to_elements( self.outline ) + for p in foglist: elem.append( p ) + return tostring(elem) + elem.set( "action", action ) if localOutline != None: - elem.setAttribute( "outline", localOutline ) + elem.set( "outline", localOutline ) if localOutline == 'points': - list = self.points_to_elements( self.outline ) - for p in list: elem.appendChild( p ) - xml_str = elem.toxml() - elem.unlink() - return xml_str + foglist = self.points_to_elements( self.outline ) + for p in foglist: elem.append( p ) + #xml_str = elem.toxml() + return tostring(elem) class fog_layer(layer_base): def __init__(self, canvas): @@ -223,11 +220,12 @@ if not self.use_fog: self.use_fog = True self.recompute_fog() - if xml_dom.hasAttribute('serial'): self.serial_number = int(xml_dom.getAttribute('serial')) - children = xml_dom._get_childNodes() + serial = xml_dom.get('serial') + if serial != None: self.serial_number = int(serial) + children = xml_dom.getchildren() for l in children: - action = l.getAttribute("action") - outline = l.getAttribute("outline") + action = l.get("action") + outline = l.get("outline") if (outline == "all"): polyline = [IPoint().make(0,0), IPoint().make(self.width-1, 0), IPoint().make(self.width-1, self.height-1), @@ -240,10 +238,10 @@ polyline = [] lastx = None lasty = None - list = l._get_childNodes() + list = l.getchildren() for point in list: - x = point.getAttribute( "x" ) - y = point.getAttribute( "y" ) + x = point.get( "x" ) + y = point.get( "y" ) if (x != lastx or y != lasty): polyline.append(IPoint().make(int(x), int(y))) lastx = x diff -r 4b2884f29a72 -r 81d0bfd5e800 orpg/mapper/fog_msg.py --- a/orpg/mapper/fog_msg.py Fri Jan 15 22:45:51 2010 -0600 +++ b/orpg/mapper/fog_msg.py Sat Jun 12 03:50:37 2010 -0500 @@ -21,13 +21,13 @@ # Author: Mark Tarrabain # Maintainer: # Version: -# $Id: fog_msg.py,v 1.16 2006/11/04 21:24:21 digitalxero Exp $ +# $Id: fog_msg.py,v Traipse 'Ornery-Orc' prof.ebral Exp $ # -__version__ = "$Id: fog_msg.py,v 1.16 2006/11/04 21:24:21 digitalxero Exp $" +__version__ = "$Id: fog_msg.py,v Traipse 'Ornery-Orc' prof.ebral Exp $" from base_msg import * from region import * -from orpg.minidom import Element +from xml.etree.ElementTree import Element, tostring import string class fog_msg(map_element_msg_base): @@ -41,19 +41,17 @@ def get_line(self,outline,action,output_act): elem = Element( "poly" ) - if ( output_act ): elem.setAttribute( "action", action ) - if ( outline == 'all' ) or ( outline == 'none' ): elem.setAttribute( "outline", outline ) + if ( output_act ): elem.set( "action", action ) + if ( outline == 'all' ) or ( outline == 'none' ): elem.set( "outline", outline ) else: - elem.setAttribute( "outline", "points" ) + elem.set( "outline", "points" ) for pair in string.split( outline, ";" ): p = string.split( pair, "," ) point = Element( "point" ) - point.setAttribute( "x", p[ 0 ] ) - point.setAttribute( "y", p[ 1 ] ) + point.set( "x", p[ 0 ] ) + point.set( "y", p[ 1 ] ) elem.appendChild( point ) - str = elem.toxml() - elem.unlink() - return str + return tostring(elem) # convenience method to use if only this line is modified # outputs a element containing only the changes to this line @@ -83,23 +81,18 @@ str(x2)+","+str(y1)+";"+ str(x2)+","+str(y2)+";"+ str(x1)+","+str(y2),action,output_action) - s = "2): if action=="del": self.fogregion.FromPolygon(polyline,0) else: self.fogregion.FromPolygon(polyline,1) diff -r 4b2884f29a72 -r 81d0bfd5e800 orpg/mapper/grid.py --- a/orpg/mapper/grid.py Fri Jan 15 22:45:51 2010 -0600 +++ b/orpg/mapper/grid.py Sat Jun 12 03:50:37 2010 -0500 @@ -21,11 +21,11 @@ # Author: OpenRPG Team # Maintainer: # Version: -# $Id: grid.py,v 1.29 2007/12/07 20:39:49 digitalxero Exp $ +# $Id: grid.py,v Traipse 'Ornery-Orc' prof.ebral Exp $ # # Description: # -__version__ = "$Id: grid.py,v 1.29 2007/12/07 20:39:49 digitalxero Exp $" +__version__ = "$Id: grid.py,v Traipse 'Ornery-Orc' prof.ebral Exp $" from base import * from isometric import * @@ -406,19 +406,20 @@ else: return '' def layerTakeDOM(self, xml_dom): - if xml_dom.hasAttribute("color"): - r,g,b = self.r_h.rgb_tuple(xml_dom.getAttribute("color")) + color = xml_dom.get('color') + if color != None: + r,g,b = self.r_h.rgb_tuple(color) self.set_color(cmpColour(r,g,b)) #backwards compatible with non-isometric map formated clients - ratio = RATIO_DEFAULT - if xml_dom.hasAttribute("ratio"): ratio = xml_dom.getAttribute("ratio") - if xml_dom.hasAttribute("mode"): - self.SetMode(int(xml_dom.getAttribute("mode"))) - if xml_dom.hasAttribute("size"): - self.unit_size = int(xml_dom.getAttribute("size")) + ratio = RATIO_DEFAULT if xml_dom.get("ratio") == None else xml_dom.get('ratio') + mode = xml_dom.get('mode') + if mode != None: self.SetMode(int(mode)) + size = xml_dom.get('size') + if size != None: + self.unit_size = int(size) self.unit_size_y = self.unit_size - if xml_dom.hasAttribute("snap"): - if (xml_dom.getAttribute("snap") == 'True') or (xml_dom.getAttribute("snap") == "1"): self.snap = True - else: self.snap = False - if xml_dom.hasAttribute("line"): - self.SetLine(int(xml_dom.getAttribute("line"))) + if (xml_dom.get("snap") == 'True') or (xml_dom.get("snap") == "1"): self.snap = True + else: self.snap = False + line = xml_dom.get('line') + if line != None: self.SetLine(int(line)) + diff -r 4b2884f29a72 -r 81d0bfd5e800 orpg/mapper/grid_handler.py --- a/orpg/mapper/grid_handler.py Fri Jan 15 22:45:51 2010 -0600 +++ b/orpg/mapper/grid_handler.py Sat Jun 12 03:50:37 2010 -0500 @@ -20,11 +20,11 @@ # Author: OpenRPG Team # Maintainer: # Version: -# $Id: grid_handler.py,v 1.20 2007/04/03 00:14:35 digitalxero Exp $ +# $Id: grid_handler.py,v Traipse 'Ornery-Orc' prof.ebral Exp $ # # Description: grid layer handler # -__version__ = "$Id: grid_handler.py,v 1.20 2007/04/03 00:14:35 digitalxero Exp $" +__version__ = "$Id: grid_handler.py,v Traipse 'Ornery-Orc' prof.ebral Exp $" from grid import * from base_handler import * @@ -40,10 +40,11 @@ self.grid_snap = wx.CheckBox(self, wx.ID_ANY, " Snap") self.grid_size = wx.TextCtrl(self, wx.ID_ANY, size=(32,-1) ) self.grid_ratio = wx.TextCtrl(self, wx.ID_ANY, size=(32,-1) ) - self.color_button = wx.Button(self, wx.ID_ANY, "Color", style=wx.BU_EXACTFIT) + self.color_button = createMaskedButton(self, dir_struct["icon"]+'grid.png', + 'Grid Color', wx.ID_ANY, '#bdbdbd', + wx.BITMAP_TYPE_PNG) self.apply_button = wx.Button(self, wx.ID_OK, "Apply", style=wx.BU_EXACTFIT) self.color_button.SetBackgroundColour(wx.BLACK) - self.color_button.SetForegroundColour(wx.WHITE) self.sizer.Add(wx.StaticText(self, -1, "Size: "), 0, wx.ALIGN_CENTER) self.sizer.Add(self.grid_size, 0, wx.ALIGN_CENTER) self.sizer.Add((6,0)) diff -r 4b2884f29a72 -r 81d0bfd5e800 orpg/mapper/grid_msg.py --- a/orpg/mapper/grid_msg.py Fri Jan 15 22:45:51 2010 -0600 +++ b/orpg/mapper/grid_msg.py Sat Jun 12 03:50:37 2010 -0500 @@ -21,11 +21,11 @@ # Author: OpenRPG Team # Maintainer: # Version: -# $Id: grid_msg.py,v 1.8 2006/11/04 21:24:21 digitalxero Exp $ +# $Id: grid_msg.py,v Traipse 'Ornery-Orc' prof.ebral Exp $ # # Description: # -__version__ = "$Id: grid_msg.py,v 1.8 2006/11/04 21:24:21 digitalxero Exp $" +__version__ = "$Id: grid_msg.py,v Traipse 'Ornery-Orc' prof.ebral Exp $" from base_msg import map_element_msg_base #from base_msg import * ## ?? import all? Deprecated!? diff -r 4b2884f29a72 -r 81d0bfd5e800 orpg/mapper/images.py --- a/orpg/mapper/images.py Fri Jan 15 22:45:51 2010 -0600 +++ b/orpg/mapper/images.py Sat Jun 12 03:50:37 2010 -0500 @@ -21,7 +21,7 @@ # Author: OpenRPG # Maintainer: # Version: -# $Id: images.py,v 1.21 2007/12/11 04:07:15 digitalxero Exp $ +# $Id: images.py,v Traipse 'Ornery-Orc' prof.ebral Exp $ # # Description: # diff -r 4b2884f29a72 -r 81d0bfd5e800 orpg/mapper/map.py --- a/orpg/mapper/map.py Fri Jan 15 22:45:51 2010 -0600 +++ b/orpg/mapper/map.py Sat Jun 12 03:50:37 2010 -0500 @@ -21,11 +21,11 @@ # Author: OpenRPG # Maintainer: # Version: -# $Id: map.py,v 1.73 2007/12/07 20:39:49 digitalxero Exp $ +# $Id: map.py,v Traipse 'Ornery-Orc' prof.ebral Exp $ # # Description: # -__version__ = "$Id: map.py,v 1.73 2007/12/07 20:39:49 digitalxero Exp $" +__version__ = "$Id: map.py,v Traipse 'Ornery-Orc' prof.ebral Exp $" from map_version import MAP_VERSION from map_msg import * @@ -45,6 +45,8 @@ from images import ImageHandler from orpg.orpgCore import component from orpg.tools.orpg_settings import settings +from xml.etree.ElementTree import ElementTree, Element, parse +from xml.etree.ElementTree import fromstring, tostring # Various marker modes for player tools on the map MARKER_MODE_NONE = 0 @@ -156,7 +158,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,27 +253,44 @@ 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) dc.SetDeviceOrigin(-topleft[0], -topleft[1]) dc.SetUserScale(scale, scale) + + layer_order = [] + for i in xrange (0, len(self.parent.layer_handlers)-1): + if self.parent.layer_tabs.GetPageText(i) in ('Background', 'Fog', 'General'): pass + else: layer_order.append(self.parent.layer_tabs.GetPageText(i)) self.layers['bg'].layerDraw(dc, scale, topleft, clientsize) - self.layers['grid'].layerDraw(dc, [topleft[0]/scale, topleft[1]/scale], - [clientsize[0]/scale, clientsize[1]/scale]) - self.layers['miniatures'].layerDraw(dc, [topleft[0]/scale, topleft[1]/scale], - [clientsize[0]/scale, clientsize[1]/scale]) - self.layers['whiteboard'].layerDraw(dc) + + for layer in layer_order: + if layer == 'Grid': self.layers['grid'].layerDraw(dc, [topleft[0]/scale, topleft[1]/scale], + [clientsize[0]/scale, clientsize[1]/scale]) + if layer == 'Miniatures': self.layers['miniatures'].layerDraw(dc, [topleft[0]/scale, topleft[1]/scale], + [clientsize[0]/scale, clientsize[1]/scale]) + if layer == 'Whiteboard': self.layers['whiteboard'].layerDraw(dc) + 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) @@ -367,8 +387,6 @@ dc.SetUserScale(self.layers['grid'].mapscale,self.layers['grid'].mapscale) # Grab the current map position pos = self.snapMarker( evt.GetLogicalPosition( dc ) ) - # Enable brush optimizations - # dc.SetOptimization( True ) # Set up the pen used for drawing our marker dc.SetPen( wx.Pen(wx.RED, 1, wx.LONG_DASH) ) # Now, based on the marker mode, draw the right thing @@ -386,8 +404,6 @@ # As long as we are in marker mode, we ned to update the stop point self.markerStop = pos dc.SetPen(wx.NullPen) - # Disable brush optimizations - #dc.SetOptimization( False ) del dc def on_tape_down(self, evt): @@ -403,8 +419,6 @@ self.markerMode = MARKER_MODE_MEASURE # Erase the old line if her have one if self.markerStart.x != -1 and self.markerStart.y != -1: - # Enable brush optimizations - #dc.SetOptimization( True ) # Set up the pen used for drawing our marker dc.SetPen( wx.Pen(wx.RED, 1, wx.LONG_DASH) ) # Set the DC function that we need @@ -416,8 +430,6 @@ # Restore the default DC function and pen dc.SetLogicalFunction(wx.COPY) dc.SetPen(wx.NullPen) - # Disable brush optimizations - #dc.SetOptimization( False ) # Save our current start and reset the stop value self.markerStart = pos self.markerStop = pos @@ -617,15 +629,16 @@ --Snowdog 5/27/03 """ try: - #parse the map DOM - xml_dom = parseXml(xml) + xml_dom = fromstring(xml) if xml_dom == None: return - node_list = xml_dom.getElementsByTagName("map") + node_list = xml_dom.findall("map") + if len(node_list) < 1: + if xml_dom.tag == 'map': node_list = [xml_dom] if len(node_list) < 1: pass else: # set map version to incoming data so layers can convert - self.map_version = node_list[0].getAttribute("version") - action = node_list[0].getAttribute("action") + self.map_version = node_list[0].get("version") + action = node_list[0].get("action") if action == "new": self.layers = {} try: self.layers['bg'] = layer_back_ground(self) @@ -638,33 +651,33 @@ except: pass try: self.layers['fog'] = fog_layer(self) except: pass - sizex = node_list[0].getAttribute("sizex") + sizex = node_list[0].get("sizex") or '' if sizex != "": sizex = int(float(sizex)) sizey = self.size[1] self.set_size((sizex,sizey)) self.size_changed = 0 - sizey = node_list[0].getAttribute("sizey") + sizey = node_list[0].get("sizey") or '' if sizey != "": sizey = int(float(sizey)) sizex = self.size[0] self.set_size((sizex,sizey)) self.size_changed = 0 - children = node_list[0]._get_childNodes() + children = node_list[0].getchildren() #fog layer must be computed first, so that no data is inadvertently revealed for c in children: - name = c._get_nodeName() + name = c.tag if name == "fog": self.layers[name].layerTakeDOM(c) for c in children: - name = c._get_nodeName() + name = c.tag if name != "fog": self.layers[name].layerTakeDOM(c) # all map data should be converted, set map version to current version self.map_version = MAP_VERSION - self.Refresh(False) - xml_dom.unlink() # eliminate circular refs + self.Refresh(True) except: pass def re_ids_in_xml(self, xml): + debug(('Developers note. Deprecated call to re_ids_in_xml!!'), parents=True) new_xml = "" tmp_map = map_msg() xml_dom = parseXml(str(xml)) @@ -709,20 +722,23 @@ self.root_dir = os.getcwd() self.current_layer = 2 self.layer_tabs = orpgTabberWnd(self, style=FNB.FNB_NO_X_BUTTON|FNB.FNB_BOTTOM|FNB.FNB_NO_NAV_BUTTONS) + self.layer_handlers = [] - self.layer_handlers.append(background_handler(self.layer_tabs,-1,self.canvas)) - self.layer_tabs.AddPage(self.layer_handlers[0],"Background") - self.layer_handlers.append(grid_handler(self.layer_tabs,-1,self.canvas)) - self.layer_tabs.AddPage(self.layer_handlers[1],"Grid") - self.layer_handlers.append(miniatures_handler(self.layer_tabs,-1,self.canvas)) - self.layer_tabs.AddPage(self.layer_handlers[2],"Miniatures", True) - self.layer_handlers.append(whiteboard_handler(self.layer_tabs,-1,self.canvas)) - self.layer_tabs.AddPage(self.layer_handlers[3],"Whiteboard") - self.layer_handlers.append(fog_handler(self.layer_tabs,-1,self.canvas)) - self.layer_tabs.AddPage(self.layer_handlers[4],"Fog") - self.layer_handlers.append(map_handler(self.layer_tabs,-1,self.canvas)) - self.layer_tabs.AddPage(self.layer_handlers[5],"General") + self.layer_handlers.append(background_handler(self.layer_tabs, -1, self.canvas)) + self.layer_tabs.AddPage(self.layer_handlers[0], "Background") + self.layer_handlers.append(grid_handler(self.layer_tabs, -1, self.canvas)) + self.layer_tabs.AddPage(self.layer_handlers[1], "Grid") + self.layer_handlers.append(miniatures_handler(self.layer_tabs, -1, self.canvas)) + self.layer_tabs.AddPage(self.layer_handlers[2], "Miniatures", True) + self.layer_handlers.append(whiteboard_handler(self.layer_tabs, -1, self.canvas)) + self.layer_tabs.AddPage(self.layer_handlers[3], "Whiteboard") + self.layer_handlers.append(fog_handler(self.layer_tabs, -1, self.canvas)) + self.layer_tabs.AddPage(self.layer_handlers[4], "Fog") + self.layer_handlers.append(map_handler(self.layer_tabs, -1, self.canvas)) + self.layer_tabs.AddPage(self.layer_handlers[5], "General") self.layer_tabs.SetSelection(2) + + self.layer_order = {1: 'grid', 2: 'miniatures', 3: 'whiteboard'} self.sizer = wx.BoxSizer(wx.VERTICAL) self.sizer.Add(self.canvas, 1, wx.EXPAND) self.sizer.Add(self.layer_tabs, 0, wx.EXPAND) diff -r 4b2884f29a72 -r 81d0bfd5e800 orpg/mapper/map_handler.py --- a/orpg/mapper/map_handler.py Fri Jan 15 22:45:51 2010 -0600 +++ b/orpg/mapper/map_handler.py Sat Jun 12 03:50:37 2010 -0500 @@ -20,11 +20,11 @@ # Author: OpenRPG Team # Maintainer: # Version: -# $Id: map_handler.py,v 1.14 2007/04/03 00:14:35 digitalxero Exp $ +# $Id: map_handler.py,v Traipse 'Ornery-Orc' prof.ebral Exp $ # # Description: map layer handler # -__version__ = "$Id: map_handler.py,v 1.14 2007/04/03 00:14:35 digitalxero Exp $" +__version__ = "$Id: map_handler.py,v Traipse 'Ornery-Orc' prof.ebral Exp $" from base_handler import * diff -r 4b2884f29a72 -r 81d0bfd5e800 orpg/mapper/map_msg.py --- a/orpg/mapper/map_msg.py Fri Jan 15 22:45:51 2010 -0600 +++ b/orpg/mapper/map_msg.py Sat Jun 12 03:50:37 2010 -0500 @@ -21,13 +21,12 @@ # Author: OpenRPG # Maintainer: # Version: -# $Id: map_msg.py,v 1.16 2007/03/09 14:11:55 digitalxero Exp $ +# $Id: map_msg.py,v Traipse 'Ornery-Orc' prof.ebral Exp $ # # Description: # -__version__ = "$Id: map_msg.py,v 1.16 2007/03/09 14:11:55 digitalxero Exp $" +__version__ = "$Id: map_msg.py,v Traipse 'Ornery-Orc' prof.ebral Exp $" -#from base import * from base_msg import * from background_msg import * from grid_msg import * @@ -54,17 +53,17 @@ def init_from_dom(self,xml_dom): self.p_lock.acquire() - if xml_dom.tagName == self.tagname: + if xml_dom.tag == self.tagname: # If this is a map message, look for the "action=new" # Notice we only do this when the root is a map tag - if self.tagname == "map" and xml_dom.hasAttribute("action") and xml_dom.getAttribute("action") == "new": + if self.tagname == "map" and xml_dom.get("action") == "new": self.clear() # Process all of the properties in each tag - if xml_dom.getAttributeKeys(): - for k in xml_dom.getAttributeKeys(): - self.init_prop(k,xml_dom.getAttribute(k)) - for c in xml_dom._get_childNodes(): - name = c._get_nodeName() + if xml_dom.keys(): + for k in xml_dom.keys(): + self.init_prop(k,xml_dom.get(k)) + for c in xml_dom.getchildren(): + name = c.tag if not self.children.has_key(name): if name == "miniatures": self.children[name] = minis_msg(self.p_lock) elif name == "grid": self.children[name] = grid_msg(self.p_lock) @@ -85,16 +84,16 @@ def set_from_dom(self,xml_dom): self.p_lock.acquire() - if xml_dom.tagName == self.tagname: + if xml_dom.tag == self.tagname: # If this is a map message, look for the "action=new" # Notice we only do this when the root is a map tag - if self.tagname == "map" and xml_dom.hasAttribute("action") and xml_dom.getAttribute("action") == "new": + if self.tagname == "map" and xml_dom.get("action") == "new": self.clear() # Process all of the properties in each tag - if xml_dom.getAttributeKeys(): - for k in xml_dom.getAttributeKeys(): self.set_prop(k,xml_dom.getAttribute(k)) - for c in xml_dom._get_childNodes(): - name = c._get_nodeName() + if xml_dom.keys(): + for k in xml_dom.keys(): self.set_prop(k,xml_dom.get(k)) + for c in xml_dom.getchildren(): + name = c.tag if not self.children.has_key(name): if name == "miniatures": self.children[name] = minis_msg(self.p_lock) elif name == "grid": self.children[name] = grid_msg(self.p_lock) diff -r 4b2884f29a72 -r 81d0bfd5e800 orpg/mapper/map_prop_dialog.py --- a/orpg/mapper/map_prop_dialog.py Fri Jan 15 22:45:51 2010 -0600 +++ b/orpg/mapper/map_prop_dialog.py Sat Jun 12 03:50:37 2010 -0500 @@ -21,11 +21,11 @@ # Author: OpenRPG # Maintainer: # Version: -# $Id: map_prop_dialog.py,v 1.16 2006/11/04 21:24:21 digitalxero Exp $ +# $Id: map_prop_dialog.py,v Traipse 'Ornery-Orc' prof.ebral Exp $ # # Description: # -__version__ = "$Id: map_prop_dialog.py,v 1.16 2006/11/04 21:24:21 digitalxero Exp $" +__version__ = "$Id: map_prop_dialog.py,v Traipse 'Ornery-Orc' prof.ebral Exp $" from orpg.orpg_windows import * from background import * diff -r 4b2884f29a72 -r 81d0bfd5e800 orpg/mapper/min_dialogs.py --- a/orpg/mapper/min_dialogs.py Fri Jan 15 22:45:51 2010 -0600 +++ b/orpg/mapper/min_dialogs.py Sat Jun 12 03:50:37 2010 -0500 @@ -21,7 +21,7 @@ # Author: Chris Davis # Maintainer: # Version: -# $Id: min_dialogs.py,v 1.27 2006/11/13 02:23:16 digitalxero Exp $ +# $Id: min_dialogs.py,v Traipse 'Ornery-Orc' prof.ebral Exp $ # # Description: This file contains some of the basic definitions for the chat # utilities in the orpg project. @@ -146,10 +146,8 @@ ############# min_xml = sel_rmin.toxml(action="new") node_begin = "' @@ -308,14 +306,11 @@ positionbox.Add(poschoicebox,0,0) listsizer.Add(positionbox,0, 0) self.listsizer = listsizer - #self.outline = wx.StaticBox(self,-1,"Miniature list properties") - #listsizer.Add(self.outline,0, wx.EXPAND) self.SetSizer(listsizer) self.SetAutoLayout(True) self.Fit() self.Bind(wx.EVT_SPINCTRL, self.on_spin, id=POS_SPIN) self.Bind(wx.EVT_TEXT, self.on_combo_box, id=POS_COMB) - #self.Bind(wx.EVT_SIZE, self.on_size) self.Bind(wx.EVT_TEXT, self.on_text, id=MIN_LABEL) self.Bind(wx.EVT_RADIOBOX, self.on_radio_box, id=MIN_HEADING) self.Bind(wx.EVT_RADIOBOX, self.on_radio_box, id=MIN_FACE) @@ -500,12 +495,10 @@ class min_edit_dialog(wx.Dialog): def __init__(self,parent,min): - #520,265 wx.Dialog.__init__(self,parent,-1,"Miniature",wx.DefaultPosition,wx.Size(520,350)) (w,h) = self.GetClientSizeTuple() mastersizer = wx.BoxSizer(wx.VERTICAL) editor = min_edit_panel(self,min) - #editor.SetDimensions(0,0,w,h-25) self.editor = editor mastersizer.Add(editor, 1, wx.EXPAND) mastersizer.Add(wx.Size(10,10)) @@ -513,7 +506,6 @@ sizer.Add(wx.Button(self, wx.ID_OK, "OK"), 1, wx.EXPAND) sizer.Add(wx.Size(10,10)) sizer.Add(wx.Button(self, wx.ID_CANCEL, "Cancel"), 1, wx.EXPAND) - #sizer.SetDimension(0,h-25,w,25) mastersizer.Add(sizer, 0, wx.EXPAND) self.SetSizer(mastersizer) self.SetAutoLayout(True) @@ -523,3 +515,4 @@ def on_ok(self,evt): self.editor.update_min() self.EndModal(wx.ID_OK) + diff -r 4b2884f29a72 -r 81d0bfd5e800 orpg/mapper/miniatures.py --- a/orpg/mapper/miniatures.py Fri Jan 15 22:45:51 2010 -0600 +++ b/orpg/mapper/miniatures.py Sat Jun 12 03:50:37 2010 -0500 @@ -21,12 +21,12 @@ # Author: Chris Davis # Maintainer: # Version: -# $Id: miniatures.py,v 1.46 2007/12/07 20:39:50 digitalxero Exp $ +# $Id: miniatures.py,v Traipse 'Ornery-Orc' prof.ebral Exp $ # # Description: This file contains some of the basic definitions for the chat # utilities in the orpg project. # -__version__ = "$Id: miniatures.py,v 1.46 2007/12/07 20:39:50 digitalxero Exp $" +__version__ = "$Id: miniatures.py,v Traipse 'Ornery-Orc' prof.ebral Exp $" from base import * import thread, time, urllib, os.path, mimetypes @@ -196,7 +196,6 @@ self.right = self.bmp.GetWidth() self.top = 0 self.bottom = self.bmp.GetHeight() - # Draw the facing marker if needed if self.face != 0: x_mid = self.pos.x + (self.bmp.GetWidth()/2) @@ -206,7 +205,6 @@ dc.SetPen(wx.WHITE_PEN) dc.SetBrush(wx.RED_BRUSH) triangle = [] - # Figure out which direction to draw the marker!! tri_list = { FACE_WEST: [cmpPoint(self.pos.x, self.pos.y), cmpPoint(self.pos.x-5, y_mid), cmpPoint(self.pos.x, y_bottom)], @@ -225,7 +223,6 @@ dc.DrawPolygon(triangle) dc.SetBrush(wx.NullBrush) dc.SetPen(wx.NullPen) - # Draw the heading if needed if self.heading: x_adjust = 0 @@ -343,31 +340,31 @@ xml_str += " />" if (action == "update" and self.isUpdated) or action == "new": self.isUpdated = False - print xml_str; return xml_str + return xml_str else: return '' def takedom(self, xml_dom): - self.id = xml_dom.getAttribute("id") - if xml_dom.hasAttribute("posx"): self.pos.x = int(xml_dom.getAttribute("posx")) - if xml_dom.hasAttribute("posy"): self.pos.y = int(xml_dom.getAttribute("posy")) - if xml_dom.hasAttribute("heading"): self.heading = int(xml_dom.getAttribute("heading")) - if xml_dom.hasAttribute("face"): self.face = int(xml_dom.getAttribute("face")) - if xml_dom.hasAttribute("path"): - self.path = urllib.unquote(xml_dom.getAttribute("path")) + self.id = xml_dom.get("id") + if xml_dom.get("posx") != None: self.pos.x = int(xml_dom.get("posx")) + if xml_dom.get("posy") != None: self.pos.y = int(xml_dom.get("posy")) + if xml_dom.get("heading") != None: self.heading = int(xml_dom.get("heading")) + if xml_dom.get("face") != None: self.face = int(xml_dom.get("face")) + if xml_dom.get("path") != None: + self.path = urllib.unquote(xml_dom.get("path")) self.set_bmp(ImageHandler.load(self.path, 'miniature', self.id)) - if xml_dom.hasAttribute("locked"): - if xml_dom.getAttribute("locked") == '1' or xml_dom.getAttribute("locked") == 'True': self.locked = True + if xml_dom.get("locked") != None: + if xml_dom.get("locked") == '1' or xml_dom.get("locked") == 'True': self.locked = True else: self.locked = False - if xml_dom.hasAttribute("hide"): - if xml_dom.getAttribute("hide") == '1' or xml_dom.getAttribute("hide") == 'True': self.hide = True + if xml_dom.get("hide") != None: + if xml_dom.get("hide") == '1' or xml_dom.get("hide") == 'True': self.hide = True else: self.hide = False - if xml_dom.hasAttribute("label"): self.label = xml_dom.getAttribute("label") - if xml_dom.hasAttribute("zorder"): self.zorder = int(xml_dom.getAttribute("zorder")) - if xml_dom.hasAttribute("align"): - if xml_dom.getAttribute("align") == '1' or xml_dom.getAttribute("align") == 'True': self.snap_to_align = 1 + if xml_dom.get("label") != None: self.label = xml_dom.get("label") + if xml_dom.get("zorder") != None: self.zorder = int(xml_dom.get("zorder")) + if xml_dom.get("align") != None: + if xml_dom.get("align") == '1' or xml_dom.get("align") == 'True': self.snap_to_align = 1 else: self.snap_to_align = 0 - if xml_dom.hasAttribute("width"): self.width = int(xml_dom.getAttribute("width")) - if xml_dom.hasAttribute("height"): self.height = int(xml_dom.getAttribute("height")) + if xml_dom.get("width") != None: self.width = int(xml_dom.get("width")) + if xml_dom.get("height") != None: self.height = int(xml_dom.get("height")) ##----------------------------- ## miniature layer @@ -376,7 +373,7 @@ def __init__(self, canvas): self.canvas = canvas layer_base.__init__(self) - self.id = -1 #added. + self.id = -1 self.miniatures = [] self.serial_number = 0 self.show_labels = True @@ -492,36 +489,36 @@ else: return "" def layerTakeDOM(self, xml_dom): - if xml_dom.hasAttribute('serial'): - self.serial_number = int(xml_dom.getAttribute('serial')) - children = xml_dom._get_childNodes() + if xml_dom.get('serial') != None: + self.serial_number = int(xml_dom.get('serial')) + children = xml_dom.getchildren() for c in children: - action = c.getAttribute("action") - id = c.getAttribute('id') + action = c.get("action") + id = c.get('id') if action == "del": mini = self.get_miniature_by_id(id) if mini: self.miniatures.remove(mini); del mini elif action == "new": - pos = cmpPoint(int(c.getAttribute('posx')),int(c.getAttribute('posy'))) - path = urllib.unquote(c.getAttribute('path')) - label = c.getAttribute('label') + pos = cmpPoint(int(c.get('posx')),int(c.get('posy'))) + path = urllib.unquote(c.get('path')) + label = c.get('label') height = width = heading = face = snap_to_align = zorder = 0 locked = hide = False - if c.hasAttribute('height'): height = int(c.getAttribute('height')) - if c.hasAttribute('width'): width = int(c.getAttribute('width')) - if c.getAttribute('locked') == 'True' or c.getAttribute('locked') == '1': locked = True - if c.getAttribute('hide') == 'True' or c.getAttribute('hide') == '1': hide = True - if c.getAttribute('heading'): heading = int(c.getAttribute('heading')) - if c.hasAttribute('face'): face = int(c.getAttribute('face')) - if c.hasAttribute('align'): snap_to_align = int(c.getAttribute('align')) - if c.getAttribute('zorder'): zorder = int(c.getAttribute('zorder')) + if c.get('height') != None: height = int(c.get('height')) + if c.get('width') != None: width = int(c.get('width')) + if c.get('locked') == 'True' or c.get('locked') == '1': locked = True + if c.get('hide') == 'True' or c.get('hide') == '1': hide = True + if c.get('heading') != None: heading = int(c.get('heading')) + if c.get('face') != None: face = int(c.get('face')) + if c.get('align') != None: snap_to_align = int(c.get('align')) + if c.get('zorder') != None: zorder = int(c.get('zorder')) min = BmpMiniature(id, path, ImageHandler.load(path, 'miniature', id), pos, heading, face, label, locked, hide, snap_to_align, zorder, width, height) self.miniatures.append(min) - if c.hasAttribute('local') and c.getAttribute('local') == 'True' and os.path.exists(urllib.unquote(c.getAttribute('localPath'))): - localPath = urllib.unquote(c.getAttribute('localPath')) + if c.get('local') == 'True' and os.path.exists(urllib.unquote(c.get('localPath'))): + localPath = urllib.unquote(c.get('localPath')) local = True - localTime = float(c.getAttribute('localTime')) + localTime = float(c.get('localTime')) if localTime-time.time() <= 144000: file = open(localPath, "rb") imgdata = file.read() diff -r 4b2884f29a72 -r 81d0bfd5e800 orpg/mapper/miniatures_handler.py --- a/orpg/mapper/miniatures_handler.py Fri Jan 15 22:45:51 2010 -0600 +++ b/orpg/mapper/miniatures_handler.py Sat Jun 12 03:50:37 2010 -0500 @@ -21,11 +21,11 @@ # Author: OpenRPG Team # Maintainer: # Version: -# $Id: miniatures_handler.py,v 1.43 2007/12/07 20:39:50 digitalxero Exp $ +# $Id: miniatures_handler.py,v Traipse 'Ornery-Orc' prof.ebral Exp $ # # Description: Miniature layer handler # -__version__ = "$Id: miniatures_handler.py,v 1.43 2007/12/07 20:39:50 digitalxero Exp $" +__version__ = "$Id: miniatures_handler.py,v Traipse 'Ornery-Orc' prof.ebral Exp $" from base_handler import * from min_dialogs import * @@ -36,7 +36,6 @@ from grid import GRID_ISOMETRIC from orpg.tools.orpg_settings import settings - from xml.etree.ElementTree import ElementTree, Element from xml.etree.ElementTree import fromstring, tostring @@ -118,7 +117,6 @@ dt = myFileDropTarget(self) self.canvas.SetDropTarget(dt) self.tooltip = wx.ToolTip('') - #wxInitAllImageHandlers() def build_ctrls(self): base_layer_handler.build_ctrls(self) diff -r 4b2884f29a72 -r 81d0bfd5e800 orpg/mapper/miniatures_msg.py --- a/orpg/mapper/miniatures_msg.py Fri Jan 15 22:45:51 2010 -0600 +++ b/orpg/mapper/miniatures_msg.py Sat Jun 12 03:50:37 2010 -0500 @@ -21,12 +21,12 @@ # Author: Chris Davis # Maintainer: # Version: -# $Id: miniatures_msg.py,v 1.8 2006/11/04 21:24:21 digitalxero Exp $ +# $Id: miniatures_msg.py,v Traipse 'Ornery-Orc' prof.ebral Exp $ # # Description: This file contains some of the basic definitions for the chat # utilities in the orpg project. # -__version__ = "$Id: miniatures_msg.py,v 1.8 2006/11/04 21:24:21 digitalxero Exp $" +__version__ = "$Id: miniatures_msg.py,v Traipse 'Ornery-Orc' prof.ebral Exp $" from base_msg import * @@ -79,11 +79,11 @@ def init_from_dom(self,xml_dom): self.p_lock.acquire() - if xml_dom.tagName == self.tagname: - if xml_dom.getAttributeKeys(): - for k in xml_dom.getAttributeKeys(): self.init_prop(k,xml_dom.getAttribute(k)) + if xml_dom.tag == self.tagname: + if xml_dom.keys(): + for k in xml_dom.keys(): self.init_prop(k,xml_dom.get(k)) - for c in xml_dom._get_childNodes(): + for c in xml_dom.getchildren(): mini = mini_msg(self.p_lock) try: mini.init_from_dom(c) except Exception, e: print e; continue @@ -103,10 +103,10 @@ def set_from_dom(self,xml_dom): self.p_lock.acquire() - if xml_dom.tagName == self.tagname: - if xml_dom.getAttributeKeys(): - for k in xml_dom.getAttributeKeys(): self.set_prop(k,xml_dom.getAttribute(k)) - for c in xml_dom._get_childNodes(): + if xml_dom.tag == self.tagname: + if xml_dom.keys(): + for k in xml_dom.keys(): self.set_prop(k,xml_dom.get(k)) + for c in xml_dom.getchildren(): mini = mini_msg(self.p_lock) try: mini.set_from_dom(c) except Exception, e: print e; continue diff -r 4b2884f29a72 -r 81d0bfd5e800 orpg/mapper/region.py --- a/orpg/mapper/region.py Fri Jan 15 22:45:51 2010 -0600 +++ b/orpg/mapper/region.py Sat Jun 12 03:50:37 2010 -0500 @@ -21,9 +21,9 @@ # Author: Mark Tarrabain # Maintainer: # Version: -# $Id: region.py,v 1.10 2006/11/04 21:24:21 digitalxero Exp $ +# $Id: region.py,v Traipse 'Ornery-Orc' prof.ebral Exp $ # -__version__ = "$Id: region.py,v 1.10 2006/11/04 21:24:21 digitalxero Exp $" +__version__ = "$Id: region.py,v Traipse 'Ornery-Orc' prof.ebral Exp $" import sys diff -r 4b2884f29a72 -r 81d0bfd5e800 orpg/mapper/whiteboard.py --- a/orpg/mapper/whiteboard.py Fri Jan 15 22:45:51 2010 -0600 +++ b/orpg/mapper/whiteboard.py Sat Jun 12 03:50:37 2010 -0500 @@ -21,12 +21,12 @@ # Author: Chris Davis # Maintainer: # Version: -# $Id: whiteboard.py,v 1.47 2007/03/09 14:11:55 digitalxero Exp $ +# $Id: whiteboard.py,v Traipse 'Ornery-Orc' prof.ebral Exp $ # # Description: This file contains some of the basic definitions for the chat # utilities in the orpg project. # -__version__ = "$Id: whiteboard.py,v 1.47 2007/03/09 14:11:55 digitalxero Exp $" +__version__ = "$Id: whiteboard.py,v Traipse 'Ornery-Orc' prof.ebral Exp $" from base import * from orpg.mapper.map_utils import * @@ -119,21 +119,21 @@ else: return '' def takedom(self, xml_dom): - self.text_string = xml_dom.getAttribute("text_string") - self.id = xml_dom.getAttribute("id") - if xml_dom.hasAttribute("posy"): self.posy = int(xml_dom.getAttribute("posy")) - if xml_dom.hasAttribute("posx"): self.posx = int(xml_dom.getAttribute("posx")) - if xml_dom.hasAttribute("weight"): - self.weight = int(xml_dom.getAttribute("weight")) + self.text_string = xml_dom.get("text_string") + self.id = xml_dom.get("id") + if xml_dom.get("posy") != None: self.posy = int(xml_dom.get("posy")) + if xml_dom.get("posx") != None: self.posx = int(xml_dom.get("posx")) + if xml_dom.get("weight"): + self.weight = int(xml_dom.get("weight")) self.font.SetWeight(self.weight) - if xml_dom.hasAttribute("style"): - self.style = int(xml_dom.getAttribute("style")) + if xml_dom.get("style") != None: + self.style = int(xml_dom.get("style")) self.font.SetStyle(self.style) - if xml_dom.hasAttribute("pointsize"): - self.pointsize = int(xml_dom.getAttribute("pointsize")) + if xml_dom.get("pointsize") != None: + self.pointsize = int(xml_dom.get("pointsize")) self.font.SetPointSize(self.pointsize) - if xml_dom.hasAttribute("color") and xml_dom.getAttribute("color") != '': - self.textcolor = xml_dom.getAttribute("color") + if xml_dom.get("color") != None and xml_dom.get("color") != '': + self.textcolor = xml_dom.get("color") if self.textcolor == '#0000000': self.textcolor = '#000000' class WhiteboardLine: @@ -231,16 +231,16 @@ return '' def takedom(self, xml_dom): - self.line_string = xml_dom.getAttribute("line_string") - self.id = xml_dom.getAttribute("id") - if xml_dom.hasAttribute("upperleftx"): self.upperleft.x = int(xml_dom.getAttribute("upperleftx")) - if xml_dom.hasAttribute("upperlefty"): self.upperleft.y = int(xml_dom.getAttribute("upperlefty")) - if xml_dom.hasAttribute("lowerrightx"): self.lowerright.x = int(xml_dom.getAttribute("lowerrightx")) - if xml_dom.hasAttribute("lowerrighty"): self.lowerright.y = int(xml_dom.getAttribute("lowerrighty")) - if xml_dom.hasAttribute("color") and xml_dom.getAttribute("color") != '': - self.linecolor = xml_dom.getAttribute("color") + self.line_string = xml_dom.get("line_string") + self.id = xml_dom.get("id") + if xml_dom.get("upperleftx") != None: self.upperleft.x = int(xml_dom.get("upperleftx")) + if xml_dom.get("upperlefty") != None: self.upperleft.y = int(xml_dom.get("upperlefty")) + if xml_dom.get("lowerrightx") != None: self.lowerright.x = int(xml_dom.get("lowerrightx")) + if xml_dom.get("lowerrighty") != None: self.lowerright.y = int(xml_dom.get("lowerrighty")) + if xml_dom.get("color") != None and xml_dom.get("color") != '': + self.linecolor = xml_dom.get("color") if self.linecolor == '#0000000': self.linecolor = '#000000' - if xml_dom.hasAttribute("width"): self.linewidth = int(xml_dom.getAttribute("width")) + if xml_dom.get("width") != None: self.linewidth = int(xml_dom.get("width")) ##----------------------------- ## whiteboard layer @@ -416,13 +416,13 @@ else: return "" def layerTakeDOM(self, xml_dom): - serial_number = xml_dom.getAttribute('serial') - if serial_number != "": self.serial_number = int(serial_number) - children = xml_dom._get_childNodes() + serial_number = xml_dom.get('serial') + if serial_number != None: self.serial_number = int(serial_number) + children = xml_dom.getchildren() for l in children: - nodename = l._get_nodeName() - action = l.getAttribute("action") - id = l.getAttribute('id') + nodename = l.tag + action = l.get("action") + id = l.get('id') try: if self.serial_number < int(id.split('-')[2]): self.serial_number = int(id.split('-')[2]) except: pass @@ -436,17 +436,17 @@ elif action == "new": if nodename == "line": try: - line_string = l.getAttribute('line_string') - upperleftx = l.getAttribute('upperleftx') - upperlefty = l.getAttribute('upperlefty') - lowerrightx = l.getAttribute('lowerrightx') - lowerrighty = l.getAttribute('lowerrighty') + line_string = l.get('line_string') + upperleftx = l.get('upperleftx') + upperlefty = l.get('upperlefty') + lowerrightx = l.get('lowerrightx') + lowerrighty = l.get('lowerrighty') upperleft = wx.Point(int(upperleftx),int(upperlefty)) lowerright = wx.Point(int(lowerrightx),int(lowerrighty)) - color = l.getAttribute('color') + color = l.get('color') if color == '#0000000': color = '#000000' - id = l.getAttribute('id') - width = int(l.getAttribute('width')) + id = l.get('id') + width = int(l.get('width')) except: line_string = upperleftx = upperlefty = lowerrightx = lowerrighty = color = 0 continue @@ -454,15 +454,15 @@ self.lines.append(line) elif nodename == "text": try: - text_string = l.getAttribute('text_string') - style = l.getAttribute('style') - pointsize = l.getAttribute('pointsize') - weight = l.getAttribute('weight') - color = l.getAttribute('color') + text_string = l.get('text_string') + style = l.get('style') + pointsize = l.get('pointsize') + weight = l.get('weight') + color = l.get('color') if color == '#0000000': color = '#000000' - id = l.getAttribute('id') - posx = l.getAttribute('posx') - posy = l.getAttribute('posy') + id = l.get('id') + posx = l.get('posx') + posy = l.get('posy') pos = wx.Point(0,0) pos.x = int(posx) pos.y = int(posy) diff -r 4b2884f29a72 -r 81d0bfd5e800 orpg/mapper/whiteboard_handler.py --- a/orpg/mapper/whiteboard_handler.py Fri Jan 15 22:45:51 2010 -0600 +++ b/orpg/mapper/whiteboard_handler.py Sat Jun 12 03:50:37 2010 -0500 @@ -21,11 +21,11 @@ # Author: OpenRPG Team # Maintainer: # Version: -# $Id: whiteboard_handler.py,v 1.37 2007/03/09 14:11:56 digitalxero Exp $ +# $Id: whiteboard_handler.py,v Traipse 'Ornery-Orc' prof.ebral Exp $ # # Description: Whiteboard layer handler # -__version__ = "$Id: whiteboard_handler.py,v 1.37 2007/03/09 14:11:56 digitalxero Exp $" +__version__ = "$Id: whiteboard_handler.py,v Traipse 'Ornery-Orc' prof.ebral Exp $" from base_handler import * from math import floor, sqrt @@ -57,14 +57,16 @@ def build_ctrls(self): base_layer_handler.build_ctrls(self) - self.color_button = wx.Button(self, wx.ID_ANY, "Pen Color", style=wx.BU_EXACTFIT) + self.color_button = createMaskedButton(self, dir_struct["icon"]+'draw.png', + 'Pen Color', wx.ID_ANY, '#bdbdbd', + wx.BITMAP_TYPE_PNG) self.color_button.SetBackgroundColour(wx.BLACK) self.color_button.SetForegroundColour(wx.WHITE) self.drawmode_ctrl = wx.Choice(self, wx.ID_ANY, choices = ["Freeform", "Polyline","Text", "Cone", "Circle"]) self.drawmode_ctrl.SetSelection(0) #always start showing "Freeform" self.radius = wx.TextCtrl(self, wx.ID_ANY, size=(32,-1) ) self.radius.SetValue("15") - self.live_refresh = wx.CheckBox(self, wx.ID_ANY, " Live Refresh") + self.live_refresh = wx.CheckBox(self, wx.ID_ANY, " Dynamic") self.live_refresh.SetValue(True) self.widthList= wx.Choice(self, wx.ID_ANY, size= wx.Size(40, 20), choices=['1','2','3','4','5','6','7','8','9','10']) @@ -78,7 +80,7 @@ self.sizer.Add(self.radius, 0, wx.EXPAND|wx.ALL, 2) self.sizer.Add(wx.Size(10,25)) self.sizer.Add(self.live_refresh, 0, wx.EXPAND) - self.sizer.Add(wx.Size(20,25)) + self.sizer.Add(wx.Size(10,25)) self.sizer.Add(self.color_button, 0, wx.EXPAND) self.sizer.Add(wx.Size(20,25)) self.Bind(wx.EVT_MOTION, self.on_motion) @@ -754,9 +756,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) diff -r 4b2884f29a72 -r 81d0bfd5e800 orpg/mapper/whiteboard_msg.py --- a/orpg/mapper/whiteboard_msg.py Fri Jan 15 22:45:51 2010 -0600 +++ b/orpg/mapper/whiteboard_msg.py Sat Jun 12 03:50:37 2010 -0500 @@ -21,12 +21,12 @@ # Author: Chris Davis # Maintainer: # Version: -# $Id: whiteboard_msg.py,v 1.12 2007/03/09 14:11:56 digitalxero Exp $ +# $Id: whiteboard_msg.py,v Traipse 'Ornery-Orc' prof.ebral Exp $ # # Description: This file contains some of the basic definitions for the chat # utilities in the orpg project. # -__version__ = "$Id: whiteboard_msg.py,v 1.12 2007/03/09 14:11:56 digitalxero Exp $" +__version__ = "$Id: whiteboard_msg.py,v Traipse 'Ornery-Orc' prof.ebral Exp $" from base_msg import * @@ -80,11 +80,11 @@ def init_from_dom(self,xml_dom): self.p_lock.acquire() - if xml_dom.tagName == self.tagname: - if xml_dom.getAttributeKeys(): - for k in xml_dom.getAttributeKeys(): self.init_prop(k,xml_dom.getAttribute(k)) - for c in xml_dom._get_childNodes(): - item = item_msg(self.p_lock,c._get_nodeName()) + if xml_dom.tag == self.tagname: + if xml_dom.keys(): + for k in xml_dom.keys(): self.init_prop(k,xml_dom.get(k)) + for c in xml_dom.getchildren(): + item = item_msg(self.p_lock,c.tag) try: item.init_from_dom(c) except Exception, e: print e @@ -105,11 +105,11 @@ def set_from_dom(self,xml_dom): self.p_lock.acquire() - if xml_dom.tagName == self.tagname: - if xml_dom.getAttributeKeys(): - for k in xml_dom.getAttributeKeys(): self.set_prop(k,xml_dom.getAttribute(k)) - for c in xml_dom._get_childNodes(): - item = item_msg(self.p_lock, c._get_nodeName()) + if xml_dom.tag == self.tagname: + if xml_dom.keys(): + for k in xml_dom.keys(): self.set_prop(k,xml_dom.get(k)) + for c in xml_dom.getchildren(): + item = item_msg(self.p_lock, c.tag) try: item.set_from_dom(c) except Exception, e: print e diff -r 4b2884f29a72 -r 81d0bfd5e800 orpg/networking/gsclient.py --- a/orpg/networking/gsclient.py Fri Jan 15 22:45:51 2010 -0600 +++ b/orpg/networking/gsclient.py Sat Jun 12 03:50:37 2010 -0500 @@ -21,13 +21,13 @@ # Author: Chris Davis # Maintainer: # Version: -# $Id: gsclient.py,v 1.53 2007/10/25 21:49:34 digitalxero Exp $ +# $Id: gsclient.py,v Traipse 'Ornery-Orc' prof.ebral Exp $ # # Description: The file contains code for the game server browser # from __future__ import with_statement -__version__ = "$Id: gsclient.py,v 1.53 2007/10/25 21:49:34 digitalxero Exp $" +__version__ = "$Id: gsclient.py,v Traipse 'Ornery-Orc' prof.ebral Exp $" import meta_server_lib import orpg.tools.rgbhex @@ -269,7 +269,6 @@ address = self.svrList[item].addy port = self.svrList[item].port self.server_list.SetItemImage(item, 1) - for server in self.bookmarks.findall('server'): if server.get('name') == name: self.bookmarks_menu.Remove( @@ -298,8 +297,8 @@ except: pass address = self.texts["address"].GetValue() if self.session.is_connected(): - if self.session.host_server == address : return #currently connected to address. Do nothing. - else: self.frame.kill_mplay_session() #address differs, disconnect. + if self.session.host_server == address : return + else: self.frame.kill_mplay_session() self.do_connect(address) def on_room_dbclick(self, evt=None): @@ -307,13 +306,11 @@ try: self.on_select(evt) except: pass group_id = str(self.room_list.GetItemData(self.cur_room_index)) - if self.NoGroups: self.NoGroups = False self.session.group_id = group_id self.on_server_dbclick() return - if self.cur_room_index >= 0: if self.cur_room_index != 0: self.set_lobbybutton(1); else: self.set_lobbybutton(0); @@ -345,7 +342,6 @@ def on_text(self, evt): id = evt.GetId() if (id == self.texts["address"].GetValue()) and (self.cur_server_index >= 0): - #print "ADDRESS id = ", id, "index = ", self.cur_server_index self.cur_server_index = -1 evt.Skip() @@ -526,17 +522,13 @@ self.texts["address"].SetValue("127.0.0.1:6774") self.serverNameSet = 1 else: pass - # Allow xml_dom to be collected except Exception, e: print "Server List not available." traceback.print_exc() - - + def failed_connection(self): if(self.cur_server_index >= 0): server_index = self.servers[self.cur_server_index] - # post_failed_connection will return a non-zero if the server - # was removed. If it was, refresh the display if(meta_server_lib.post_failed_connection(server_index.get('id'), meta=server_index.get('meta'), address=server_index.get('address'), port=server_index.get('port'))): @@ -613,11 +605,9 @@ msg = "%s is creating room \'%s.\'" % (self.session.name, name) self.session.send(msg) self.session.send_create_group(name, pwd, boot_pwd, minversion) - self.set_lobbybutton(1); #enable the Lobby quickbutton + self.set_lobbybutton(1); def on_size(self, evt): - # set column widths for room list - # set column widths for server list pass def colorize_group_list(self, groups): diff -r 4b2884f29a72 -r 81d0bfd5e800 orpg/networking/meta_server_lib.py --- a/orpg/networking/meta_server_lib.py Fri Jan 15 22:45:51 2010 -0600 +++ b/orpg/networking/meta_server_lib.py Sat Jun 12 03:50:37 2010 -0500 @@ -22,14 +22,14 @@ # Author: Chris Davis # Maintainer: # Version: -# $Id: meta_server_lib.py,v 1.40 2007/04/04 01:18:42 digitalxero Exp $ +# $Id: meta_server_lib.py,v Traipse 'Ornery-Orc' prof.ebral Exp $ # # Description: A collection of functions to communicate with the meta server. # #added debug flag for meta messages to cut console server spam --Snowdog -META_DEBUG = 0 +META_DEBUG = False __version__ = "$Id: meta_server_lib.py,v 1.40 2007/04/04 01:18:42 digitalxero Exp $" @@ -39,22 +39,18 @@ from orpg.dirpath import dir_struct import urllib, time, sys, traceback, re -#import orpg.minidom from threading import * from random import uniform +import urllib2 from urllib import urlopen, urlencode from orpg.tools.orpg_log import debug -from xml.etree.ElementTree import Element, fromstring - +from xml.etree.ElementTree import Element, fromstring, parse, tostring metacache_lock = RLock() -def get_server_dom(data=None,path=None, string=False): - # post data at server and get the resulting DOM - if path == None: - # get meta server URI - path = getMetaServerBaseURL() +def get_server_dom(data=None, path=None, string=False): + if path[len(path)-1] != "/": path += '/' # POST the data if META_DEBUG: @@ -63,9 +59,9 @@ print "==========================================" print data print - file = urlopen(path, data) - data = file.read() - file.close() + #recvdata = urllib2.Request(path, data) + response = urllib2.urlopen(path, data) + data = response.read() # Remove any leading or trailing data. This can happen on some satellite connections p = re.compile('(.*?)',re.DOTALL|re.IGNORECASE) @@ -79,9 +75,8 @@ print data print # build dom - etreeEl = data - if not string: return fromstring(etreeEl) - else: return etreeEl + if string: return data + else: return fromstring(data) def post_server_data(name, realHostName=None): if realHostName: data = urlencode({"server_data[name]":name, @@ -92,7 +87,7 @@ else: data = urlencode({"server_data[name]":name, "server_data[version]":PROTOCOL_VERSION, "act":"new"}) - path = component.get('settings').get('MetaServerBaseURL') #getMetaServerBaseURL() + path = component.get('settings').get('MetaServerBaseURL') #getMetaServerList() etreeEl = get_server_dom(data, path) return int(etreeEl.get('id')) @@ -113,49 +108,38 @@ def byStartAttribute(first, second): # This function is used to easily sort a list of nodes by their start time # Ensure there is something to sort with for each - first_start = int(first.get('start')) or 0 second_start = int(second.get('start')) or 0 - # Return the result of the cmp function on the two strings return cmp(first_start, second_start) def byNameAttribute(first, second): # This function is used to easily sort a list of nodes by their name attribute # Ensure there is something to sort with for each - first_name = first.get('name') or '' second_name = second.get('name') or '' - # Return the result of the cmp function on the two strings return cmp(first_name,second_name) -def get_server_list(versions = None, sort_by="start"): +def get_server_list(versions=None, sort_by="start"): data = urlencode({"version":PROTOCOL_VERSION,"ports":"%"}) - all_metas = getMetaServers(versions, 1) # get the list of metas - base_meta = getMetaServerBaseURL() - + #all_metas = getMetaServers(versions, False) # get the list of metas + meta_list = getMetaServerList() #all_metas.reverse() # The last one checked will take precedence, so reverse the order # so that the top one on the actual list is checked last return_hash = {} # this will end up with an amalgamated list of servers - for meta in all_metas: # check all of the metas + for meta in meta_list: # check all of the metas #get the server's xml from the current meta bad_meta = 0 #print "Getting server list from " + meta + "..." - try: xml_dom = get_server_dom(data=data, path=meta) - except: bad_meta = 1 #print "Trouble getting servers from " + meta + "..." + try: xml_dom = get_server_dom(data, meta.get('url')) + except: bad_meta = 1; print "Trouble getting servers from " + meta.get('url') + "..." if bad_meta: continue - if base_meta == meta: updateMetaCache(xml_dom) #print "This is our base meta: " + meta node_list = xml_dom.findall('server') - if len(node_list): # if there are entries in the node list - # otherwise, just loop to next meta - - # for each node found, we're going to check the nodes from prior - # metas in the list. If a match is found, then use the new values. + if len(node_list): for n in node_list: - # set them from current node if not n.get('name'): n.set('name','NO_NAME_GIVEN') name = n.get('name') if not n.get('num_users'): n.set('num_users','N/A') @@ -167,24 +151,15 @@ n.set('meta',meta) end_point = str(address) + ":" + str(port) if return_hash.has_key(end_point): + print end_point + print n + if META_DEBUG: print "Replacing duplicate server entry at " + end_point return_hash[end_point] = n - - # At this point, we have an amalgamated list of servers - # Now, we have to construct a new DOM to pass back. - - # Create a servers element server_list = Element('servers') - - # get the nodes stored in return_hash sort_list = return_hash.values() - - # sort them by their name attribute. Uses byNameAttribute() - # defined above as a comparison function if sort_by == "start": sort_list.sort(byStartAttribute) elif sort_by == "name": sort_list.sort(byNameAttribute) - - # Add each node to the DOM for n in sort_list: server_list.append(n) return server_list @@ -218,121 +193,32 @@ if META_DEBUG: traceback.print_exc() print "Meta Server Lib: UpdateMetaCache(): " + str(e) -def getRawMetaList(path=None): - ### Alpha ### - """This code will allow for a list of metas to be created. Future developement will more integrate the list of metas""" - if path != None: - metas = [] - data = urlencode({"version":PROTOCOL_VERSION,"ports":"%"}) - xml_dom = get_server_dom(data, path) - node_list = fromstring(xml_dom).findall('meta_server') - if len(node_list): - for n in node_list: - metas.append(n.get('path')) - return metas + +def getMetaServerList(): + # get meta server URL + meta_list = fromstring(""" + + + + """ + ) try: - try: - metacache_lock.acquire() - # Read in the metas - validate.config_file("metaservers.cache","metaservers.cache") - ini = open(dir_struct["user"]+"metaservers.cache","r") - metas = ini.readlines() - ini.close() - return metas - finally: - metacache_lock.release() - except Exception, e: - if META_DEBUG: traceback.print_exc() - print "Meta Server Lib: getRawMetaList(): " + str(e) - return [] - -def getMetaServers(versions = None, pick_random=0): - """ - get meta server URLs as a list - versions is a list of acceptable version numbers. - A False truth value will use getMetaServerBaseURL() - set a default if we have weird reading problems - default_url = "http://www.openrpg.com/openrpg_servers.php" - """ - - ### Pre Alpha Design ### - """ Here is how to handle Multiple Meta servers, and probably the best way to do it. Create an XML file that contains nodes with the various servers. Users will grab that meta data and have the option to connect to multiple meta servers which will allow them to find all the rooms. A check box should be used so if one server faile the users can continue without much lag. When creating a server hosts will need to select a meta to go too. This should be in the final of Ornery Orc.""" - meta_names = [] - if(versions): # If versions are supplied, then look in metaservers.conf - try: - """ - read in the metas from file - format of file is one meta entry per line - each entry will be the meta url, followed by one or more version numbers that it - handle. Generally, this will be either a 1 for the original Meta format, or - 2 for the new one. - """ - # Read in the metas - #Adding a path object will attempt to look for a meta_network. - metas = getRawMetaList() - - # go through each one to check if it should be returned, based on the - # version numbers allowed. - for meta in metas: - # split the line on whitespace - # obviously, your meta servers urls shouldn't contain whitespace. duh. - words = meta.split() - success = 0 # init success flag for version check - for version in versions: # run through each allowed version from caller - if version in words[1:]: # if the allowed version token was found - success += 1 # then increment the success indicator - if success: # if the meta entry is acceptable to the caller - meta_names.append(words[0]) # add the entry - if META_DEBUG: print "adding metaserver " + meta - - # at this point, we should have at least one name from the cache. If not ... - if not meta_names: - default_meta = getMetaServerBaseURL() # grab the meta from ini.xml - meta_names.append(default_meta) # add it to the return list - # print "Warning!!\nNo valid metaservers cached." - # print "Using meta from MetaServerBaseURL: " + default_meta + "\n" - # if we have more than one and want a random one - elif pick_random: - if META_DEBUG: print "choosing random meta from: " + str(meta_names) - i = int(uniform(0,len(meta_names))) - #meta = meta_names[i] - meta_names = [meta_names[i]] - if META_DEBUG: print "using: " + str(meta_names) - else: - if META_DEBUG: print "using all metas: " + str(meta_names) - return meta_names - except Exception,e: - print e - #print "using default meta server URI: " + default_url - metas = [] - #metas.append(default_url) - return metas # return an empty list - else: # otherwise, use MetaServerBaseURL() - url = getMetaServerBaseURL() - meta_names.append(url) - return meta_names - -def getMetaServerBaseURL(): - # get meta server URL - url = "http://www.openrpg.com/openrpg_servers.php" - try: + component.get('validate').config_file("metaservers.xml","default_metaservers.xml") component.get('validate').config_file("settings.xml","default_settings.xml") - ini = open(dir_struct["user"]+"settings.xml","r") - txt = ini.read() - xml = component.get('xml') - tree = xml.parseXml(txt)._get_documentElement() - ini.close() - node_list = tree.getElementsByTagName("MetaServerBaseURL") - if node_list: - url = node_list[0].getAttribute("value") - # allow tree to be collected - try: tree.unlink() - except: pass - - except Exception,e: - print e - #print "using meta server URI: " + url - return url + setting = parse(dir_struct["user"]+"settings.xml") + tree = setting.getroot() + node_list = tree.getiterator("MetaServers") + if len(node_list) == 0: + component.get('frame').add_setting('Meta Servers') + setting = parse(dir_struct["user"]+"settings.xml") + metas = parse(dir_struct["user"]+'metaservers.xml').getroot() + else: + meta = node_list[0].get("value") + metas = parse(dir_struct["user"]+meta).getroot() + meta_list = metas.findall('meta') + return meta_list + except Exception,e: print e + return meta_list """ Beginning of Class registerThread @@ -397,7 +283,7 @@ it easier to have multiple registerThreads going to keep the server registered on multiple (compatible) Metas. """ - if MetaPath == None: self.path = getMetaServerBaseURL() # Do this if no Meta specified + if MetaPath == None: self.path = getMetaServerList() # Do this if no Meta specified else: self.path = MetaPath def getIdAndCookie(self): @@ -470,16 +356,18 @@ if not self.isAlive(): # check to see if this thread is dead return 1 # If so, return an error result # Do the actual unregistering here - data = urlencode( {"server_data[id]":self.id, + data = urlencode( { "server_data[id]":self.id, "server_data[cookie]":self.cookie, "server_data[version]":PROTOCOL_VERSION, "act":"unregister"} ) - try: # this POSTS the request and returns the result - xml_dom = get_server_dom(data=data, path=self.path) - if xml_dom.get("errmsg"): - print "Error durring unregistration: " + xml_dom.get("errmsg") - except: - if META_DEBUG: print "Problem talking to Meta. Will go ahead and die, letting Meta remove us." + for path in getMetaServerList(): + try: # this POSTS the request and returns the result + etreeEl = get_server_dom(data, path.get('url')) + if etreeEl.get("errmsg") != None: + print "Error durring unregistration: " + etreeEl.get("errmsg") + except Exception, e: + if META_DEBUG: print "Problem talking to Meta. Will go ahead and die, letting Meta remove us." + if META_DEBUG: print e # If there's an error, echo it to the console # No special handling is required. If the de-registration worked we're done. If @@ -510,11 +398,14 @@ # Set the server's attibutes, if specified. if name: self.name = name - if num_users != None: self.num_users = num_users + if num_users != None: + try: self.num_users = len(num_users) + except: self.num_users = num_users; print num_users + else: self.num_users = 0 if realHostName: self.realHostName = realHostName # build POST data if self.realHostName: - data = urlencode( {"server_data[id]":self.id, + data = urlencode( { "server_data[id]":self.id, "server_data[cookie]":self.cookie, "server_data[name]":self.name, "server_data[port]":self.port, @@ -524,38 +415,40 @@ "server_data[address]": self.realHostName } ) else: if META_DEBUG: print "Letting meta server decide the hostname to list..." - data = urlencode( {"server_data[id]":self.id, + data = urlencode( { "server_data[id]":self.id, "server_data[cookie]":self.cookie, "server_data[name]":self.name, "server_data[port]":self.port, "server_data[version]":PROTOCOL_VERSION, "server_data[num_users]":self.num_users, "act":"register"} ) - try: # this POSTS the request and returns the result - etreeEl = get_server_dom(data=data, path=self.path) - except: - if META_DEBUG: print "Problem talking to server. Setting interval for retry ..." - if META_DEBUG: print data - if META_DEBUG: print - self.interval = 0 - """ - If we are in the registerThread thread, then setting interval to 0 - will end up causing a retry in about 6 seconds (see self.run()) - If we are in the main thread, then setting interval to 0 will do one - of two things: - 1) Do the same as if we were in the registerThread - 2) Cause the next, normally scheduled register() call to use the values - provided in this call. - - Which case occurs depends on where the registerThread thread is when - the main thread calls register(). - """ - return 0 # indicates that it was okay to call, not that no errors occurred + for path in getMetaServerList(): + try: # this POSTS the request and returns the result + etreeEl = get_server_dom(data, path.get('url')) + except Exception, e: + if META_DEBUG: print "Problem talking to server. Setting interval for retry ..." + if META_DEBUG: print data + if META_DEBUG: print e + self.interval = 0 + """ + If we are in the registerThread thread, then setting interval to 0 + will end up causing a retry in about 6 seconds (see self.run()) + If we are in the main thread, then setting interval to 0 will do one + of two things: + 1) Do the same as if we were in the registerThread + 2) Cause the next, normally scheduled register() call to use the values + provided in this call. + + Which case occurs depends on where the registerThread thread is when + the main thread calls register(). + """ + return 0 # indicates that it was okay to call, not that no errors occurred # If there is a DOM returned .... - if etreeEl: + if etreeEl != None: # If there's an error, echo it to the console - if etreeEl.get("errmsg"): + print tostring(etreeEl) + if etreeEl.get("errmsg") != None: print "Error durring registration: " + etreeEl.get("errmsg") if META_DEBUG: print data if META_DEBUG: print @@ -581,11 +474,12 @@ self.interval = int(etreeEl.get("interval")) self.id = etreeEl.get("id") self.cookie = etreeEl.get("cookie") - if not etreeEl.get("errmsg"): updateMetaCache(xml_dom) - except: + #if etreeEl.get("errmsg") == None: updateMetaCache(xml_dom) + except Exception, e: if META_DEBUG: print if META_DEBUG: print "OOPS! Is the Meta okay? It should be returning an id, cookie, and interval." if META_DEBUG: print "Check to see what it really returned.\n" + if META_DEBUG: print e # Let xml_dom get garbage collected try: xml_dom.unlink() except: pass diff -r 4b2884f29a72 -r 81d0bfd5e800 orpg/networking/mplay_client.py --- a/orpg/networking/mplay_client.py Fri Jan 15 22:45:51 2010 -0600 +++ b/orpg/networking/mplay_client.py Sat Jun 12 03:50:37 2010 -0500 @@ -21,16 +21,14 @@ # Author: Chris Davis # Maintainer: # Version: -# $Id: mplay_client.py,v 1.71 2007/05/12 20:41:54 digitalxero Exp $ +# $Id: mplay_client.py,v Traipse 'Ornery-Orc' prof.ebral Exp $ # # Description: This file contains the code for the client stubs of the multiplayer # features in the orpg project. # -__version__ = "$Id: mplay_client.py,v 1.71 2007/05/12 20:41:54 digitalxero Exp $" +__version__ = "$Id: mplay_client.py,v Traipse 'Ornery-Orc' prof.ebral Exp $" -### Alpha ### -##import orpg.minidom ## Deprecated. xml.parseXml calls minidom.parseString so it was superfluous and wasteful. import socket, Queue, thread, traceback, errno, os, time from threading import Event, Lock @@ -40,7 +38,7 @@ from orpg.orpg_version import CLIENT_STRING, PROTOCOL_VERSION, VERSION from orpg.orpgCore import component -from orpg.orpg_xml import xml +#from orpg.orpg_xml import xml from orpg.tools.orpg_log import debug from orpg.tools.settings import settings @@ -83,6 +81,7 @@ STATUS_SET_URL = 1 def parseXml(data): + debug(('Developers note. Deprecated call to parseXml!!'), parents=True) "parse and return doc" doc = xml.parseXml(data) doc.normalize() @@ -123,7 +122,7 @@ self.ROLE_LURKER = "Lurker" ## --TaS try: self.ip = socket.gethostbyname(socket.gethostname()) - except: self.ip = socket.gethostbyname('localhost') + except: self.ip = socket.gethostbyname('localhost') self.remote_ip = None self.version = VERSION self.protocol_version = PROTOCOL_VERSION @@ -389,7 +388,6 @@ def __init__(self,name,callbacks): client_base.__init__(self) component.add('mp_client', self) - self.xml = component.get('xml') self.set_name(name) self.on_receive = callbacks['on_receive'] self.on_mplay_event = callbacks['on_mplay_event'] @@ -625,7 +623,6 @@ el.set('from', self.id) el.set('pwd', pwd) el.set('group_id', str(group_id)) - self.outbox.put(tostring(el)) def poll(self, evt=None): @@ -766,7 +763,6 @@ self.on_player_event(mplay_event(PLAYER_DEL, self.players[id])) if self.players.has_key(id): del self.players[id] if id == self.id: self.do_disconnect() - # the next two cases handle the events that are used to let you know when others are typing elif act == "update": if id == self.id: self.players[id] = player @@ -842,7 +838,7 @@ outgoing = self.toxml('del') if iselement(outgoing): outgoing = tostring(outgoing) self.outbox.put(outgoing) - ## Client Side Disconect Forced -- Snowdog 10-09-2003 + ## Client Side Disconnect Forced -- Snowdog 10-09-2003 #pause to allow GUI events time to sync. time.sleep(1) self.do_disconnect() @@ -862,3 +858,4 @@ self.unique_cookie += 1 return_str = self.id + "-" + str(self.unique_cookie) return return_str + diff -r 4b2884f29a72 -r 81d0bfd5e800 orpg/networking/mplay_messaging.py --- a/orpg/networking/mplay_messaging.py Fri Jan 15 22:45:51 2010 -0600 +++ b/orpg/networking/mplay_messaging.py Sat Jun 12 03:50:37 2010 -0500 @@ -21,24 +21,20 @@ # Author: Dj Gilcrease # Maintainer: # Version: -# $Id: mplay_messaging.py,v 1.5 2007/05/06 16:42:59 digitalxero Exp $ +# $Id: mplay_messaging.py,v Traipse 'Ornery-Orc' prof.ebral Exp $ # # Description: This file contains the code for the client / server messaging # -__version__ = "$Id: mplay_messaging.py,v 1.5 2007/05/06 16:42:59 digitalxero Exp $" +__version__ = "$Id: mplay_messaging.py,v Traipse 'Ornery-Orc' prof.ebral Exp $" -import socket -import Queue -import thread -import traceback +import socket, Queue, thread, traceback, os, time + from threading import Event, Lock from xml.sax.saxutils import escape from struct import pack, unpack, calcsize from string import * from orpg.orpg_version import VERSION, PROTOCOL_VERSION, CLIENT_STRING, SERVER_MIN_CLIENT_VERSION -import os -import time from orpg.tools.orpg_log import logger from orpg.orpgCore import component @@ -91,20 +87,6 @@ self.players = {} self.groups = {} - #Setup Stuff from the Server - """ - if kwargs.has_key('inbox'): self.inbox = kwargs['inbox'] - if kwargs.has_key('sock'): self.sock = kwargs['sock'] - if kwargs.has_key('ip'): self.ip = kwargs['ip'] - if kwargs.has_key('role'): self.role = kwargs['role'] - if kwargs.has_key('id'): self.id = kwargs['id'] - if kwargs.has_key('group_id'): self.group_id = kwargs['group_id'] - if kwargs.has_key('name'): self.name = kwargs['name'] - if kwargs.has_key('version'): self.version = kwargs['version'] - if kwargs.has_key('protocol_version'): self.protocol_version = kwargs['protocol_version'] - if kwargs.has_key('client_string'): self.client_string = kwargs['client_string'] - """ - ### Alpha ### self.inbox = kwargs['inbox'] or pass self.sock = kwargs['sock'] or pass @@ -207,7 +189,6 @@ def __str__(self): return "%s(%s)\nIP:%s\ngroup_id:%s\n%s (%s)" % (self.name, self.id, self.ip, self.group_id, self.idle_time(), self.connected_time()) - # idle time functions added by snowdog 3/31/04 def update_idle_time(self): self.lastmessagetime = time.time() @@ -326,7 +307,6 @@ #Message Action thread expires and closes here. return - #Privet functions def sendThread( self, arg ): "Sending thread. This thread reads from the data queue and writes to the socket." # Wait to be told it's okay to start running @@ -352,11 +332,7 @@ def sendMsg( self, sock, msg ): """Very simple function that will properly encode and send a message to te remote on the specified socket.""" - - # Calculate our message length length = len( msg ) - - # Encode the message length into network byte order lp = pack( 'i', socket.htonl( length ) ) try: @@ -434,13 +410,11 @@ msgData = "" try: lenData = self.recvData( sock, self.lensize ) - # Now, convert to a usable form (length,) = unpack( 'i', lenData ) length = socket.ntohl( length ) # Read exactly the remaining amount of data msgData = self.recvData( sock, length ) - if self.isServer: logger.debug("('data_recv', " + str(length+4) + ")") except: logger.exception("Exception: messenger->recvMsg():\n" + traceback.format_exc()) return msgData @@ -448,3 +422,4 @@ if __name__ == "__main__": test = messenger(None) print test.build_message('hello', "This is a test message", attrib1="hello world", attrib2="hello world2", attrib3="hello world3") + diff -r 4b2884f29a72 -r 81d0bfd5e800 orpg/networking/mplay_server.py --- a/orpg/networking/mplay_server.py Fri Jan 15 22:45:51 2010 -0600 +++ b/orpg/networking/mplay_server.py Sat Jun 12 03:50:37 2010 -0500 @@ -22,7 +22,7 @@ # Author: Chris Davis # Maintainer: # Version: -# $Id: mplay_server.py,v 1.155 2008/01/24 03:52:03 digitalxero Exp $ +# $Id: mplay_server.py,v Traipse 'Ornery-Orc' prof.ebral Exp $ # # Description: This file contains the code for the server of the multiplayer # features in the orpg project. @@ -33,7 +33,7 @@ from __future__ import with_statement -__version__ = "$Id: mplay_server.py,v 1.155 2008/01/24 03:52:03 digitalxero Exp $" +__version__ = "$Id: mplay_server.py,v Traipse 'Ornery-Orc' prof.ebral Exp $" #!/usr/bin/env python """ @@ -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) @@ -325,6 +325,7 @@ self.saveBanList() except Exception, e: self.log_msg("Exception in initBanList() " + str(e)) + self.log_msg( ('exception', str(e)) ) # This method writes out the server's ban list added by Darren def saveBanList( self ): @@ -343,6 +344,7 @@ file.close() except Exception, e: self.log_msg("Exception in saveBanList() " + str(e)) + self.log_msg( ('exception', str(e)) ) # This method reads in the server's configuration file and reconfigs the server # as needed, over-riding any default values as requested. @@ -526,6 +528,7 @@ except Exception, e: traceback.print_exc() self.log_msg("Exception in initServerConfig() " + str(e)) + self.log_msg( ('exception', str(e)) ) def makePersistentRooms(self): 'Creates rooms on the server as defined in the server config file.' @@ -571,6 +574,7 @@ return pr except: self.log_msg("Exception occured in isPersistentRoom(self,id)") + self.log_msg( ('exception', str(e)) ) return 0 #----------------------------------------------------- @@ -612,7 +616,7 @@ def register_callback(instance, xml_dom = None, source=None): if xml_dom: # if we get something - if source == getMetaServerBaseURL(): # if the source of this DOM is the authoritative meta + if source == getMetaServerList(): # if the source of this DOM is the authoritative meta try: metacache_lock.acquire() curlist = getRawMetaList() # read the raw meta cache lines into a list @@ -644,21 +648,22 @@ def registerRooms(self, args=None): rooms = '' - id = '0' - time.sleep(500) - for rnum in self.groups.keys(): - rooms += urllib.urlencode( {"room_data[rooms][" + str(rnum) + "][name]":self.groups[rnum].name, - "room_data[rooms][" + str(rnum) + "][pwd]":str(self.groups[rnum].pwd != "")})+'&' - for pid in self.groups[rnum].players: - rooms += urllib.urlencode( {"room_data[rooms][" + str(rnum) + "][players]["+str(pid)+"]":self.players[pid].name,})+'&' + serverId = '0' + x = 0 for meta in self.metas.keys(): - while id == '0': - id, cookie = self.metas[meta].getIdAndCookie() - data = urllib.urlencode( {"room_data[server_id]":id, - "act":'registerrooms'}) - get_server_dom(data+'&'+rooms, self.metas[meta].path, string=True) + while serverId == '0': + serverId, cookie = self.metas[meta].getIdAndCookie() + if serverId != '0': + for rnum in self.groups.keys(): + rooms += urllib.urlencode({"room_data[rooms][" +str(rnum)+ "][name]":self.groups[rnum].name, + "room_data[rooms][" +str(rnum)+ "][pwd]":str(self.groups[rnum].pwd != ""), + "room_data[rooms][" +str(rnum)+ "][players]":str(len(self.groups[rnum].players)) + })+'&' + data = urllib.urlencode({"room_data[server_id]":serverId, + "act":'registerrooms'}) + get_server_dom(data+'&'+rooms, meta.get('url'), string=True) - def register(self,name_given=None): + def register(self, name_given=None): if name_given == None: name = self.name else: self.name = name = name_given name = self.clean_published_servername(name) @@ -668,11 +673,10 @@ else: num_players = 0 # request only Meta servers compatible with version 2 - metalist = getMetaServers(versions=["2"]) + metalist = getMetaServerList() if self.show_meta_messages != 0: self.log_msg("Found these valid metas:") - for meta in metalist: self.log_msg("Meta:" + meta) - + for meta in metalist: self.log_msg("Meta:" + meta.get('url')) """ # Go through the list and see if there is already a running register # thread for the meta. @@ -682,7 +686,6 @@ # iterate through the currently running metas and prune any # not currently listed in the Meta Server list. """ - if self.show_meta_messages != 0: self.log_msg( "Checking running register threads for outdated metas.") for meta in self.metas.keys(): if self.show_meta_messages != 0: self.log_msg("meta:" + meta + ": ") @@ -695,7 +698,7 @@ # Now call register() for alive metas or start one if we need one for meta in metalist: - if self.metas.has_key(meta) and self.metas[meta] and self.metas[meta].isAlive(): + if (self.metas.has_key(meta) and self.metas[meta] and self.metas[meta].isAlive()): self.metas[meta].register(name=name, realHostName=self.server_address, num_users=num_players) @@ -775,8 +778,8 @@ try: sentl = sock.send( lp ) # Send the encoded length sentm = sock.send( msg ) # Now, send the message the the length was describing - except socket.error, e: self.log_msg( e ) - except Exception, e: self.log_msg( e ) + except socket.error, e: self.log_msg( ('exception', str(e)) ); self.log_msg( e ) + except Exception, e: self.log_msg( e ); self.log_msg( ('exception', str(e)) ) def recvData( self, sock, readSize ): @@ -818,7 +821,7 @@ try: if useCompression and cmpType != None: msgData = cmpType.decompress(msgData) except: traceback.print_exc() - except Exception, e: self.log_msg( "Exception: recvMsg(): " + str(e) ) + except Exception, e: self.log_msg( "Exception: recvMsg(): " + str(e) ); self.log_msg( ('exception', str(e)) ) return msgData def kill_server(self): @@ -886,8 +889,14 @@ print "'help' or '?' or 'h' - for this help message" print - def broadcast(self,msg): - self.send_to_all("0","" + msg + "") + def broadcast(self, msg): + broadcast = '' +msg+ '' + chat = Element('chat') + chat.set('type', '1') + chat.set('version', '1.0') + chat.text = broadcast + msg = self.buildMsg('all', '0', '1', tostring(chat)) + self.send_to_all('0', msg) def console_log(self): if self.log_to_console == 1: @@ -910,6 +919,7 @@ print except Exception, e: self.log_msg(str(e)) + self.log_msg( ('exception', str(e)) ) self.p_lock.release() """ @@ -996,6 +1006,7 @@ print except Exception, e: self.log_msg(str(e)) + self.log_msg( ('exception', str(e)) ) self.p_lock.release() """ @@ -1028,6 +1039,7 @@ print "\nStatistics: groups: " + str(len(self.groups)) + " players: " + str(len(self.players)) except Exception, e: self.log_msg(str(e)) + self.log_msg( ('exception', str(e)) ) self.p_lock.release() @@ -1045,6 +1057,7 @@ print "Bad Player Ref (#" + id + ") in group" except Exception, e: self.log_msg(str(e)) + self.log_msg( ('exception', str(e)) ) self.p_lock.release() def update_request(self,newsock, xml_dom): @@ -1069,7 +1082,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,22 +1114,24 @@ # 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:
" - bad_xml_string += "OpenRPG bugs " - bad_xml_string += "(http://sourceforge.net/tracker/?group_id=2237&atid=102237)
" - self.sendMsg( newsock, "" + bad_xml_string, - new_stub.useCompression, new_stub.compressionType) + bad_xml_string += "Traipse-Dev " + bad_xml_string += "(http://www.assembla.com/spaces/traipse_dev/tickets/)
" + msg = self.buildMsg(props['id'], props['id'], '0', bad_xml_string) + self.sendMsg( newsock, msg, new_stub.useCompression, new_stub.compressionType) time.sleep(2) newsock.close() print "Error in parse found from " + str(remote_host) + ". Disconnected." print " Offending data(" + str(len(data)) + "bytes)=" + data print "Exception=" + str(e) + self.log_msg( ('exception', str(e)) ) #if xml_dom: xml_dom.unlink() return @@ -1195,11 +1210,9 @@ self.log_msg(("update_group", (self.groups[LOBBY_ID].name, LOBBY_ID, len(self.groups[LOBBY_ID].players) ) )) cmsg = ("connect", props) ################################################# self.log_msg(cmsg) - - # If already registered then re-register, thereby updating the Meta - # on the number of players - if self.be_registered: - self.register() + for meta in self.metas.keys(): + self.metas[meta].num_users = len(self.players) + thread.start_new_thread(self.registerRooms,(0,)) except: traceback.print_exc() @@ -1214,7 +1227,7 @@ newsock.close() # Display the lobby message - self.SendLobbyMessage(newsock,props['id']) + self.SendLobbyMessage(newsock, props['id']) def checkClientVersion(self, clientversion): minv = self.minClientVersion.split('.') @@ -1234,8 +1247,9 @@ # prepend this server's version string to the the lobby message """ try: - lobbyMsg = "You have connected to an OpenRPG " - lobbyMsg += "server, version '" + VERSION + "'" + lobbyMsg = "You have connected to a " + lobbyMsg += DISTRO +' '+ 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 +1264,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, "" + lobbyMsg, self.players[player_id].useCompression, self.players[player_id].compressionType) @@ -1275,6 +1288,7 @@ except Exception, e: self.log_msg(("Error binding request socket!", e)) + self.log_msg( ('exception', str(e)) ) self.alive = 0 while self.alive: @@ -1291,9 +1305,10 @@ """ thread.start_new_thread(self.acceptedNewConnectionThread, ( newsock, addr )) - except: + except Exception, e: print "The following exception caught accepting new connection:" traceback.print_exc() + self.log_msg( ('exception', str(e)) ) # At this point, we're done and cleaning up. self.log_msg("server socket listening thread exiting...") @@ -1314,6 +1329,7 @@ try: newsock.close() except Exception, e: self.log_msg( str(e) ) + self.log_msg( ('exception', str(e)) ) print str(e) return #returning causes connection thread instance to terminate if data == "": @@ -1335,10 +1351,11 @@ except: try: newsock.close() - except: pass + except Exception, e: pass self.log_msg( "Error in parse found from " + str(addr) + ". Disconnected.") self.log_msg(" Offending data(" + str(len(data)) + "bytes)=" + data) self.log_msg( "Exception:") + self.log_msg( ('exception', str(e)) ) traceback.print_exc() return #returning causes connection thread instance to terminate @@ -1356,6 +1373,7 @@ print "The following message: " + str(data) print "from " + str(addr) + " created the following exception: " traceback.print_exc() + self.log_msg( ('exception', str(e)) ) return #returning causes connection thread instance to terminate """ @@ -1390,26 +1408,33 @@ data = None except Exception, e: self.log_msg(str(e)) + self.log_msg( ('exception', str(e)) ) self.log_msg("message handler thread exiting...") 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 print "Exception=" + str(e) + self.log_msg( ('exception', str(e)) ) def message_action(self, xml_dom, data): tag_name = xml_dom.tag if self.svrcmds.has_key(tag_name): self.svrcmds[tag_name]['function'](xml_dom, data) - else: raise Exception, "Not a valid header!" + else: + raise Exception, "Not a valid header!" + self.log_msg( ('exception', 'Not a valid header!') ) #Message Action thread expires and closes here. return @@ -1513,6 +1538,7 @@ print "Bad input: " + data except Exception,e: self.log_msg(str(e)) + self.log_msg( ('exception', str(e)) ) def join_group(self, xml_dom, data): try: @@ -1546,6 +1572,7 @@ self.move_player(from_id, group_id) except Exception, e: self.log_msg(str(e)) + self.log_msg( ('exception', str(e)) ) """ # move_player function -- added by Snowdog 4/03 @@ -1563,6 +1590,7 @@ else: self.players[from_id].role = "Lurker" except Exception, e: print "exception in move_player() " + self.log_msg( ('exception', str(e)) ) traceback.print_exc() old_group_id = self.players[from_id].change_group(group_id, self.groups) @@ -1591,6 +1619,7 @@ except Exception, e: roomMsg = "" self.log_msg(str(e)) + self.log_msg( ('exception', str(e)) ) # Spit that darn message out now! self.players[from_id].outbox.put("" + roomMsg) @@ -1603,10 +1632,12 @@ #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: self.log_msg(str(e)) + self.log_msg( ('exception', str(e)) ) thread.start_new_thread(self.registerRooms,(0,)) def return_room_roles(self, from_id, group_id): @@ -1632,7 +1663,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" @@ -1765,7 +1796,7 @@ else: self.send_to_all("0",self.groups[group_id].toxml('update')) #The register Rooms thread thread.start_new_thread(self.registerRooms,(0,)) - except Exception, e: self.log_msg(str(e)) + except Exception, e: self.log_msg( ('exception', str(e)) ) def del_player(self, id, group_id): try: @@ -1775,15 +1806,10 @@ del self.players[id] self.log_msg(dmsg) self.log_msg(("disconnect",id)) - """ - # If already registered then re-register, thereby updating the Meta - # on the number of players - # Note: Upon server shutdown, the server is first unregistered, so - # this code won't be repeated for each player being deleted. - """ - if self.be_registered: - self.register() - except Exception, e: self.log_msg(str(e)) + for meta in self.metas.keys(): + self.metas[meta].num_users = len(self.players) + thread.start_new_thread(self.registerRooms,(0,)) + except Exception, e: self.log_msg( ('exception', str(e)) ) self.log_msg("Explicit garbage collection shows %s undeletable items." % str(gc.collect())) def incoming_player_handler(self, xml_dom, data): @@ -1798,7 +1824,7 @@ try: self.send_player_list(id,group_id) self.send_group_list(id) - except Exception, e: traceback.print_exc() + except Exception, e: self.log_msg( ('exception', str(e)) ); traceback.print_exc() elif act=="del": self.del_player(id,group_id) self.check_group(id, group_id) @@ -1840,8 +1866,11 @@ to_id = xml_dom.get("to") from_id = xml_dom.get("from") group_id = xml_dom.get("group_id") + ## Backwards compatibility with older clients end = data.find(">") msg = data[end+1:] + if msg[-6:] == '': msg = msg[:-6] + data = msg if from_id == "0" or len(from_id) == 0: print "WARNING!! Message received with an invalid from_id. Message dropped." @@ -1865,21 +1894,27 @@ self.players[from_id].self_message('The lobby map may not be altered.') elif to_id.lower() == 'all': #valid map for all players that is not the lobby. - self.send_to_group(from_id,group_id,data) + msg = self.buildMsg('all', from_id, group_id, data) + self.send_to_group(from_id,group_id,msg) self.groups[group_id].game_map.init_from_xml(msg) else: #attempting to send map to specific individuals which is not supported. self.players[from_id].self_message('Invalid map message. Message not sent to others.') elif msg[:6] == '' + msg = self.buildMsg('all', '0', group_id, msg) self.log_msg("ban_msg:" + ban_msg) if (silent == 0): self.send_to_group("0", group_id, ban_msg) time.sleep( .1 ) @@ -2096,6 +2138,7 @@ except Exception, e: traceback.print_exc() self.log_msg('Exception in admin_ban() ' + str(e)) + self.log_msg( ('exception', str(e)) ) def admin_unban(self, ip): self.admin_build_banlist() @@ -2106,6 +2149,7 @@ except Exception, e: traceback.print_exc() self.log_msg('Exception in admin_unban() ' + str(e)) + self.log_msg( ('exception', str(e)) ) def admin_banlist(self): msg = [] @@ -2145,7 +2189,6 @@ except: pass def send(self,msg,player,group): - debug(msg) self.players[player].send(msg,player,group) def send_to_all(self,from_id,data): @@ -2158,11 +2201,11 @@ except Exception, e: traceback.print_exc() self.log_msg("Exception: send_to_all(): " + str(e)) + self.log_msg( ('exception', str(e)) ) def send_to_group(self, from_id, group_id, data): #data = ("" + data + "") data = ServerPlugins.postParseIncoming(data) #Function breaks here. - debug(data) try: self.p_lock.acquire() keys = self.groups[group_id].get_player_ids() @@ -2172,6 +2215,7 @@ except Exception, e: traceback.print_exc() self.log_msg("Exception: send_to_group(): " + str(e)) + self.log_msg( ('exception', str(e)) ) def send_player_list(self,to_id,group_id): try: @@ -2183,17 +2227,17 @@ except Exception, e: traceback.print_exc() self.log_msg("Exception: send_player_list(): " + str(e)) + self.log_msg( ('exception', str(e)) ) 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)) traceback.print_exc() + self.log_msg( ('exception', str(e)) ) """ # KICK_ALL_CLIENTS() @@ -2211,6 +2255,7 @@ except Exception, e: traceback.print_exc() self.log_msg("Exception: kick_all_clients(): " + str(e)) + self.log_msg( ('exception', str(e)) ) """ # This really has little value as it will only catch people that are hung @@ -2236,7 +2281,12 @@ self.admin_kick(k,"Removing dead client", self.silent_auto_kick) except Exception, e: self.log_msg("Exception: check_group_members(): " + str(e)) + self.log_msg( ('exception', str(e)) ) + def buildMsg(self, toId, fromId, roomId, data): + msg = '' + msg += data+ '' + return msg def remote_admin_handler(self,xml_dom,data): """ @@ -2285,106 +2335,112 @@ #determine action to take based on command (cmd) if cmd == "list": #return player list to this user. - msg ="" + self.player_list_remote() + msg = self.buildMsg(pid, '0', gid, self.player_list_remote()) self.players[pid].outbox.put(msg) elif cmd == "banip": ip = xml_dom.get("bip") name = xml_dom.get("bname") - msg = " Banned: " + str(ip) + msg = self.buildMsg(pid, '0', gid, str(ip)) self.admin_banip(ip, name) elif cmd == "ban": id = xml_dom.get("bid") - msg = " Banned!" + msg = self.buildMsg(id, '0', gid, 'Banned!') self.players[pid].outbox.put(msg) self.admin_ban(id, "") ### Alpha ### and untested elif cmd == "boot": id = xml_dom.get("bid") - msg = " Booted!" + msg = self.buildMsg(id, '0', gid, 'Booted!!') self.players[pid].outbox.put(msg) self.admin_kick(id, "") ############# elif cmd == "unban": ip = xml_dom.get("ip") self.admin_unban(ip) - msg = " Unbaned: " + str(ip) + msg = self.buildMsg(pid, '0', gid, str(ip)) self.players[pid].outbox.put(msg) elif cmd == "banlist": - msg = "" + self.admin_banlist() + msg = self.buildMsg(pid, '0', gid, self.admin_banlist()) self.players[pid].outbox.put(msg) elif cmd == "killgroup": ugid = xml_dom.get("gid") if ugid == "0": - m = "" - m += "Cannot Remove Lobby! Remote administrator request denied!" - self.players[pid].outbox.put(m) + m + "Cannot Remove Lobby! Remote administrator request denied!" + msg = self.buildMsg(pid, '0', gid, m) + self.players[pid].outbox.put(msg) else: result = self.prune_room(ugid) - msg = "" + str(result) + msg = self.buildMsg(pid, '0', gid, str(result)) self.players[pid].outbox.put(msg) elif cmd == "message": tuid = xml_dom.get("to_id") msg = xml_dom.get("msg") - pmsg = "" + msg + pmsg = self.buildMsg(tuid, '0', self.players[tuid].group_id, msg) try: self.players[tuid].outbox.put(pmsg) except: - msg = "" + self.uptime(1) + msg = self.uptime(1) + msg = self.buildMsg(pid, '0', gid, msg) self.players[pid].outbox.put(msg) elif cmd == "help": - msg = "" - msg += self.AdminHelpMessage() + msg = self.AdminHelpMessage() + msg = self.buildMsg(pid, '0', gid, msg) self.players[pid].outbox.put( msg) elif cmd == "roompasswords": # Toggle if room passwords are allowed on this server - msg = "" - msg += self.RoomPasswords() + msg = self.RoomPasswords() + msg = self.buildMsg(pid, '0', gid, msg) self.players[pid].outbox.put( msg) elif cmd == "createroom": rm_name = xml_dom.get("name") rm_pass = xml_dom.get("pass") rm_boot = xml_dom.get("boot") result = self.create_temporary_persistant_room(rm_name, rm_boot, rm_pass) - msg = "" + result + msg = self.buildMsg(pid, '0', gid, result) self.players[pid].outbox.put(msg) elif cmd == "nameroom": rm_id = xml_dom.get("rmid") rm_name = xml_dom.get("name") result = self.change_group_name(rm_id,rm_name,pid) - msg ="" + result + msg = self.buildMsg(pid, '0', gid, result) self.players[pid].outbox.put(msg) elif cmd == "passwd": tgid = xml_dom.get("gid") npwd = xml_dom.get("pass") if tgid == "0": - msg ="" - msg += "Server password may not be changed remotely!" + msg = "Server password may not be changed remotely!" + msg = self.buildMsg(pid, '0', gid, msg) self.players[pid].outbox.put(msg) else: try: self.groups[tgid].boot_pwd = npwd - msg ="Password changed for room " + tgid + msg = "Password changed for room " + tgid + msg = self.buildMsg(pid, '0', gid, msg) self.players[pid].outbox.put(msg) except: pass elif cmd == "savemaps": for g in self.groups.itervalues(): g.save_map() - msg ="Persistent room maps saved" + msg = "Persistent room maps saved" + msg = self.buildMsg(pid, '0', gid, msg) self.players[pid].outbox.put(msg) else: - msg ="[Unknown Remote Administration Command]" + msg = "[Unknown Remote Administration Command]" + msg = self.buildMsg(pid, '0', gid, msg) self.players[pid].outbox.put(msg) except Exception, e: self.log_msg("Exception: Remote Admin Handler Error: " + str(e)) traceback.print_exc() + self.log_msg( ('exception', str(e)) ) def toggleRemoteKill(self): if self.allowRemoteKill: self.allowRemoteKill = False @@ -2552,8 +2608,8 @@ pl += "" pl += "Statistics: groups: " + str(len(self.groups)) + " " pl += "players: " + str(len(self.players)) + "" - except Exception, e: self.log_msg(str(e)) + except Exception, e: self.log_msg(str(e)); self.log_msg( ('exception', str(e)) ) self.p_lock.release() return pl -server = mplay_server() +server = mplay_server() diff -r 4b2884f29a72 -r 81d0bfd5e800 orpg/networking/mplay_server_gui.py --- a/orpg/networking/mplay_server_gui.py Fri Jan 15 22:45:51 2010 -0600 +++ b/orpg/networking/mplay_server_gui.py Sat Jun 12 03:50:37 2010 -0500 @@ -6,24 +6,22 @@ __appname__=' OpenRPG GUI Server v0.7 ' __version__='$Revision: 1.26 $'[11:-2] -__cvsinfo__='$Id: mplay_server_gui.py,v 1.26 2007/11/06 00:32:39 digitalxero Exp $'[5:-2] +__cvsinfo__="$Id: mplay_server_gui.py,v Traipse 'Ornery-Orc' prof.ebral Exp $"[5:-2] __doc__="""OpenRPG Server Graphical Interface""" -import os, sys, time, types +import os, sys, time, types, webbrowser from orpg.dirpath import dir_struct from orpg.tools.validate import validate from orpg.orpg_wx import * from threading import Thread -import webbrowser - from meta_server_lib import post_server_data, remove_server from mplay_server import mplay_server, server from xml.dom import minidom from orpg.orpgCore import component -from orpg.tools.orpg_log import debug +from orpg.tools.orpg_log import debug, DebugConsole from orpg.tools.orpg_settings import settings from xml.etree.ElementTree import ElementTree, Element, iselement @@ -32,11 +30,7 @@ # Constants ###################################### SERVER_RUNNING = 1 SERVER_STOPPED = 0 - -### Alpha ### MENU_MODIFY_BANLIST = wx.NewId() -############# - MENU_PLAYER_CREATE_ROOM = wx.NewId() # Our new event type that gets posted from one @@ -157,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)) @@ -168,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): @@ -268,7 +262,6 @@ self.SetItem(item) def update(self, player): - #try: int(player); i = self.FindItemData( -1, int(player) ) i = self.FindItemData( -1, int(player["id"]) ) if i > -1: self.SetStringItem(i, 1, self.stripHtml(player["name"])) @@ -328,7 +321,7 @@ BanMsg = wx.TextEntryDialog( self, "Enter A Message To Send:", "Ban Message", message, wx.OK|wx.CANCEL|wx.CENTRE ) if BanMsg.ShowModal() == wx.ID_OK: message = BanMsg.GetValue() - else: message = '' + else: return Silent = wx.MessageDialog(None, 'Silent Ban?', 'Question', wx.YES_NO | wx.NO_DEFAULT | wx.ICON_QUESTION) if Silent.ShowModal() == wx.ID_YES: silent = 1 @@ -337,14 +330,30 @@ self.remove( playerID ) elif menuItem == 4: msg = self.GetMessageInput( "Send a message to player" ) - if len(msg): self.main.server.server.send( msg, playerID, str(groupID) ) + + broadcast = '' +msg+ '' + chat = Element('chat') + chat.set('type', '1') + chat.set('version', '1.0') + chat.text = broadcast + msg = self.main.server.server.buildMsg(str(playerID), '0', '1', msg) + + if len(msg): self.main.server.server.players[playerID].outbox.put(msg) #Leave this in for now. elif menuItem == 5: msg = self.GetMessageInput( "Send message to room of this player") + + broadcast = '' +msg+ '' + chat = Element('chat') + chat.set('type', '1') + chat.set('version', '1.0') + chat.text = broadcast + msg = self.main.server.server.buildMsg('all', '0', '1', tostring(chat)) + if len(msg): self.main.server.server.send_to_group('0', str(groupID), msg ) elif menuItem == 6: msg = self.GetMessageInput( "Broadcast Server Message" ) - if len(msg): self.main.server.server.broadcast( msg ) + if len(msg): self.main.server.server.broadcast(msg ) elif menuItem == 3: version_string = self.main.server.server.obtain_by_id(playerID, 'client_string') if version_string: wx.MessageBox("Running client version " + version_string,"Version") @@ -361,8 +370,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 = "" @@ -391,6 +400,7 @@ cb["delete_group"] = self.OnDeleteGroup cb["join_group"] = self.OnJoinGroup cb['update_group'] = self.OnUpdateGroup + cb['exception'] = self.OnException cb["role"] = self.OnSetRole self.callbacks = cb @@ -408,10 +418,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) @@ -419,23 +429,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) @@ -444,37 +455,82 @@ 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') + + # Traipse Suite of Additions. + self.traipseSuite = wx.Menu() + self.debugger = DebugConsole(self) + self.mainMenu.Insert(3, self.traipseSuite, "&Traipse Suite") - self.mainMenu.Enable( 2, False ) - self.mainMenu.Enable( 4, False ) - self.mainMenu.Enable( 5, False ) + #Debugger Console + self.debugConsole = wx.MenuItem(self.traipseSuite, -1, "Debug Console", "Debug Console") + self.Bind(wx.EVT_MENU, self.OnMB_DebugConsole, self.debugConsole) + self.traipseSuite.AppendItem(self.debugConsole) + + self.SetMenuBar(self.mainMenu) + + 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 OnException(self, error): + self.TraipseSuiteWarn('debug') + self.debugger.console.AppendText(".. " + str(error) +'\n') + + def OnMB_DebugConsole(self, evt): + self.TraipseSuiteWarnCleanup('debug') + if self.debugger.IsShown() == True: self.debugger.Hide() + else: self.debugger.Show() + + def TraipseSuiteWarn(self, menuitem): + ### Allows for the reuse of the 'Attention' menu. + ### component.get('frame').TraipseSuiteWarn('item') ### Portable + self.mainMenu.Remove(3) + self.mainMenu.Insert(3, self.traipseSuite, "&Traipse Suite!") + if menuitem == 'debug': + if self.debugger.IsShown() == True: + self.mainMenu.Remove(3) + self.mainMenu.Insert(3, self.traipseSuite, "&Traipse Suite") + else: + self.debugConsole.SetBitmap(wx.Bitmap(dir_struct["icon"] + 'spotlight.png')) + self.traipseSuite.RemoveItem(self.debugConsole) + self.traipseSuite.AppendItem(self.debugConsole) + + def TraipseSuiteWarnCleanup(self, menuitem): + ### Allows for portable cleanup of the 'Attention' menu. + ### component.get('frame').TraipseSuiteWarnCleanup('item') ### Portable + self.mainMenu.Remove(3) + self.mainMenu.Insert(3, self.traipseSuite, "&Traipse Suite") + if menuitem == 'debug': + self.traipseSuite.RemoveItem(self.debugConsole) + self.debugConsole.SetBitmap(wx.Bitmap(dir_struct["icon"] + 'clear.gif')) + self.traipseSuite.AppendItem(self.debugConsole) + 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 @@ -529,12 +585,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 @@ -563,28 +621,29 @@ def OnStart(self, event = None): """ Start server. """ if self.STATUS == SERVER_STOPPED: - # see if we already have name specified + ## Set name and admin password as empty + self.serverName = '' + self.bootPwd = '' + # see if we already have serverName and bootPwd specified try: validate.config_file( "server_ini.xml", "default_server_ini.xml" ) configDoc = parse(dir_struct["user"] + 'server_ini.xml').getroot() - if configDoc.get("name"): self.serverName = configDoc.get("name") + self.serverName = configDoc.get("name") + if configDoc.get("admin"): self.bootPwd = configDoc.get("admin") + elif configDoc.get("boot"): self.bootPwd = configDoc.get("boot") 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() - # see if we already have password specified - try: - validate.config_file( "server_ini.xml", "default_server_ini.xml" ) - configDoc = parse(dir_struct["user"] + 'server_ini.xml').getroot() - if configDoc.get("admin"): self.bootPwd = configDoc.get("admin") - elif configDoc.get("boot"): self.bootPwd = configDoc.get("boot") - except: pass 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() @@ -593,25 +652,26 @@ 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") - def OnStop(self, event = None): + def OnStop(self, event=None): """ Stop server. """ if self.STATUS == SERVER_RUNNING: - self.OnUnregister() + self.OnUnregister(event) self.server.stop() 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.conns.DeleteAllItems() + if event != 'Quit': + 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.conns.DeleteAllItems() def OnRegister(self, event = None): """ Call into mplay_server's register() function. @@ -622,8 +682,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() @@ -636,11 +696,12 @@ """ wx.BeginBusyCursor() self.server.server.unregister() - 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)") + if event != 'Quit': + 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() def ModifyBanList(self, event): @@ -667,7 +728,7 @@ def ExitConfirmed(self, event=None): """ Quit the program. """ - self.OnStop() + self.OnStop('Quit') self.BanListDialog.Destroy() wx.CallAfter(self.Destroy) diff -r 4b2884f29a72 -r 81d0bfd5e800 orpg/orpg_version.py --- a/orpg/orpg_version.py Fri Jan 15 22:45:51 2010 -0600 +++ b/orpg/orpg_version.py Sat Jun 12 03:50:37 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 Alpha" +DISTRO = "Traipse" DIS_VER = "Ornery Orc" -BUILD = "100115-02" +BUILD = "100505-00" # This version is for network capability. PROTOCOL_VERSION = "1.2" diff -r 4b2884f29a72 -r 81d0bfd5e800 orpg/orpg_windows.py --- a/orpg/orpg_windows.py Fri Jan 15 22:45:51 2010 -0600 +++ b/orpg/orpg_windows.py Sat Jun 12 03:50:37 2010 -0500 @@ -21,12 +21,12 @@ # Author: Chris Davis # Maintainer: # Version: -# $Id: orpg_windows.py,v 1.42 2007/12/07 20:59:16 digitalxero Exp $ +# $Id: orpg_windows.py,v Traipse 'Ornery-Orc' prof.ebral Exp $ # # Description: orpg custom windows # -__version__ = "$Id: orpg_windows.py,v 1.42 2007/12/07 20:59:16 digitalxero Exp $" +__version__ = "$Id: orpg_windows.py,v Traipse 'Ornery-Orc' prof.ebral Exp $" from orpg.orpg_wx import * from orpg.orpgCore import * @@ -56,49 +56,54 @@ pos = string.rfind(file_name,'.') ext = string.lower(file_name[pos+1:]) img_type = 0 - recycle_bin = {"gif": wx.BITMAP_TYPE_GIF, "jpg": wx.BITMAP_TYPE_JPEG, + recycle_bin = {"gif": wx.BITMAP_TYPE_GIF, "jpg": wx.BITMAP_TYPE_JPEG, "jpeg": wx.BITMAP_TYPE_JPEG, "bmp": wx.BITMAP_TYPE_BMP, "png": wx.BITMAP_TYPE_PNG} - if recycle_bin.has_key(ext): img_type = recycle_bin[ext] - else: img_type = None - del recycle_bin; return img_type + if recycle_bin.has_key(ext): img_type = recycle_bin[ext] + else: img_type = None + del recycle_bin; return img_type ################################ ## Tabs ################################ class orpgTabberWnd(FNB.FlatNotebook): - def __init__(self, parent, closeable=False, size=wx.DefaultSize, style = False): + def __init__(self, parent, closeable=False, size=wx.DefaultSize, style=False): nbstyle = FNB.FNB_HIDE_ON_SINGLE_TAB|FNB.FNB_BACKGROUND_GRADIENT + if style: nbstyle |= style FNB.FlatNotebook.__init__(self, parent, -1, size=size, style=nbstyle) rgbcovert = orpg.tools.rgbhex.RGBHex() self.log = component.get("log") self.log.log("Enter orpgTabberWnd", ORPG_DEBUG) self.settings = component.get("settings") - tabtheme = self.settings.get_setting('TabTheme') - tabtext = self.settings.get_setting('TabTextColor') + tabtheme = self.settings.get('TabTheme') + tabtext = self.settings.get('TabTextColor') (tred, tgreen, tblue) = rgbcovert.rgb_tuple(tabtext) - tabbedwindows = component.get("tabbedWindows") - tabbedwindows.append(self) - component.add("tabbedWindows", tabbedwindows) + component.get("tabbedWindows").append(self) theme_dict = {'slanted&aqua': FNB.FNB_VC8, 'slanted&bw': FNB.FNB_VC8, 'flat&aqua': FNB.FNB_FANCY_TABS, - 'flat&bw': FNB.FNB_FANCY_TABS, 'customflat': FNB.FNB_FANCY_TABS, 'customslant': FNB.FNB_VC8, - 'slanted&colorful': FNB.FNB_VC8|FNB.FNB_COLORFUL_TABS, 'slant&colorful': FNB.FNB_VC8|FNB.FNB_COLORFUL_TABS} - nbstyle |= theme_dict[tabtheme] - if style: nbstyle |= style - self.SetWindowStyleFlag(nbstyle) + 'flat&bw': FNB.FNB_FANCY_TABS, 'customflat': FNB.FNB_FANCY_TABS, 'customslant': FNB.FNB_VC8} + #'slanted&colorful': FNB.FNB_VC8|FNB.FNB_COLORFUL_TABS, 'slant&colorful': FNB.FNB_VC8|FNB.FNB_COLORFUL_TABS} + if theme_dict.has_key(tabtheme): style |= theme_dict[tabtheme] + else: style |= theme_dict['customflat']; self.settings.change('TabTheme', 'customflat') + self.SetWindowStyleFlag(style) + + tabbg = self.settings.get('TabBackgroundGradient') + (red, green, blue) = rgbcovert.rgb_tuple(tabbg) + self.SetTabAreaColour(wx.Color(red, green, blue)) # Tas - sirebral. Planned changes to the huge statement below. if tabtheme == 'slanted&aqua': self.SetGradientColourTo(wx.Color(0, 128, 255)) self.SetGradientColourFrom(wx.WHITE) + self.SetNonActiveTabTextColour(wx.BLACK) elif tabtheme == 'slanted&bw': self.SetGradientColourTo(wx.WHITE) self.SetGradientColourFrom(wx.WHITE) + self.SetNonActiveTabTextColour(wx.BLACK) elif tabtheme == 'flat&aqua': - self.SetGradientColourFrom(wx.Color(0, 128, 255)) - self.SetGradientColourTo(wx.WHITE) + self.SetGradientColourTo(wx.Color(0, 128, 255)) + self.SetGradientColourFrom(wx.WHITE) self.SetNonActiveTabTextColour(wx.BLACK) elif tabtheme == 'flat&bw': @@ -107,28 +112,21 @@ self.SetNonActiveTabTextColour(wx.BLACK) elif tabtheme == 'customflat': - gfrom = self.settings.get_setting('TabGradientFrom') - (red, green, blue) = rgbcovert.rgb_tuple(gfrom) - self.SetGradientColourFrom(wx.Color(red, green, blue)) + (red, green, blue) = rgbcovert.rgb_tuple(self.settings.get_setting('TabGradientTo')) + self.SetGradientColourTo(wx.Color(red, green, blue)) - gto = self.settings.get_setting('TabGradientTo') - (red, green, blue) = rgbcovert.rgb_tuple(gto) - self.SetGradientColourTo(wx.Color(red, green, blue)) + (red, green, blue) = rgbcovert.rgb_tuple(self.settings.get_setting('TabGradientFrom')) + self.SetGradientColourFrom(wx.Color(red, green, blue)) self.SetNonActiveTabTextColour(wx.Color(tred, tgreen, tblue)) elif tabtheme == 'customslant': - gfrom = self.settings.get_setting('TabGradientFrom') - (red, green, blue) = rgbcovert.rgb_tuple(gfrom) - self.SetGradientColourFrom(wx.Color(red, green, blue)) + (red, green, blue) = rgbcovert.rgb_tuple(self.settings.get_setting('TabGradientTo')) + self.SetGradientColourTo(wx.Color(red, green, blue)) - gto = self.settings.get_setting('TabGradientTo') - (red, green, blue) = rgbcovert.rgb_tuple(gto) - self.SetGradientColourTo(wx.Color(red, green, blue)) + (red, green, blue) = rgbcovert.rgb_tuple(self.settings.get_setting('TabGradientFrom')) + self.SetGradientColourFrom(wx.Color(red, green, blue)) self.SetNonActiveTabTextColour(wx.Color(tred, tgreen, tblue)) - tabbg = self.settings.get_setting('TabBackgroundGradient') - (red, green, blue) = rgbcovert.rgb_tuple(tabbg) - self.SetTabAreaColour(wx.Color(red, green, blue)) self.Refresh() self.log.log("Exit orpgTabberWnd", ORPG_DEBUG) diff -r 4b2884f29a72 -r 81d0bfd5e800 orpg/orpg_xml.py --- a/orpg/orpg_xml.py Fri Jan 15 22:45:51 2010 -0600 +++ b/orpg/orpg_xml.py Sat Jun 12 03:50:37 2010 -0500 @@ -21,18 +21,17 @@ # Author: Chris Davis # Maintainer: # Version: -# $Id: orpg_xml.py,v 1.12 2007/07/19 20:33:10 digitalxero Exp $ +# $Id: orpg_xml.py,v Traipse 'Ornery-Orc' prof.ebral Exp $ # # Description: xml utilies # from orpg import minidom import string - from orpg.tools.orpg_log import logger, debug class xml: - debug('Deprecated call to orpg_xml!!') + debug(('Developers note. Deprecated call to orpg_xml!!'), parents=True) def __init__(self): pass diff -r 4b2884f29a72 -r 81d0bfd5e800 orpg/player_list.py --- a/orpg/player_list.py Fri Jan 15 22:45:51 2010 -0600 +++ b/orpg/player_list.py Sat Jun 12 03:50:37 2010 -0500 @@ -22,12 +22,12 @@ # Author: Chris Davis # Maintainer: # Version: -# $Id: player_list.py,v 1.29 2007/03/30 19:12:06 digitalxero Exp $ +# $Id: player_list.py,v Traipse 'Ornery-Orc' prof.ebral Exp $ # # Description: This is the main entry point of the oprg application # -__version__ = "$Id: player_list.py,v 1.29 2007/03/30 19:12:06 digitalxero Exp $" +__version__ = "$Id: player_list.py,v Traipse 'Ornery-Orc' prof.ebral Exp $" from orpg.orpg_windows import * from orpg.dirpath import dir_struct diff -r 4b2884f29a72 -r 81d0bfd5e800 orpg/pluginhandler.py --- a/orpg/pluginhandler.py Fri Jan 15 22:45:51 2010 -0600 +++ b/orpg/pluginhandler.py Sat Jun 12 03:50:37 2010 -0500 @@ -1,5 +1,7 @@ from orpg.orpg_wx import * from orpg.orpgCore import component +from xml.etree.ElementTree import ElementTree, Element, parse +from xml.etree.ElementTree import fromstring, tostring class PluginHandler: # Initialization subroutine. @@ -82,22 +84,22 @@ self.settings.add_setting(self.name, setting, value, options, help) def plugin_send_msg(self, to, plugin_msg): - xml_dom = self.xml.parseXml(plugin_msg) - xml_dom = xml_dom._get_documentElement() - xml_dom.setAttribute('from', str(self.session.id)) - xml_dom.setAttribute('to', str(to)) - xml_dom.setAttribute('group_id', str(self.session.group_id)) - tag_name = xml_dom._get_tagName() + xml_dom = fromstring(plugin_msg) + #xml_dom = xml_dom.getroot() + xml_dom.set('from', str(self.session.id)) + xml_dom.set('to', str(to)) + xml_dom.set('group_id', str(self.session.group_id)) + tag_name = xml_dom.tag if not tag_name in self.session.core_msg_handlers: xml_msg = '' + xml_dom.toxml() + xml_msg += '" />' + tostring(xml_dom) self.session.outbox.put(xml_msg) else: #Spoofing attempt pass - xml_dom.unlink() + #xml_dom.unlink() def message(self, text): return text diff -r 4b2884f29a72 -r 81d0bfd5e800 orpg/templates/default_LobbyMessage.html --- a/orpg/templates/default_LobbyMessage.html Fri Jan 15 22:45:51 2010 -0600 +++ b/orpg/templates/default_LobbyMessage.html Sat Jun 12 03:50:37 2010 -0500 @@ -1,40 +1,38 @@ - - - - - - - - -
-
-
- - - - - - - -
- Many thanks goes to all of those who contributed! -
- The developers in alphabetical order are: -
- Thomas Baleno, Andrew Bennett, Lex Berezhny, Ted Berg, - Bernhard Bergbauer, Chris Blocher ,Ben Collins-Sussman, Robin Cook, Greg Copeland, - Chris Davis, Michael Edwards, Andrew Ettinger, Dj Gilcrease, Todd Faris, - Christopher Hickman, Paul Hosking, Scott Mackay, Brian Manning, - Jesse McConnell, Brian Osman, Rome Reginelli, Christopher Rouse, Dave Sanders, Mark Tarrabain, - David Byron, and Tyler Starke. -
- This product is licensed under the GNU GPL License. -
-
- - + + + + + + + + + +
+ Welcome to an OpenRPG Server +
+ Add a message here. +
+ The OpenRPG Project +
+ Who is this force? +
+ Here is an example Room Message that can be easily modified to fit the needs of your server. + The room message has two rows and two cells. One row is for headers, and one row is for cells. + The main area here can be an introduction, and the side area to the right can contain a game schedule. +

If you have created a Wiki or forums, be sure and put links to those as well.

+
+ Thomas Baleno, Andrew Bennett, Lex Berezhny, Ted Berg, + Bernhard Bergbauer, Chris Blocher, Ben Collins-Sussman, Robin Cook, Greg Copeland, + Chris Davis, Michael Edwards, Andrew Ettinger, Dj Gilcrease, Todd Faris, + Christopher Hickman, Paul Hosking, Scott Mackay, Brian Manning, + Jesse McConnell, Brian Osman, Rome Reginelli, Christopher Rouse, Dave Sanders, Mark Tarrabain, + David Byron, David Vrabel, and Tyler Starke. +

And of course, the Community!

+

Many thanks to all who contributed!

+
+ diff -r 4b2884f29a72 -r 81d0bfd5e800 orpg/templates/default_Lobby_map.xml --- a/orpg/templates/default_Lobby_map.xml Fri Jan 15 22:45:51 2010 -0600 +++ b/orpg/templates/default_Lobby_map.xml Sat Jun 12 03:50:37 2010 -0500 @@ -1,7 +1,7 @@ - + diff -r 4b2884f29a72 -r 81d0bfd5e800 orpg/templates/default_settings.xml --- a/orpg/templates/default_settings.xml Fri Jan 15 22:45:51 2010 -0600 +++ b/orpg/templates/default_settings.xml Sat Jun 12 03:50:37 2010 -0500 @@ -2,10 +2,9 @@ - + - - + diff -r 4b2884f29a72 -r 81d0bfd5e800 orpg/templates/feature.xml --- a/orpg/templates/feature.xml Fri Jan 15 22:45:51 2010 -0600 +++ b/orpg/templates/feature.xml Sat Jun 12 03:50:37 2010 -0500 @@ -1,6 +1,159 @@ - - - Quick Help: + + + + Welcome to Traipse OpenRPG. + +This small user manual should help users learn about the details of OpenRPG that are often times obscure. + +What is OpenRPG: +OpenRPG is a virtual game table software that allows users to connect via a network. The software includes a Map, Chat, and a Game Tree. + +What is Traipse OpenRPG: +Traipse OpenRPG is a fork of the original software that is designed to be easy for users, extremely stable, and really powerful. + +Traipse has features that set it apart from all other distributions of OpenRPG. The Traipse Suite includes a powerful Update Manager that makes it easy for new developers to create and share their own fork. The Suite also contains an in house Debug Console so users can see what errors, if any, occur. + +The User Manual: +The user manual is divided into Chapters and Sections. Each Chapter will go over the various features of OpenRPG and attempt to explain them in an easy to understand format. + +Adding to the Manual: +Do you see something that could be explained eaiser? Report the problem as a bug and it will be added to the manual. + + + + The Chat window is a basic HTML Parser. It understands all basic HTML tags including table, td, tr, span, font, to name a few. + +The chat includes a set of commands. You can learn about the commands by entering /help + +The chat also has Settings in the Chat menu that allow you see a Chat Time Index, Images, or strip the HTML and see raw text. + + + + + The Tabs: +The Map is divided into 7 tabs. They are Background, Grid, Miniatures, Whiteboard, Fog, and General. There are 6 layers to the map, one tab for each layer except General. + +When you select one of the tabs you may access that map layer and it's settings. You may only select tabs based on your role. + +Lurker or in the Lobby: +You cannot access any map tab or changes it's settings. + +Player: +You have access to the Miniatures tab and the Whiteboard tab. + +GM: +You have access to all of the tabs. + +The Layers: +A small description of each of the layers. + +Background: +You can set an image as the background, an image as a tile, or you can set a color. + +Grid: +You can change the grid size, lines, turn off the grid snap, and change the grid shape. + +Miniatures: +You can add new or remove miniatures and change mini properties and labels. + +Whiteboard: +With the whiteboard you can draw lines or add text to the map. + +Fog: +The fog layer hides the entire map from the prying eyes of players. + + + + + Namespace 2.0 + +Internal Namespace: !=NodeName=! or !=GridName::Row,Colum=! +External Namespace: !&Container::NodeName&! or !&Container::GridName::Row,Colum&! + +Namespace 2.0 now has two different ways of finding nodes in your gametree: Internal and +External. The new version will find nodes differently based on which method you use. With External you start looking from the gametree but can define a "container" to be more specific. With Internal you start looking from the "node" the reference is in and look through the tree backwards. You can now reference cells within a grid using either. + +*An explanation of terms* +Gametree: The list of objects on the left-hand side of the window that holds all your nodes. +Node: Refers to any object in the gametree. +Container: Refers only to those nodes that are capable of storing other nodes (Splitter, +Tabbers, Folder, Forms, etc.). Used here, it usually refers to the largest container, i.e. the +one that shows up in the gametree when fully collapsed. A Container can contain other +containers. +Internal Namespace: !=NodeName=! +-Used from within a node to call another node in the same container, such as a list node +calling a text node or grid. *Note* Will not work if multiple nodes within the same container +have the same name. Multiple nodes within the entirety of the gametree can have the same names +though as long as they are in different containers. +-Uses the !=NodeName=! syntax for normal nodes. +-Uses !=GridName::Row,Colum=! to reference cells within a grid + +Examples: +!=Strength=! +(Will find the node named “Strength” in the same container and insert it in place of +!=Strength=!) + +!=Ability Scores::3,5=! +(Will find cell in Row number 3 and Colum number 5 and insert the information contained there +in place of !=Ability Scores::3,5=! )External Namespace: !&Container::NodeName&! +-Can only be used from chat (currently) to call a node from anywhere in the gametree. You must +specify the container the node is in. You only have to specify the ‘largest’ container +(typically the one that shows in the gametree when fully collapsed). It doesn’t matter how +many smaller containers within the same container it’s in, you need only reference the +largest. *Note* Will not work if multiple nodes within the same container have the same name. +Multiple nodes within the entirety of the gametree can have the same names though as long as +they are in different containers. +-Uses the !&Container::NodeName&! syntax for normal nodes. +-Uses !&Container::NodeName::Row,Colum&! to reference cells within a grid. + +Examples: +!&3.5 Character Sheet::Strength&! +(Will find the node named “Strength” within the larger container “3.5 Character Sheet” and +insert it in place of !&3.5 Character Sheet::Strength&!) + +!&3.5 Character Sheet::Ability Scores::3,5&! +(Will find the cell in Row 3, Colum 5 in within the larger container “3.5 Character Sheet” and +insert its contents in place of !&3.5 Character Sheet::Ability Scores::3,5&!)Other Notes: +If you have similar nodes (i.e. have a lot of the same node names in them) located within the +same Larger container, Internal Namespace will still work as normal. With External Namespace, +you will have to specify which of the smaller containers you wish to call from. + +For example, if you have a folder container that has two nodes in it, Internal will still work +fine from within either. However, if you are trying to use External, it you will have to +specify which of smaller containers you want like so: +!&LargerContainer::SmallerContainer::NodeName&! + +I.E.: +The Largest container is called “Character Sheets.” It contains three other, Smaller +containers called “Luke,” “Leia,” and “Vader.” If you want to call the “Strength” node located +in “Leia” you will have to specify it like so: !&Character Sheets::Leia::Strength&!. The Namespace 2.0 is so far my greatest gift to OpenRPG. Namespace 2.0 surpasses the other Namespaces styles because it has a lightning bolt effect. + +In 1.7.1 you could use a reference such as !@Name@! to get the name of the Behir (Example Node). The biggest problem with the Namespace was it would only look at the top most node. + +Traipse changes how Namespace works by allowing users to be more specific without needing to be too specific. Namespace 2.0 works in a similar fashion, by finding the top most node with a similar name and attempting to use it. Yet, if you want to be more specific you can add node names to the reference and Namespace will find them in order. + +Below are some examples uses of the new Namespace. To try them out, create a 4e PC Sheet node and press the Send button. + +<b>1:</b> !&4e PC Sheet::Slot 1&! +<b>2:</b> !&4e PC Sheet::Belt::Slot 1&! +<b>3:</b> !&4e PC Sheet::Inventory&! +<b>4:</b> !&4e PC Sheet::Inventory::Slot 1&! + + Did you see what happened with the last two? Thankfully there is more than one way to get a node! + +(Create a 4e PC Sheet node from the Templates and press Send ---v to try it) + + Grids can now be called from by adding a Row, Column to the end of the grid reference. + +Example: !&Abilities::2,2&! + + + Quick Help: + +Designer Note: +=== +For the life span of Ornery Orc the new Child, Parent, Root reference will exist, but in Pious the reference system will not transfer. This is because of the way the new Namespace works. Namespace will become the exclusive referencing system +=== The referencing system is an update to the Core of how the Game Tree works. In it's current state I understand the syntax is difficult to pick up. Here are some tips to help you grasp the syntax further @@ -57,130 +210,69 @@ In the OpenRPG Core model your Game Tree has a lot more freedom, but only if you grant it, which I always felt was a design flaw. Comparably, with Traipse you can access any data on the Game Tree, no matter where the location. This freedom will help with future design and I feel it also frees up the hands of the GM who does not need to Index, un-Index, Namespace, un-Namspace the various creatures he or she may have in a Game Tree. - - <b>Root Reference</b> + + + <b>Root Reference</b> Works at the tree level. Must be exact. <b>Root Reference 1:</b> !@Reference Examples::Group::Child@! -<b>Root Reference 2:</b> !@Reference Examples::Grid::(2,1)@! - - <b>Grid Reference</b> +<b>Root Reference 2:</b> !@Reference Examples::Grid::2,1@! + + + <b>Grid Reference</b> Works by looking at the (Row, Column) of a Grid. -<b>Grid Reference 1:</b> !@Reference Examples::Grid::(1,1)@! -<b>Grid Reference 2:</b> !!Grid::(1,1)!! - - <b>Child Reference</b> +<b>Grid Reference 1:</b> !@Reference Examples::Grid::1,1@! +<b>Grid Reference 2:</b> !!Grid::1,1!! + + + <b>Child Reference</b> Works at the current tree location. <b>Child Reference 1:</b> !!Group::Child!! <b>Child Reference 2:</b> !!Group::Group_2::Child_2!! - - <b>Parent Reference</b> -Works by indexing the map of the node with the Reference. -Works with a Child Reference only. - -<b>Parent Reference 1:</b> !!Group::Group_2::Group_3::Child_3!! -<b>Parent Reference 2:</b> !!Group::Group_2::Child_2!! - - - - !#Group::Child#! - - - !#Group::Child#! - - Child Node Data - - - - 0 - 0 - - - !!Group::Child!! - 0 - - - - - - - Welcome to Traipse OpenRPG. - -This small user manual should help users learn about the details of OpenRPG that are often times obscure. - -What is OpenRPG: -OpenRPG is a virtual game table software that allows users to connect via a network. The software includes a Map, Chat, and a Game Tree. - -What is Traipse OpenRPG: -Traipse OpenRPG is a fork of the original software that is designed to be easy for users, extremely stable, and really powerful. - -Traipse has features that set it apart from all other distributions of OpenRPG. The Traipse Suite includes a powerful Update Manager that makes it easy for new developers to create and share their own fork. The Suite also contains an in house Debug Console so users can see what errors, if any, occur. - - The Chat window is a basic HTML Parser. It understands all basic HTML tags including table, td, tr, span, font, to name a few. - -The chat includes a set of commands. You can learn about the commands by entering /help - -The chat also has Settings in the Chat menu that allow you see a Chat Time Index, Images, or strip the HTML and see raw text. - - The Tabs: -The Map is divided into 7 tabs. They are Background, Grid, Miniatures, Whiteboard, Fog, and General. There are 6 layers to the map, one tab for each layer except General. + + + <b>Parent Reference</b> +Works by indexing the tree map of the node with the Reference. Allows you to start from a 'Parent'. -When you select one of the tabs you may access that map layer and it's settings. You may only select tabs based on your role. - -Lurker or in the Lobby: You cannot access any map tab or changes it's settings. - -Player: You have access to the Miniatures tab and the Whiteboard tab. - -GM: You have access to all of the tabs. - -The Layers: -A small description of each of the layers. - -Background: You can set an image as the background, an image as a tile, or you can set a color. - -Grid: You can change the grid size, lines, turn off the grid snap, and change the grid shape. - -Miniatures: You can add new or remove miniatures and change mini properties and labels. - -Whiteboard: With the whiteboard you can draw lines or add text to the map. - -Fog: The fog layer hides the entire map from the prying eyes of players. - - With the new additions to the Game Tree using nodes has never been easier nor has it ever been more fluid. Included here is a list of the additions to the Game Tree referencing model as well as some tips on how to make the Game Tree work the way it was intended. - -Grid Nodes: - Grid nodes are now reference-able with the coordinates of the grid. Example: !@Grid::(1,1)@! -The example will return the top left most cell data. The grid understands coordinates like this (Row, Column) - - Grid nodes can reference node data just like any other node can. With a new added feature grids are even more useful. By using a new die rolling syntax you can draw just the number of the modified roll. While this will not pass during game play, you can use it with the grid node to create a random chart. The new die roll syntax is [#XdY]. # works just like q, yet it returns only the modified die result. - - Here is an example with a 3 x 3 Grid -Example: !@Grid::([#1d3], [#1d3])@! - -The result will be a random event from the grid. - -Bonus Node Included: A 52 Card Deck with 4 columns and 13 rows. (4 * 13 = 52) - -List Nodes: - List nodes now have a check box that allows users to send the content as a macro. List nodes are a prime reference holder because users can place a lot of references into one small node. - - For the best results from a list node my tip to users would be to create a list node and place it next to the character sheet they are using, inside a the PC Sheet. The list will then use the Child Referencing syntax, but the PC Sheet can go anywhere in the tree and the player will have easy access to all the references. - -(List Nodes inside a Tool created PC sheet vanish when moved, or I would recommend the list be placed inside these sheets also.) - - Here is an example of a Fortitude save inside the recommended list node: !!Fort::Check!! - -Text Nodes: - Text nodes remain little changed. I agree with all the 1.7.1 users who tell me, if it's not broke don't fix it. With that in mind I have some good tips for text nodes. - - Text nodes can be used in conjunction with the new grid features to create random encounters. A GM could place a list of text nodes into a folder and the grid could reference the nodes. - - Text nodes also work great when you need to have story text at hand that you don't want to type out during play. Create chapters with folder nodes and add the adventure text to different nodes. You can then use a List Node or a Grid Node to reference the different chapters. - -Bonus Node Included: A small book node with 1 Chapter and 3 Parts. Traipse node referencing is unlike other distributions of OpenRPG. The Game Tree mapping is a fluid map that changes with the location of your nodes. This allows you to create a reference node that will stay with your character sheet, and if you change the location of your character sheet the reference will still work. +<b>Parent Reference 1:</b> !!Group::Group_2::Child_2!! +<b>Parent Reference 2:</b> !#Bonus Nodes::Deck::Draw#! + + + + + !#Group::Child#! + + + + !#Group::Child#! + + + + + Child Node Data + + + + + + 0 + 0 + + + !!Group::Child!! + 0 + + + + + + + + + Traipse node referencing is unlike other distributions of OpenRPG. The Game Tree mapping is a fluid map that changes with the location of your nodes. This allows you to create a reference node that will stay with your character sheet, and if you change the location of your character sheet the reference will still work. (Note: Renaming your node causes problems with the tree mapping until you restart the software. You can just move the node and the software will reset the Game Tree map) @@ -232,8 +324,46 @@ Examples: !@Kammen-Pai::Cast::Ray of Frost@! -!@Kammen-Pai::Feat::Ability Focus@! - In Traipse starting a server has never been easier. The setup is as easy as 1., 2., 3 +!@Kammen-Pai::Feat::Ability Focus@! + + + With the new additions to the Game Tree using nodes has never been easier nor has it ever been more fluid. Included here is a list of the additions to the Game Tree referencing model as well as some tips on how to make the Game Tree work the way it was intended. + +Grid Nodes: + Grid nodes are now reference-able with the coordinates of the grid. Example: !@Grid::(1,1)@! +The example will return the top left most cell data. The grid understands coordinates like this (Row, Column) + + Grid nodes can reference node data just like any other node can. With a new added feature grids are even more useful. By using a new die rolling syntax you can draw just the number of the modified roll. While this will not pass during game play, you can use it with the grid node to create a random chart. The new die roll syntax is [#XdY]. # works just like q, yet it returns only the modified die result. + + Here is an example with a 3 x 3 Grid +Example: !@Grid::([#1d3], [#1d3])@! + +The result will be a random event from the grid. + +Bonus Node Included: A 52 Card Deck with 4 columns and 13 rows. (4 * 13 = 52) + +List Nodes: + List nodes now have a check box that allows users to send the content as a macro. List nodes are a prime reference holder because users can place a lot of references into one small node. + + For the best results from a list node my tip to users would be to create a list node and place it next to the character sheet they are using, inside a the PC Sheet. The list will then use the Child Referencing syntax, but the PC Sheet can go anywhere in the tree and the player will have easy access to all the references. + +(List Nodes inside a Tool created PC sheet vanish when moved, or I would recommend the list be placed inside these sheets also.) + + Here is an example of a Fortitude save inside the recommended list node: !!Fort::Check!! + +Text Nodes: + Text nodes remain little changed. I agree with all the 1.7.1 users who tell me, if it's not broke don't fix it. With that in mind I have some good tips for text nodes. + + Text nodes can be used in conjunction with the new grid features to create random encounters. A GM could place a list of text nodes into a folder and the grid could reference the nodes. + + Text nodes also work great when you need to have story text at hand that you don't want to type out during play. Create chapters with folder nodes and add the adventure text to different nodes. You can then use a List Node or a Grid Node to reference the different chapters. + +Bonus Node Included: A small book node with 1 Chapter and 3 Parts. + + + + + In Traipse starting a server has never been easier. The setup is as easy as 1., 2., 3 1. You will need to first start the Server GUI or the basic text based Server at least once so your software creates the server_ini.xml files in your myfiles directory. You can start it once and quit. @@ -244,174 +374,284 @@ 3. This is the hardest step. You need to make sure your selected port is forwarded by your router and open to your firewall. That's it! You can now start the server and register it to the meta for all users to enjoy! - - Do you see something that could be explained eaiser? Report the problem as a bug and it will be added to the manual. - - - - - - - - - - - - - - - - <br /> + + + + + + + + + + + + + + + + + + + + + + + <br /> <b>Chapter 1 Part 1</b> <br /><br /> An introduction to your adventure module can be placed here. - - <br /> + + + <br /> <b>Chapter 1 Part 2</b> <br /><br /> The adventurers have come this far. - - <br /> + + + <br /> <b>Chapter 1 Part 3</b> <br /><br /> Is this the end already? - - - - - AS - AD - ACAH - - KS - KD - KCKH - QSQDQCQHJSJDJCJH10S10D10C10H9S9D9C9H8S8D8C8H7S7D7C7H6S6D6C6H5S5D5C5H4S4D4C4H3S3D3C3H2S2D2C2H - - - - - !!52 Card Deck::([#1d13], [#1d4])!! - - - - - - - - - - !!Set 1::Enc 1!! - !!Set 2::Enc 1!! - - !!Set 1::Enc 2!! - !!Set 2::Enc 2!! - !!Set 1::Enc 3!! - - - - - - Hoot Hoot. It's an owl. - - Set 2 Random Encounter. - - - Dark Elves. Watch out! - - Kobolds a plenty. - - A Wandering Minotaur - - - - - - - - - + + + + + + + + AS + AD + AC + AH + + + KS + KD + KC + KH + + + QS + QD + QC + QH + + + JS + JD + JC + JH + + + 10S + 10D + 10C + 10H + + + 9S + 9D + 9C + 9H + + + 8S + 8D + 8C + 8H + + + 7S + 7D + 7C + 7H + + + 6S + 6D + 6C + 6H + + + 5S + 5D + 5C + 5H + + + 4S + 4D + 4C + 4H + + + 3S + 3D + 3C + 3H + + + 2S + 2D + 2C + 2H + + + + + + + + !=52 Card Deck::([#1d13], [#1d4])=! + + + + + + + + + + + + + !=Set 1::Enc 1=! + !=Set 2::Enc 1=! + + + !=Set 1::Enc 2=! + !=Set 2::Enc 2=! + + + !=Set 1::Enc 3=! + + + + + + + + + + Hoot Hoot. It's an owl. + + + Set 2 Random Encounter. + + + + + Dark Elves. Watch out! + + + Kobolds a plenty. + + + A Wandering Minotaur + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - + + + - - - - - - - - - - - - - - - + + - - - - + + - - - - - + + - - + + - - - - - - - - - - - - + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file + + + + + + + + + \ No newline at end of file diff -r 4b2884f29a72 -r 81d0bfd5e800 orpg/templates/nodes/4e_char_sheet.xml --- a/orpg/templates/nodes/4e_char_sheet.xml Fri Jan 15 22:45:51 2010 -0600 +++ b/orpg/templates/nodes/4e_char_sheet.xml Sat Jun 12 03:50:37 2010 -0500 @@ -1,4 +1,4 @@ -This node is designed to be as generic as possible. It should contain the core basics for users to fill out with game information that is specific to their character. +This node is designed to be as generic as possible. It should contain the core basics for users to fill out with game information that is specific to their character. The node is also designed to be organized with speed of use in mind. Since the majority of nodes are inside Tabbers you can easily use the top node and find all of your data inside. In fact, that is how I am writing this. @@ -30,29 +30,29 @@ ** I went with this format so users could create their Utility nodes and share with others. The nodes can contain Role Play information as well as attack and damage rolls. Also, the nodes can be completely genric, referencing the Name Text node and still look specific **It's just a node to hold your Inventory This bears repeating: -It comes with a Back Pack text node that you can clone to make bags and other containers. - - - - +It comes with a Back Pack text node that you can clone to make bags and other containers. + + + + - + - - + + - - + + - - + + - - + + text @@ -66,51 +66,7 @@ 1 1 - - - - Str - 8 - (!!Abilities::(1,2)!!-10)/2 - - Dex - 8 - (!!Abilities::(2,2)!!-10)/2 - - Con - 8 - (!!Abilities::(3,2)!!-10)/2 - - Int - 8 - (!!Abilities::(4,2)!!-10)/2 - - Wis - 8 - (!!Abilities::(5,2)!!-10)/2 - - Cha - 8 - (!!Abilities::(6,2)!!-10)/2 - - - - - - - - Armor - Bonus - - - Total - !!To Hit::(2,3)!! + !!To Hit::(2,4)!! - - BAB0Str Mod!#Abilities::(1,3)#! - - - - + Weapon @@ -120,7 +76,21 @@ Sword d6 - Maced8 + Maced8 + + + + + + + Armor + Bonus + + + Total + !=To Hit::(3,2)=! + !=To Hit::(4,2)=! + + BAB15Str Mod!=Abilities::(1,3)=! @@ -128,13 +98,13 @@ Armor - Bonus + Bonus Total - !!AC Bonus::(2,3)!! + !=AC Bonus::(3,2)=!+!=AC Bonus::(4,2)=! - Misc0 + Armor!!Armor::(2,2)!!Misc0 @@ -142,13 +112,13 @@ Armor - Bonus + Bonus Total - !!Armor::(2,3)!! + !=Armor::(3,2)=! - Base10 + Base10ArmorShield @@ -156,28 +126,64 @@ Armor - Bonus + Bonus Descripton Total - !!Feats(2,3)!! + !=Feats::(3,2)=! - Feat0 + Feat0 - + + + + Str + 12 + (!=Abilities::(1,2)=!-10)/2 + + Dex + 8 + (!=Abilities::(2,2)=!-10)/2 + + Con + 14 + (!=Abilities::(3,2)=!-10)/2 + + Int + 18 + (!=Abilities::(4,2)=!-10)/2 + + Wis + 8 + (!=Abilities::(5,2)=!-10)/2 + + Cha + 8 + (!=Abilities::(6,2)=!-10)/2 + + + + + /me uses an At Will <b>Attack:</b> [1d20+2+!#Abilities::(2,3)#!] <b>Damage:</b> [2!#Combat::Weapons::(2,2)#!] - + /me uses an Encounter <b>Attack:</b> [1d20+2+!#Abilities::(2,3)#!] <b>Damage:</b> [2!#Combat::Weapons::(2,2)#!] - + /me uses an Daily <b>Attack:</b> [1d20+2+!#Abilities::(2,3)#!] <b>Damage:</b> [2!#Combat::Weapons::(2,2)#!] - - Empty. - \ No newline at end of file + + Nothing + + Nothing + + Nothing + + Nothing + \ No newline at end of file diff -r 4b2884f29a72 -r 81d0bfd5e800 orpg/templates/nodes/split.xml --- a/orpg/templates/nodes/split.xml Fri Jan 15 22:45:51 2010 -0600 +++ b/orpg/templates/nodes/split.xml Sat Jun 12 03:50:37 2010 -0500 @@ -1,3 +1,2 @@ - - - \ No newline at end of file + + diff -r 4b2884f29a72 -r 81d0bfd5e800 orpg/templates/nodes/textctrl.xml --- a/orpg/templates/nodes/textctrl.xml Fri Jan 15 22:45:51 2010 -0600 +++ b/orpg/templates/nodes/textctrl.xml Sat Jun 12 03:50:37 2010 -0500 @@ -1,4 +1,1 @@ - - - text - +Text \ No newline at end of file diff -r 4b2884f29a72 -r 81d0bfd5e800 orpg/tools/FlatNotebook.py --- a/orpg/tools/FlatNotebook.py Fri Jan 15 22:45:51 2010 -0600 +++ b/orpg/tools/FlatNotebook.py Sat Jun 12 03:50:37 2010 -0500 @@ -74,6 +74,7 @@ # Beginning Of FLATNOTEBOOK wxPython Code #---------------------------------------------------------------------- +print 'Flatnotebook' import wx import random import math diff -r 4b2884f29a72 -r 81d0bfd5e800 orpg/tools/aliaslib.py --- a/orpg/tools/aliaslib.py Fri Jan 15 22:45:51 2010 -0600 +++ b/orpg/tools/aliaslib.py Sat Jun 12 03:50:37 2010 -0500 @@ -21,12 +21,12 @@ # Author: Dj Gilcrease # Maintainer: # Version: -# $Id: aliaslib.py,v 1.20 2007/08/09 05:23:21 digitalxero Exp $ +# $Id: aliaslib.py,v Traipse 'Ornery-Orc' prof.ebral Exp $ # # Description: nodehandler for alias. # -__version__ = "$Id: aliaslib.py,v 1.20 2007/08/09 05:23:21 digitalxero Exp $" +__version__ = "$Id: aliaslib.py,v Traipse 'Ornery-Orc' prof.ebral Exp $" from orpg.orpg_wx import * from orpg.orpgCore import component @@ -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): @@ -174,7 +175,6 @@ f.close() def OnMB_FileExportToTree(self, event): - #tree = component.get("tree") xml = '").replace("'", "'") @@ -496,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' @@ -504,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) @@ -689,8 +683,6 @@ self.regExList[self.filterIdx] = list def FormatText(self, event): - #self.textColorBtn = wx.Button(self, wx.ID_ANY, "Color") - #self.textColorBtn.SetForegroundColour(wx.BLACK) id = event.GetId() txt = self.textWnd.GetValue() (beg, end) = self.textWnd.GetSelection() diff -r 4b2884f29a72 -r 81d0bfd5e800 orpg/tools/inputValidator.py --- a/orpg/tools/inputValidator.py Fri Jan 15 22:45:51 2010 -0600 +++ b/orpg/tools/inputValidator.py Sat Jun 12 03:50:37 2010 -0500 @@ -25,7 +25,7 @@ # user input generated text. # -__version__ = "$Id: inputValidator.py,v 1.11 2006/11/04 21:24:22 digitalxero Exp $" +__version__ = "$Id: inputValidator.py,v Traipse 'Ornery-Orc' prof.ebral Exp $" ## diff -r 4b2884f29a72 -r 81d0bfd5e800 orpg/tools/orpg_log.py --- a/orpg/tools/orpg_log.py Fri Jan 15 22:45:51 2010 -0600 +++ b/orpg/tools/orpg_log.py Sat Jun 12 03:50:37 2010 -0500 @@ -21,7 +21,7 @@ # Author: Dj Gilcrease # Maintainer: # Version: -# $Id: orpg_log.py,v 1.9 2007/05/06 16:43:02 digitalxero Exp $ +# $Id: orpg_log.py,v Traipse 'Ornery-Orc' prof.ebral Exp $ # # Description: classes for orpg log messages # @@ -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. @@ -102,13 +102,15 @@ self.report = wx.Button(self, wx.ID_ANY, 'Bug Report') sizer = wx.GridBagSizer(hgap=1, vgap=1) sizer.Add(self.console, (0,0), span=(1,2), flag=wx.EXPAND) - sizer.Add(self.bt_clear, (1,0), flag=wx.ALIGN_LEFT) - sizer.Add(self.report, (1,1), flag=wx.ALIGN_LEFT) + sizer.Add(self.bt_clear, (1,0), span=(1,1), flag=wx.ALIGN_LEFT) + sizer.Add(self.report, (1,1), span=(1,1), flag=wx.ALIGN_RIGHT|wx.EXPAND) sizer.AddGrowableCol(0) sizer.AddGrowableRow(0) self.SetSizer(sizer) + #self.Layout() self.SetAutoLayout(True) - self.SetSize((450, 175)) + self.SetSize((450, 275)) + self.SetMinSize((450, 275)) self.Bind(wx.EVT_CLOSE, self.Min) self.Bind(wx.EVT_BUTTON, self.clear, self.bt_clear) self.Bind(wx.EVT_BUTTON, self.bug_report, self.report) diff -r 4b2884f29a72 -r 81d0bfd5e800 orpg/tools/orpg_settings.py --- a/orpg/tools/orpg_settings.py Fri Jan 15 22:45:51 2010 -0600 +++ b/orpg/tools/orpg_settings.py Sat Jun 12 03:50:37 2010 -0500 @@ -33,7 +33,8 @@ from orpg.tools.orpg_log import logger from orpg.tools.validate import validate -from orpg.orpg_xml import xml +from xml.etree.ElementTree import ElementTree, Element, parse +from xml.etree.ElementTree import fromstring, tostring from orpg.tools.settings import settings class orpgSettingsWnd(wx.Dialog): @@ -70,29 +71,28 @@ def build_gui(self): validate.config_file("settings.xml","default_settings.xml") filename = dir_struct["user"] + "settings.xml" - temp_file = open(filename) - temp_file.close() - children = self.settings.xml_dom._get_childNodes() - for c in children: self.build_window(c,self.tabber) + temp_file = parse(filename) + children = self.settings.xml_dom.getchildren() + for c in children: self.build_window(c, self.tabber) def build_window(self, xml_dom, parent_wnd): - name = xml_dom._get_nodeName() + name = xml_dom.tag #container = 0 if name=="tab": temp_wnd = self.do_tab_window(xml_dom,parent_wnd) return temp_wnd def do_tab_window(self, xml_dom, parent_wnd): - type = xml_dom.getAttribute("type") - name = xml_dom.getAttribute("name") + type = xml_dom.get("type") + name = xml_dom.get("name") if type == "grid": temp_wnd = self.do_grid_tab(xml_dom, parent_wnd) parent_wnd.AddPage(temp_wnd, name, False) elif type == "tab": temp_wnd = orpgTabberWnd(parent_wnd, style=FNB.FNB_NO_X_BUTTON) - children = xml_dom._get_childNodes() + children = xml_dom.getchildren() for c in children: - if c._get_nodeName() == "tab": self.do_tab_window(c, temp_wnd) + if c.tag == "tab": self.do_tab_window(c, temp_wnd) temp_wnd.SetSelection(0) parent_wnd.AddPage(temp_wnd, name, False) elif type == "text": @@ -103,12 +103,12 @@ def do_grid_tab(self, xml_dom, parent_wnd): settings = [] - children = xml_dom._get_childNodes() + children = xml_dom.getchildren() for c in children: - name = c._get_nodeName() - value = c.getAttribute("value") - help = c.getAttribute("help") - options = c.getAttribute("options") + name = c.tag + value = c.get("value") + help = c.get("help") + options = c.get("options") settings.append([name, value, options, help]) temp_wnd = settings_grid(parent_wnd, settings, self.changes) return temp_wnd @@ -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 "' + rm.getRoller() + '" roller.') except Exception, e: - print e rm.setRoller('std') - self.settings.change('dieroller', 'std') - self.chat.SystemPost('"' + changes + '" is an invalid roller. Setting roller to "std"') + rm.setRoller(cur_die) + self.settings.change('dieroller', cur_die) + self.chat.SystemPost('"' + changes + '" is an invalid roller.') + self.chat.InfoPost('Available die rollers: ' +str(rm.listRollers()) ) + self.chat.InfoPost('You are using the "' +cur_die+ '" die roller.') def colortree_ok(self, changes): top_frame = component.get('frame') @@ -306,4 +309,3 @@ for i in range(0,cols): self.SetColSize(i,col_w) self.Refresh() -#settings = orpg.tools.settings.Settings() diff -r 4b2884f29a72 -r 81d0bfd5e800 orpg/tools/passtool.py --- a/orpg/tools/passtool.py Fri Jan 15 22:45:51 2010 -0600 +++ b/orpg/tools/passtool.py Sat Jun 12 03:50:37 2010 -0500 @@ -21,7 +21,7 @@ # Author: Todd "Snowdog" Faris # Maintainer: # Version: -# $Id: passtool.py,v 1.9 2006/11/04 21:24:22 digitalxero Exp $ +# $Id: passtool.py,v Traipse 'Ornery-Orc' prof.ebral Exp $ # # Description: password helper. remembers passwords so user # doesn't have to type passwords over and over diff -r 4b2884f29a72 -r 81d0bfd5e800 orpg/tools/predTextCtrl.py --- a/orpg/tools/predTextCtrl.py Fri Jan 15 22:45:51 2010 -0600 +++ b/orpg/tools/predTextCtrl.py Sat Jun 12 03:50:37 2010 -0500 @@ -60,48 +60,17 @@ return self.asciiChar -# This class implements the tree structure to hold the words -# -# Defines: -# __init__(self,filename) -# updateMostCommon(self,target) -# setWord(self,wordText,priority,sumFlag) -# addWord(self,wordText) -# setWord(self,wordText) -# setWordPriority(self,wordText,priority) -# findWordNode(self,wordText) returns class Letter -# findWordPriority(self,wordText) returns int -# getPredition(self,k,cur) returns string class LetterTreeClass(object): - # Initialization subroutine. - # - # self : instance of self - # filename : name of word file to use - # - # returns None - # - # Purpose: Constructor for LetterTree. Basically, it initializes itself with a word file, if present. def __init__(self, singletonKey): if not isinstance(singletonKey, _SingletonKey): raise invalid_argument(_("Use LetterTree() to get access to singleton")) - self.rootNode = Letter("",None) # rootNode is a class Letter - self.rootNode.children = {} # initialize the children list - + self.rootNode = Letter("",None) + self.rootNode.children = {} - # updateMostCommon subroutine. - # - # self : instance of self - # target : class Letter that was updated - # - # Returns None - # - # Purpose: Updates all of the parent nodes of the target, such that their mostCommon member - # points to the proper class Letter, based on the newly updated priorities. def updateMostCommon(self, target): - # cur is a class Letter - prev = target.parentNode # prev is a class Letter + prev = target.parentNode while prev: if prev.mostCommon is None: prev.mostCommon = target @@ -110,106 +79,44 @@ prev.mostCommon = target prev = prev.parentNode - + def setWord(self,wordText,priority = 1,sumFlag = 0): + cur = self.rootNode + for ch in wordText: + if cur.children.has_key(ch): + cur = cur.children[ch] + else: + newLetter = Letter(ch,cur) + if cur is self.rootNode: + newLetter.parentNode = None + cur.children[ch] = newLetter + cur = newLetter + if sumFlag: cur.priority += priority + else: cur.priority = priority + self.updateMostCommon(cur) - # setWord subroutine. - # - # self : instance of self - # wordText : string representing word to add - # priority : integer priority to set the word - # sumFlag : if True, add the priority to the existing, else assign the priority - # - # Returns: None - # - # Purpose: Sets or increments the priority of a word, adding the word if necessary - def setWord(self,wordText,priority = 1,sumFlag = 0): - cur = self.rootNode # start from the root - for ch in wordText: # for each character in the word - if cur.children.has_key(ch): # check to see if we've found a new word - cur = cur.children[ch] # if we haven't found a new word, move to the next letter and try again - else: # in this clause, we're creating a new branch, as the word is new - newLetter = Letter(ch,cur) # create a new class Letter using this ascii code and the current letter as a parent - if cur is self.rootNode: # special case: Others expect the top level letters to point to None, not self.rootNode - newLetter.parentNode = None - cur.children[ch] = newLetter # add the new letter to the list of children of the current letter - cur = newLetter # make the new letter the current one for the next time through - - # at this point, cur is pointing to the last letter of either a new or existing word. - if sumFlag: cur.priority += priority # if the caller wants to add to the existing (0 if new) - else: cur.priority = priority # else, the set the priority directly - self.updateMostCommon(cur) # this will run back through the tree to fix up the mostCommon members - - # addWord subroutine. - # - # self : instance of self - # wordText : string representing word to add - # - # Returns: None - # - # Purpose: Convenience method that wraps setWord. Used to add words known not to exist. def addWord(self,wordText): self.setWord(wordText,priority = 1) - # incWord subroutine. - # - # self : instance of self - # wordText : string representing word to add - # - # Returns: None - # - # Purpose: Convenience method that wraps setWord. Used to increment the priority of existing words and add new words. - # Note: Generally, this method can be used instead of addWord. - def incWord(self,wordText): self.setWord(wordText,priority = 1, sumFlag = 1) - # setWordPriority subroutine. - # - # self : instance of self - # wordText : string representing word to add - # priority: int that is the new priority - # - # Returns: None - # - # Purpose: Convenience method that wraps setWord. Sets existing words to priority or adds new words with priority = priority - def setWordPriority(self,wordText,priority): self.setWord(wordText,priority = priority) - # findWordNode subroutine. - # - # self : instance of self - # wordText : string representing word to add - # - # Returns: class Letter or None if word isn't found. - # - # Purpose: Given a word, it returns the class Letter node that corresponds to the word. Used mostly in prep for a call to - # getPrediction() - - def findWordNode(self,wordText): #returns class Letter that represents the last letter in the word - cur = self.rootNode # start at the root - for ch in wordText: # move through each letter in the word - if cur.children.has_key(ch): # if the next letter exists, make cur equal that letter and loop + def findWordNode(self,wordText): + cur = self.rootNode + for ch in wordText: + if cur.children.has_key(ch): cur = cur.children[ch] - else: return None # return None if letter not found - return cur # return cur, as this points to the last letter if we got this far - - - # findWordPriority subroutine. - # - # self : instance of self - # wordText : string representing word to add - # - # Returns: Int representing the word's priority or 0 if not found. - # - # Purpose: Returns the priority of the given word + else: return None + return cur def findWordPriority(self,wordText): - cur = self.findWordNode(wordText) # find the class Letter node that corresponds to this word - if cur: return cur.priority # if it was found, return it's priority - else: return 0 # else, return 0, meaning word not found + cur = self.findWordNode(wordText) + if cur: return cur.priority + else: return 0 def printTree(self, current=None): letters = [] @@ -222,50 +129,18 @@ letters.append(m) return letters - # getPrediction subroutine. - # - # self : instance of self - # k : ASCII char that was typed - # cur : class Letter that points to the current node in LetterTree - # - # Returns: The predicted text or "" if none found - # - # Purpose: This is the meat and potatoes of data structure. It takes the "current" Letter node and the next key typed - # and returns it's guess of the rest of the word, based on the highest priority letter in the rest of the branch. def getPrediction(self,k,cur): - if cur.children.has_key(k) : # check to see if the key typed is a sub branch - # If so, make a prediction. Otherwise, do the else at the bottom of - # the method (see below). - - cur = cur.children[k] # set the cur to the typed key's class Letter in the sub-branch - - backtrace = cur.mostCommon # backtrace is a class Letter. It's used as a placeholder to back trace - # from the last letter of the mostCommon word in the - # sub-tree up through the tree until we meet ourself at cur. We'll - # build the guess text this way - - returnText = "" # returnText is a string. This will act as a buffer to hold the string - # we build. - - while cur is not backtrace: # Here's the loop. We loop until we've snaked our way back to cur - - returnText = backtrace.asciiChar + returnText # Create a new string that is the character at backtrace + everything - # so far. So, for "tion" we'll build "n","on","ion","tion" as we .. - - backtrace = backtrace.parentNode # ... climb back towards cur - - return returnText # And, having reached here, we've met up with cur, and returnText holds - # the string we built. Return it. - - else: # This is the else to the original if. - # If the letter typed isn't in a sub branch, then - # the letter being typed isn't in our tree, so - return "" # return the empty string - - -# End of class LetterTree! - + if cur.children.has_key(k) : + cur = cur.children[k] + backtrace = cur.mostCommon + returnText = '' + while cur is not backtrace: + returnText = backtrace.asciiChar + returnText + backtrace = backtrace.parentNode + return returnText + else: + return "" class _SingletonKey(object): @@ -277,62 +152,24 @@ __key = _SingletonKey() LetterTree = LetterTreeClass(__key) -# This class extends wx.TextCtrl -# -# Extends: wx.TextCtrl -# -# Overrides: -# wx.TextCtrl.__init__(self,parent,id,value,size,style,name) -# wx.TextCtrl.OnChar(self,Event) -# -# Defines: -# findWord(self,insert,st) + class predTextCtrl(ExpandoTextCtrl): - # Initialization subroutine. - # - # self : instance of self - # parent: reference to parent window (wxWindow, me-thinks) - # id: new Window Id, default to -1 to create new (I think: see docs for wxPython) - # value: String that is the initial value the control holds, defaulting to "" - # size: defaults to wx.DefaultSize - # style: defaults to 0 - # name: defaults to "text" - # keyHook: must be a function pointer that takes self and a GetKeyCode object - # validator: defaults to None - # - # Note: These parameters are essentially just passed back to the native wx.TextCtrl. - # I basically just included (stole) enough of them from chatutils.py to make - # it work. Known missing args are pos and validator, which aren't used by - # chatutils.py. - # - # Returns: None - # - # Purpose: Constructor for predTextCtrl. Calls wx.TextCtrl.__init__ to get default init - # behavior and then inits a LetterTree and captures the parent for later use in - # passing events up the chain. def __init__(self, parent, id = -1, value = "", size = (30,30), style = 0, name = "text", keyHook = None, validator=None): - - # Call super() for default behavior if validator: ExpandoTextCtrl.__init__(self, parent, id=id, value=value, size=size, style=style, name=name, validator=validator ) else: ExpandoTextCtrl.__init__(self, parent, id=id, value=value, size=size, style=style, name=name) - self.tree = LetterTree # Instantiate a new LetterTree. - # TODO: make name of word file an argument. - self.parent = parent # Save parent for later use in passing KeyEvents - self.cur = self.tree.rootNode # self.cur is a short cut placeholder for typing consecutive chars - # It may be vestigal - self.keyHook = keyHook # Save the keyHook passed in + self.tree = LetterTree + self.parent = parent + self.cur = self.tree.rootNode + self.keyHook = keyHook ExpandoTextCtrl._wrapLine = self._wrapLine def _wrapLine(self, line, dc, width): - # Estimate where the control will wrap the lines and - # return the count of extra lines needed. - # Re writes ExpandoTextCtrl _wrapLine function pte = dc.GetPartialTextExtents(line) width -= wx.SystemSettings.GetMetric(wx.SYS_VSCROLL_X) idx = 0 @@ -342,9 +179,7 @@ while idx < len(pte): if line[idx] == ' ': spc = idx if pte[idx] - start > width: - # we've reached the max width, add a new line count += 1 - # did we see a space? if so restart the count at that pos if spc != -1: idx = spc + 1 spc = -1 @@ -353,31 +188,7 @@ idx += 1 return count - # findWord subroutine. - # - # self : instance of self - # insert: index of last char in st - # st : string from insert to the left - # - # Note: This implementation is about the third one for this method. Originally, - # st was an arbitrary string and insert was the point within - # this string to begin looking left. Since, I finally got it - # to work right as it is around 2 in the morning, I'm not touching it, for now. - # - # Returns: String that is the word or "" if none found. This generally doesn't - # happen, as st usually ends in a letter, which will be returned. - # - # Purpose: This function is generally used to figure out the beginning of the - # current word being typed, for later use in a LetterTree.getPrediction() def findWord(self, insert, st): - - # Good luck reading this one. Basically, I started out with an idea, and fiddled with the - # constants as best I could until it worked. It's not a piece of work of which I'm too - # proud. Basically, it's intent is to check each character to the left until it finds one - # that isn't a letter. If it finds such a character, it stops and returns the slice - # from that point to insert. Otherwise, it returns the whole thing, due to begin being - # initialized to 0 - begin = 0 for offset in range(insert - 1): if st[-(offset + 2)] not in string.ascii_letters: @@ -385,210 +196,96 @@ break return st[begin:insert] - - # OnChar subroutine. - # - # self : instance of self - # event: a GetKeyCode object - # - # Returns: None - # - # Purpose: This function is the key event handler for predTextCtrl. It handles what it - # needs to and passes the event on to it's parent's OnChar method. def OnChar(self,event): - # Before we do anything, call the keyHook handler, if not None - # This is currently used to implement the typing/not_typing messages in a manner that - # doesn't place the code here. Maybe I should reconsider that. :) if(self.keyHook): - if self.keyHook(event) == 1: # if the passed in keyHook routine returns a one, it wants no predictive behavior + if self.keyHook(event) == 1: self.parent.OnChar(event) return - - # This bit converts the GetKeyCode() return (int) to a char if it's in a certain range asciiKey = "" if (event.GetKeyCode() < 256) and (event.GetKeyCode() > 19): asciiKey = chr(event.GetKeyCode()) - - if asciiKey == "": # If we didn't convert it to a char, then process based on the int GetKeyCodes - if event.GetKeyCode() == wx.WXK_TAB: # We want to hook tabs to allow the user to signify acceptance of a - # predicted word. - # Handle Tab key - fromPos = toPos = 0 # get the current selection range + if asciiKey == "": + if event.GetKeyCode() == wx.WXK_TAB: + fromPos = toPos = 0 (fromPos,toPos) = self.GetSelection() - if (toPos - fromPos) == 0: # if there is no selection, pass tab on + if (toPos - fromPos) == 0: self.parent.OnChar(event) return - else: # This means at least one char is selected - self.SetInsertionPoint(toPos) # move the insertion point to the end of the selection - self.SetSelection(toPos,toPos) # and set the selection to no chars - # The prediction, if any, had been inserted into the text earlier, so - # moving the insertion point to the spot directly afterwards is - # equivalent to acceptance. Without this, the next typed key would - # clobber the prediction. - - return # Don't pass tab on in this case + else: + self.SetInsertionPoint(toPos) + self.SetSelection(toPos,toPos) + return - elif event.GetKeyCode() == wx.WXK_RETURN: # We want to hook returns, so that we can update the word list - st = self.GetValue() # Grab the text from the control - newSt = "" # Init a buffer - # This block of code, by popular demand, changes the behavior of the control to ignore any prediction that - # hasn't been "accepted" when the enter key is struck. - (startSel,endSel) = self.GetSelection() # get the curren selection - - # - # Start update - # Changed the following to allow for more friendly behavior in - # a multilined predTextCtrl. - # - # front = st[:startSel] # Slice off the text to the front of where we are - # back = st[endSel:] # Slice off the text to the end from where we are - # st = front + back # This expression creates a string that get rid - # of any selected text. - # self.SetValue(st) - + elif event.GetKeyCode() == wx.WXK_RETURN: + st = self.GetValue() + newSt = "" + (startSel,endSel) = self.GetSelection() self.Remove( startSel, endSel ) st = string.strip( self.GetValue() ) - # - # End update - # - - # this loop will walk through every character in st and add it to - # newSt if it's a letter. If it's not a letter, (e.g. a comma or - # hyphen) a space is added to newSt in it's place. for ch in st: if ch not in string.ascii_letters: newSt += " " else: newSt += ch - # Now that we've got a string of just letter sequences (words) and spaces - # split it and to a LetterTree.incWord on the lowercase version of it. - # Reminder: incWord will increment the priority of existing words and add - # new ones for aWord in string.split(newSt): self.tree.incWord(string.lower(aWord)) - self.parent.OnChar(event) # Now that all of the words are added, pass the event and return + self.parent.OnChar(event) return - # We want to capture the right arrow key to fix a slight UI bug that occurs when one right arrows - # out of a selection. I set the InsertionPoint to the beginning of the selection. When the default - # right arrow event occurs, the selection goes away, but the cursor is in an unexpected location. - # This snippet fixes this behavior and then passes on the event. elif event.GetKeyCode() == wx.WXK_RIGHT: (startSel,endSel) = self.GetSelection() self.SetInsertionPoint(endSel) self.parent.OnChar(event) return - # Ditto as wx.WXK_RIGHT, but for completeness sake elif event.GetKeyCode() == wx.WXK_LEFT: (startSel,endSel) = self.GetSelection() self.SetInsertionPoint(startSel) self.parent.OnChar(event) return else: - # Handle any other non-ascii events by calling parent's OnChar() - self.parent.OnChar(event) #Call super.OnChar to get default behavior + + self.parent.OnChar(event) return elif asciiKey in string.ascii_letters: - # This is the real meat and potatoes of predTextCtrl. This is where most of the - # wx.TextCtrl logic is changed. - (startSel,endSel) = self.GetSelection() # get the curren selection - st = self.GetValue() # and the text in the control - front = st[:startSel] # Slice off the text to the front of where we are - back = st[endSel:] # Slice off the text to the end from where we are - st = front + asciiKey + back # This expression creates a string that will insert the - # typed character (asciiKey is generated at the - # beginning of OnChar()) into the text. If there - # was text selected, that text will not be part - # of the new string, due to the way front and back - # were sliced. + (startSel,endSel) = self.GetSelection() + st = self.GetValue() + front = st[:startSel] + back = st[endSel:] + st = front + asciiKey + back + insert = startSel + 1 + curWord = "" + if (len(back) == 0) or (back[0] not in string.ascii_letters): - insert = startSel + 1 # creates an int that denotes where the new InsertionPoint - # should be. - curWord = "" # Assume there's a problem with finding the curWord - if (len(back) == 0) or (back[0] not in string.ascii_letters): # We should only insert a prediction if we are typing - # at the end of a word, not in the middle. There are - # three cases: we are typing at the end of the string or - # we are typing in the middle of the string and the next - # char is NOT a letter or we are typing in the middle of the - # string and the next char IS a letter. Only the former two - # cases denote that we should make a prediction - # Note: The order of the two logical clauses here is important! - # If len(back) == 0, then the expression back[0] will - # blow up with an out of bounds array subscript. Luckily - # the or operator is a short-circuit operator and in this - # case will only evaluate back[0] if len(back) != 0, in - # which we're safely in bounds. + curWord = self.findWord(insert,front + asciiKey) + else: + self.parent.OnChar(event) + return - curWord = self.findWord(insert,front + asciiKey) # Now that we know we're supposed to make a prediction, - # let's find what word root to use in our prediction. - # Note: This is using the confusing findWord method. I - # send it insert and the text from the beginning - # of the text through the key just entered. This is - # NOT the original usage, but it does work. See - # findWord() for more details. - - else: # Here, we've found we're in the middle of a word, so we're - # going to call the parent's event handler. + if curWord == "": self.parent.OnChar(event) return - if curWord == "": # Here, we do a quick check to make sure we have a good root - # word. If not, allow the default thing to happen. Of course, - # now that I'm documenting this, it occurs to me to wonder why - # I didn't do the same thing I just talked about. Hmmmmmm. - - self.parent.OnChar(event) # we're done here + self.cur = self.tree.findWordNode(string.lower(curWord[:-1])) + if self.cur is None: + self.parent.OnChar(event) return - - self.cur = self.tree.findWordNode(string.lower(curWord[:-1])) # Still with me? We're almost done. At this point, we - # need to convert our word string to a Letter node, - # because that's what getPrediction expects. Notice - # that we're feeding in the string with the last - # char sliced off. For developmentally historical - # reasons, getPrediction wants the node just before - # the typed character and the typed char separately. - - - if self.cur is None: - self.parent.OnChar(event) # if there's no word or no match, we're done - return - - - # get the prediction - predictText = self.tree.getPrediction(string.lower(asciiKey),self.cur) # This is the big prediction, as noted above - # Note the use of string.lower() because we - # keep the word list in all lower case,but we - # want to be able to match any capitalization + predictText = self.tree.getPrediction(string.lower(asciiKey),self.cur) if predictText == "": - self.parent.OnChar(event) # if there's no prediction, we're done + self.parent.OnChar(event) return - - # And now for the big finale. We're going to take the string st - # we created earlier and insert the prediction right after the - # newly typed character. - front = st[:insert] # Grab a new front from st - back = st[insert:] # Grab a new back - - st = front + predictText + back # Insert the prediction + front = st[:insert] + back = st[insert:] - self.SetValue(st) # Now, overwrite the controls text with the new text - self.SetInsertionPoint(insert) # Set the proper insertion point, directly behind the - # newly typed character and directly in front of the - # predicted text. + st = front + predictText + back + self.SetValue(st) + self.SetInsertionPoint(insert) + self.SetSelection(insert,insert+len(predictText)) + return + else: - self.SetSelection(insert,insert+len(predictText)) # Very important! Set the selection to encompass the predicted - # text. This way, the user can ignore the prediction by simply - # continuing to type. Remember, if the user wants the prediction - # s/he must strike the tab key at this point. Of course, one could - # just use the right arrow key as well, but that's not as easy to - # reach. + self.parent.OnChar(event) + return - return # Done! Do NOT pass the event on at this point, because it's all done. - else: - # Handle every other non-letter ascii (e.g. semicolon) by passing the event on. - self.parent.OnChar(event) #Call super.OnChar to get default behavior - return -# End of class predTextCtrl! diff -r 4b2884f29a72 -r 81d0bfd5e800 orpg/tools/pubsub.py --- a/orpg/tools/pubsub.py Fri Jan 15 22:45:51 2010 -0600 +++ b/orpg/tools/pubsub.py Sat Jun 12 03:50:37 2010 -0500 @@ -24,7 +24,7 @@ :Author: Oliver Schoenborn :Since: Apr 2004 -:Version: $Id: pubsub.py,v 1.8 2006/06/11 00:12:59 RD Exp $ +:Version: $Id: pubsub.py,v Traipse 'Ornery-Orc' prof.ebral Exp $ :Copyright: \(c) 2004 Oliver Schoenborn :License: wxWidgets """ diff -r 4b2884f29a72 -r 81d0bfd5e800 orpg/tools/rgbhex.py --- a/orpg/tools/rgbhex.py Fri Jan 15 22:45:51 2010 -0600 +++ b/orpg/tools/rgbhex.py Sat Jun 12 03:50:37 2010 -0500 @@ -21,7 +21,7 @@ # Author: Chris Davis # Maintainer: # Version: -# $Id: rgbhex.py,v 1.10 2007/02/19 16:33:20 digitalxero Exp $ +# $Id: rgbhex.py,v Traipse 'Ornery-Orc' prof.ebral Exp $ # # Description: rgb to hex utility diff -r 4b2884f29a72 -r 81d0bfd5e800 orpg/tools/scriptkit.py --- a/orpg/tools/scriptkit.py Fri Jan 15 22:45:51 2010 -0600 +++ b/orpg/tools/scriptkit.py Sat Jun 12 03:50:37 2010 -0500 @@ -21,7 +21,7 @@ # Author: Ted Berg # Maintainer: # Version: -# $Id: scriptkit.py,v 1.15 2006/11/04 21:24:22 digitalxero Exp $ +# $Id: scriptkit.py,v Traipse 'Ornery-Orc' prof.ebral Exp $ # # Description: Class that contains convenience methods for various operations. Was created with the purpose # of exposing a simple API to users of an as yet uncreated scripting interface. @@ -30,7 +30,7 @@ import time from orpg.orpg_windows import * -from orpg.orpg_xml import * +#from orpg.orpg_xml import * from orpg.orpg_wx import * import orpg.chat.chat_msg @@ -45,7 +45,7 @@ self.map = component.get( 'map' ) self.settings = component.get( 'settings' ) self.session = component.get('session') - self.xml = component.get('xml') + #self.xml = component.get('xml') def addMiniatureToMap( self, min_label, min_url, unique=0 ): """Adds a new miniature icon to the map. Miniature will be labeled unless autolabel is diff -r 4b2884f29a72 -r 81d0bfd5e800 orpg/tools/server_probe.py --- a/orpg/tools/server_probe.py Fri Jan 15 22:45:51 2010 -0600 +++ b/orpg/tools/server_probe.py Sat Jun 12 03:50:37 2010 -0500 @@ -23,7 +23,7 @@ # Author: Chris Davis # Maintainer: # Version: -# $Id: server_probe.py,v 1.10 2006/11/04 21:24:22 digitalxero Exp $ +# $Id: server_probe.py,v Traipse 'Ornery-Orc' prof.ebral Exp $ # # Description: This is a periodic maintenance script for removing # Unresponsive servers from the meta list. diff -r 4b2884f29a72 -r 81d0bfd5e800 orpg/tools/settings.py --- a/orpg/tools/settings.py Fri Jan 15 22:45:51 2010 -0600 +++ b/orpg/tools/settings.py Sat Jun 12 03:50:37 2010 -0500 @@ -2,41 +2,32 @@ from orpg.tools.orpg_log import logger from orpg.tools.validate import validate -from orpg.orpg_xml import xml +from xml.etree.ElementTree import ElementTree, Element, parse +from xml.etree.ElementTree import fromstring, tostring from orpg.orpgCore import component from orpg.dirpath import dir_struct class Settings: def __init__(self): - self.xml = component.get("xml") self.changes = [] validate.config_file("settings.xml","default_settings.xml") self.filename = dir_struct["user"] + "settings.xml" - temp_file = open(self.filename) - txt = temp_file.read() - temp_file.close() - - self.xml_dom = xml.parseXml(txt) - - if self.xml_dom is None: self.rebuildSettings() - self.xml_dom = self.xml_dom._get_documentElement() + xml_dom = parse(dir_struct["user"] + "settings.xml") + if xml_dom == None: self.rebuildSettings() + else: self.xml_dom = xml_dom.getroot() def rebuildSettings(self): logger.info("Settings file has be corrupted, rebuilding settings.", True) try: os.remove(self.filename) except: pass - validate.config_file("settings.xml","default_settings.xml") - temp_file = open(self.filename) - txt = temp_file.read() - temp_file.close() - self.xml_dom = xml.parseXml(txt) + self.xml_dom = parse(self.filename).getroot() def get_setting(self, name): ##Depricated return self.get(name) def get(self, name): - try: return self.xml_dom.getElementsByTagName(name)[0].getAttribute("value") + try: return self.xml_dom.getiterator(name)[0].get("value") except: return 0 def get_setting_keys(self): ##Depricated @@ -44,30 +35,30 @@ def get_keys(self): keys = [] - tabs = self.xml_dom.getElementsByTagName("tab") + tabs = self.xml_dom.getiterator("tab") for i in xrange(0, len(tabs)): - if tabs[i].getAttribute("type") == 'grid': - children = tabs[i]._get_childNodes() - for c in children: keys.append(c._get_tagName()) + if tabs[i].get("type") == 'grid': + children = tabs[i].getchildren() + for c in children: keys.append(c.tag) return keys def set_setting(self, name, value): ##Depricated self.change(name, value) def change(self, name, value): - self.xml_dom.getElementsByTagName(name)[0].setAttribute("value", value) + self.xml_dom.getiterator(name)[0].set("value", value) def add_setting(self, tab, setting, value, options, help): ##Depricated return self.add(tab, setting, value, options, help) def add(self, tab, setting, value, options, help): - if len(self.xml_dom.getElementsByTagName(setting)) > 0: return False - tabs = self.xml_dom.getElementsByTagName("tab") - newsetting = xml.parseXml('<' + setting + ' value="' + value + '" options="' + - options + '" help="' + help + '" />')._get_documentElement() + if len(self.xml_dom.getiterator(setting)) > 0: return False + tabs = self.xml_dom.getiterator("tab") + newsetting = fromstring('<' + setting + ' value="' + value + '" options="' + + options + '" help="' + help + '" />') for i in xrange(0, len(tabs)): - if tabs[i].getAttribute("name") == tab and tabs[i].getAttribute("type") == 'grid': - tabs[i].appendChild(newsetting) + if tabs[i].get("name") == tab and tabs[i].get("type") == 'grid': + tabs[i].append(newsetting) return True return False @@ -75,49 +66,44 @@ tab_xml = '' else: tab_xml += 'name="' + tabname + '" type="' + tabtype + '">' - newtab = xml.parseXml(tab_xml)._get_documentElement() + newtab = fromstring(tab_xml) if parent != None: - tabs = self.xml_dom.getElementsByTagName("tab") + tabs = self.xml_dom.getiterator("tab") for i in xrange(0, len(tabs)): - if tabs[i].getAttribute("name") == parent and tabs[i].getAttribute("type") == 'tab': - children = tabs[i]._get_childNodes() + if tabs[i].get("name") == parent and tabs[i].get("type") == 'tab': + children = tabs[i].getchildren() for c in children: - if c.getAttribute("name") == tabname: return False - tabs[i].appendChild(newtab) + if c.get("name") == tabname: return False + tabs[i].append(newtab) return True else: - children = self.xml_dom._get_childNodes() + children = self.xml_dom.getchildren() for c in children: - if c.getAttribute("name") == tabname: return False - self.xml_dom.appendChild(newtab) + if c.get("name") == tabname: return False + self.xml_dom.append(newtab) return True return False def updateIni(self): defaultFile = orpg.dirpath.dir_struct['template'] + 'default_settings.xml' - temp_file = open(defaultFile) - txt = temp_file.read() - temp_file.close() - default_dom = xml.parseXml(txt)._get_documentElement() - for child in default_dom.getChildren(): - if child._get_tagName() == 'tab' and child.hasChildNodes(): self.proccessChildren(child) - default_dom.unlink() + default_dom = parse(defaultfile) + for child in default_dom.getchildren(): + if child.tag == 'tab': self.proccessChildren(child) def proccessChildren(self, dom, parent=None): - if dom._get_tagName() == 'tab': - self.add_tab(parent, dom.getAttribute("name"), dom.getAttribute("type")) + if dom.tag == 'tab': self.add_tab(parent, dom.get("name"), dom.get("type")) - for child in dom.getChildren(): - if child._get_tagName() == 'tab' and child.hasChildNodes(): - self.proccessChildren(child, dom.getAttribute("name")) + for child in dom.getchildren(): + if child.tag == 'tab': self.proccessChildren(child, dom.get("name")) else: - self.add_setting(dom.getAttribute("name"), child._get_tagName(), - child.getAttribute("value"), child.getAttribute("options"), - child.getAttribute("help")) + self.add_setting(dom.get("name"), child.tag, + child.get("value"), child.get("options"), + child.get("help")) def save(self): + #self.xml_dom.write(self.filename) temp_file = open(self.filename, "w") - temp_file.write(xml.toxml(self.xml_dom,1)) + temp_file.write(tostring(self.xml_dom)) temp_file.close() settings = Settings() diff -r 4b2884f29a72 -r 81d0bfd5e800 orpg/tools/toolBars.py --- a/orpg/tools/toolBars.py Fri Jan 15 22:45:51 2010 -0600 +++ b/orpg/tools/toolBars.py Sat Jun 12 03:50:37 2010 -0500 @@ -25,7 +25,7 @@ # # -__version__ = "$Id: toolBars.py,v 1.13 2006/11/04 21:24:22 digitalxero Exp $" +__version__ = "$Id: toolBars.py,v Traipse 'Ornery-Orc' prof.ebral Exp $" ## diff -r 4b2884f29a72 -r 81d0bfd5e800 orpg/tools/validate.py --- a/orpg/tools/validate.py Fri Jan 15 22:45:51 2010 -0600 +++ b/orpg/tools/validate.py Sat Jun 12 03:50:37 2010 -0500 @@ -1,11 +1,3 @@ -# file: config_files.py -# -# Author: Todd Faris (Snowdog) -# Date: 5/10/2005 -# -# Misc. config file service methods -# - from orpg.dirpath import dir_struct import os from orpg.orpgCore import component diff -r 4b2884f29a72 -r 81d0bfd5e800 plugins/bcg/__init__.py diff -r 4b2884f29a72 -r 81d0bfd5e800 plugins/bcg/tok_dialogs.py --- a/plugins/bcg/tok_dialogs.py Fri Jan 15 22:45:51 2010 -0600 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,531 +0,0 @@ -# Copyright (C) 2000-2001 The OpenRPG Project -# -# openrpg-dev@lists.sourceforge.net -# -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation; either version 2 of the License, or -# (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. -# -- -# -# File: mapper/min_dialogs.py -# Author: Chris Davis -# Maintainer: -# Version: -# $Id: min_dialogs.py,v 1.27 2006/11/13 02:23:16 digitalxero Exp $ -# -# Description: This file contains some of the basic definitions for the chat -# utilities in the orpg project. - -##----------------------------- -## token List Panel -##----------------------------- - -from tokens import * - -class min_list_panel(wx.Dialog): - - def __init__(self, parent,layers, log, pos =(-1,-1)): - wx.Dialog.__init__(self, parent,-1, log,pos = (-1,-1), size = (785,175), style=wx.RESIZE_BORDER) - listID = wx.NewId() - self.parent = parent - self.min = layers['tokens'].tokens - self.grid = layers['grid'] - self.layers = layers - self.listID = listID - list_sizer = wx.BoxSizer(wx.VERTICAL) - self.list_sizer = list_sizer - listctrl = wx.ListCtrl(self, listID, style=wx.LC_REPORT | wx.SUNKEN_BORDER) - self.listctrl = listctrl - self.Centre(wx.BOTH) - self.log = log - self.list_sizer.Add(self.listctrl,1,wx.EXPAND) - self.listctrl.InsertColumn(0,"POS ") - self.listctrl.InsertColumn(0,"LOCKED") - self.listctrl.InsertColumn(0,"HEADING") - self.listctrl.InsertColumn(0,"FACING") - self.listctrl.InsertColumn(0,"LABEL") - self.listctrl.InsertColumn(0,"PATH") - self.listctrl.SetColumnWidth(1, wx.LIST_AUTOSIZE_USEHEADER) - self.listctrl.SetColumnWidth(2, wx.LIST_AUTOSIZE_USEHEADER) - self.listctrl.SetColumnWidth(3, wx.LIST_AUTOSIZE_USEHEADER) - self.listctrl.SetColumnWidth(4, wx.LIST_AUTOSIZE_USEHEADER) - self.listctrl.SetColumnWidth(5, wx.LIST_AUTOSIZE_USEHEADER) - self.list_sizer.Add(wx.Button(self, wx.ID_OK, "DONE"),0,wx.ALIGN_CENTER) - self.refresh() - self.Bind(wx.EVT_BUTTON, self.on_ok, id=wx.ID_OK) - self.listctrl.Bind(wx.EVT_COMMAND_RIGHT_CLICK, self.OnRightClick, id=listID) - self.listctrl.Bind(wx.EVT_RIGHT_UP, self.OnRightClick) - self.listctrl.Bind(wx.EVT_RIGHT_DOWN, self.OnRightDown) - self.SetSizer(self.list_sizer) - self.SetAutoLayout(True) - self.Fit() - - def OnRightClick(self,event): - if self.listctrl.GetSelectedItemCount() > 0: - menu = wx.Menu() - lPopupID1 = wx.NewId() - lPopupID2 = wx.NewId() - lPopupID3 = wx.NewId() - menu.Append(lPopupID1, "&Edit") - menu.Append(lPopupID2, "&Delete") - menu.Append(lPopupID3, "To &Gametree") - self.Bind(wx.EVT_MENU, self.onEdit, id=lPopupID1) - self.Bind(wx.EVT_MENU, self.onDelete, id=lPopupID2) - self.Bind(wx.EVT_MENU, self.onToGametree, id=lPopupID3) - self.PopupMenu(menu, cmpPoint(self.x, self.y)) - menu.Destroy() - event.Skip() - - def refresh(self): - self.SetMinSize((600,175)); - for m in self.min: - self.listctrl.InsertStringItem(self.min.index(m),self.min[self.min.index(m)].path) - self.listctrl.SetStringItem(self.min.index(m),1,self.min[self.min.index(m)].label) - self.listctrl.SetStringItem(self.min.index(m),2,`self.min[self.min.index(m)].heading`) - #self.listctrl.SetStringItem(self.min.index(m),3,`self.min[self.min.index(m)].face`) - self.listctrl.SetStringItem(self.min.index(m),4,`self.min[self.min.index(m)].locked`) - self.listctrl.SetStringItem(self.min.index(m),5,`self.min[self.min.index(m)].pos`) - oldcolumnwidth = self.listctrl.GetColumnWidth(0) - self.listctrl.SetColumnWidth(0, wx.LIST_AUTOSIZE) - if oldcolumnwidth < self.listctrl.GetColumnWidth(0): self.listctrl.SetColumnWidth(0, wx.LIST_AUTOSIZE) - else: self.listctrl.SetColumnWidth(0, oldcolumnwidth) - self.list_sizer=self.list_sizer - - def onEdit(self,event): - min_list = [] - min_index = [] - loop_count = 0 - item =-1 - while True: - loop_count += 1 - item = self.listctrl.GetNextItem(item,wx.LIST_NEXT_ALL, wx.LIST_STATE_SELECTED) - if item == -1: break - min_list.append(self.min[item]) - min_index.append(item-loop_count+1) - if len(min_list) > 0: dlg = min_list_edit_dialog(self.parent,min_index, min_list,self.layers) - if dlg.ShowModal() == wx.ID_OK: pass - self.listctrl.DeleteAllItems() - self.refresh() - event.Skip() - - def onDelete(self,event): - loop_count = 0 - item = -1 - while True: - loop_count += 1 - item = self.listctrl.GetNextItem(item,wx.LIST_NEXT_ALL, wx.LIST_STATE_SELECTED) - if item == -1: break - self.layers["tokens"].del_token(self.min[item-loop_count+1]) - self.listctrl.DeleteAllItems() - self.refresh() - event.Skip() - - def onToGametree(self,event): - min_list = [] - min_index = [] - loop_count = 0 - item =-1 - while True: - loop_count += 1 - item = self.listctrl.GetNextItem(item,wx.LIST_NEXT_ALL, wx.LIST_STATE_SELECTED) - if item == -1: break - min_list.append(self.min[item]) - min_index.append(item-loop_count+1) - if len(min_list) > 0: - for sel_rmin in min_list: - ############# - min_xml = sel_rmin.toxml(action="new") - node_begin = "' - print "Sending this XML to insert_xml:" + node_xml - gametree.insert_xml(node_xml) - ############# - self.listctrl.DeleteAllItems() - self.refresh() - event.Skip() - - def OnRightDown(self,event): - self.x = event.GetX() - self.y = event.GetY() - event.Skip() - - def on_ok(self,evt): - self.EndModal(wx.ID_OK) - -class min_list_edit_dialog(wx.Dialog): - def __init__(self,parent,min_index, min_list, layers): - wx.Dialog.__init__(self,parent,-1,"token List",wx.DefaultPosition,wx.Size(600,530)) - self.layers = layers - grid = layers['grid'] - min = layers['tokens'] - self.min_list = min_list - self.min_index = min_index - self.min = min - sizer1 = wx.BoxSizer(wx.VERTICAL) - sizer = wx.BoxSizer(wx.HORIZONTAL) - self.grid = grid - editor = min_list_edit_panel(self, min_index, min_list,layers) - sizer1.Add(editor, 1, wx.EXPAND) - sizer.Add(wx.Button(self, wx.ID_OK, "OK"), 1, wx.EXPAND) - sizer.Add(wx.Size(10,10)) - sizer.Add(wx.Size(10,10)) - sizer.Add(wx.Button(self, wx.ID_CANCEL, "Cancel"), 1, wx.EXPAND) - sizer1.Add(sizer, 0, wx.EXPAND) - self.editor = editor - self.Bind(wx.EVT_BUTTON, self.on_ok, id=wx.ID_OK) - self.SetSizer(sizer1) - self.SetAutoLayout(True) - self.Fit() - - def on_revert(self,evt): - pass - - def on_ok(self,evt): - self.editor.on_ok(self.layers) - self.EndModal(wx.ID_OK) - -class min_list_edit_panel(wx.Panel): - def __init__(self, parent, min_index, min_list,layers): - LABEL_COMBO = wx.NewId() - PATH_COMBO = wx.NewId() - POS_COMB = wx.NewId() - MIN_POS = wx.NewId() - POS_SPIN = wx.NewId() - self.grid = layers['grid'] - self.min = layers['tokens'].tokens - self.min_list = min_list - self.min_index = min_index - self.layers = layers - wx.Panel.__init__(self, parent, -1) - self.min=min - listsizer = wx.StaticBoxSizer(wx.StaticBox(self,-1,"Token list properties"), wx.VERTICAL) - labelsizer = wx.BoxSizer(wx.HORIZONTAL) - self.labelcheck = wx.CheckBox(self,-1,"Serialize") - labelsizer.Add(wx.StaticText(self, -1, "Label: "), 0, wx.EXPAND) - labelsizer.Add(self.labelcheck,wx.ALIGN_RIGHT,wx.EXPAND) - listsizer.Add(labelsizer,0, wx.EXPAND) - self.labelcombo = wx.ComboBox(self, LABEL_COMBO,"no change",style=wx.CB_DROPDOWN) - listsizer.Add(self.labelcombo,0, wx.EXPAND) - self.pathcombo = wx.ComboBox(self, PATH_COMBO, "no change",style=wx.CB_DROPDOWN) - self.positioncombo = wx.ComboBox(self, POS_COMB, "no change", choices=["no change"], style=wx.CB_READONLY) - #self.positioncombo.SetValue(`min_list[0].pos`) - self.labelcombo.Append("no change") - self.pathcombo.Append("no change") - for m in min_list: - self.labelcombo.Append(min_list[min_list.index(m)].label) - self.pathcombo.Append(min_list[min_list.index(m)].path) - self.positioncombo.Append(`min_list[min_list.index(m)].pos`) - listsizer.Add(wx.StaticText(self, -1, "Path:"), 0, wx.EXPAND) - listsizer.Add(self.pathcombo, 0, wx.EXPAND) - listsizer.Add(wx.Size(10,10)) - self.heading = wx.RadioBox(self, MIN_HEADING, "Heading", - choices=["None","N","NE","E","SE","S","SW","W","NW","no change"], majorDimension=5, style=wx.RA_SPECIFY_COLS) - self.heading.SetSelection( 9 ) - listsizer.Add( self.heading, 0, wx.EXPAND ) - listsizer.Add(wx.Size(10,10)) - - ## Remove - #self.face = wx.RadioBox(self, MIN_FACE, "Facing", - # choices=["None","N","NE","E","SE","S","SW","W","NW","no change"], majorDimension=5, style=wx.RA_SPECIFY_COLS) - #self.face.SetSelection(9) - #listsizer.Add(self.face, 0, wx.EXPAND) - - ### - ###Group together locked, Hide, and snap radioboxes in group2 box - ### - group2 = wx.BoxSizer(wx.HORIZONTAL) - self.locked = wx.RadioBox(self, MIN_LOCK, "Lock", - choices=["Don't lock","Lock","no change"],majorDimension=1,style=wx.RA_SPECIFY_COLS) - self.locked.SetSelection(2) - self.hide = wx.RadioBox(self, MIN_HIDE, "Hide", - choices=["Don't hide", "Hide", "no change"],majorDimension=1,style=wx.RA_SPECIFY_COLS) - self.hide.SetSelection(2) - self.snap = wx.RadioBox(self,MIN_ALIGN,"Snap", - choices=["Center","Top left","no change"],majorDimension=1,style=wx.RA_SPECIFY_COLS) - self.snap.SetSelection(2) - group2.Add(self.locked, 0, wx.EXPAND) - group2.Add(wx.Size(10,0)) - group2.Add(self.hide, 0, wx.EXPAND) - group2.Add(wx.Size(10,0)) - group2.Add(self.snap, 0, wx.EXPAND) - group2.Add(wx.Size(10,0)) - listsizer.Add(group2,0,0) - ### - ###Group together the postion radiobox and the and its selection elements - ### - xpos = int(min_list[0].pos[0]) - #xpos = int(`min_list[0].pos`[1:`min_list[0].pos`.index(',')]) - ypos = int(min_list[0].pos[1]) - #ypos = int(`min_list[0].pos`[`min_list[0].pos`.rfind(',')+1:len(`min_list[0].pos`)-1]) - self.scx = wx.SpinCtrl(self, POS_SPIN, "", (-1,-1), wx.Size(75,25)) - self.scx.SetRange(0,self.grid.return_grid()[0]) - self.scx.SetValue(xpos) - self.scy = wx.SpinCtrl(self, POS_SPIN, "", (-1,-1), wx.Size(75,25)) - self.scy.SetRange(0,self.grid.return_grid()[1]) - self.scy.SetValue(1) - self.scy.SetValue(ypos) - positionbox = wx.BoxSizer(wx.HORIZONTAL) - self.poschoice = wx.RadioBox(self,MIN_POS,"Position", - choices=["Manual", "Existing", "no change"],majorDimension=1,style=wx.RA_SPECIFY_COLS) - self.poschoice.SetSelection(2) - positionbox.Add(self.poschoice,0,0) - ### - ### group together choices under position choice boxsizer - ### - poschoicebox = wx.BoxSizer(wx.VERTICAL) - ### - ### spinbox contains the x and y spinctrls - ### - spinbox = wx.BoxSizer(wx.HORIZONTAL) - group2.Add(positionbox,0, wx.EXPAND) - xpos = wx.StaticText(self, -1,"XPOS: ") - spinbox.Add(xpos,0, 0) - spinbox.Add(self.scx, 0, 0) - ypos = wx.StaticText(self, -1,"YPOS: ") - spinbox.Add(ypos,0, 0) - spinbox.Add(self.scy, 0, 0) - poschoicebox.Add(wx.Size(0,15)) - poschoicebox.Add(spinbox,0,0) - ### - ### kludge is just a way to horizontaly position text. .Add doesn't seem to work. - ### - kluge = wx.BoxSizer(wx.HORIZONTAL) - klugetext = wx.StaticText(self, -1, " ") - kluge.Add(klugetext,0,0) - kluge.Add(self.positioncombo,0,0) - poschoicebox.Add(wx.Size(0,1)) - poschoicebox.Add(kluge,0,0) - positionbox.Add(poschoicebox,0,0) - listsizer.Add(positionbox,0, 0) - self.listsizer = listsizer - #self.outline = wx.StaticBox(self,-1,"token list properties") - #listsizer.Add(self.outline,0, wx.EXPAND) - self.SetSizer(listsizer) - self.SetAutoLayout(True) - self.Fit() - self.Bind(wx.EVT_SPINCTRL, self.on_spin, id=POS_SPIN) - self.Bind(wx.EVT_TEXT, self.on_combo_box, id=POS_COMB) - #self.Bind(wx.EVT_SIZE, self.on_size) - self.Bind(wx.EVT_TEXT, self.on_text, id=MIN_LABEL) - self.Bind(wx.EVT_RADIOBOX, self.on_radio_box, id=MIN_HEADING) - self.Bind(wx.EVT_RADIOBOX, self.on_radio_box, id=MIN_FACE) - - def on_ok(self,min): - self.min = min - for m in self.min_list: - if self.hide.GetSelection() !=2: m.hide = self.hide.GetSelection() - if self.heading.GetSelection() !=9: m.heading = self.heading.GetSelection() - #if self.face.GetSelection() !=9: m.face = self.face.GetSelection() - if self.locked.GetSelection() !=2: m.locked = self.locked.GetSelection() - if self.snap.GetSelection() !=2: m.snap_to_align = self.snap.GetSelection() - if self.labelcombo.GetValue() != "no change": - m.label = self.labelcombo.GetValue() - if self.labelcheck.GetValue(): m.label += " " + `self.layers['tokens'].next_serial()` - if self.pathcombo.GetValue() != "no change": - path = self.pathcombo.GetValue() - image = self.evaluate(path) - if str(image[1]) != '-1': - m.path = image[0] - m.bmp = image[1] - else: - image[-1] = -1 - while image[1] == -1: - image = 0 - self.dlg = wx.TextEntryDialog(self, - 'You entered an invalid URL for the image path. Please Enter a valid URL or cancel to leave the old url unchanged') - if self.dlg.ShowModal() == wx.ID_OK: - path = self.dlg.GetValue() - image = self.evaluate(path) - if image[1] != -1: - m.path = image[0] - m.bmp = image[1] - self.dlg.Destroy() - else: break - if self.poschoice.GetSelection() !=2: - if self.poschoice.GetSelection() == 0: m.pos = cmpPoint(self.scx.GetValue(),self.scy.GetValue()) - else: - pos = self.positioncombo.GetValue() - m.pos = cmpPoint(int(`pos`[2:`pos`.index(",")]),int(`pos`[`pos`.rfind(',')+1:len(`pos`)-2])) - self.layers["tokens"].canvas.send_map_data() - - def evaluate(self, ckpath): - path = [] - if ckpath[:7] != "http://": ckpath = "http://" + ckpath - path = self.check_path(ckpath) - return [ckpath, path] - - def check_path(self, path): - if ImageHandler.Cache.has_key(path): return ImageHandler.Cache[path] - img = ImageHandler.directLoad(path) - if img is None: return -1 - return img - - def on_text(self,evt): - id=evt.GetId() - - def on_spin(self,evt): - self.poschoice.SetSelection(0) - - def on_combo_box(self,evt): - self.poschoice.SetSelection(1) - - def on_radio_box(self,evt): - id=evt.GetId() - index = evt.GetInt() - - def on_size(self,evt): - s = self.GetClientSizeTuple() - self.listsizer.SetDimension(20,20,s[0]-40,s[1]-40) - self.outline.SetDimensions(5,5,s[0]-10,s[1]-10) - -##----------------------------- -## token Prop Panel -##----------------------------- - -MIN_LABEL = wx.NewId() -MIN_HEADING = wx.NewId() -MIN_FACE = wx.NewId() -MIN_HIDE = wx.NewId() -MIN_LOCK = wx.NewId() -MIN_ALIGN = wx.NewId() -wxID_MIN_WIDTH = wx.NewId() -wxID_MIN_HEIGHT = wx.NewId() -wxID_MIN_SCALING = wx.NewId() - -class min_edit_panel(wx.Panel): - def __init__(self, parent, min): - wx.Panel.__init__(self, parent, -1) - self.min = min - sizer = wx.StaticBoxSizer(wx.StaticBox(self,-1,"token"), wx.VERTICAL) - sizerSize = wx.BoxSizer(wx.HORIZONTAL) - hSizer = wx.BoxSizer(wx.HORIZONTAL) - self.label = wx.TextCtrl(self, MIN_LABEL, min.label) - sizer.Add(wx.StaticText(self, -1, "Label:"), 0, wx.EXPAND) - sizer.Add(self.label, 0, wx.EXPAND) - sizer.Add(wx.Size(10,10)) - self.heading = wx.RadioBox(self, MIN_HEADING, "Heading", - choices=["None","N","NE", - "E","SE","S", - "SW","W","NW"],majorDimension=5,style=wx.RA_SPECIFY_COLS) - self.heading.SetSelection(min.heading) - #self.face = wx.RadioBox(self, MIN_FACE, "Facing", - # choices=["None","N","NE", - # "E","SE","S", - # "SW","W","NW"],majorDimension=5,style=wx.RA_SPECIFY_COLS) - #self.face.SetSelection(min.face) - self.locked = wx.CheckBox(self, MIN_LOCK, " Lock") - self.locked.SetValue(min.locked) - self.hide = wx.CheckBox(self, MIN_HIDE, " Hide") - self.hide.SetValue(min.hide) - sizer.Add(self.heading, 0, wx.EXPAND) - sizer.Add(wx.Size(10,10)) - #sizer.Add(self.face, 0, wx.EXPAND) - sizer.Add(wx.Size(10,10)) - # - #image resizing - # - self.min_width_old_value = str(self.min.bmp.GetWidth()) - self.min_width = wx.TextCtrl(self, wxID_MIN_WIDTH, self.min_width_old_value) - sizerSize.Add(wx.StaticText(self, -1, "Width: "), 0, wx.ALIGN_CENTER) - sizerSize.Add(self.min_width, 1, wx.EXPAND) - sizerSize.Add(wx.Size(20, 25)) - - #TODO:keep in mind that self.min is a local copy??? - self.min_height_old_value = str(self.min.bmp.GetHeight()) - self.min_height = wx.TextCtrl(self, wxID_MIN_HEIGHT, self.min_height_old_value) - sizerSize.Add(wx.StaticText(self, -1, "Height: "),0,wx.ALIGN_CENTER) - sizerSize.Add(self.min_height, 1, wx.EXPAND) - self.min_scaling = wx.CheckBox(self, wxID_MIN_SCALING, "Lock scaling") - self.min_scaling.SetValue(True) - sizerSize.Add(self.min_scaling, 1, wx.EXPAND) - sizer.Add(sizerSize, 0, wx.EXPAND) - sizer.Add(wx.Size(10, 10)) - - # Now, add the last items on in their own sizer - hSizer.Add(self.locked, 0, wx.EXPAND) - hSizer.Add(wx.Size(10,10)) - hSizer.Add(self.hide, 0, wx.EXPAND) - - # Add the hSizer to the main sizer - sizer.Add( hSizer ) - self.sizer = sizer - self.SetSizer(self.sizer) - self.SetAutoLayout(True) - self.Fit() - - #self.Bind(wx.EVT_SIZE, self.on_size) - self.Bind(wx.EVT_TEXT, self.on_text, id=MIN_LABEL) - self.Bind(wx.EVT_TEXT, self.on_scaling, id=wxID_MIN_WIDTH) - self.Bind(wx.EVT_TEXT, self.on_scaling, id=wxID_MIN_HEIGHT) - self.Bind(wx.EVT_RADIOBOX, self.on_radio_box, id=MIN_HEADING) - #self.Bind(wx.EVT_RADIOBOX, self.on_radio_box, id=MIN_FACE) - - def on_scaling(self, evt): - if self.min_scaling.GetValue() == False: return - elif self.min_width.GetValue() and wxID_MIN_WIDTH == evt.GetId() and self.min_width.GetInsertionPoint(): - self.min_height.SetValue(str(int((float(self.min_width.GetValue()) / float(self.min_width_old_value)) * float(self.min_height_old_value))) ) - elif self.min_height.GetValue() and wxID_MIN_HEIGHT == evt.GetId() and self.min_height.GetInsertionPoint(): - self.min_width.SetValue(str(int((float(self.min_height.GetValue()) / float(self.min_height_old_value)) * float(self.min_width_old_value))) ) - - def update_min(self): - self.min.set_min_props(self.heading.GetSelection(), - #self.face.GetSelection(), - self.label.GetValue(), - self.locked.GetValue(), - self.hide.GetValue(), - self.min_width.GetValue(), - self.min_height.GetValue()) - - def on_radio_box(self,evt): - id = evt.GetId() - index = evt.GetInt() - - def on_text(self,evt): - id = evt.GetId() - - def on_size(self,evt): - s = self.GetClientSizeTuple() - self.sizer.SetDimension(20,20,s[0]-40,s[1]-40) - self.outline.SetDimensions(5,5,s[0]-10,s[1]-10) - -class min_edit_dialog(wx.Dialog): - def __init__(self,parent,min): - #520,265 - wx.Dialog.__init__(self,parent,-1,"token",wx.DefaultPosition,wx.Size(520,350)) - (w,h) = self.GetClientSizeTuple() - mastersizer = wx.BoxSizer(wx.VERTICAL) - editor = min_edit_panel(self,min) - #editor.SetDimensions(0,0,w,h-25) - self.editor = editor - mastersizer.Add(editor, 1, wx.EXPAND) - mastersizer.Add(wx.Size(10,10)) - sizer = wx.BoxSizer(wx.HORIZONTAL) - sizer.Add(wx.Button(self, wx.ID_OK, "OK"), 1, wx.EXPAND) - sizer.Add(wx.Size(10,10)) - sizer.Add(wx.Button(self, wx.ID_CANCEL, "Cancel"), 1, wx.EXPAND) - #sizer.SetDimension(0,h-25,w,25) - mastersizer.Add(sizer, 0, wx.EXPAND) - self.SetSizer(mastersizer) - self.SetAutoLayout(True) - self.Fit() - self.Bind(wx.EVT_BUTTON, self.on_ok, id=wx.ID_OK) - - def on_ok(self,evt): - self.editor.update_min() - self.EndModal(wx.ID_OK) diff -r 4b2884f29a72 -r 81d0bfd5e800 plugins/bcg/token_handler.py --- a/plugins/bcg/token_handler.py Fri Jan 15 22:45:51 2010 -0600 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,883 +0,0 @@ -# Copyright (C) 2000-2001 The OpenRPG Project -# -# openrpg-dev@lists.sourceforge.net -# -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation; either version 2 of the License, or -# (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. -# -- -# -# File: mapper/whiteboard_hander.py -# Author: OpenRPG Team -# Maintainer: -# Version: -# $Id: token_handler.py,v 1.43 2007/12/07 20:39:50 digitalxero Exp $ -# -# Description: Token layer handler; derived from token Layer handler -# -__version__ = "$Id: token_handler.py,v 1.43 2007/12/07 20:39:50 madmathlabs Exp $" - -from orpg.mapper.base_handler import * -from tok_dialogs import * -import thread -import time -import mimetypes -import urllib -import xml.dom.minidom as minidom -import wx - -## rewrite Grid -from orpg.mapper.grid import GRID_RECTANGLE -from orpg.mapper.grid import GRID_HEXAGON -from orpg.mapper.grid import GRID_ISOMETRIC -import os - -from orpg.tools.orpg_settings import settings - -## Jesus H! No Face, rotate! -TOK_ROT_LEFT = wx.NewId() -ROT_LEFT_45 = wx.NewId() -LABEL_TOOL = wx.NewId() -LAYER_TOOL = wx.NewId() -TOK_LIST_TOOL = wx.NewId() -TOK_TOOL = wx.NewId() -TOK_URL = wx.NewId() -SERIAL_TOOL = wx.NewId() -TOK_MOVE = wx.NewId() -TOK_REMOVE = wx.NewId() -TOK_PROP_DLG = wx.NewId() -TOK_FACING_NONE = wx.NewId() -TOK_FACING_MATCH = wx.NewId() -TOK_FACING_EAST = wx.NewId() -TOK_FACING_WEST = wx.NewId() -TOK_FACING_NORTH = wx.NewId() -TOK_FACING_SOUTH = wx.NewId() -TOK_FACING_NORTHEAST = wx.NewId() -TOK_FACING_SOUTHEAST = wx.NewId() -TOK_FACING_SOUTHWEST = wx.NewId() -TOK_FACING_NORTHWEST = wx.NewId() -TOK_HEADING_NONE = wx.NewId() -TOK_HEADING_MATCH = wx.NewId() -TOK_HEADING_EAST = wx.NewId() -TOK_HEADING_WEST = wx.NewId() -TOK_HEADING_NORTH = wx.NewId() -TOK_HEADING_SOUTH = wx.NewId() -TOK_HEADING_NORTHEAST = wx.NewId() -TOK_HEADING_SOUTHEAST = wx.NewId() -TOK_HEADING_SOUTHWEST = wx.NewId() -TOK_HEADING_NORTHWEST = wx.NewId() -TOK_HEADING_SUBMENU = wx.NewId() -TOK_FACING_SUBMENU = wx.NewId() -TOK_ALIGN_SUBMENU = wx.NewId() -TOK_ALIGN_GRID_CENTER = wx.NewId() -TOK_ALIGN_GRID_TL = wx.NewId() -TOK_TITLE_HACK = wx.NewId() -TOK_TO_GAMETREE = wx.NewId() -TOK_BACK_ONE = wx.NewId() -TOK_FORWARD_ONE = wx.NewId() -TOK_TO_BACK = wx.NewId() -TOK_TO_FRONT = wx.NewId() -TOK_LOCK_BACK = wx.NewId() -TOK_LOCK_FRONT = wx.NewId() -TOK_FRONTBACK_UNLOCK = wx.NewId() -TOK_ZORDER_SUBMENU = wx.NewId() -TOK_SHOW_HIDE = wx.NewId() -TOK_LOCK_UNLOCK = wx.NewId() -MAP_REFRESH_MINI_URLS = wx.NewId() - -class myFileDropTarget(wx.FileDropTarget): - def __init__(self, handler): - wx.FileDropTarget.__init__(self) - self.m_handler = handler - def OnDropFiles(self, x, y, filenames): - self.m_handler.on_drop_files(x, y, filenames) - -class token_handler(base_layer_handler): - - def __init__(self, parent, id, canvas): - self.sel_min = None - self.auto_label = 1 - self.use_serial = 1 - self.auto_label_cb = None - self.canvas = canvas - self.settings = settings - self.mini_rclick_menu_extra_items = {} - self.background_rclick_menu_extra_items = {} - base_layer_handler.__init__(self, parent, id, canvas) - # id is the index of the last good menu choice or 'None' - # if the last menu was left without making a choice - # should be -1 at other times to prevent events overlapping - self.lastMenuChoice = None - self.drag_mini = None - self.tooltip_delay_miliseconds = 500 - self.tooltip_timer = wx.CallLater(self.tooltip_delay_miliseconds, self.on_tooltip_timer) - self.tooltip_timer.Stop() - dt = myFileDropTarget(self) - self.canvas.SetDropTarget(dt) - #wxInitAllImageHandlers() - - def build_ctrls(self): - base_layer_handler.build_ctrls(self) - # add controls in reverse order! (unless you want them after the default tools) - self.auto_label_cb = wx.CheckBox(self, wx.ID_ANY, ' Auto Label ', (-1,-1),(-1,-1)) - self.auto_label_cb.SetValue(self.auto_label) - self.min_url = wx.ComboBox(self, wx.ID_ANY, "http://", style=wx.CB_DROPDOWN | wx.CB_SORT) - self.localBrowse = wx.Button(self, wx.ID_ANY, 'Browse', style=wx.BU_EXACTFIT) - minilist = createMaskedButton( self, dir_struct["icon"]+'questionhead.gif', 'Edit token properties', wx.ID_ANY) - miniadd = wx.Button(self, wx.ID_OK, "Add Token", style=wx.BU_EXACTFIT) - self.sizer.Add(self.auto_label_cb,0,wx.ALIGN_CENTER) - self.sizer.Add((6, 0)) - self.sizer.Add(self.min_url, 1, wx.ALIGN_CENTER) - self.sizer.Add((6, 0)) - self.sizer.Add(miniadd, 0, wx.ALIGN_CENTER) - self.sizer.Add((6, 0)) - self.sizer.Add(self.localBrowse, 0, wx.ALIGN_CENTER) - self.sizer.Add((6, 0)) - self.sizer.Add(minilist, 0, wx.ALIGN_CENTER) - self.Bind(wx.EVT_BUTTON, self.on_min_list, minilist) - self.Bind(wx.EVT_BUTTON, self.on_token, miniadd) - self.Bind(wx.EVT_BUTTON, self.on_browse, self.localBrowse) - self.Bind(wx.EVT_CHECKBOX, self.on_label, self.auto_label_cb) - - def on_browse(self, evt): - if not self.role_is_gm_or_player(): return - dlg = wx.FileDialog(None, "Select a Token to load", dir_struct["user"]+'webfiles/', - wildcard="Image files (*.bmp, *.gif, *.jpg, *.png)|*.bmp;*.gif;*.jpg;*.png", style=wx.OPEN) - if not dlg.ShowModal() == wx.ID_OK: - dlg.Destroy() - return - file = open(dlg.GetPath(), "rb") - imgdata = file.read() - file.close() - filename = dlg.GetFilename() - (imgtype,j) = mimetypes.guess_type(filename) - postdata = urllib.urlencode({'filename':filename, 'imgdata':imgdata, 'imgtype':imgtype}) - - ## Removal of Remote Server? - if self.settings.get_setting('LocalorRemote') == 'Remote': - # make the new mini appear in top left of current viewable map - dc = wx.ClientDC(self.canvas) - self.canvas.PrepareDC(dc) - dc.SetUserScale(self.canvas.layers['grid'].mapscale,self.canvas.layers['grid'].mapscale) - x = dc.DeviceToLogicalX(0) - y = dc.DeviceToLogicalY(0) - thread.start_new_thread(self.canvas.layers['token'].upload, - (postdata, dlg.GetPath()), {'pos':cmpPoint(x,y)}) - else: - try: min_url = component.get("cherrypy") + filename - except: return #chat.InfoPost('CherryPy is not started!') - min_url = dlg.GetDirectory().replace(dir_struct["user"]+'webfiles' + os.sep, - component.get("cherrypy")) + '/' + filename - # build url - if min_url == "" or min_url == "http://": return - if min_url[:7] != "http://": min_url = "http://" + min_url - # make label - if self.auto_label and min_url[-4:-3] == '.': - start = min_url.rfind("/") + 1 - min_label = min_url[start:len(min_url)-4] - if self.use_serial: min_label = '%s %d' % ( min_label, self.canvas.layers['token'].next_serial() ) - else: min_label = "" - if self.min_url.FindString(min_url) == -1: self.min_url.Append(min_url) - try: - id = 'mini-' + self.canvas.frame.session.get_next_id() - # make the new mini appear in top left of current viewable map - dc = wx.ClientDC(self.canvas) - self.canvas.PrepareDC(dc) - dc.SetUserScale(self.canvas.layers['grid'].mapscale,self.canvas.layers['grid'].mapscale) - x = dc.DeviceToLogicalX(0) - y = dc.DeviceToLogicalY(0) - self.canvas.layers['token'].add_token(id, min_url, pos=cmpPoint(x,y), label=min_label) - except: - # When there is an exception here, we should be decrementing the serial_number for reuse!! - unablemsg= "Unable to load/resolve URL: " + min_url + " on resource \"" + min_label + "\"!!!\n\n" - dlg = wx.MessageDialog(self,unablemsg, 'Url not found',wx.ICON_EXCLAMATION) - dlg.ShowModal() - dlg.Destroy() - self.canvas.layers['token'].rollback_serial() - self.canvas.send_map_data() - self.canvas.Refresh(False) - - - def build_menu(self,label = "Token"): - ## Menu Changes: Rotate - ## Menu into Component - ## Remove To GameTree option - base_layer_handler.build_menu(self,label) - self.main_menu.AppendSeparator() - self.main_menu.Append(LABEL_TOOL,"&Auto label","",1) - self.main_menu.Check(LABEL_TOOL,self.auto_label) - self.main_menu.Append(SERIAL_TOOL,"&Number minis","",1) - self.main_menu.Check(SERIAL_TOOL, self.use_serial) - self.main_menu.Append(MAP_REFRESH_MINI_URLS,"&Refresh tokens") # Add the menu item - self.main_menu.AppendSeparator() - self.main_menu.Append(TOK_MOVE, "Move") - self.canvas.Bind(wx.EVT_MENU, self.on_map_board_menu_item, id=MAP_REFRESH_MINI_URLS) # Set the handler - self.canvas.Bind(wx.EVT_MENU, self.on_label, id=LABEL_TOOL) - self.canvas.Bind(wx.EVT_MENU, self.on_serial, id=SERIAL_TOOL) - # build token menu - self.min_menu = wx.Menu() - # Rectangles and hexagons require slightly different menus because of - # facing and heading possibilities. - - rot_left = wx.Menu() - rot_left_45 = rot_left.Append(-1, '45*') - self.canvas.Bind(wx.EVT_MENU, self.rot_left_45, rot_left_45) - rot_right = wx.Menu() - - rot_right_45 = rot_right.Append(-1, '45*') - self.canvas.Bind(wx.EVT_MENU, self.rot_right_45, rot_right_45) - ## Replace with Rotate. Left - Right, 45 - 90 degress. - """ - face_menu = wx.Menu() - face_menu.Append(TOK_FACING_NONE,"&None") - face_menu.Append(TOK_FACING_NORTH,"&North") - face_menu.Append(TOK_FACING_NORTHEAST,"Northeast") - face_menu.Append(TOK_FACING_EAST,"East") - face_menu.Append(TOK_FACING_SOUTHEAST,"Southeast") - face_menu.Append(TOK_FACING_SOUTH,"&South") - face_menu.Append(TOK_FACING_SOUTHWEST,"Southwest") - face_menu.Append(TOK_FACING_WEST,"West") - face_menu.Append(TOK_FACING_NORTHWEST,"Northwest") - """ - ### - - heading_menu = wx.Menu() - heading_menu.Append(TOK_HEADING_NONE,"&None") - heading_menu.Append(TOK_HEADING_NORTH,"&North") - heading_menu.Append(TOK_HEADING_NORTHEAST,"Northeast") - heading_menu.Append(TOK_HEADING_EAST,"East") - heading_menu.Append(TOK_HEADING_SOUTHEAST,"Southeast") - heading_menu.Append(TOK_HEADING_SOUTH,"&South") - heading_menu.Append(TOK_HEADING_SOUTHWEST,"Southwest") - heading_menu.Append(TOK_HEADING_WEST,"West") - heading_menu.Append(TOK_HEADING_NORTHWEST,"Northwest") - - align_menu = wx.Menu() - align_menu.Append(TOK_ALIGN_GRID_CENTER,"&Center") - align_menu.Append(TOK_ALIGN_GRID_TL,"&Top-Left") - # This is a hack to simulate a menu title, due to problem in Linux - if wx.Platform == '__WXMSW__': self.min_menu.SetTitle(label) - else: - self.min_menu.Append(TOK_TITLE_HACK,label) - self.min_menu.AppendSeparator() - self.min_menu.Append(TOK_SHOW_HIDE,"Show / Hide") - self.min_menu.Append(TOK_LOCK_UNLOCK, "Lock / Unlock") - self.min_menu.Append(TOK_REMOVE,"&Remove") - - ##Remove - #self.min_menu.Append(TOK_TO_GAMETREE,"To &Gametree") - ### - - self.min_menu.AppendMenu(TOK_HEADING_SUBMENU,"Set &Heading",heading_menu) - - ##Remove - self.min_menu.AppendMenu(TOK_ROT_LEFT,"&Rotate Left",rot_left) - self.min_menu.AppendMenu(wx.ID_ANY,"&Rotate Right",rot_right) - ### - - self.min_menu.AppendMenu(TOK_ALIGN_SUBMENU,"Snap-to &Alignment",align_menu) - self.min_menu.AppendSeparator() - zorder_menu = wx.Menu() - zorder_menu.Append(TOK_BACK_ONE,"Back one") - zorder_menu.Append(TOK_FORWARD_ONE,"Forward one") - zorder_menu.Append(TOK_TO_BACK,"To back") - zorder_menu.Append(TOK_TO_FRONT,"To front") - zorder_menu.AppendSeparator() - zorder_menu.Append(TOK_LOCK_BACK,"Lock to back") - zorder_menu.Append(TOK_LOCK_FRONT,"Lock to front") - zorder_menu.Append(TOK_FRONTBACK_UNLOCK,"Unlock Front/Back") - self.min_menu.AppendMenu(TOK_ZORDER_SUBMENU, "Token Z-Order",zorder_menu) - #self.min_menu.Append(TOK_LOCK,"&Lock") - self.min_menu.AppendSeparator() - self.min_menu.Append(TOK_PROP_DLG,"&Properties") - - - #self.min_menu.AppendSeparator() - #self.min_menu.Append(TOK_MOVE, "Move") - - self.canvas.Bind(wx.EVT_MENU, self.on_min_menu_item, id=TOK_MOVE) - self.canvas.Bind(wx.EVT_MENU, self.on_min_menu_item, id=TOK_SHOW_HIDE) - self.canvas.Bind(wx.EVT_MENU, self.on_min_menu_item, id=TOK_LOCK_UNLOCK) - self.canvas.Bind(wx.EVT_MENU, self.on_min_menu_item, id=TOK_REMOVE) - - ##Remove - #self.canvas.Bind(wx.EVT_MENU, self.on_min_menu_item, id=TOK_TO_GAMETREE) - ### - - #self.canvas.Bind(wx.EVT_MENU, self.on_min_menu_item, id=TOK_LOCK) - self.canvas.Bind(wx.EVT_MENU, self.on_min_menu_item, id=TOK_PROP_DLG) - - ##Remove - self.canvas.Bind(wx.EVT_MENU, self.on_min_menu_item, id=TOK_FACING_NONE) - self.canvas.Bind(wx.EVT_MENU, self.on_min_menu_item, id=TOK_FACING_EAST) - self.canvas.Bind(wx.EVT_MENU, self.on_min_menu_item, id=TOK_FACING_WEST) - self.canvas.Bind(wx.EVT_MENU, self.on_min_menu_item, id=TOK_FACING_NORTH) - self.canvas.Bind(wx.EVT_MENU, self.on_min_menu_item, id=TOK_FACING_SOUTH) - self.canvas.Bind(wx.EVT_MENU, self.on_min_menu_item, id=TOK_FACING_NORTHEAST) - self.canvas.Bind(wx.EVT_MENU, self.on_min_menu_item, id=TOK_FACING_SOUTHEAST) - self.canvas.Bind(wx.EVT_MENU, self.on_min_menu_item, id=TOK_FACING_SOUTHWEST) - self.canvas.Bind(wx.EVT_MENU, self.on_min_menu_item, id=TOK_FACING_NORTHWEST) - ### - - self.canvas.Bind(wx.EVT_MENU, self.on_min_menu_item, id=TOK_HEADING_NONE) - self.canvas.Bind(wx.EVT_MENU, self.on_min_menu_item, id=TOK_HEADING_EAST) - self.canvas.Bind(wx.EVT_MENU, self.on_min_menu_item, id=TOK_HEADING_WEST) - self.canvas.Bind(wx.EVT_MENU, self.on_min_menu_item, id=TOK_HEADING_NORTH) - self.canvas.Bind(wx.EVT_MENU, self.on_min_menu_item, id=TOK_HEADING_SOUTH) - self.canvas.Bind(wx.EVT_MENU, self.on_min_menu_item, id=TOK_HEADING_NORTHEAST) - self.canvas.Bind(wx.EVT_MENU, self.on_min_menu_item, id=TOK_HEADING_SOUTHEAST) - self.canvas.Bind(wx.EVT_MENU, self.on_min_menu_item, id=TOK_HEADING_SOUTHWEST) - self.canvas.Bind(wx.EVT_MENU, self.on_min_menu_item, id=TOK_HEADING_NORTHWEST) - self.canvas.Bind(wx.EVT_MENU, self.on_min_menu_item, id=TOK_ALIGN_GRID_CENTER) - self.canvas.Bind(wx.EVT_MENU, self.on_min_menu_item, id=TOK_ALIGN_GRID_TL) - self.canvas.Bind(wx.EVT_MENU, self.on_min_menu_item, id=TOK_BACK_ONE) - self.canvas.Bind(wx.EVT_MENU, self.on_min_menu_item, id=TOK_FORWARD_ONE) - self.canvas.Bind(wx.EVT_MENU, self.on_min_menu_item, id=TOK_TO_BACK) - self.canvas.Bind(wx.EVT_MENU, self.on_min_menu_item, id=TOK_TO_FRONT) - self.canvas.Bind(wx.EVT_MENU, self.on_min_menu_item, id=TOK_LOCK_BACK) - self.canvas.Bind(wx.EVT_MENU, self.on_min_menu_item, id=TOK_LOCK_FRONT) - self.canvas.Bind(wx.EVT_MENU, self.on_min_menu_item, id=TOK_FRONTBACK_UNLOCK) - ######### add plugin added menu items ######### - if len(self.mini_rclick_menu_extra_items)>0: - self.min_menu.AppendSeparator() - for item in self.mini_rclick_menu_extra_items.items(): self.min_menu.Append(item[1], item[0]) - if len(self.background_rclick_menu_extra_items)>0: - self.main_menu.AppendSeparator() - for item in self.background_rclick_menu_extra_items.items(): - self.main_menu.Append(item[1], item[0]) - - def do_min_menu(self,pos): - self.canvas.PopupMenu(self.min_menu,pos) - - def rot_left_45(self, evt): - #self.sel_rmin.rotate += 0.785 - self.sel_rmin.rotate += 1.046 - #component.get('drawn')[self.sel_rmin] = False - - def rot_right_45(self, evt): - #self.sel_rmin.rotate -= 0.785 - self.sel_rmin.rotate -= 1.046 - - def do_min_select_menu(self, min_list, pos): - # to prevent another event being processed - self.lastMenuChoice = None - self.min_select_menu = wx.Menu() - self.min_select_menu.SetTitle("Select Token") - loop_count = 1 - try: - for m in min_list: - # Either use the token label for the selection list - if m.label: self.min_select_menu.Append(loop_count, m.label) - # Or use part of the images filename as an identifier - else: - string_split = string.split(m.path,"/",) - last_string = string_split[len(string_split)-1] - self.min_select_menu.Append(loop_count, 'Unlabeled - ' + last_string[:len(last_string)-4]) - self.canvas.Bind(wx.EVT_MENU, self.min_selected, id=loop_count) - loop_count += 1 - self.canvas.PopupMenu(self.min_select_menu,pos) - except: pass - - def min_selected(self,evt): - # this is the callback function for the menu that is used to choose - # between minis when you right click, left click or left double click - # on a stack of two or more - self.canvas.Refresh(False) - self.canvas.send_map_data() - self.lastMenuChoice = evt.GetId()-1 - - def on_min_menu_item(self,evt): - id = evt.GetId() - if id == TOK_MOVE: - if self.sel_min: - self.moveSelectedMini(self.last_rclick_pos) - self.deselectAndRefresh() - return - elif id == TOK_REMOVE: self.canvas.layers['token'].del_token(self.sel_rmin) - - ##Remove - elif id == TOK_TO_GAMETREE: - min_xml = self.sel_rmin.toxml(action="new") - node_begin = "' - #print "Sending this XML to insert_xml:" + node_xml - gametree.insert_xml(str(node_xml)) - - elif id == TOK_SHOW_HIDE: - if self.sel_rmin.hide: self.sel_rmin.hide = 0 - else: self.sel_rmin.hide = 1 - elif id == TOK_LOCK_UNLOCK: - if self.sel_rmin.locked: self.sel_rmin.locked = False - else: self.sel_rmin.locked = True - if self.sel_rmin == self.sel_min: - # when we lock / unlock the selected mini make sure it isn't still selected - # or it might easily get moved by accident and be hard to move back - self.sel_min.selected = False - self.sel_min.isUpdated = True - self.sel_min = None - recycle_bin = {TOK_HEADING_NONE: FACE_NONE, TOK_HEADING_NORTH: FACE_NORTH, - TOK_HEADING_NORTHWEST: FACE_NORTHWEST, TOK_HEADING_NORTHEAST: FACE_NORTHEAST, - TOK_HEADING_EAST: FACE_EAST, TOK_HEADING_SOUTHEAST: FACE_SOUTHEAST, TOK_HEADING_SOUTHWEST: FACE_SOUTHWEST, - TOK_HEADING_SOUTH: FACE_SOUTH, TOK_HEADING_WEST: FACE_WEST} - if recycle_bin.has_key(id): - self.sel_rmin.heading = recycle_bin[id] - del recycle_bin - recycle_bin = {TOK_FACING_NONE: FACE_NONE, TOK_FACING_NORTH: FACE_NORTH, - TOK_FACING_NORTHWEST: FACE_NORTHWEST, TOK_FACING_NORTHEAST: FACE_NORTHEAST, - TOK_FACING_EAST: FACE_EAST, TOK_FACING_SOUTHEAST: FACE_SOUTHEAST, TOK_FACING_SOUTHWEST: FACE_SOUTHWEST, - TOK_FACING_SOUTH: FACE_SOUTH, TOK_FACING_WEST: FACE_WEST} - if recycle_bin.has_key(id): - self.sel_rmin.face = recycle_bin[id] - del recycle_bin - elif id == TOK_ALIGN_GRID_CENTER: self.sel_rmin.snap_to_align = SNAPTO_ALIGN_CENTER - elif id == TOK_ALIGN_GRID_TL: self.sel_rmin.snap_to_align = SNAPTO_ALIGN_TL - elif id == TOK_PROP_DLG: - old_lock_value = self.sel_rmin.locked - dlg = min_edit_dialog(self.canvas.frame.GetParent(),self.sel_rmin) - if dlg.ShowModal() == wx.ID_OK: - if self.sel_rmin == self.sel_min and self.sel_rmin.locked != old_lock_value: - # when we lock / unlock the selected mini make sure it isn't still selected - # or it might easily get moved by accident and be hard to move back - self.sel_min.selected = False - self.sel_min.isUpdated = True - self.sel_min = None - self.canvas.Refresh(False) - self.canvas.send_map_data() - return - - elif id == TOK_BACK_ONE: - # This assumes that we always start out with a z-order - # that starts at 0 and goes up to the number of - # minis - 1. If this isn't the case, then execute - # a self.canvas.layers['token'].collapse_zorder() - # before getting the oldz to test - # Save the selected minis current z-order - oldz = self.sel_rmin.zorder - # Make sure the mini isn't sticky front or back - if (oldz != TOK_STICKY_BACK) and (oldz != TOK_STICKY_FRONT): - ## print "old z-order = " + str(oldz) - self.sel_rmin.zorder -= 1 - # Re-collapse to normalize - # Note: only one update (with the final values) will be sent - self.canvas.layers['token'].collapse_zorder() - - elif id == TOK_FORWARD_ONE: - # This assumes that we always start out with a z-order - # that starts at 0 and goes up to the number of - # minis - 1. If this isn't the case, then execute - # a self.canvas.layers['token'].collapse_zorder() - # before getting the oldz to test - # Save the selected minis current z-order - oldz = self.sel_rmin.zorder - ## print "old z-order = " + str(oldz) - self.sel_rmin.zorder += 1 - - # Re-collapse to normalize - # Note: only one update (with the final values) will be sent - self.canvas.layers['token'].collapse_zorder() - - elif id == TOK_TO_FRONT: - # This assumes that we always start out with a z-order - # that starts at 0 and goes up to the number of - # minis - 1. If this isn't the case, then execute - # a self.canvas.layers['token'].collapse_zorder() - # before getting the oldz to test - # Save the selected minis current z-order - oldz = self.sel_rmin.zorder - - # Make sure the mini isn't sticky front or back - if (oldz != TOK_STICKY_BACK) and (oldz != TOK_STICKY_FRONT): - ## print "old z-order = " + str(oldz) - # The new z-order will be one more than the last index - newz = len(self.canvas.layers['token'].token) - ## print "new z-order = " + str(newz) - self.sel_rmin.zorder = newz - # Re-collapse to normalize - # Note: only one update (with the final values) will be sent - self.canvas.layers['token'].collapse_zorder() - - elif id == TOK_TO_BACK: - # This assumes that we always start out with a z-order - # that starts at 0 and goes up to the number of - # minis - 1. If this isn't the case, then execute - # a self.canvas.layers['token'].collapse_zorder() - # before getting the oldz to test - # Save the selected minis current z-order - oldz = self.sel_rmin.zorder - # Make sure the mini isn't sticky front or back - if (oldz != TOK_STICKY_BACK) and (oldz != TOK_STICKY_FRONT): - ## print "old z-order = " + str(oldz) - - # Since 0 is the lowest in a normalized order, be one less - newz = -1 - ## print "new z-order = " + str(newz) - self.sel_rmin.zorder = newz - # Re-collapse to normalize - # Note: only one update (with the final values) will be sent - self.canvas.layers['token'].collapse_zorder() - - elif id == TOK_FRONTBACK_UNLOCK: - #print "Unlocked/ unstickified..." - if self.sel_rmin.zorder == TOK_STICKY_BACK: self.sel_rmin.zorder = TOK_STICKY_BACK + 1 - elif self.sel_rmin.zorder == TOK_STICKY_FRONT: self.sel_rmin.zorder = TOK_STICKY_FRONT - 1 - elif id == TOK_LOCK_BACK: self.sel_rmin.zorder = TOK_STICKY_BACK - elif id == TOK_LOCK_FRONT: self.sel_rmin.zorder = TOK_STICKY_FRONT - # Pretty much, we always want to refresh when we go through here - # This helps us remove the redundant self.Refresh() on EVERY menu event - # that we process above. - self.sel_rmin.isUpdated = True - self.canvas.Refresh(False) - self.canvas.send_map_data() - - def on_token(self, evt): - session = self.canvas.frame.session - if (session.my_role() != session.ROLE_GM) and (session.my_role() != session.ROLE_PLAYER) and (session.use_roles()): - self.infoPost("You must be either a player or GM to use the token Layer") - return - min_url = self.min_url.GetValue() - # build url - if min_url == "" or min_url == "http://": return - if min_url[:7] != "http://" : min_url = "http://" + min_url - # make label - if self.auto_label and min_url[-4:-3] == '.': - start = min_url.rfind("/") + 1 - min_label = min_url[start:len(min_url)-4] - if self.use_serial: - min_label = '%s %d' % ( min_label, self.canvas.layers['token'].next_serial() ) - else: min_label = "" - if self.min_url.FindString(min_url) == -1: self.min_url.Append(min_url) - try: - id = 'mini-' + self.canvas.frame.session.get_next_id() - # make the new mini appear in top left of current viewable map - dc = wx.ClientDC(self.canvas) - self.canvas.PrepareDC(dc) - dc.SetUserScale(self.canvas.layers['grid'].mapscale,self.canvas.layers['grid'].mapscale) - x = dc.DeviceToLogicalX(0) - y = dc.DeviceToLogicalY(0) - self.canvas.layers['token'].add_token(id, min_url, pos=cmpPoint(x,y), label=min_label) - except: - # When there is an exception here, we should be decrementing the serial_number for reuse!! - unablemsg= "Unable to load/resolve URL: " + min_url + " on resource \"" + min_label + "\"!!!\n\n" - #print unablemsg - dlg = wx.MessageDialog(self,unablemsg, 'Url not found',wx.ICON_EXCLAMATION) - dlg.ShowModal() - dlg.Destroy() - self.canvas.layers['token'].rollback_serial() - self.canvas.send_map_data() - self.canvas.Refresh(False) - #except Exception, e: - #wx.MessageBox(str(e),"token Error") - - def on_label(self,evt): - self.auto_label = not self.auto_label - self.auto_label_cb.SetValue(self.auto_label) - #self.send_map_data() - #self.Refresh() - - def on_min_list(self,evt): - session = self.canvas.frame.session - if (session.my_role() != session.ROLE_GM): - self.infoPost("You must be a GM to use this feature") - return - #d = min_list_panel(self.frame.GetParent(),self.canvas.layers,"token list") - d = min_list_panel(self.canvas.frame,self.canvas.layers,"token list") - if d.ShowModal() == wx.ID_OK: d.Destroy() - self.canvas.Refresh(False) - - def on_serial(self, evt): - self.use_serial = not self.use_serial - - def on_map_board_menu_item(self,evt): - id = evt.GetId() - if id == MAP_REFRESH_MINI_URLS: # Note: this doesn't change the mini, so no need to update the map - for mini in self.canvas.layers['token'].tokens: # For all minis - mini.set_bmp(ImageHandler.load(mini.path, 'token', mini.id)) # Reload their bmp member - self.canvas.Refresh(False) - -#################################################################### - ## old functions, changed an awful lot - - def on_left_down(self, evt): - if not self.role_is_gm_or_player() or self.alreadyDealingWithMenu(): return - mini = self.find_mini(evt, evt.CmdDown() and self.role_is_gm()) - if mini: - deselecting_selected_mini = (mini == self.sel_min) #clicked on the selected mini - self.deselectAndRefresh() - self.drag_mini = mini - if deselecting_selected_mini: return - self.sel_min = mini - self.sel_min.selected = True - self.canvas.Refresh() - else: - self.drag_mini = None - pos = self.getLogicalPosition(evt) - self.moveSelectedMini(pos) - self.deselectAndRefresh() - - def on_right_down(self, evt): - if not self.role_is_gm_or_player() or self.alreadyDealingWithMenu(): return - self.last_rclick_pos = self.getLogicalPosition(evt) - mini = self.find_mini(evt, evt.CmdDown() and self.role_is_gm()) - if mini: - self.sel_rmin = mini - if self.sel_min: self.min_menu.Enable(TOK_MOVE, True) - else: self.min_menu.Enable(TOK_MOVE, False) - self.prepare_mini_rclick_menu(evt) - self.do_min_menu(evt.GetPosition()) - else:# pass it on - if self.sel_min: self.main_menu.Enable(TOK_MOVE, True) - else: self.main_menu.Enable(TOK_MOVE, False) - self.prepare_background_rclick_menu(evt) - base_layer_handler.on_right_down(self, evt) - -#################################################################### - ## new functions - - def on_drop_files(self, x, y, filepaths): - # currently we ignore multiple files - filepath = filepaths[0] - start1 = filepath.rfind("\\") + 1 # check for both slashes in path to be on the safe side - start2 = filepath.rfind("/") + 1 - if start1 < start2: start1 = start2 - filename = filepath[start1:] - pos = filename.rfind('.') - ext = filename[pos:].lower() - #ext = filename[-4:].lower() - if(ext != ".bmp" and ext != ".gif" and ext != ".jpg" and ext != ".jpeg" and ext != ".png"): - self.infoPost("Supported file extensions are: *.bmp, *.gif, *.jpg, *.jpeg, *.png") - return - file = open(filepath, "rb") - imgdata = file.read() - file.close() - dc = wx.ClientDC(self.canvas) - self.canvas.PrepareDC(dc) - dc.SetUserScale(self.canvas.layers['grid'].mapscale,self.canvas.layers['grid'].mapscale) - x = dc.DeviceToLogicalX(x) - y = dc.DeviceToLogicalY(y) - (imgtype,j) = mimetypes.guess_type(filename) - postdata = urllib.urlencode({'filename':filename, 'imgdata':imgdata, 'imgtype':imgtype}) - thread.start_new_thread(self.canvas.layers['token'].upload, (postdata, filepath), {'pos':cmpPoint(x,y)}) - - def on_tooltip_timer(self, *args): - pos = args[0] - dc = wx.ClientDC(self.canvas) - self.canvas.PrepareDC(dc) - dc.SetUserScale(self.canvas.layers['grid'].mapscale,self.canvas.layers['grid'].mapscale) - pos = wx.Point(dc.DeviceToLogicalX(pos.x), dc.DeviceToLogicalY(pos.y)) - mini_list = self.getMiniListOrSelectedMini(pos) - if len(mini_list) > 0: - print mini_list - tooltip = self.get_mini_tooltip(mini_list); print tooltip - self.canvas.SetToolTipString(tooltip) - else: self.canvas.SetToolTipString("") - - def on_motion(self,evt): - if evt.Dragging() and evt.LeftIsDown(): - if self.canvas.drag is None and self.drag_mini is not None: - drag_bmp = self.drag_mini.bmp - if self.drag_mini.width and self.drag_mini.height: - tmp_image = drag_bmp.ConvertToImage() - tmp_image.Rescale(int(self.drag_mini.width * self.canvas.layers['grid'].mapscale), - int(self.drag_mini.height * self.canvas.layers['grid'].mapscale)) - tmp_image.ConvertAlphaToMask() - - ### Should show rotated image when dragging. - if self.drag_mini.rotate != 0 : - tmp_image = tmp_image.Rotate(self.drag_mini.rotate, - (self.drag_mini.width/2, self.drag_mini.height/2)) - - drag_bmp = tmp_image.ConvertToBitmap() - mask = wx.Mask(drag_bmp, wx.Colour(tmp_image.GetMaskRed(), - tmp_image.GetMaskGreen(), tmp_image.GetMaskBlue())) - drag_bmp.SetMask(mask) - tmp_image = tmp_image.ConvertToGreyscale() - self.drag_mini.gray = True - self.drag_mini.isUpdated = True - def refresh(): - self.canvas.drag.Hide() - self.canvas.Refresh(False) - wx.CallAfter(refresh) - self.canvas.drag = wx.DragImage(drag_bmp) - self.drag_offset = self.getLogicalPosition(evt)- self.drag_mini.pos - self.canvas.drag.BeginDrag((int(self.drag_offset.x * self.canvas.layers['grid'].mapscale), - int(self.drag_offset.y * self.canvas.layers['grid'].mapscale)), self.canvas, False) - elif self.canvas.drag is not None: - self.canvas.drag.Move(evt.GetPosition()) - self.canvas.drag.Show() - # reset tool tip timer - self.canvas.SetToolTipString("") - self.tooltip_timer.Restart(self.tooltip_delay_miliseconds, evt.GetPosition()) - - def on_left_up(self,evt): - if self.canvas.drag: - self.canvas.drag.Hide() - self.canvas.drag.EndDrag() - self.canvas.drag = None - pos = self.getLogicalPosition(evt) - pos = pos - self.drag_offset - if self.canvas.layers['grid'].snap: - nudge = int(self.canvas.layers['grid'].unit_size/2) - if self.canvas.layers['grid'].mode != GRID_ISOMETRIC: - if self.drag_mini.snap_to_align == SNAPTO_ALIGN_CENTER: - pos = pos + (int(self.drag_mini.bmp.GetWidth()/2),int(self.drag_mini.bmp.GetHeight()/2)) - else: pos = pos + (nudge, nudge) - else:# GRID_ISOMETRIC - if self.drag_mini.snap_to_align == SNAPTO_ALIGN_CENTER: - pos = pos + (int(self.drag_mini.bmp.GetWidth()/2), self.drag_mini.bmp.GetHeight()) - else: pass # no nudge for the isomorphic / top-left - self.sel_min = self.drag_mini - # check to see if the mouse is inside the window still - w = self.canvas.GetClientSizeTuple() # this is the window size, minus any scrollbars - p = evt.GetPosition() # compare the window size, w with the non-logical position - c = self.canvas.size # this is the grid size, compare with the logical position, pos - # both are [width, height] - if p.x>=0 and pos.x=0 and pos.y session.ROLE_GM) and (session.my_role() <> session.ROLE_PLAYER) and (session.use_roles()): - self.infoPost("You must be either a player or GM to use the token Layer") - return False - return True - - def role_is_gm(self): - session = self.canvas.frame.session - if (session.my_role() <> session.ROLE_GM) and (session.use_roles()): return False - return True - - def alreadyDealingWithMenu(self): - return self.lastMenuChoice is not None - - def getLastMenuChoice(self): - choice = self.lastMenuChoice - self.lastMenuChoice = None - return choice - - def getLogicalPosition(self, evt): - dc = wx.ClientDC(self.canvas) - self.canvas.PrepareDC(dc) - dc.SetUserScale(self.canvas.layers['grid'].mapscale,self.canvas.layers['grid'].mapscale) - pos = evt.GetLogicalPosition(dc) - return pos - - def getMiniListOrSelectedMini(self, pos, include_locked=False): - if self.sel_min and self.sel_min.hit_test(pos): - # clicked on the selected mini - assume that is the intended target - # and don't give a choice of it and any other minis stacked with it - mini_list = [] - mini_list.append(self.sel_min) - return mini_list - mini_list = self.canvas.layers['token'].find_token(pos, (not include_locked)) - if mini_list: return mini_list - mini_list = [] - return mini_list - - def deselectAndRefresh(self): - if self.sel_min: - self.sel_min.selected = False - self.sel_min.isUpdated = True - self.canvas.Refresh(False) - self.canvas.send_map_data() - self.sel_min = None - - def moveSelectedMini(self, pos): - if self.sel_min: self.moveMini(pos, self.sel_min) - - def moveMini(self, pos, mini): - grid = self.canvas.layers['grid'] - mini.pos = grid.get_snapped_to_pos(pos, mini.snap_to_align, mini.bmp.GetWidth(), mini.bmp.GetHeight()) - - def find_mini(self, evt, include_locked): - if not self.role_is_gm_or_player() or self.alreadyDealingWithMenu(): return - pos = self.getLogicalPosition(evt) - mini_list = self.getMiniListOrSelectedMini(pos, include_locked) - mini = None - if len(mini_list) > 1: - try: self.do_min_select_menu(mini_list, evt.GetPosition()) - except: pass - choice = self.getLastMenuChoice() - if choice == None: return None # left menu without making a choice, eg by clicking outside menu - mini = mini_list[choice] - elif len(mini_list) == 1: mini = mini_list[0] - return mini - diff -r 4b2884f29a72 -r 81d0bfd5e800 plugins/bcg/tokens.py --- a/plugins/bcg/tokens.py Fri Jan 15 22:45:51 2010 -0600 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,600 +0,0 @@ -# Copyright (C) 2000-2001 The OpenRPG Project -# -# openrpg-dev@lists.sourceforge.net -# -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation; either version 2 of the License, or -# (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. -# -- -# -# File: mapper/tokens.py -# Author: Chris Davis -# Maintainer: -# Version: -# $Id: tokens.py,v 1.46 2007/12/07 20:39:50 digitalxero Exp $ -# -# Description: This file contains some of the basic definitions for the chat -# utilities in the orpg project. -# -__version__ = "$Id: tokens.py,v 1.46 2007/12/07 20:39:50 digitalxero Exp $" - -from orpg.mapper.base import * -import thread -import time -import urllib -import os.path - -from orpg.tools.orpg_settings import settings - -MIN_STICKY_BACK = -0XFFFFFF -MIN_STICKY_FRONT = 0xFFFFFF - -##---------------------------------------- -## token object -##---------------------------------------- - -FACE_NONE = 0 -FACE_NORTH = 1 -FACE_NORTHEAST = 2 -FACE_EAST = 3 -FACE_SOUTHEAST = 4 -FACE_SOUTH = 5 -FACE_SOUTHWEST = 6 -FACE_WEST = 7 -FACE_NORTHWEST = 8 -SNAPTO_ALIGN_CENTER = 0 -SNAPTO_ALIGN_TL = 1 - -def cmp_zorder(first,second): - f = first.zorder - s = second.zorder - if f == None: f = 0 - if s == None: s = 0 - if f == s: value = 0 - elif f < s: value = -1 - else: value = 1 - return value - -class BmpToken: - def __init__(self, id,path, bmp, pos=cmpPoint(0,0), - heading=FACE_NONE, rotate=0, label="", - locked=False, hide=False, snap_to_align=SNAPTO_ALIGN_CENTER, - zorder=0, width=0, height=0, log=None, local=False, localPath='', localTime=-1): - self.heading = heading - self.rotate = rotate - self.label = label - self.path = path - self.bmp = bmp - self.pos = pos - self.selected = False - self.locked = locked - self.snap_to_align = snap_to_align - self.hide = hide - self.id = id - self.zorder = zorder - self.left = 0 - self.local = local - self.localPath = localPath - self.localTime = localTime - if not width: self.width = 0 - else: self.width = width - if not height: self.height = 0 - else: self.height = height - self.right = bmp.GetWidth() - self.top = 0 - self.bottom = bmp.GetHeight() - self.isUpdated = False - self.gray = False - self.drawn = {} - - def __del__(self): - del self.bmp - self.bmp = None - - def set_bmp(self, bmp): - self.bmp = bmp - - def set_min_props(self, heading=FACE_NONE, rotate=0, label="", locked=False, hide=False, width=0, height=0): - self.heading = heading - self.rotate = rotate - self.label = label - if locked: self.locked = True - else: self.locked = False - if hide: self.hide = True - else: self.hide = False - self.width = int(width) - self.height = int(height) - self.isUpdated = True - - def hit_test(self, pt): - rect = self.get_rect() - result = None - result = rect.InsideXY(pt.x, pt.y) - return result - - def get_rect(self): - ret = wx.Rect(self.pos.x, self.pos.y, self.bmp.GetWidth(), self.bmp.GetHeight()) - return ret - - def draw(self, dc, mini_layer, op=wx.COPY): - if isinstance(self.bmp, tuple): - self.bmp = wx.ImageFromMime(self.bmp[1], self.bmp[2]).ConvertToBitmap() - if self.bmp != None and self.bmp.Ok(): - # check if hidden and GM: we outline the mini in grey (little bit smaller than the actual size) - # and write the label in the center of the mini - if self.hide and mini_layer.canvas.frame.session.my_role() == mini_layer.canvas.frame.session.ROLE_GM: - # set the width and height of the image - if self.width and self.height: - tmp_image = self.bmp.ConvertToImage() - tmp_image.Rescale(int(self.width), int(self.height)) - tmp_image.ConvertAlphaToMask() - self.bmp = tmp_image.ConvertToBitmap() - mask = wx.Mask(self.bmp, wx.Colour(tmp_image.GetMaskRed(), - tmp_image.GetMaskGreen(), tmp_image.GetMaskBlue())) - self.bmp.SetMask(mask) - del tmp_image - del mask - self.left = 0 - self.right = self.bmp.GetWidth() - self.top = 0 - self.bottom = self.bmp.GetHeight() - # grey outline - graypen = wx.Pen("gray", 1, wx.DOT) - dc.SetPen(graypen) - dc.SetBrush(wx.TRANSPARENT_BRUSH) - #if width or height < 20 then offset = 1 - if self.bmp.GetWidth() <= 20: xoffset = 1 - else: xoffset = 5 - if self.bmp.GetHeight() <= 20: yoffset = 1 - else: yoffset = 5 - dc.DrawRectangle(self.pos.x + xoffset, - self.pos.y + yoffset, self.bmp.GetWidth() - (xoffset * 2), - self.bmp.GetHeight() - (yoffset * 2)) - dc.SetBrush(wx.NullBrush) - dc.SetPen(wx.NullPen) - ## draw label in the center of the mini - label = mini_layer.get_mini_label(self) - if len(label): - dc.SetTextForeground(wx.RED) - (textWidth,textHeight) = dc.GetTextExtent(label) - x = self.pos.x +((self.bmp.GetWidth() - textWidth) /2) - 1 - y = self.pos.y + (self.bmp.GetHeight() / 2) - dc.SetPen(wx.GREY_PEN) - dc.SetBrush(wx.LIGHT_GREY_BRUSH) - dc.DrawRectangle(x, y, textWidth+2, textHeight+2) - if (textWidth+2 > self.right): - self.right += int((textWidth+2-self.right)/2)+1 - self.left -= int((textWidth+2-self.right)/2)+1 - self.bottom = y+textHeight+2-self.pos.y - dc.SetPen(wx.NullPen) - dc.SetBrush(wx.NullBrush) - dc.DrawText(label, x+1, y+1) - - #selected outline - if self.selected: - dc.SetPen(wx.RED_PEN) - dc.SetBrush(wx.TRANSPARENT_BRUSH) - dc.DrawRectangle(self.pos.x, self.pos.y, self.bmp.GetWidth(), self.bmp.GetHeight()) - dc.SetBrush(wx.NullBrush) - dc.SetPen(wx.NullPen) - return True - elif self.hide: return True - - else: - # set the width and height of the image - bmp = self.bmp - if self.width and self.height: - tmp_image = self.bmp.ConvertToImage() - tmp_image.Rescale(int(self.width), int(self.height)) - tmp_image.ConvertAlphaToMask() - self.bmp = tmp_image.ConvertToBitmap() - mask = wx.Mask(self.bmp, wx.Colour(tmp_image.GetMaskRed(), - tmp_image.GetMaskGreen(), tmp_image.GetMaskBlue())) - self.bmp.SetMask(mask) - if self.gray: - tmp_image = tmp_image.ConvertToGreyscale() - bmp = tmp_image.ConvertToBitmap() - else: bmp = self.bmp - - if self.rotate != 0: - x = bmp.GetWidth(); print x - y = bmp.GetHeight(); print y - img = bmp.ConvertToImage() - img = img.Rotate(self.rotate, (3, 80), True) - img.ConvertAlphaToMask() - - bmp = img.ConvertToBitmap() - mask = wx.Mask(bmp, wx.Colour(img.GetMaskRed(), - img.GetMaskGreen(), img.GetMaskBlue())) - bmp.SetMask(mask) - - dc.DrawBitmap(bmp, self.pos.x, self.pos.y, True) - component.get('drawn')[bmp] = True - self.left = 0 - self.right = self.bmp.GetWidth() - self.top = 0 - self.bottom = self.bmp.GetHeight() - - # Draw the heading if needed - if self.heading: - x_adjust = 0 - y_adjust = 4 - x_half = self.bmp.GetWidth()/2 - y_half = self.bmp.GetHeight()/2 - x_quarter = self.bmp.GetWidth()/4 - y_quarter = self.bmp.GetHeight()/4 - x_3quarter = x_quarter*3 - y_3quarter = y_quarter*3 - x_full = self.bmp.GetWidth() - y_full = self.bmp.GetHeight() - x_center = self.pos.x + x_half - y_center = self.pos.y + y_half - # Remember, the pen/brush must be a different color than the - # facing marker!!!! We'll use black/cyan for starters. - # Also notice that we will draw the heading on top of the - # larger facing marker. - dc.SetPen(wx.BLACK_PEN) - dc.SetBrush(wx.CYAN_BRUSH) - triangle = [] - - # Figure out which direction to draw the marker!! - if self.heading == FACE_NORTH: - triangle.append(cmpPoint(x_center - x_quarter, y_center - y_half )) - triangle.append(cmpPoint(x_center, y_center - y_3quarter )) - triangle.append(cmpPoint(x_center + x_quarter, y_center - y_half )) - elif self.heading == FACE_SOUTH: - triangle.append(cmpPoint(x_center - x_quarter, y_center + y_half )) - triangle.append(cmpPoint(x_center, y_center + y_3quarter )) - triangle.append(cmpPoint(x_center + x_quarter, y_center + y_half )) - elif self.heading == FACE_NORTHEAST: - triangle.append(cmpPoint(x_center + x_quarter, y_center - y_half )) - triangle.append(cmpPoint(x_center + x_3quarter, y_center - y_3quarter )) - triangle.append(cmpPoint(x_center + x_half, y_center - y_quarter )) - elif self.heading == FACE_EAST: - triangle.append(cmpPoint(x_center + x_half, y_center - y_quarter )) - triangle.append(cmpPoint(x_center + x_3quarter, y_center )) - triangle.append(cmpPoint(x_center + x_half, y_center + y_quarter )) - elif self.heading == FACE_SOUTHEAST: - triangle.append(cmpPoint(x_center + x_half, y_center + y_quarter )) - triangle.append(cmpPoint(x_center + x_3quarter, y_center + y_3quarter )) - triangle.append(cmpPoint(x_center + x_quarter, y_center + y_half )) - elif self.heading == FACE_SOUTHWEST: - triangle.append(cmpPoint(x_center - x_quarter, y_center + y_half )) - triangle.append(cmpPoint(x_center - x_3quarter, y_center + y_3quarter )) - triangle.append(cmpPoint(x_center - x_half, y_center + y_quarter )) - elif self.heading == FACE_WEST: - triangle.append(cmpPoint(x_center - x_half, y_center + y_quarter )) - triangle.append(cmpPoint(x_center - x_3quarter, y_center )) - triangle.append(cmpPoint(x_center - x_half, y_center - y_quarter )) - elif self.heading == FACE_NORTHWEST: - triangle.append(cmpPoint(x_center - x_half, y_center - y_quarter )) - triangle.append(cmpPoint(x_center - x_3quarter, y_center - y_3quarter )) - triangle.append(cmpPoint(x_center - x_quarter, y_center - y_half )) - dc.DrawPolygon(triangle) - dc.SetBrush(wx.NullBrush) - dc.SetPen(wx.NullPen) - #selected outline - if self.selected: - dc.SetPen(wx.RED_PEN) - dc.SetBrush(wx.TRANSPARENT_BRUSH) - dc.DrawRectangle(self.pos.x, self.pos.y, self.bmp.GetWidth(), self.bmp.GetHeight()) - dc.SetBrush(wx.NullBrush) - dc.SetPen(wx.NullPen) - # draw label - label = mini_layer.get_mini_label(self) - if len(label): - dc.SetTextForeground(wx.RED) - (textWidth,textHeight) = dc.GetTextExtent(label) - x = self.pos.x +((self.bmp.GetWidth() - textWidth) /2) - 1 - y = self.pos.y + self.bmp.GetHeight() + 6 - dc.SetPen(wx.WHITE_PEN) - dc.SetBrush(wx.WHITE_BRUSH) - dc.DrawRectangle(x,y,textWidth+2,textHeight+2) - if (textWidth+2 > self.right): - self.right += int((textWidth+2-self.right)/2)+1 - self.left -= int((textWidth+2-self.right)/2)+1 - self.bottom = y+textHeight+2-self.pos.y - dc.SetPen(wx.NullPen) - dc.SetBrush(wx.NullBrush) - dc.DrawText(label,x+1,y+1) - self.top-=5 - self.bottom+=5 - self.left-=5 - self.right+=5 - return True - else: return False - - def toxml(self, action="update"): - if action == "del": - xml_str = "" - return xml_str - xml_str = "= 10): font_size -= 2 - self.label_font = wx.Font(font_size, wx.FONTFAMILY_DEFAULT, wx.FONTSTYLE_NORMAL, wx.FONTWEIGHT_NORMAL, - False, settings.get_setting('defaultfont')) - - def next_serial(self): - self.serial_number += 1 - return self.serial_number - - def get_next_highest_z(self): - z = len(self.tokens)+1 - return z - - def cleanly_collapse_zorder(self): - # lock the zorder stuff - sorted_tokens = self.tokens[:] - sorted_tokens.sort(cmp_zorder) - i = 0 - for mini in sorted_tokens: - mini.zorder = i - i = i + 1 - # unlock the zorder stuff - - def collapse_zorder(self): - # lock the zorder stuff - sorted_tokens = self.tokens[:] - sorted_tokens.sort(cmp_zorder) - i = 0 - for mini in sorted_tokens: - if (mini.zorder != MIN_STICKY_BACK) and (mini.zorder != MIN_STICKY_FRONT): mini.zorder = i - else: pass - i = i + 1 - # unlock the zorder stuff - - def rollback_serial(self): - self.serial_number -= 1 - - def add_token(self, id, path, pos=cmpPoint(0,0), label="", heading=FACE_NONE, - rotate=0, width=0, height=0, local=False, localPath='', localTime=-1): - bmp = ImageHandler.load(path, 'token', id) - if bmp: - mini = BmpToken(id, path, bmp, pos, heading, rotate, label, - zorder=self. get_next_highest_z(), width=width, - height=height, local=local, localPath=localPath, localTime=localTime) - self.tokens.append(mini) - self.drawn[mini.bmp] = False - xml_str = "" - xml_str += mini.toxml("new") - xml_str += "" - component.get('session').send(xml_str) - - def get_token_by_id(self, id): - for mini in self.tokens: - if str(mini.id) == str(id): - return mini - return None - - def del_token(self, min): - xml_str = "" - xml_str += min.toxml("del") - xml_str += "" - self.canvas.frame.session.send(xml_str) - self.tokens.remove(min) - del min - self.collapse_zorder() - - def del_all_tokens(self): - while len(self.tokens): - min = self.tokens.pop() - del min - self.collapse_zorder() - - def layerDraw(self, dc, topleft, size): - dc.SetFont(self.label_font) - sorted_tokens = self.tokens[:] - sorted_tokens.sort(cmp_zorder) - for m in sorted_tokens: - if (m.pos.x>topleft[0]-m.right and - m.pos.y>topleft[1]-m.bottom and - m.pos.x 0: - return min_list - else: return None - - def layerToXML(self, action="update"): - """ format """ - minis_string = "" - if self.tokens: - for m in self.tokens: minis_string += m.toxml(action) - if minis_string != '': - s = "