Mercurial > traipse_dev
comparison orpg/chat/chatwnd.py @ 195:b633f4c64aae alpha
Traipse Alpha 'OpenRPG' {100219-00}
Traipse is a distribution of OpenRPG that is designed to be easy to setup and go. Traipse also makes it easy for
developers to work on code without fear of sacrifice. 'Ornery-Orc' continues the trend of 'Grumpy' and adds fixes to
the code. 'Ornery-Orc's main goal is to offer more advanced features and enhance the productivity of the user.
Update Summary (Patch-2)
New Features:
New Namespace method with two new syntaxes
Fixes:
Fix to Server GUI startup errors
Fix to Server GUI Rooms tab updating
Fix to Chat and Settings if non existant die roller is picked
Fix to Dieroller and .open() used with .vs(). Successes are correctly calculated
Fix to Alias Lib's Export to Tree, Open, Save features
Fix to alias node, now works properly
Fix to Splitter node, minor GUI cleanup
author | sirebral |
---|---|
date | Sat, 24 Apr 2010 08:37:20 -0500 |
parents | 4b2884f29a72 |
children | 0bc44a57ae6c |
comparison
equal
deleted
inserted
replaced
182:4b2884f29a72 | 195:b633f4c64aae |
---|---|
19 # | 19 # |
20 # File: chatutils.py | 20 # File: chatutils.py |
21 # Author: Chris Davis | 21 # Author: Chris Davis |
22 # Maintainer: | 22 # Maintainer: |
23 # Version: | 23 # Version: |
24 # $Id: chatwnd.py,v 1.177 2007/12/07 20:39:48 digitalxero Exp $ | 24 # $Id: chatwnd.py,v Traipse 'Ornery-Orc' prof.ebral Exp $ |
25 # | 25 # |
26 # Description: This file contains some of the basic definitions for the chat | 26 # Description: This file contains some of the basic definitions for the chat |
27 # utilities in the orpg project. | 27 # utilities in the orpg project. |
28 # | 28 # |
29 # History | 29 # History |
35 # + Added strip_script_tags() to post() to remove crash point. See chat_util.py | 35 # + Added strip_script_tags() to post() to remove crash point. See chat_util.py |
36 # 2005-04-25 Snowdog | 36 # 2005-04-25 Snowdog |
37 # + Added simple_html_repair() to post() to fix malformed html in the chat window | 37 # + Added simple_html_repair() to post() to fix malformed html in the chat window |
38 # | 38 # |
39 | 39 |
40 __version__ = "$Id: chatwnd.py,v 1.177 2007/12/07 20:39:48 digitalxero Exp $" | 40 __version__ = "$Id: chatwnd.py,v Traipse 'Ornery-Orc' prof.ebral Exp $" |
41 | 41 |
42 | 42 |
43 ## | 43 ## |
44 ## Module Loading | 44 ## Module Loading |
45 ## | 45 ## |
46 import os, time, re, sys, traceback, webbrowser, commands, chat_msg, chat_util | 46 import os, time, re, sys, traceback, webbrowser, commands, chat_msg, chat_util |
47 | 47 |
48 from orpg.orpg_version import VERSION | 48 from orpg.orpg_version import VERSION, DISTRO, DIS_VER, BUILD |
49 from orpg.orpg_windows import * | 49 from orpg.orpg_windows import * |
50 from orpg.player_list import WG_LIST | 50 from orpg.player_list import WG_LIST |
51 from orpg.dirpath import dir_struct | 51 from orpg.dirpath import dir_struct |
52 #from orpg.tools.metamenus import MenuEx #Needed? | |
53 from string import * | 52 from string import * |
54 | 53 |
55 import cStringIO # for reading inline imagedata as a stream | 54 import cStringIO # for reading inline imagedata as a stream |
56 from HTMLParser import HTMLParser | 55 from HTMLParser import HTMLParser |
57 from wx.lib.expando import EVT_ETC_LAYOUT_NEEDED | 56 from wx.lib.expando import EVT_ETC_LAYOUT_NEEDED |
60 import orpg.tools.inputValidator | 59 import orpg.tools.inputValidator |
61 from orpg.tools.validate import validate | 60 from orpg.tools.validate import validate |
62 from orpg.tools.orpg_settings import settings | 61 from orpg.tools.orpg_settings import settings |
63 import orpg.tools.predTextCtrl | 62 import orpg.tools.predTextCtrl |
64 from orpg.tools.orpg_log import logger, debug | 63 from orpg.tools.orpg_log import logger, debug |
64 from orpg.tools.InterParse import Parse | |
65 from orpg.orpgCore import component | 65 from orpg.orpgCore import component |
66 from xml.etree.ElementTree import tostring | 66 from xml.etree.ElementTree import tostring |
67 | 67 |
68 from orpg.networking.mplay_client import MPLAY_CONNECTED # needed to only send typing/not_typing messages while connected | 68 from orpg.networking.mplay_client import MPLAY_CONNECTED |
69 | |
70 NEWCHAT = False | 69 NEWCHAT = False |
71 try: | 70 try: |
72 import wx.webview | 71 import wx.webview |
73 NEWCHAT = True | 72 NEWCHAT = True |
74 except: pass | 73 except: pass |
81 | 80 |
82 def __init__(self): | 81 def __init__(self): |
83 self.accum = "" | 82 self.accum = "" |
84 self.special_tags = ['hr', 'br', 'img'] | 83 self.special_tags = ['hr', 'br', 'img'] |
85 | 84 |
86 def handle_data(self, data): # quote cdata literally | 85 def handle_data(self, data): |
87 self.accum += data | 86 self.accum += data |
88 | 87 |
89 def handle_entityref(self, name): # entities must be preserved exactly | 88 def handle_entityref(self, name): |
90 self.accum += "&" + name + ";" | 89 self.accum += "&" + name + ";" |
91 | 90 |
92 def handle_starttag(self, tag, attrs): | 91 def handle_starttag(self, tag, attrs): |
93 if tag in self.special_tags: | 92 if tag in self.special_tags: |
94 self.accum += '<' + tag | 93 self.accum += '<' + tag |
95 for attrib in attrs: self.accum += ' ' + attrib[0] + '="' + attrib[1] + '"' | 94 for attrib in attrs: self.accum += ' ' + attrib[0] + '="' + attrib[1] + '"' |
96 self.accum += '>' | 95 self.accum += '>' |
97 | 96 |
98 def handle_charref(self, name): # charrefs too | 97 def handle_charref(self, name): |
99 self.accum += "&#" + name + ";" | 98 self.accum += "&#" + name + ";" |
100 htmlstripper = HTMLStripper() | 99 htmlstripper = HTMLStripper() |
101 | 100 |
102 # utility function; see Post(). | |
103 | 101 |
104 def strip_html(string): | 102 def strip_html(string): |
105 "Return string tripped of html tags." | 103 "Return string tripped of html tags." |
106 htmlstripper.reset() | 104 htmlstripper.reset() |
107 htmlstripper.accum = "" | 105 htmlstripper.accum = "" |
112 | 110 |
113 def log( settings, c, text ): | 111 def log( settings, c, text ): |
114 filename = settings.get_setting('GameLogPrefix') | 112 filename = settings.get_setting('GameLogPrefix') |
115 if filename > '' and filename[0] != commands.ANTI_LOG_CHAR: | 113 if filename > '' and filename[0] != commands.ANTI_LOG_CHAR: |
116 filename = filename + time.strftime( '-%Y-%m-%d.html', time.localtime( time.time() ) ) | 114 filename = filename + time.strftime( '-%Y-%m-%d.html', time.localtime( time.time() ) ) |
117 #filename = time.strftime( filename, time.localtime( time.time() ) ) | |
118 timestamp = time.ctime(time.time()) | 115 timestamp = time.ctime(time.time()) |
119 header = '[%s] : ' % ( timestamp ); | 116 header = '[%s] : ' % ( timestamp ); |
120 if settings.get_setting('TimeStampGameLog') != '1': header = '' | 117 if settings.get_setting('TimeStampGameLog') != '1': header = '' |
121 try: | 118 try: |
122 f = open( dir_struct["user"] + filename, 'a' ) | 119 f = open( dir_struct["user"] + filename, 'a' ) |
123 f.write( '<div class="'+c+'">%s%s</div>\n' % ( header, text ) ) | 120 f.write( '<div class="'+c+'">%s%s</div>\n' % ( header, text ) ) |
124 f.close() | 121 f.close() |
125 except: | 122 except Exception, e: |
126 print "could not open " + dir_struct["user"] + filename + ", ignoring..." | 123 print "could not open " + dir_struct["user"] + filename + ", ignoring..." |
124 print 'Error given', e | |
127 pass | 125 pass |
128 | 126 |
129 # This class displayes the chat information in html? | 127 # This class displayes the chat information in html? |
130 # | 128 # |
131 # Defines: | 129 # Defines: |
134 # CalculateAllFonts(self, defaultsize) | 132 # CalculateAllFonts(self, defaultsize) |
135 # SetDefaultFontAndSize(self, fontname) | 133 # SetDefaultFontAndSize(self, fontname) |
136 # | 134 # |
137 class chat_html_window(wx.html.HtmlWindow): | 135 class chat_html_window(wx.html.HtmlWindow): |
138 """ a wxHTMLwindow that will load links """ | 136 """ a wxHTMLwindow that will load links """ |
139 # initialization subroutine | 137 |
140 # | |
141 # !self : instance of self | |
142 # !parent : | |
143 # !id : | |
144 | |
145 def __init__(self, parent, id): | 138 def __init__(self, parent, id): |
146 wx.html.HtmlWindow.__init__(self, parent, id, | 139 wx.html.HtmlWindow.__init__(self, parent, id, |
147 style=wx.SUNKEN_BORDER|wx.html.HW_SCROLLBAR_AUTO|wx.NO_FULL_REPAINT_ON_RESIZE) | 140 style=wx.SUNKEN_BORDER|wx.html.HW_SCROLLBAR_AUTO|wx.NO_FULL_REPAINT_ON_RESIZE) |
148 self.parent = parent | 141 self.parent = parent |
149 self.build_menu() | 142 self.build_menu() |
150 self.Bind(wx.EVT_LEFT_UP, self.LeftUp) | 143 self.Bind(wx.EVT_LEFT_UP, self.LeftUp) |
151 self.Bind(wx.EVT_RIGHT_DOWN, self.onPopup) | 144 self.Bind(wx.EVT_RIGHT_DOWN, self.onPopup) |
152 if "gtk2" in wx.PlatformInfo: self.SetStandardFonts() | 145 if "gtk2" in wx.PlatformInfo: self.SetStandardFonts() |
153 # def __init__ - end | 146 |
154 | |
155 | |
156 def onPopup(self, evt): | 147 def onPopup(self, evt): |
157 self.PopupMenu(self.menu) | 148 self.PopupMenu(self.menu) |
158 | 149 |
159 | |
160 def LeftUp(self, event): | 150 def LeftUp(self, event): |
161 event.Skip() | 151 event.Skip() |
162 wx.CallAfter(self.parent.set_chat_text_focus, None) | 152 wx.CallAfter(self.parent.set_chat_text_focus, None) |
163 | 153 |
164 | |
165 def build_menu(self): | 154 def build_menu(self): |
166 self.menu = wx.Menu() | 155 self.menu = wx.Menu() |
167 item = wx.MenuItem(self.menu, wx.ID_ANY, "Copy", "Copy") | 156 item = wx.MenuItem(self.menu, wx.ID_ANY, "Copy", "Copy") |
168 self.Bind(wx.EVT_MENU, self.OnM_EditCopy, item) | 157 self.Bind(wx.EVT_MENU, self.OnM_EditCopy, item) |
169 self.menu.AppendItem(item) | 158 self.menu.AppendItem(item) |
172 wx.TheClipboard.UsePrimarySelection(False) | 161 wx.TheClipboard.UsePrimarySelection(False) |
173 wx.TheClipboard.Open() | 162 wx.TheClipboard.Open() |
174 wx.TheClipboard.SetData(wx.TextDataObject(self.SelectionToText())) | 163 wx.TheClipboard.SetData(wx.TextDataObject(self.SelectionToText())) |
175 wx.TheClipboard.Close() | 164 wx.TheClipboard.Close() |
176 | 165 |
177 | |
178 def scroll_down(self): | 166 def scroll_down(self): |
179 maxrange = self.GetScrollRange(wx.VERTICAL) | 167 maxrange = self.GetScrollRange(wx.VERTICAL) |
180 pagesize = self.GetScrollPageSize(wx.VERTICAL) | 168 pagesize = self.GetScrollPageSize(wx.VERTICAL) |
181 self.Scroll(-1, maxrange-pagesize) | 169 self.Scroll(-1, maxrange-pagesize) |
182 | 170 |
183 | |
184 def mouse_wheel(self, event): | 171 def mouse_wheel(self, event): |
185 amt = event.GetWheelRotation() | 172 amt = event.GetWheelRotation() |
186 units = amt/(-(event.GetWheelDelta())) | 173 units = amt/(-(event.GetWheelDelta())) |
187 self.ScrollLines(units*3) | 174 self.ScrollLines(units*3) |
188 | 175 |
195 return self.GetPageSource().replace(self.Header(), '') | 182 return self.GetPageSource().replace(self.Header(), '') |
196 | 183 |
197 | 184 |
198 def GetPageSource(self): | 185 def GetPageSource(self): |
199 return self.GetParser().GetSource() | 186 return self.GetParser().GetSource() |
200 | |
201 # This subroutine fires up the webbrowser when a link is clicked. | |
202 # | |
203 # !self : instance of self | |
204 # !linkinfo : instance of a class that contains the link information | |
205 | 187 |
206 def OnLinkClicked(self, linkinfo): | 188 def OnLinkClicked(self, linkinfo): |
207 href = linkinfo.GetHref() | 189 href = linkinfo.GetHref() |
208 wb = webbrowser.get() | 190 wb = webbrowser.get() |
209 wb.open(href) | 191 wb.open(href) |
210 # def OnLinkClicked - end | 192 |
211 | |
212 | |
213 def CalculateAllFonts(self, defaultsize): | 193 def CalculateAllFonts(self, defaultsize): |
214 return [int(defaultsize * 0.4), | 194 return [int(defaultsize * 0.4), |
215 int(defaultsize * 0.7), | 195 int(defaultsize * 0.7), |
216 int(defaultsize), | 196 int(defaultsize), |
217 int(defaultsize * 1.3), | 197 int(defaultsize * 1.3), |
218 int(defaultsize * 1.7), | 198 int(defaultsize * 1.7), |
219 int(defaultsize * 2), | 199 int(defaultsize * 2), |
220 int(defaultsize * 2.5)] | 200 int(defaultsize * 2.5)] |
221 | 201 |
222 | |
223 def SetDefaultFontAndSize(self, fontname, fontsize): | 202 def SetDefaultFontAndSize(self, fontname, fontsize): |
224 """Set 'fontname' to the default chat font. | 203 """Set 'fontname' to the default chat font. |
225 Returns current font settings in a (fontname, fontsize) tuple.""" | 204 Returns current font settings in a (fontname, fontsize) tuple.""" |
226 self.SetFonts(fontname, "", self.CalculateAllFonts(int(fontsize))) | 205 self.SetFonts(fontname, "", self.CalculateAllFonts(int(fontsize))) |
227 return (self.GetFont().GetFaceName(), self.GetFont().GetPointSize()) | 206 return (self.GetFont().GetFaceName(), self.GetFont().GetPointSize()) |
237 self.build_menu() | 216 self.build_menu() |
238 self.Bind(wx.EVT_LEFT_UP, self.LeftUp) | 217 self.Bind(wx.EVT_LEFT_UP, self.LeftUp) |
239 self.Bind(wx.EVT_RIGHT_DOWN, self.onPopup) | 218 self.Bind(wx.EVT_RIGHT_DOWN, self.onPopup) |
240 self.Bind(wx.webview.EVT_WEBVIEW_BEFORE_LOAD, self.OnLinkClicked) | 219 self.Bind(wx.webview.EVT_WEBVIEW_BEFORE_LOAD, self.OnLinkClicked) |
241 | 220 |
242 #Wrapers so I dont have to add special Code | |
243 def SetPage(self, htmlstring): | 221 def SetPage(self, htmlstring): |
244 self.SetPageSource(htmlstring) | 222 self.SetPageSource(htmlstring) |
245 | 223 |
246 def AppendToPage(self, htmlstring): | 224 def AppendToPage(self, htmlstring): |
247 self.SetPageSource(self.GetPageSource() + htmlstring) | 225 self.SetPageSource(self.GetPageSource() + htmlstring) |
364 self.create_gm_tab() | 342 self.create_gm_tab() |
365 self.SetSelection(0) | 343 self.SetSelection(0) |
366 | 344 |
367 def get_tab_index(self, chatpanel): | 345 def get_tab_index(self, chatpanel): |
368 "Return the index of a chatpanel in the wxNotebook." | 346 "Return the index of a chatpanel in the wxNotebook." |
369 | |
370 for i in xrange(self.GetPageCount()): | 347 for i in xrange(self.GetPageCount()): |
371 if (self.GetPage(i) == chatpanel): | 348 if (self.GetPage(i) == chatpanel): |
372 return i | 349 return i |
373 | 350 |
374 def create_gm_tab(self): | 351 def create_gm_tab(self): |
448 def onPageChanged(self, event): | 425 def onPageChanged(self, event): |
449 """When private chattabs are selected, set the bitmap back to 'normal'.""" | 426 """When private chattabs are selected, set the bitmap back to 'normal'.""" |
450 selected_idx = event.GetSelection() | 427 selected_idx = event.GetSelection() |
451 self.SetPageImage(selected_idx, 1) | 428 self.SetPageImage(selected_idx, 1) |
452 page = self.GetPage(selected_idx) | 429 page = self.GetPage(selected_idx) |
453 #wx.CallAfter(page.set_chat_text_focus, 0) | |
454 event.Skip() | 430 event.Skip() |
455 | 431 |
456 """ | 432 """ |
457 This class defines and builds the Chat Frame for OpenRPG | 433 This class defines and builds the Chat Frame for OpenRPG |
458 | 434 |
503 self.activeplugins = component.get('plugins') | 479 self.activeplugins = component.get('plugins') |
504 self.parent = parent | 480 self.parent = parent |
505 # who receives outbound messages, either "all" or "playerid" string | 481 # who receives outbound messages, either "all" or "playerid" string |
506 self.sendtarget = sendtarget | 482 self.sendtarget = sendtarget |
507 self.type = tab_type | 483 self.type = tab_type |
508 #self.sound_player = component.get('sound') #Removing! | |
509 # create die roller manager | |
510 #self.DiceManager = component.get('DiceManager') #Removing! | |
511 # create rpghex tool | |
512 self.r_h = orpg.tools.rgbhex.RGBHex() | 484 self.r_h = orpg.tools.rgbhex.RGBHex() |
513 self.h = 0 | 485 self.h = 0 |
514 self.set_colors() | 486 self.set_colors() |
515 self.version = VERSION | 487 self.version = VERSION |
516 self.histidx = -1 | 488 self.histidx = -1 |
534 self.defaultFilterName = 'No Filter' | 506 self.defaultFilterName = 'No Filter' |
535 self.advancedFilter = False | 507 self.advancedFilter = False |
536 self.lastSend = 0 # this is used to help implement the player typing indicator | 508 self.lastSend = 0 # this is used to help implement the player typing indicator |
537 self.lastPress = 0 # this is used to help implement the player typing indicator | 509 self.lastPress = 0 # this is used to help implement the player typing indicator |
538 self.Bind(wx.EVT_SIZE, self.OnSize) | 510 self.Bind(wx.EVT_SIZE, self.OnSize) |
539 self.Bind(EVT_ETC_LAYOUT_NEEDED, self.OnSize) #require to keep text at bottom of chat when text entry expands --SD | 511 self.Bind(EVT_ETC_LAYOUT_NEEDED, self.OnSize) |
540 self.build_ctrls() | 512 self.build_ctrls() |
541 StartupFont = self.settings.get_setting("defaultfont") | 513 StartupFont = self.settings.get_setting("defaultfont") |
542 StartupFontSize = self.settings.get_setting("defaultfontsize") | 514 StartupFontSize = self.settings.get_setting("defaultfontsize") |
543 if(StartupFont != "") and (StartupFontSize != ""): | 515 if(StartupFont != "") and (StartupFontSize != ""): |
544 try: self.set_default_font(StartupFont, int(StartupFontSize)) | 516 try: self.set_default_font(StartupFont, int(StartupFontSize)) |
776 def get_hot_keys(self): | 748 def get_hot_keys(self): |
777 # dummy menus for hotkeys | 749 # dummy menus for hotkeys |
778 self.build_menu() | 750 self.build_menu() |
779 entries = [] | 751 entries = [] |
780 entries.append((wx.ACCEL_CTRL, ord('H'), self.setChatFocusMenu.GetId())) | 752 entries.append((wx.ACCEL_CTRL, ord('H'), self.setChatFocusMenu.GetId())) |
781 #entries.append((wx.ACCEL_CTRL, wx.WXK_TAB, SWAP_TABS)) | |
782 return entries | 753 return entries |
783 | 754 |
784 | 755 |
785 def forward_tabs(self, evt): | 756 def forward_tabs(self, evt): |
786 self.parent.AdvanceSelection() | 757 self.parent.AdvanceSelection() |
787 | 758 |
788 def back_tabs(self, evt): | 759 def back_tabs(self, evt): |
789 self.parent.AdvanceSelection(False) | 760 self.parent.AdvanceSelection(False) |
790 | 761 |
791 # This subroutine builds the controls for the chat frame | |
792 # | |
793 # !self : instance of self | |
794 | |
795 def build_ctrls(self): | 762 def build_ctrls(self): |
796 self.chatwnd = chat_html_window(self,-1) | 763 self.chatwnd = chat_html_window(self,-1) |
797 self.set_colors() | 764 self.set_colors() |
798 wx.CallAfter(self.chatwnd.SetPage, self.chatwnd.Header()) | 765 wx.CallAfter(self.chatwnd.SetPage, self.chatwnd.Header()) |
766 welcome = "<b>Welcome to <a href='http://www.knowledgearcana.com//content/view/199/128/'>" | |
767 welcome += DISTRO +'</a> '+ DIS_VER +' {'+BUILD+'},' | |
768 welcome += ' built on OpenRPG '+ VERSION +'</b>' | |
799 if (self.sendtarget == "all"): | 769 if (self.sendtarget == "all"): |
800 wx.CallAfter(self.Post, self.colorize(self.syscolor, | 770 wx.CallAfter(self.Post, self.colorize(self.syscolor, welcome)) |
801 "<b>Welcome to <a href='http://www.openrpg.com'>OpenRPG</a> version " + self.version + "... </b>")) | |
802 #self.chat_cmds.on_help() | |
803 self.chattxt = orpg.tools.predTextCtrl.predTextCtrl(self, -1, "", | 771 self.chattxt = orpg.tools.predTextCtrl.predTextCtrl(self, -1, "", |
804 style=wx.TE_PROCESS_ENTER |wx.TE_PROCESS_TAB|wx.TE_LINEWRAP, | 772 style=wx.TE_PROCESS_ENTER |wx.TE_PROCESS_TAB|wx.TE_LINEWRAP, |
805 keyHook = self.myKeyHook, validator=None ) | 773 keyHook = self.myKeyHook, validator=None ) |
806 self.build_bar() | 774 self.build_bar() |
807 self.basesizer = wx.BoxSizer(wx.VERTICAL) | 775 self.basesizer = wx.BoxSizer(wx.VERTICAL) |
836 self.Bind(wx.EVT_BUTTON, self.lock_scroll, self.scroll_lock) | 804 self.Bind(wx.EVT_BUTTON, self.lock_scroll, self.scroll_lock) |
837 self.chattxt.Bind(wx.EVT_MOUSEWHEEL, self.chatwnd.mouse_wheel) | 805 self.chattxt.Bind(wx.EVT_MOUSEWHEEL, self.chatwnd.mouse_wheel) |
838 self.chattxt.Bind(wx.EVT_CHAR, self.chattxt.OnChar) | 806 self.chattxt.Bind(wx.EVT_CHAR, self.chattxt.OnChar) |
839 self.chattxt.Bind(wx.EVT_KEY_DOWN, self.on_chat_key_down) | 807 self.chattxt.Bind(wx.EVT_KEY_DOWN, self.on_chat_key_down) |
840 self.chattxt.Bind(wx.EVT_TEXT_COPY, self.chatwnd.OnM_EditCopy) | 808 self.chattxt.Bind(wx.EVT_TEXT_COPY, self.chatwnd.OnM_EditCopy) |
841 # def build_ctrls - end | |
842 | 809 |
843 def build_bar(self): | 810 def build_bar(self): |
844 self.toolbar_sizer = wx.BoxSizer(wx.HORIZONTAL) | 811 self.toolbar_sizer = wx.BoxSizer(wx.HORIZONTAL) |
845 self.scroll_lock = None | 812 self.scroll_lock = None |
846 self.numDieText = None | 813 self.numDieText = None |
853 self.toolbar_sizer.Add(self.textpop_lock, 0, wx.EXPAND) | 820 self.toolbar_sizer.Add(self.textpop_lock, 0, wx.EXPAND) |
854 self.toolbar_sizer.Add(self.scroll_lock, 0, wx.EXPAND) | 821 self.toolbar_sizer.Add(self.scroll_lock, 0, wx.EXPAND) |
855 self.build_formating() | 822 self.build_formating() |
856 self.build_colorbutton() | 823 self.build_colorbutton() |
857 | 824 |
858 | |
859 def build_scroll(self): | 825 def build_scroll(self): |
860 self.scroll_lock = wx.Button( self, wx.ID_ANY, "Scroll ON",size= wx.Size(80,25)) | 826 self.scroll_lock = wx.Button( self, wx.ID_ANY, "Scroll ON",size= wx.Size(80,25)) |
861 | 827 |
862 | |
863 def build_alias(self): | 828 def build_alias(self): |
864 self.aliasSizer = wx.BoxSizer(wx.HORIZONTAL) | 829 self.aliasSizer = wx.BoxSizer(wx.HORIZONTAL) |
865 self.aliasList = wx.Choice(self, wx.ID_ANY, size=(100, 25), choices=[self.defaultAliasName]) | 830 self.aliasList = wx.Choice(self, wx.ID_ANY, size=(100, 25), choices=[self.defaultAliasName]) |
866 self.aliasButton = createMaskedButton( self, dir_struct["icon"] + 'player.gif', | 831 self.aliasButton = createMaskedButton( self, dir_struct["icon"] + 'player.gif', |
867 'Refresh list of aliases from Game Tree', | 832 'Refresh list of aliases from Game Tree', |
947 def toggle_formating(self, act): | 912 def toggle_formating(self, act): |
948 if act == '0': self.toolbar_sizer.Show(self.formatSizer, False) | 913 if act == '0': self.toolbar_sizer.Show(self.formatSizer, False) |
949 else: self.toolbar_sizer.Show(self.formatSizer, True) | 914 else: self.toolbar_sizer.Show(self.formatSizer, True) |
950 self.toolbar_sizer.Layout() | 915 self.toolbar_sizer.Layout() |
951 | 916 |
952 # Heroman - Ideally, we would use static labels... | |
953 | |
954 def build_colorbutton(self): | 917 def build_colorbutton(self): |
955 self.color_button = createMaskedButton(self, dir_struct["icon"]+'textcolor.gif', | 918 self.color_button = createMaskedButton(self, dir_struct["icon"]+'textcolor.gif', |
956 'Text Color', wx.ID_ANY, '#bdbdbd', | 919 'Text Color', wx.ID_ANY, '#bdbdbd', |
957 wx.BITMAP_TYPE_GIF) | 920 wx.BITMAP_TYPE_GIF) |
958 | 921 |
981 self.session.set_status_url(link) | 944 self.session.set_status_url(link) |
982 except: pass | 945 except: pass |
983 else: logger.general("Error, self.chatwnd.GetInternalRepresentation() return None") | 946 else: logger.general("Error, self.chatwnd.GetInternalRepresentation() return None") |
984 evt.Skip() | 947 evt.Skip() |
985 | 948 |
986 # This subroutine is registered with predTextCtrl to be run for every OnChar event | |
987 # It checks if we need to send a typing message | |
988 | |
989 # | |
990 # self: duh | |
991 # event: raw KeyEvent from OnChar() | |
992 | |
993 def myKeyHook(self, event): | 949 def myKeyHook(self, event): |
994 if self.session.get_status() == MPLAY_CONNECTED: # only do if we're connected | 950 if self.session.get_status() == MPLAY_CONNECTED: # only do if we're connected |
995 thisPress = time.time() # thisPress is local temp variable | 951 thisPress = time.time() # thisPress is local temp variable |
996 if (thisPress - self.lastSend) > 4: # Check to see if it's been 5 seconds since our last notice | 952 if (thisPress - self.lastSend) > 4: # Check to see if it's been 5 seconds since our last notice |
997 # If we're not already typing, then self.lastSend will be 0 | 953 # If we're not already typing, then self.lastSend will be 0 |
1003 return 1 | 959 return 1 |
1004 else: | 960 else: |
1005 logger.debug("Exit chat_panel->myKeyHook(self, event) return 0") | 961 logger.debug("Exit chat_panel->myKeyHook(self, event) return 0") |
1006 return 0 | 962 return 0 |
1007 | 963 |
1008 # This subroutine gets called once a second by the typing Timer | |
1009 # It checks if we need to send a not_typing message | |
1010 # | |
1011 # self: duh | |
1012 | |
1013 def typingTimerFunc(self, event): | 964 def typingTimerFunc(self, event): |
1014 #following added by mDuo13 | 965 #following added by mDuo13 |
1015 ##############refresh_counter()############## | 966 ##############refresh_counter()############## |
1016 for plugin_fname in self.activeplugins.keys(): | 967 for plugin_fname in self.activeplugins.keys(): |
1017 plugin = self.activeplugins[plugin_fname] | 968 plugin = self.activeplugins[plugin_fname] |
1025 thisTime = time.time() # thisTime is a local temp variable | 976 thisTime = time.time() # thisTime is a local temp variable |
1026 if (thisTime - self.lastPress) > 4: # Check to see if it's been 5 seconds since our last keystroke | 977 if (thisTime - self.lastPress) > 4: # Check to see if it's been 5 seconds since our last keystroke |
1027 # If we're not already typing, then self.lastSend will be 0 | 978 # If we're not already typing, then self.lastSend will be 0 |
1028 | 979 |
1029 self.sendTyping(0) # send a typing event here (0 for False) | 980 self.sendTyping(0) # send a typing event here (0 for False) |
1030 # This subroutine actually takes care of sending the messages for typing/not_typing events | 981 |
1031 # | |
1032 # self: duh | |
1033 # typing: boolean | |
1034 | |
1035 | |
1036 def sendTyping(self, typing): | 982 def sendTyping(self, typing): |
1037 if typing: | 983 if typing: |
1038 self.lastSend = time.time() # remember our send time for use in myKeyHook() | 984 self.lastSend = time.time() # remember our send time for use in myKeyHook() |
1039 #I think this is cleaner | 985 #I think this is cleaner |
1040 status_text = self.settings.get_setting('TypingStatusAlias') | 986 status_text = self.settings.get_setting('TypingStatusAlias') |
1045 #I think this is cleaner | 991 #I think this is cleaner |
1046 status_text = self.settings.get_setting('IdleStatusAlias') | 992 status_text = self.settings.get_setting('IdleStatusAlias') |
1047 if status_text == "" or status_text == None: status_text = "Idle" | 993 if status_text == "" or status_text == None: status_text = "Idle" |
1048 self.session.set_text_status(status_text) | 994 self.session.set_text_status(status_text) |
1049 | 995 |
1050 # This subroutine sets the colors of the chat based on the settings in the | |
1051 # self instance. | |
1052 # | |
1053 # !self : instance of self | |
1054 | |
1055 def set_colors(self): | 996 def set_colors(self): |
1056 # chat window backround color | 997 # chat window backround color |
1057 self.bgcolor = self.settings.get_setting('bgcolor') | 998 self.bgcolor = self.settings.get_setting('bgcolor') |
1058 # chat window normal text color | 999 # chat window normal text color |
1059 self.textcolor = self.settings.get_setting('textcolor') | 1000 self.textcolor = self.settings.get_setting('textcolor') |
1065 self.infocolor = self.settings.get_setting('infocolor') | 1006 self.infocolor = self.settings.get_setting('infocolor') |
1066 # color of emotes | 1007 # color of emotes |
1067 self.emotecolor = self.settings.get_setting('emotecolor') | 1008 self.emotecolor = self.settings.get_setting('emotecolor') |
1068 # color of whispers | 1009 # color of whispers |
1069 self.whispercolor = self.settings.get_setting('whispercolor') | 1010 self.whispercolor = self.settings.get_setting('whispercolor') |
1070 # def set_colors - end | |
1071 | |
1072 # This subroutine will insert text into the chat window | |
1073 # | |
1074 # !self : instance of self | |
1075 # !txt : text to be inserted into the chat window | |
1076 | 1011 |
1077 def set_chat_text(self, txt): | 1012 def set_chat_text(self, txt): |
1078 self.chattxt.SetValue(txt) | 1013 self.chattxt.SetValue(txt) |
1079 self.chattxt.SetFocus() | 1014 self.chattxt.SetFocus() |
1080 self.chattxt.SetInsertionPointEnd() | 1015 self.chattxt.SetInsertionPointEnd() |
1081 # def set_chat_text - end | |
1082 | 1016 |
1083 | 1017 |
1084 def get_chat_text(self): | 1018 def get_chat_text(self): |
1085 return self.chattxt.GetValue() | 1019 return self.chattxt.GetValue() |
1086 | 1020 |
1087 # This subroutine sets the focus to the chat window | 1021 # This subroutine sets the focus to the chat window |
1088 | 1022 |
1089 def set_chat_text_focus(self, event): | 1023 def set_chat_text_focus(self, event): |
1090 wx.CallAfter(self.chattxt.SetFocus) | 1024 wx.CallAfter(self.chattxt.SetFocus) |
1091 # def set_chat_text_focus - end | |
1092 | |
1093 # This subrtouine grabs the user input and make the special keys and | |
1094 # modifiers work. | |
1095 # | |
1096 # !self : instance of self | |
1097 # !event : | |
1098 # | |
1099 # Note: self.chattxt now handles it's own Key events. It does, however still | |
1100 # call it's parent's (self) OnChar to handle "default" behavior. | |
1101 | 1025 |
1102 def submit_chat_text(self, s): | 1026 def submit_chat_text(self, s): |
1103 self.histidx = -1 | 1027 self.histidx = -1 |
1104 self.temptext = "" | 1028 self.temptext = "" |
1105 self.history = [s] + self.history | 1029 self.history = [s] + self.history |
1106 #if not len(macroText): self.chattxt.SetValue("") | |
1107 | 1030 |
1108 # play sound | 1031 # play sound |
1109 sound_file = self.settings.get_setting("SendSound") | 1032 sound_file = self.settings.get_setting("SendSound") |
1110 if sound_file != '': component.get('sound').play(sound_file) | 1033 if sound_file != '': component.get('sound').play(sound_file) |
1111 if s[0] != "/": ## it's not a slash command | 1034 if s[0] != "/": ## it's not a slash command |
1142 | 1065 |
1143 ## UP KEY | 1066 ## UP KEY |
1144 elif event.GetKeyCode() == wx.WXK_UP: | 1067 elif event.GetKeyCode() == wx.WXK_UP: |
1145 logger.debug("event.GetKeyCode() == wx.WXK_UP") | 1068 logger.debug("event.GetKeyCode() == wx.WXK_UP") |
1146 if self.histidx < len(self.history)-1: | 1069 if self.histidx < len(self.history)-1: |
1147 #text that's not in history but also hasn't been sent to chat gets stored in self.temptext | |
1148 #this way if someone presses the up key, they don't lose their current message permanently | |
1149 #(unless they also press enter at the time) | |
1150 if self.histidx is -1: self.temptext = self.chattxt.GetValue() | 1070 if self.histidx is -1: self.temptext = self.chattxt.GetValue() |
1151 self.histidx += 1 | 1071 self.histidx += 1 |
1152 self.chattxt.SetValue(self.history[self.histidx]) | 1072 self.chattxt.SetValue(self.history[self.histidx]) |
1153 self.chattxt.SetInsertionPointEnd() | 1073 self.chattxt.SetInsertionPointEnd() |
1154 else: | 1074 else: |
1155 self.histidx = len(self.history) -1#in case it got too high somehow, this should fix it | 1075 self.histidx = len(self.history) -1 |
1156 #self.InfoPost("**Going up? I don't think so.**") | |
1157 #print self.histidx, "in",self.history | |
1158 | 1076 |
1159 ## DOWN KEY | 1077 ## DOWN KEY |
1160 elif event.GetKeyCode() == wx.WXK_DOWN: | 1078 elif event.GetKeyCode() == wx.WXK_DOWN: |
1161 logger.debug("event.GetKeyCode() == wx.WXK_DOWN") | 1079 logger.debug("event.GetKeyCode() == wx.WXK_DOWN") |
1162 #histidx of -1 indicates currently viewing text that's not in self.history | 1080 #histidx of -1 indicates currently viewing text that's not in self.history |
1164 self.histidx -= 1 | 1082 self.histidx -= 1 |
1165 if self.histidx is -1: #remember, it just decreased | 1083 if self.histidx is -1: #remember, it just decreased |
1166 self.chattxt.SetValue(self.temptext) | 1084 self.chattxt.SetValue(self.temptext) |
1167 else: self.chattxt.SetValue(self.history[self.histidx]) | 1085 else: self.chattxt.SetValue(self.history[self.histidx]) |
1168 self.chattxt.SetInsertionPointEnd() | 1086 self.chattxt.SetInsertionPointEnd() |
1169 else: self.histidx = -1 #just in case it somehow got below -1, this should fix it | 1087 else: self.histidx = -1 |
1170 #self.InfoPost("**Going down? I don't think so.**") | |
1171 #print self.histidx, "in",self.history | |
1172 | 1088 |
1173 ## TAB KEY | 1089 ## TAB KEY |
1174 elif event.GetKeyCode() == wx.WXK_TAB: | 1090 elif event.GetKeyCode() == wx.WXK_TAB: |
1175 logger.debug("event.GetKeyCode() == wx.WXK_TAB") | 1091 logger.debug("event.GetKeyCode() == wx.WXK_TAB") |
1176 if s !="": | 1092 if s !="": |
1240 return | 1156 return |
1241 | 1157 |
1242 ## NOTHING | 1158 ## NOTHING |
1243 else: event.Skip() | 1159 else: event.Skip() |
1244 logger.debug("Exit chat_panel->OnChar(self, event)") | 1160 logger.debug("Exit chat_panel->OnChar(self, event)") |
1245 # def OnChar - end | |
1246 | |
1247 | 1161 |
1248 def onDieRoll(self, evt): | 1162 def onDieRoll(self, evt): |
1249 """Roll the dice based on the button pressed and the die modifiers entered, if any.""" | 1163 """Roll the dice based on the button pressed and the die modifiers entered, if any.""" |
1250 # Get any die modifiers if they have been entered | 1164 # Get any die modifiers if they have been entered |
1251 numDie = self.numDieText.GetValue() | 1165 numDie = self.numDieText.GetValue() |
1258 dieText += dieMod | 1172 dieText += dieMod |
1259 dieText = "[" + dieText + "]" | 1173 dieText = "[" + dieText + "]" |
1260 self.ParsePost(dieText, 1, 1) | 1174 self.ParsePost(dieText, 1, 1) |
1261 self.chattxt.SetFocus() | 1175 self.chattxt.SetFocus() |
1262 | 1176 |
1263 # This subroutine saves a chat buffer as html to a file chosen via a | |
1264 # FileDialog. | |
1265 # | |
1266 # !self : instance of self | |
1267 # !evt : | |
1268 | |
1269 def on_chat_save(self, evt): | 1177 def on_chat_save(self, evt): |
1270 f = wx.FileDialog(self,"Save Chat Buffer",".","","HTM* (*.htm*)|*.htm*|HTML (*.html)|*.html|HTM (*.htm)|*.htm",wx.SAVE) | 1178 f = wx.FileDialog(self,"Save Chat Buffer",".","","HTM* (*.htm*)|*.htm*|HTML (*.html)|*.html|HTM (*.htm)|*.htm",wx.SAVE) |
1271 if f.ShowModal() == wx.ID_OK: | 1179 if f.ShowModal() == wx.ID_OK: |
1272 file = open(f.GetPath(), "w") | 1180 file = open(f.GetPath(), "w") |
1273 file.write(self.ResetPage() + "</body></html>") | 1181 file.write(self.ResetPage() + "</body></html>") |
1274 file.close() | 1182 file.close() |
1275 f.Destroy() | 1183 f.Destroy() |
1276 os.chdir(dir_struct["home"]) | 1184 os.chdir(dir_struct["home"]) |
1277 # def on_chat_save - end | 1185 |
1278 | |
1279 | |
1280 def ResetPage(self): | 1186 def ResetPage(self): |
1281 self.set_colors() | 1187 self.set_colors() |
1282 buffertext = self.chatwnd.Header() + "\n" | 1188 buffertext = self.chatwnd.Header() + "\n" |
1283 buffertext += chat_util.strip_body_tags(self.chatwnd.StripHeader()).replace("<br>", | 1189 buffertext += chat_util.strip_body_tags(self.chatwnd.StripHeader()).replace("<br>", |
1284 "<br />").replace('</html>', | 1190 "<br />").replace('</html>', |
1285 '').replace("<br />", | 1191 '').replace("<br />", |
1286 "<br />\n").replace("\n\n", '') | 1192 "<br />\n").replace("\n\n", '') |
1287 return buffertext | 1193 return buffertext |
1288 | 1194 |
1289 # This subroutine sets the color of selected text, or base text color if | |
1290 # nothing is selected | |
1291 | |
1292 def on_text_color(self, event): | 1195 def on_text_color(self, event): |
1293 hexcolor = self.r_h.do_hex_color_dlg(self) | 1196 hexcolor = self.r_h.do_hex_color_dlg(self) |
1294 if hexcolor != None: | 1197 if hexcolor != None: |
1295 (beg,end) = self.chattxt.GetSelection() | 1198 (beg,end) = self.chattxt.GetSelection() |
1296 if beg != end: | 1199 if beg != end: |
1303 self.color_button.SetBackgroundColour(hexcolor) | 1206 self.color_button.SetBackgroundColour(hexcolor) |
1304 self.mytextcolor = hexcolor | 1207 self.mytextcolor = hexcolor |
1305 self.settings.set_setting('mytextcolor',hexcolor) | 1208 self.settings.set_setting('mytextcolor',hexcolor) |
1306 self.set_colors() | 1209 self.set_colors() |
1307 self.Post() | 1210 self.Post() |
1308 # def on_text_color - end | 1211 |
1309 | |
1310 # This subroutine take a color and a text string and formats it into html. | |
1311 # | |
1312 # !self : instance of self | |
1313 # !color : color for the text to be set | |
1314 # !text : text string to be included in the html. | |
1315 | |
1316 def colorize(self, color, text): | 1212 def colorize(self, color, text): |
1317 """Puts font tags of 'color' around 'text' value, and returns the string""" | 1213 """Puts font tags of 'color' around 'text' value, and returns the string""" |
1318 return "<font color='" + color + "'>" + text + "</font>" | 1214 return "<font color='" + color + "'>" + text + "</font>" |
1319 # def colorize - end | 1215 |
1320 | |
1321 # This subroutine takes and event and inserts text with the basic format | |
1322 # tags included. | |
1323 # | |
1324 # !self : instance of self | |
1325 # !event : | |
1326 | |
1327 def on_text_format(self, event): | 1216 def on_text_format(self, event): |
1328 id = event.GetId() | 1217 id = event.GetId() |
1329 txt = self.chattxt.GetValue() | 1218 txt = self.chattxt.GetValue() |
1330 (beg,end) = self.chattxt.GetSelection() | 1219 (beg,end) = self.chattxt.GetSelection() |
1331 if beg != end: sel_txt = txt[beg:end] | 1220 if beg != end: sel_txt = txt[beg:end] |
1336 if beg != end: txt = txt[:beg] + sel_txt + txt[end:] | 1225 if beg != end: txt = txt[:beg] + sel_txt + txt[end:] |
1337 else: txt = sel_txt | 1226 else: txt = sel_txt |
1338 self.chattxt.SetValue(txt) | 1227 self.chattxt.SetValue(txt) |
1339 self.chattxt.SetInsertionPointEnd() | 1228 self.chattxt.SetInsertionPointEnd() |
1340 self.chattxt.SetFocus() | 1229 self.chattxt.SetFocus() |
1341 # def on_text_format - end | 1230 |
1342 | |
1343 | |
1344 def lock_scroll(self, event): | 1231 def lock_scroll(self, event): |
1345 if self.lockscroll: | 1232 if self.lockscroll: |
1346 self.lockscroll = False | 1233 self.lockscroll = False |
1347 self.scroll_lock.SetLabel("Scroll ON") | 1234 self.scroll_lock.SetLabel("Scroll ON") |
1348 if len(self.storedata) != 0: | 1235 if len(self.storedata) != 0: |
1351 self.scroll_down() | 1238 self.scroll_down() |
1352 else: | 1239 else: |
1353 self.lockscroll = True | 1240 self.lockscroll = True |
1354 self.scroll_lock.SetLabel("Scroll OFF") | 1241 self.scroll_lock.SetLabel("Scroll OFF") |
1355 | 1242 |
1356 # This subroutine will popup a text window with the chatbuffer contents | |
1357 # | |
1358 # !self : instance of self | |
1359 # !event : | |
1360 | |
1361 def pop_textpop(self, event): | 1243 def pop_textpop(self, event): |
1362 """searchable popup text view of chatbuffer""" | 1244 """searchable popup text view of chatbuffer""" |
1363 h_buffertext = self.ResetPage() | 1245 h_buffertext = self.ResetPage() |
1364 h_dlg = orpgScrolledMessageFrameEditor(self, h_buffertext, "Text View of Chat Window", None, (500,300)) | 1246 h_dlg = orpgScrolledMessageFrameEditor(self, h_buffertext, "Text View of Chat Window", None, (500,300)) |
1365 h_dlg.Show(True) | 1247 h_dlg.Show(True) |
1366 | 1248 |
1367 # This subroutine will change the dimension of the window | |
1368 # | |
1369 # !self : instance of self | |
1370 # !event : | |
1371 | |
1372 def OnSize(self, event=None): | 1249 def OnSize(self, event=None): |
1373 event.Skip() | 1250 event.Skip() |
1374 wx.CallAfter(self.scroll_down) | 1251 wx.CallAfter(self.scroll_down) |
1375 # def OnSize - end | 1252 |
1376 | |
1377 | |
1378 def scroll_down(self): | 1253 def scroll_down(self): |
1379 self.Freeze() | 1254 self.Freeze() |
1380 self.chatwnd.scroll_down() | 1255 self.chatwnd.scroll_down() |
1381 self.Thaw() | 1256 self.Thaw() |
1382 | 1257 |
1384 | 1259 |
1385 def PurgeChat(self): | 1260 def PurgeChat(self): |
1386 self.set_colors() | 1261 self.set_colors() |
1387 self.chatwnd.SetPage(self.chatwnd.Header()) | 1262 self.chatwnd.SetPage(self.chatwnd.Header()) |
1388 | 1263 |
1389 | |
1390 def system_message(self, text): | 1264 def system_message(self, text): |
1391 self.send_chat_message(text,chat_msg.SYSTEM_MESSAGE) | 1265 self.send_chat_message(text,chat_msg.SYSTEM_MESSAGE) |
1392 self.SystemPost(text) | 1266 self.SystemPost(text) |
1393 | 1267 |
1394 | |
1395 def info_message(self, text): | 1268 def info_message(self, text): |
1396 self.send_chat_message(text,chat_msg.INFO_MESSAGE) | 1269 self.send_chat_message(text,chat_msg.INFO_MESSAGE) |
1397 self.InfoPost(text) | 1270 self.InfoPost(text) |
1398 | 1271 |
1399 | |
1400 def get_gms(self): | 1272 def get_gms(self): |
1401 the_gms = [] | 1273 the_gms = [] |
1402 for playerid in self.session.players: | 1274 for playerid in self.session.players: |
1403 if len(self.session.players[playerid])>7: | 1275 if len(self.session.players[playerid])>7: |
1404 if self.session.players[playerid][7]=="GM" and self.session.group_id != '0': the_gms += [playerid] | 1276 if self.session.players[playerid][7]=="GM" and self.session.group_id != '0': the_gms += [playerid] |
1405 return the_gms | 1277 return the_gms |
1406 | 1278 |
1407 | |
1408 def GetName(self): | 1279 def GetName(self): |
1409 self.AliasLib = component.get('alias') | 1280 self.AliasLib = component.get('alias') |
1410 player = self.session.get_my_info() | 1281 player = self.session.get_my_info() |
1411 if self.AliasLib != None: | 1282 if self.AliasLib != None: |
1412 self.AliasLib.alias = self.aliasList.GetStringSelection(); | 1283 self.AliasLib.alias = self.aliasList.GetStringSelection(); |
1413 if self.AliasLib.alias[0] != self.defaultAliasName: | 1284 if self.AliasLib.alias[0] != self.defaultAliasName: |
1414 logger.debug("Exit chat_panel->GetName(self)") | 1285 logger.debug("Exit chat_panel->GetName(self)") |
1415 return [self.chat_display_name([self.AliasLib.alias[0], player[1], player[2]]), self.AliasLib.alias[1]] | 1286 return [self.chat_display_name([self.AliasLib.alias[0], player[1], player[2]]), self.AliasLib.alias[1]] |
1416 return [self.chat_display_name(player), "Default"] | 1287 return [self.chat_display_name(player), "Default"] |
1417 | 1288 |
1418 | |
1419 def GetFilteredText(self, text): | 1289 def GetFilteredText(self, text): |
1420 advregex = re.compile('\"(.*?)\"', re.I) | 1290 advregex = re.compile('\"(.*?)\"', re.I) |
1421 self.AliasLib = component.get('alias') | 1291 self.AliasLib = component.get('alias') |
1422 if self.AliasLib != None: | 1292 if self.AliasLib != None: |
1423 self.AliasLib.filter = self.filterList.GetSelection()-1; | 1293 self.AliasLib.filter = self.filterList.GetSelection()-1; |
1428 match = m.group(0) | 1298 match = m.group(0) |
1429 newmatch = re.sub(rule[0], rule[1], match) | 1299 newmatch = re.sub(rule[0], rule[1], match) |
1430 text = text.replace(match, newmatch) | 1300 text = text.replace(match, newmatch) |
1431 return text | 1301 return text |
1432 | 1302 |
1433 | |
1434 def emote_message(self, text): | 1303 def emote_message(self, text): |
1435 text = self.NormalizeParse(text) | 1304 text = Parse.Normalize(text) |
1436 text = self.colorize(self.emotecolor, text) | 1305 text = self.colorize(self.emotecolor, text) |
1437 | |
1438 if self.type == MAIN_TAB and self.sendtarget == 'all': self.send_chat_message(text,chat_msg.EMOTE_MESSAGE) | 1306 if self.type == MAIN_TAB and self.sendtarget == 'all': self.send_chat_message(text,chat_msg.EMOTE_MESSAGE) |
1439 elif self.type == MAIN_TAB and self.sendtarget == "gm": | 1307 elif self.type == MAIN_TAB and self.sendtarget == "gm": |
1440 msg_type = chat_msg.WHISPER_EMOTE_MESSAGE | 1308 msg_type = chat_msg.WHISPER_EMOTE_MESSAGE |
1441 the_gms = self.get_gms() | 1309 the_gms = self.get_gms() |
1442 for each_gm in the_gms: self.send_chat_message(text,chat_msg.WHISPER_EMOTE_MESSAGE, str(each_gm)) | 1310 for each_gm in the_gms: self.send_chat_message(text,chat_msg.WHISPER_EMOTE_MESSAGE, str(each_gm)) |
1447 elif self.type == NULL_TAB: pass | 1315 elif self.type == NULL_TAB: pass |
1448 name = self.GetName()[0] | 1316 name = self.GetName()[0] |
1449 text = "** " + name + " " + text + " **" | 1317 text = "** " + name + " " + text + " **" |
1450 self.EmotePost(text) | 1318 self.EmotePost(text) |
1451 | 1319 |
1452 | |
1453 def whisper_to_players(self, text, player_ids): | 1320 def whisper_to_players(self, text, player_ids): |
1454 tabbed_whispers_p = self.settings.get_setting("tabbedwhispers") | 1321 tabbed_whispers_p = self.settings.get_setting("tabbedwhispers") |
1455 # Heroman - apply any filtering selected | 1322 text = Parse.Normalize(text) |
1456 text = self.NormalizeParse(text) | |
1457 player_names = "" | 1323 player_names = "" |
1458 # post to our chat before we colorize | |
1459 for m in player_ids: | 1324 for m in player_ids: |
1460 id = m.strip() | 1325 id = m.strip() |
1461 if self.session.is_valid_id(id): | 1326 if self.session.is_valid_id(id): |
1462 returned_name = self.session.get_player_by_player_id(id)[0] | 1327 returned_name = self.session.get_player_by_player_id(id)[0] |
1463 player_names += returned_name | 1328 player_names += returned_name |
1467 player_names += ", " | 1332 player_names += ", " |
1468 comma = "," | 1333 comma = "," |
1469 comma.join(player_ids) | 1334 comma.join(player_ids) |
1470 if (self.sendtarget == "all"): | 1335 if (self.sendtarget == "all"): |
1471 self.InfoPost("<i>whispering to "+ player_names + " " + text + "</i> ") | 1336 self.InfoPost("<i>whispering to "+ player_names + " " + text + "</i> ") |
1472 # colorize and loop, sending whisper messages to all valid clients | |
1473 text = self.colorize(self.mytextcolor, text) | 1337 text = self.colorize(self.mytextcolor, text) |
1474 for id in player_ids: | 1338 for id in player_ids: |
1475 id = id.strip() | 1339 id = id.strip() |
1476 if self.session.is_valid_id(id): self.send_chat_message(text,chat_msg.WHISPER_MESSAGE,id) | 1340 if self.session.is_valid_id(id): self.send_chat_message(text,chat_msg.WHISPER_MESSAGE,id) |
1477 else: self.InfoPost(id + " Unknown!") | 1341 else: self.InfoPost(id + " Unknown!") |
1499 if turnedoff: self.settings.set_setting("ShowIDInChat", "1") | 1363 if turnedoff: self.settings.set_setting("ShowIDInChat", "1") |
1500 msg.set_alias(playername) | 1364 msg.set_alias(playername) |
1501 if send: self.session.send(msg.toxml(),player_id) | 1365 if send: self.session.send(msg.toxml(),player_id) |
1502 del msg | 1366 del msg |
1503 | 1367 |
1504 #### incoming chat message handler ##### | |
1505 | |
1506 def post_incoming_msg(self, msg, player): | 1368 def post_incoming_msg(self, msg, player): |
1507 | |
1508 # pull data | |
1509 type = msg.get_type() | 1369 type = msg.get_type() |
1510 text = msg.get_text() | 1370 text = msg.get_text() |
1511 alias = msg.get_alias() | 1371 alias = msg.get_alias() |
1512 # who sent us the message? | 1372 # who sent us the message? |
1513 if alias: display_name = self.chat_display_name([alias, player[1], player[2]]) | 1373 if alias: display_name = self.chat_display_name([alias, player[1], player[2]]) |
1520 try: text, type, name = plugin.plugin_incoming_msg(text, type, display_name, player) | 1380 try: text, type, name = plugin.plugin_incoming_msg(text, type, display_name, player) |
1521 except Exception, e: | 1381 except Exception, e: |
1522 if str(e) != "'module' object has no attribute 'receive_msg'": | 1382 if str(e) != "'module' object has no attribute 'receive_msg'": |
1523 logger.general(traceback.format_exc()) | 1383 logger.general(traceback.format_exc()) |
1524 logger.general("EXCEPTION: " + str(e)) | 1384 logger.general("EXCEPTION: " + str(e)) |
1525 #end mDuo13 added code | |
1526 #image stripping for players' names | |
1527 strip_img = self.settings.get_setting("Show_Images_In_Chat") | 1385 strip_img = self.settings.get_setting("Show_Images_In_Chat") |
1528 if (strip_img == "0"): display_name = chat_util.strip_img_tags(display_name) | 1386 if (strip_img == "0"): display_name = chat_util.strip_img_tags(display_name) |
1529 #end image stripping. --mDuo13, July 11th, 2005 | |
1530 # default sound | |
1531 recvSound = "RecvSound" | 1387 recvSound = "RecvSound" |
1532 # act on the type of messsage | 1388 # act on the type of messsage |
1533 if (type == chat_msg.CHAT_MESSAGE): | 1389 if (type == chat_msg.CHAT_MESSAGE): |
1534 text = "<b>" + display_name + "</b>: " + text | 1390 text = "<b>" + display_name + "</b>: " + text |
1535 self.Post(text) | 1391 self.Post(text) |
1622 self.parent.newMsg(0) | 1478 self.parent.newMsg(0) |
1623 # playe sound | 1479 # playe sound |
1624 sound_file = self.settings.get_setting(recvSound) | 1480 sound_file = self.settings.get_setting(recvSound) |
1625 if sound_file != '': | 1481 if sound_file != '': |
1626 component.get('sound').play(sound_file) | 1482 component.get('sound').play(sound_file) |
1483 | |
1627 #### Posting helpers ##### | 1484 #### Posting helpers ##### |
1628 | 1485 |
1629 | |
1630 def InfoPost(self, s): | 1486 def InfoPost(self, s): |
1631 self.Post(self.colorize(self.infocolor, s), c='info') | 1487 self.Post(self.colorize(self.infocolor, s), c='info') |
1632 | 1488 |
1633 | |
1634 def SystemPost(self, s): | 1489 def SystemPost(self, s): |
1635 self.Post(self.colorize(self.syscolor, s), c='system') | 1490 self.Post(self.colorize(self.syscolor, s), c='system') |
1636 | 1491 |
1637 | |
1638 def EmotePost(self, s): | 1492 def EmotePost(self, s): |
1639 self.Post(self.colorize(self.emotecolor, s), c='emote') | 1493 self.Post(self.colorize(self.emotecolor, s), c='emote') |
1640 | 1494 |
1641 #### Standard Post method ##### | 1495 #### Standard Post method ##### |
1642 | 1496 |
1673 s = self.colorize(self.mytextcolor, s) | 1527 s = self.colorize(self.mytextcolor, s) |
1674 else: name = "" | 1528 else: name = "" |
1675 if aliasInfo[1] != 'Default': | 1529 if aliasInfo[1] != 'Default': |
1676 self.settings.set_setting("mytextcolor", defaultcolor) | 1530 self.settings.set_setting("mytextcolor", defaultcolor) |
1677 self.set_colors() | 1531 self.set_colors() |
1678 #following line based on sourceforge patch #880403 from mDuo | |
1679 # EDIT: Had to rework blank line check to handle malformed HTML throwing error. | |
1680 # this limits the effectiveness of this check -SD | |
1681 lineHasText = 1 | 1532 lineHasText = 1 |
1682 try: lineHasText = strip_html(s).replace(" ","").replace(" ","").strip()!="" | 1533 try: lineHasText = strip_html(s).replace(" ","").replace(" ","").strip()!="" |
1683 except: | 1534 except: |
1684 # HTML parser has errored out (most likely). Being as all we are doing is | |
1685 # scanning for empty/blank lines anyway there is no harm in letting a | |
1686 # troublesome message though. Worst case is a blank line to chat. | |
1687 lineHasText = 1 | 1535 lineHasText = 1 |
1688 if lineHasText: | 1536 if lineHasText: |
1689 #following added by mDuo13 | 1537 #following added by mDuo13 |
1690 if myself: | 1538 if myself: |
1691 s2 = s | 1539 s2 = s |
1729 elif self.type == WHISPER_TAB: self.whisper_to_players(s, [self.sendtarget]) | 1577 elif self.type == WHISPER_TAB: self.whisper_to_players(s, [self.sendtarget]) |
1730 elif self.type == NULL_TAB: pass | 1578 elif self.type == NULL_TAB: pass |
1731 else: self.InfoPost("Failed to send message, unknown send type for this tab") | 1579 else: self.InfoPost("Failed to send message, unknown send type for this tab") |
1732 self.parsed=0 | 1580 self.parsed=0 |
1733 | 1581 |
1734 # | |
1735 # TimeIndexString() | |
1736 # | |
1737 # time indexing for chat display only (don't log time indexing) | |
1738 # added by Snowdog 4/04 | |
1739 | |
1740 def TimeIndexString(self): | 1582 def TimeIndexString(self): |
1741 try: | 1583 try: |
1742 mtime = "" | 1584 mtime = "" |
1743 if self.settings.get_setting('Chat_Time_Indexing') == "0": pass | 1585 if self.settings.get_setting('Chat_Time_Indexing') == "0": pass |
1744 elif self.settings.get_setting('Chat_Time_Indexing') == "1": | 1586 elif self.settings.get_setting('Chat_Time_Indexing') == "1": |
1747 except Exception, e: | 1589 except Exception, e: |
1748 logger.general(traceback.format_exc()) | 1590 logger.general(traceback.format_exc()) |
1749 logger.general("EXCEPTION: " + str(e)) | 1591 logger.general("EXCEPTION: " + str(e)) |
1750 return "[ERROR]" | 1592 return "[ERROR]" |
1751 | 1593 |
1752 #### Post with parsing dice #### | |
1753 | |
1754 def ParsePost(self, s, send=False, myself=False): | 1594 def ParsePost(self, s, send=False, myself=False): |
1755 s = self.NormalizeParse(s) | 1595 s = Parse.Normalize(s) |
1756 self.set_colors() | 1596 self.set_colors() |
1757 self.Post(s,send,myself) | 1597 self.Post(s,send,myself) |
1758 | |
1759 def NormalizeParse(self, s): | |
1760 for plugin_fname in self.activeplugins.keys(): | |
1761 plugin = self.activeplugins[plugin_fname] | |
1762 try: s = plugin.pre_parse(s) | |
1763 except Exception, e: | |
1764 if str(e) != "'module' object has no attribute 'post_msg'": | |
1765 logger.general(traceback.format_exc()) | |
1766 logger.general("EXCEPTION: " + str(e)) | |
1767 if self.parsed == 0: | |
1768 s = self.ParseNode(s) | |
1769 s = self.ParseDice(s) | |
1770 s = self.ParseFilter(s) | |
1771 self.parsed = 1 | |
1772 return s | |
1773 | |
1774 def ParseFilter(self, s): | |
1775 s = self.GetFilteredText(s) | |
1776 return s | |
1777 | |
1778 def ParseNode(self, s): | |
1779 """Parses player input for embedded nodes rolls""" | |
1780 cur_loc = 0 | |
1781 #[a-zA-Z0-9 _\-\.] | |
1782 reg = re.compile("(!@(.*?)@!)") | |
1783 matches = reg.findall(s) | |
1784 for i in xrange(0,len(matches)): | |
1785 newstr = self.ParseNode(self.resolve_nodes(matches[i][1])) | |
1786 s = s.replace(matches[i][0], newstr, 1) | |
1787 return s | |
1788 | |
1789 def ParseDice(self, s): | |
1790 """Parses player input for embedded dice rolls""" | |
1791 reg = re.compile("\[([^]]*?)\]") | |
1792 matches = reg.findall(s) | |
1793 for i in xrange(0,len(matches)): | |
1794 newstr = self.PraseUnknowns(matches[i]) | |
1795 qmode = 0 | |
1796 newstr1 = newstr | |
1797 if newstr[0].lower() == 'q': | |
1798 newstr = newstr[1:] | |
1799 qmode = 1 | |
1800 if newstr[0].lower() == '#': | |
1801 newstr = newstr[1:] | |
1802 qmode = 2 | |
1803 try: newstr = component.get('DiceManager').proccessRoll(newstr) | |
1804 except: pass | |
1805 if qmode == 1: | |
1806 s = s.replace("[" + matches[i] + "]", | |
1807 "<!-- Official Roll [" + newstr1 + "] => " + newstr + "-->" + newstr, 1) | |
1808 elif qmode == 2: | |
1809 s = s.replace("[" + matches[i] + "]", newstr[len(newstr)-2:-1], 1) | |
1810 else: s = s.replace("[" + matches[i] + "]", | |
1811 "[" + newstr1 + "<!-- Official Roll -->] => " + newstr, 1) | |
1812 return s | |
1813 | |
1814 def PraseUnknowns(self, s): | |
1815 # Uses a tuple. Usage: ?Label}dY. If no Label is assigned then use ?}DY | |
1816 newstr = "0" | |
1817 reg = re.compile("(\?\{*)([a-zA-Z ]*)(\}*)") | |
1818 matches = reg.findall(s) | |
1819 for i in xrange(0,len(matches)): | |
1820 lb = "Replace '?' with: " | |
1821 if len(matches[i][0]): | |
1822 lb = matches[i][1] + "?: " | |
1823 dlg = wx.TextEntryDialog(self, lb, "Missing Value?") | |
1824 dlg.SetValue('') | |
1825 if matches[i][0] != '': | |
1826 dlg.SetTitle("Enter Value for " + matches[i][1]) | |
1827 if dlg.ShowModal() == wx.ID_OK: newstr = dlg.GetValue() | |
1828 if newstr == '': newstr = '0' | |
1829 s = s.replace(matches[i][0], newstr, 1).replace(matches[i][1], '', 1).replace(matches[i][2], '', 1) | |
1830 dlg.Destroy() | |
1831 return s | |
1832 | 1598 |
1833 # This subroutine builds a chat display name. | 1599 # This subroutine builds a chat display name. |
1834 # | 1600 # |
1835 def chat_display_name(self, player): | 1601 def chat_display_name(self, player): |
1836 if self.settings.get_setting("ShowIDInChat") == "0": | 1602 if self.settings.get_setting("ShowIDInChat") == "0": |
1852 dlg.Destroy() | 1618 dlg.Destroy() |
1853 return hexcolor | 1619 return hexcolor |
1854 else: | 1620 else: |
1855 dlg.Destroy() | 1621 dlg.Destroy() |
1856 return None | 1622 return None |
1623 | |
1857 # def get_color - end | 1624 # def get_color - end |
1858 | |
1859 def replace_quotes(self, s): | 1625 def replace_quotes(self, s): |
1860 in_tag = 0 | 1626 in_tag = 0 |
1861 i = 0 | 1627 i = 0 |
1862 rs = s[:] | 1628 rs = s[:] |
1863 for c in s: | 1629 for c in s: |
1867 elif c == '"': | 1633 elif c == '"': |
1868 if in_tag: rs = rs[:i] + "'" + rs[i+1:] | 1634 if in_tag: rs = rs[:i] + "'" + rs[i+1:] |
1869 i += 1 | 1635 i += 1 |
1870 return rs | 1636 return rs |
1871 | 1637 |
1872 def resolve_loop(self, node, path, step, depth): | |
1873 if step == depth: | |
1874 return self.resolution(node) | |
1875 else: | |
1876 child_list = node.findall('nodehandler') | |
1877 for child in child_list: | |
1878 if step == depth: break | |
1879 if child.get('name') == path[step]: | |
1880 node = child | |
1881 step += 1 | |
1882 if node.get('class') in ('dnd35char_handler', | |
1883 "SWd20char_handler", | |
1884 "d20char_handler", | |
1885 "dnd3echar_handler"): self.resolve_cust_loop(node, path, step, depth) | |
1886 elif node.get('class') == 'rpg_grid_handler': self.resolve_grid(node, path, step, depth) | |
1887 else: self.resolve_loop(node, path, step, depth) | |
1888 | |
1889 def resolve_grid(self, node, path, step, depth): | |
1890 if step == depth: | |
1891 self.data = 'Invalid Grid Reference!' | |
1892 return | |
1893 cell = tuple(path[step].strip('(').strip(')').split(',')) | |
1894 grid = node.find('grid') | |
1895 rows = grid.findall('row') | |
1896 col = rows[int(self.ParseDice(cell[0]))-1].findall('cell') | |
1897 try: self.data = self.ParseMap(col[int(self.ParseDice(cell[1]))-1].text, node) or 'No Cell Data' | |
1898 except: self.data = 'Invalid Grid Reference!' | |
1899 return | |
1900 | |
1901 def resolution(self, node): | |
1902 if self.passed == False: | |
1903 self.passed = True | |
1904 if node.get('class') == 'textctrl_handler': | |
1905 s = str(node.find('text').text) | |
1906 else: s = 'Nodehandler for '+ node.get('class') + ' not done!' or 'Invalid Reference!' | |
1907 else: | |
1908 s = '' | |
1909 s = self.ParseMap(s, node) | |
1910 s = self.ParseParent(s, node.get('map')) | |
1911 self.data = s | |
1912 | |
1913 def ParseMap(self, s, node): | |
1914 """Parses player input for embedded nodes rolls""" | |
1915 cur_loc = 0 | |
1916 reg = re.compile("(!!(.*?)!!)") | |
1917 matches = reg.findall(s) | |
1918 for i in xrange(0,len(matches)): | |
1919 tree_map = node.get('map') | |
1920 tree_map = tree_map + '::' + matches[i][1] | |
1921 newstr = '!@'+ tree_map +'@!' | |
1922 s = s.replace(matches[i][0], newstr, 1) | |
1923 s = self.ParseNode(s) | |
1924 s = self.ParseParent(s, tree_map) | |
1925 return s | |
1926 | |
1927 def ParseParent(self, s, tree_map): | |
1928 """Parses player input for embedded nodes rolls""" | |
1929 cur_loc = 0 | |
1930 reg = re.compile("(!#(.*?)#!)") | |
1931 matches = reg.findall(s) | |
1932 for i in xrange(0,len(matches)): | |
1933 ## Build the new tree_map | |
1934 new_map = tree_map.split('::') | |
1935 del new_map[len(new_map)-1] | |
1936 parent_map = matches[i][1].split('::') | |
1937 ## Find an index or use 1 for ease of use. | |
1938 try: index = new_map.index(parent_map[0]) | |
1939 except: index = 1 | |
1940 ## Just replace the old tree_map from the index. | |
1941 new_map[index:len(new_map)] = parent_map | |
1942 newstr = '::'.join(new_map) | |
1943 newstr = '!@'+ newstr +'@!' | |
1944 s = s.replace(matches[i][0], newstr, 1) | |
1945 #s = self.ParseMap(s, node) ## Needs to be added | |
1946 s = self.ParseNode(s) | |
1947 return s | |
1948 | |
1949 def resolve_nodes(self, s): | |
1950 self.passed = False | |
1951 self.data = 'Invalid Reference!' | |
1952 value = "" | |
1953 path = s.split('::') | |
1954 depth = len(path) | |
1955 self.gametree = component.get('tree') | |
1956 try: node = self.gametree.tree_map[path[0]]['node'] | |
1957 except Exception, e: return self.data | |
1958 if node.get('class') in ('dnd35char_handler', | |
1959 "SWd20char_handler", | |
1960 "d20char_handler", | |
1961 "dnd3echar_handler"): self.resolve_cust_loop(node, path, 1, depth) | |
1962 elif node.get('class') == 'rpg_grid_handler': self.resolve_grid(node, path, 1, depth) | |
1963 else: self.resolve_loop(node, path, 1, depth) | |
1964 return self.data | |
1965 | |
1966 def resolve_cust_loop(self, node, path, step, depth): | |
1967 node_class = node.get('class') | |
1968 ## Code needs clean up. Either choose .lower() or .title(), then reset the path list's content ## | |
1969 if step == depth: self.resolution(node) | |
1970 ##Build Abilities dictionary## | |
1971 if node_class not in ('d20char_handler', "SWd20char_handler"): ab = node.find('character').find('abilities') | |
1972 else: ab = node.find('abilities') | |
1973 ab_list = ab.findall('stat'); pc_stats = {} | |
1974 | |
1975 for ability in ab_list: | |
1976 pc_stats[ability.get('name')] = ( | |
1977 str(ability.get('base')), | |
1978 str((int(ability.get('base'))-10)/2) ) | |
1979 pc_stats[ability.get('abbr')] = ( | |
1980 str(ability.get('base')), | |
1981 str((int(ability.get('base'))-10)/2) ) | |
1982 | |
1983 if node_class not in ('d20char_handler', "SWd20char_handler"): ab = node.find('character').find('saves') | |
1984 else: ab = node.find('saves') | |
1985 ab_list = ab.findall('save') | |
1986 for save in ab_list: | |
1987 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]) ) ) | |
1988 if save.get('name') == 'Fortitude': abbr = 'Fort' | |
1989 if save.get('name') == 'Reflex': abbr = 'Ref' | |
1990 if save.get('name') == 'Will': abbr = 'Will' | |
1991 pc_stats[abbr] = ( str(save.get('base')), str(int(save.get('magmod')) + int(save.get('miscmod')) + int(pc_stats[save.get('stat')][1]) ) ) | |
1992 | |
1993 if path[step].lower() == 'skill': | |
1994 if node_class not in ('d20char_handler', "SWd20char_handler"): node = node.find('snf') | |
1995 node = node.find('skills') | |
1996 child_list = node.findall('skill') | |
1997 for child in child_list: | |
1998 if path[step+1].lower() == child.get('name').lower(): | |
1999 if step+2 == depth: self.data = child.get('rank') | |
2000 elif path[step+2].lower() == 'check': | |
2001 self.data = '<b>Skill Check:</b> ' + child.get('name') + ' [1d20+'+str( int(child.get('rank')) + int(pc_stats[child.get('stat')][1]) )+']' | |
2002 return | |
2003 | |
2004 if path[step].lower() == 'feat': | |
2005 if node_class not in ('d20char_handler', "SWd20char_handler"): node = node.find('snf') | |
2006 node = node.find('feats') | |
2007 child_list = node.findall('feat') | |
2008 for child in child_list: | |
2009 if path[step+1].lower() == child.get('name').lower(): | |
2010 if step+2 == depth: self.data = '<b>'+child.get('name')+'</b>'+': '+child.get('desc') | |
2011 return | |
2012 if path[step].lower() == 'cast': | |
2013 if node_class not in ('d20char_handler', "SWd20char_handler"): node = node.find('snp') | |
2014 node = node.find('spells') | |
2015 child_list = node.findall('spell') | |
2016 for child in child_list: | |
2017 if path[step+1].lower() == child.get('name').lower(): | |
2018 if step+2 == depth: self.data = '<b>'+child.get('name')+'</b>'+': '+child.get('desc') | |
2019 return | |
2020 if path[step].lower() == 'attack': | |
2021 if node_class not in ('d20char_handler', "SWd20char_handler"): node = node.find('combat') | |
2022 if path[step+1].lower() == 'melee' or path[step+1].lower() == 'm': | |
2023 bonus_text = '(Melee)' | |
2024 bonus = node.find('attacks') | |
2025 bonus = bonus.find('melee') | |
2026 bonus = bonus.attrib; d = int(pc_stats['Str'][1]) | |
2027 elif path[step+1].lower() == 'ranged' or path[step+1].lower() == 'r': | |
2028 bonus_text = '(Ranged)' | |
2029 bonus = node.find('attacks') | |
2030 bonus = bonus.find('ranged') | |
2031 bonus = bonus.attrib; d = int(pc_stats['Dex'][1]) | |
2032 for b in bonus: | |
2033 d += int(bonus[b]) | |
2034 bonus = str(d) | |
2035 if path[step+2] == None: self.data = bonus | |
2036 else: | |
2037 weapons = node.find('attacks') | |
2038 weapons = weapons.findall('weapon') | |
2039 for child in weapons: | |
2040 if path[step+2].lower() == child.get('name').lower(): | |
2041 self.data = '<b>Attack: '+bonus_text+'</b> '+child.get('name')+' [1d20+'+bonus+'] ' + 'Damage: ['+child.get('damage')+']' | |
2042 return | |
2043 elif pc_stats.has_key(path[step].title()): | |
2044 if step+1 == depth: self.data = pc_stats[path[step].title()][0] + ' +('+pc_stats[path[step].title()][1]+')' | |
2045 elif path[step+1].title() == 'Mod': self.data = pc_stats[path[step].title()][1] | |
2046 elif path[step+1].title() == 'Check': self.data = '<b>'+path[step].title()+' Check:</b> [1d20+'+str(pc_stats[path[step].title()][1])+']' | |
2047 return |