comparison orpg/gametree/nodehandlers/dnd3e.py @ 152:6081bdc2b8d5 beta

Traipse Beta 'OpenRPG' {091125-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 (Beta) Added Bookmarks Fix to Remote Admin Commands Minor fix to text based Server Fix to Pretty Print, from Core Fix to Splitter Nodes not being created Fix to massive amounts of images loading, from Core Added 'boot' command to remote admin Added confirmation window for sent nodes Minor changes to allow for portability to an OpenSUSE linux OS Miniatures Layer pop up box allows users to turn off Mini labels, from FlexiRPG Zoom Mouse plugin added Images added to Plugin UI Switching to Element Tree Map efficiency, from FlexiRPG Added Status Bar to Update Manager default_manifest.xml renamed to default_upmana.xml Cleaner clode for saved repositories New TrueDebug Class in orpg_log (See documentation for usage) Mercurial's hgweb folder is ported to upmana Pretty important update that can help remove thousands of dead children from your gametree. Children, <forms />, <group_atts />, <horizontal />, <cols />, <rows />, <height />, etc... are all tags now. Check your gametree and look for dead children!! New Gametree Recursion method, mapping, and context sensitivity. !Infinite Loops return error instead of freezing the software! New Syntax added for custom PC sheets Tip of the Day added, from Core and community Fixed Whiteboard ID to prevent random line or text deleting. Modified ID's to prevent non updated clients from ruining the fix.
author sirebral
date Wed, 25 Nov 2009 06:16:35 -0600
parents dcf4fbe09b70
children bf799efe7a8a
comparison
equal deleted inserted replaced
150:6c5f46a5924b 152:6081bdc2b8d5
23 # Version: 23 # Version:
24 # $Id: dnd3e.py,v 1.33 2006/11/04 21:24:21 digitalxero Exp $ 24 # $Id: dnd3e.py,v 1.33 2006/11/04 21:24:21 digitalxero Exp $
25 # 25 #
26 # Description: The file contains code for the dnd3e nodehanlers 26 # Description: The file contains code for the dnd3e nodehanlers
27 # 27 #
28 # qpatch by lead.b. All modified lines denoted by # 1.500x[or] as below 28
29 # 1.5001r fix for unable to update misc modifier for saves
30 # 1.5002r fix for dnd_globals not scoping 1 character's data from another -or
31 # causing abends or other problems due to lack of intialization from
32 # char abilities. getCharacterProp function added.
33 # This includes fix for "total on saves", making "rclick" on skill
34 # work to send roll to window,"total on skill rolls",
35 # 1.5004r getting ac mod for
36 # those skill which have armour class adjustments was broken.
37 # 1.5005r perhaps no lines marked. Under dnd3eattacks, the misc. value for
38 # both Melee and Ranged do not get re-displayed if the panel is closed
39 # and re-opened, tho the adjustment still seems to be in total... perhap
40 # total just isn't getting recalculated?
41 # 1.5006r on rclick on a weapon, on first attack roll is generated, additional
42 # crash,terminating the sequence.
43 # 1.5008r extended bonuses for "extra" attacks don't include all items.
44 # 1.5009r while 1.5008 is "resolved", not sure it is correct for special monk
45 # attacks. I'm pretty sure I fixed this.
46 # 1.5014r powerpoints are broken.
47 # 1.5017r if you bring up the entire character in edit mode (dlclick on
48 # top node of character), and click
49 # "Money and Inventory" tab, then change the amount of "plat" a
50 # character has, the name on the tree will be updated to match
51 # the "plat" entry.
52 # 1.5019r if str bonus was 0, forgot + for aStrengthMod.
53 # ---v 1.6 cut. above corrected by 1.6.
54 # -- items marked 1.5xxx were found prior 1.6 but not added (enhancements)
55 # or corrected (bugs, default if not stated) at that cut point
56 # 1.5003r this is currently just a "this is busted" flag, this is an rclick on
57 # on the saves node (above the fort/wil/ref saves) itself. It throws an
58 # error message into the python window, then nothing... Not even sure what
59 # it is -supposed- to do. set to do nothing, which I think is fine.
60 # 1.5011r enhancement. Damage for thrown weapon should get str adder.
61 # Don't think this is accounted for. Remember, JUST damage, not to-hit.
62 # included into 1.6002, marking resolved to simplify list.
63 # 1.5012r enhancement. str penalty to dam for bow/slings should be applied.
64 # but it's not. Remember, this is just for damage, not to-hit.
65 # 1.5015r if you bring up the entire character in edit mode (dlclick on
66 # top node of character), and click
67 # "Spells and Powers" tab, then "Psionic Powers", push the "Refresh
68 # Powers" button, the powers are refreshed but if you select the
69 # "PowerPoints" tab, the update is not reflected there. Must close
70 # and reopen edit session for refresh. (Already corrected misspelling of
71 # "Pionic" -> "Psionic")
72 # 1.6000r eliminate misc debug items, include things like getCharacterProp which
73 # never got used. Documenting for completeness. Minor changes for clarity
74 # 1.6001r bug, melee weapons, such as dagger, which have a range are currently
75 # being treated simply as ranged weapons... this mean dex bonuses
76 # are being applied for to-hit Vs strength. Melee thrown are treated
77 # different than ranged.
78 # 1.6003r bug, if double weapon handle damage specified as 1d8/1d6 as 1d8
79 # for single weapon usage. The correct usage for double weapon will
80 # for short term at least remove requirement to have to update
81 # memorized list. - med priority
82 # 1.6008r C:\Program Files\openrpg1\orpg\templates\nodes\dnd3e.xml minor
83 # typos corrected, added comment on psionics. Remember to replace!
84 # 1.6009r tohtml fails, thus send to chat fails and pretty print fails.
85 # 1.6010r tohtml for power points needs some clean up.
86 # 1.6011r if multiple weapons are chosen for deletion from character inventory,
87 # at least one wrong weapons will be deleted.
88 # 1.6012r flurry attack negative only applied to med monk, applies to all.
89 # 1.6013r penalties on stats on tohtml showed +-3, instead of just -3.
90 # 1.6014r rclick on "Skills" node above actual skills throws an error msg to
91 # python window.
92 # 1.6015r rclick on "Attacks" or "Abilities Score" node throws an error msg to
93 # python window.
94 # 1.6016r enhancement add comment to rclick footnotes to get footnote details.
95 # 1.6018r resolve saves not updating on panel if open when ability scores change
96 # change
97 # 1.6021r didn't roll extra monk attacks if base to it bonus was 0.
98 # 1.6022r monks always got d20 damage, reversed order of checks to fix.
99 # v1.8 cut.
100 # -- items marked 1.6xxx were found prior 1.8 but not added (enhancements)
101 # or corrected (bugs, default if not stated) at that cut point
102 # 1.5007o enhancement. str bows not accounted for correctly.
103 # thoughts: use new element tag to indicate strBow(3).
104 # 1.5010r proposed enhancement. Adding character name to frames around stuff.
105 # - marking resolved... determined to not do.
106 # 1.5013o enhancement. this is for all "off-hand" attacks stuff. Eg: str bonus
107 # only 1/2 for "off-hand" for both to-hit and damage (unless penalty! ;-)
108 # Probably other things, as I see nothing in here to account for them.
109 # 1.5016o enhancement. swim check does not reflect weight check.
110 # 1.5018o enhancement. actual psionic abilities list.
111 # 1.6002o enhancement. modify code to take advanage of new footnote field for
112 # indicating which weapons are Thrown, as opposed to improvised thrown
113 # weapons; which are treated differently. Allow for throwing of melee
114 # weapons (with 1.6001 all melee are unthrowable) recast of 1.5011,
115 # which I'm marking resolved.
116 # 1.6004o feature request from 541659 Ability to remove skills, at least those
117 # that can't be used untrained. This would also require ability to re-add
118 # skills later. Short term solution may be to ability to clearly mark
119 # skill which can't be used yet. - low priority.
120 # 1.6005o feature request from 541659 Custom feats, without the need to edit
121 # data/dnd3e/dnd3efeats.xml Note, while standard feats may be affecting
122 # how tool will generate rolls, etc; it is unlikely that custom feats will
123 # will be able to do this; but should be able to be include from a
124 # complete "character sheet" perspective. - low priority (since
125 # dnd3efeats can be edited to add feats)
126 # 1.6006o feature request from 541659 Do sorcerer and bard spells right;
127 # for short term at least remove requirement to have to update
128 # memorized list. - med priority
129 # 1.6007o feature request from 541659 Make tabs optional to be able to remove
130 # tabs which are unused by a particular character. Would need ability
131 # to add them back in, since character might later add a class which
132 # would need them. - very low priority
133 # 1.6017o enhancement when editing footnotes for weapons,
134 # provide full table of footnotes in companion window to help.
135 # 1.6019o enhancement Forum request to add "flatfooted" to ac matrix
136 # 1.6020o enh add column to skills to allow tracking of skill points allocated.
137 # 1.9000r clean up of excess comments from 1.6 and earlier.
138 # 1.9001r if str or dex changes, Melee/Ranged combat ability does not update
139 # until refreshed by a change.
140 # 1.9002r depending on what subwindows were open, changing stat scores could
141 # crash out entire orpg environment.
142 #
143 # r- resolved
144 # o- open
145 #
146
147 #import orpg.tools.orpg_settings #Not used??
148 #import orpg.minidom
149 from core import * 29 from core import *
150 from containers import * 30 from containers import *
151 from string import * #a 1.6003 31 from string import * #a 1.6003
152 from inspect import * #a 1.9001 32 from inspect import * #a 1.9001
153 from orpg.dirpath import dir_struct 33 from orpg.dirpath import dir_struct
170 target = node 50 target = node
171 while target != None: 51 while target != None:
172 root = target 52 root = target
173 target = target.hparent 53 target = target.hparent
174 return root 54 return root
175 #o 1.5002 (this whole comment block) 55
176 # if a method runs getRoot for its instance and assigns the 56 # if a method runs getRoot for its instance and assigns the
177 # value returned to self.root, you can get to instances X via Y 57 # value returned to self.root, you can get to instances X via Y
178 # instance handle via invocation 58 # instance handle via invocation
179 # --------------- --- ----------- 59 # --------------- --- -----------
180 # classes via self.root.classes 60 # classes via self.root.classes
204 # then to refer to the instance where you need it: 84 # then to refer to the instance where you need it:
205 # self.root.{instance handle}.{whatever you need} 85 # self.root.{instance handle}.{whatever you need}
206 # # replace {instance handle} with your designation 86 # # replace {instance handle} with your designation
207 # # replace {whatever you need} with the attribute/method u want. 87 # # replace {whatever you need} with the attribute/method u want.
208 88
209 #d 1.6000 not used.
210 #def getCharacterProp(forgetIt):
211 # return None
212
213 #a 1.6 convinience function added safeGetAttr
214 def safeGetAttr(node, label, defRetV=None): 89 def safeGetAttr(node, label, defRetV=None):
215 cna=node.attrib 90 cna=node.attrib
216 for key in cna: 91 for key in cna:
217 if key == label: 92 if key == label: return cna[key]
218 return cna[key]
219 #retV=node.get(lable) # get does not distingish between
220 # the attribute not being present vs it having a value of ""
221 # This is bad for this routine, thus not used.
222 return defRetV 93 return defRetV
223 #a 1.6... safeGetAttr end. 94
224 95
225 ########End of My global Stuff######## 96 ########End of My global Stuff########
226 ########Start of Main Node Handlers####### 97 ########Start of Main Node Handlers#######
227 class dnd3echar_handler(container_handler): 98 class dnd3echar_handler(container_handler):
228 """ Node handler for a dnd3e charactor 99 """ Node handler for a dnd3e charactor
232 node_handler.__init__(self,xml_dom,tree_node) 103 node_handler.__init__(self,xml_dom,tree_node)
233 self.Version = "v1.901" #a 1.6000 general documentation, usage. 104 self.Version = "v1.901" #a 1.6000 general documentation, usage.
234 105
235 print "dnd3echar_handler - version:", self.Version #m 1.6000 106 print "dnd3echar_handler - version:", self.Version #m 1.6000
236 107
237 self.hparent = None #a 1.5002 allow ability to run up tree, this is the 108 self.hparent = None
238 #a 1.5002 top of the handler tree, this is used to flag where to stop
239 #a 1.5002 on the way up. Changing this will break getRoot(self)
240
241 self.frame = component.get('frame') 109 self.frame = component.get('frame')
242 self.child_handlers = {} 110 self.child_handlers = {}
243 self.new_child_handler('howtouse','HowTo use this tool',dnd3ehowto,'note') 111 self.new_child_handler('howtouse','HowTo use this tool',dnd3ehowto,'note')
244 self.new_child_handler('general','GeneralInformation',dnd3egeneral,'gear') 112 self.new_child_handler('general','GeneralInformation',dnd3egeneral,'gear')
245 self.new_child_handler('inventory','MoneyAndInventory',dnd3einventory,'money') 113 self.new_child_handler('inventory','MoneyAndInventory',dnd3einventory,'money')
246 self.new_child_handler('character','ClassesAndStats',dnd3eclassnstats,'knight') 114 self.new_child_handler('character','ClassesAndStats',dnd3eclassnstats,'knight')
247 self.new_child_handler('snf','SkillsAndFeats',dnd3eskillsnfeats,'book') 115 self.new_child_handler('snf','SkillsAndFeats',dnd3eskillsnfeats,'book')
248 self.new_child_handler('combat','Combat',dnd3ecombat,'spears') 116 self.new_child_handler('combat','Combat',dnd3ecombat,'spears')
249 self.new_child_handler('snp','SpellsAndPowers',dnd3esnp,'flask') 117 self.new_child_handler('snp','SpellsAndPowers',dnd3esnp,'flask')
250 #wxMenuItem(self.tree.std_menu, dnd3e_EXPORT, "Export...", "Export")
251 #print "dnd3echar_handler init - "+\
252 # "self.child_handlers:",self.child_handlers # a (debug) 1.5002
253 self.myeditor = None 118 self.myeditor = None
254
255 119
256 def new_child_handler(self,tag,text,handler_class,icon='gear'): 120 def new_child_handler(self,tag,text,handler_class,icon='gear'):
257 node_list = self.xml.findall(tag) 121 node_list = self.xml.findall(tag)
258 tree = self.tree 122 tree = self.tree
259 i = self.tree.icons[icon] 123 i = self.tree.icons[icon]
263 self.child_handlers[tag] = handler 127 self.child_handlers[tag] = handler
264 128
265 def get_design_panel(self,parent): 129 def get_design_panel(self,parent):
266 return tabbed_panel(parent,self,1) 130 return tabbed_panel(parent,self,1)
267 131
268
269 def get_use_panel(self,parent): 132 def get_use_panel(self,parent):
270 return tabbed_panel(parent,self,2) 133 return tabbed_panel(parent,self,2)
271 134
272 def tohtml(self): 135 def tohtml(self):
273 html_str = "<table><tr><td colspan=2 >" 136 html_str = "<table><tr><td colspan=2 >"
274 #d block for 1.6009 start
275 #html_str += self.child_handlers['general'].tohtml()+"</td></tr>"
276 #html_str += "<tr><td width='50%' valign=top >
277 # "+self.child_handlers['abilities'].tohtml()
278 #html_str += "<P>" + self.child_handlers['saves'].tohtml()
279 #html_str += "<P>" + self.child_handlers['attacks'].tohtml()
280 #html_str += "<P>" + self.child_handlers['ac'].tohtml()
281 #html_str += "<P>" + self.child_handlers['feats'].tohtml()
282 #html_str += "<P>" + self.child_handlers['spells'].tohtml()
283 #html_str += "<P>" + self.child_handlers['divine'].tohtml()
284 #html_str += "<P>" + self.child_handlers['powers'].tohtml()
285 #html_str += "<P>" + self.child_handlers['inventory'].tohtml() +"</td>"
286 #html_str += "<td width='50%' valign=top >
287 # "+self.child_handlers['classes'].tohtml()
288 #html_str += "<P>" + self.child_handlers['hp'].tohtml()
289 #html_str += "<P>" + self.child_handlers['pp'].tohtml()
290 #html_str += "<P>" + self.child_handlers['skills'].tohtml() +"</td>"
291 #d block for 1.6009 end
292 #a block for 1.6009 start
293 html_str += self.general.tohtml()+"</td></tr>" 137 html_str += self.general.tohtml()+"</td></tr>"
294 html_str += "<tr><td width='50%' valign=top >"+self.abilities.tohtml() 138 html_str += "<tr><td width='50%' valign=top >"+self.abilities.tohtml()
295 html_str += "<P>" + self.saves.tohtml() 139 html_str += "<P>" + self.saves.tohtml()
296 html_str += "<P>" + self.attacks.tohtml() 140 html_str += "<P>" + self.attacks.tohtml()
297 html_str += "<P>" + self.ac.tohtml() 141 html_str += "<P>" + self.ac.tohtml()
302 html_str += "<P>" + self.inventory.tohtml() +"</td>" 146 html_str += "<P>" + self.inventory.tohtml() +"</td>"
303 html_str += "<td width='50%' valign=top >"+self.classes.tohtml() 147 html_str += "<td width='50%' valign=top >"+self.classes.tohtml()
304 html_str += "<P>" + self.hp.tohtml() 148 html_str += "<P>" + self.hp.tohtml()
305 html_str += "<P>" + self.pp.tohtml() 149 html_str += "<P>" + self.pp.tohtml()
306 html_str += "<P>" + self.skills.tohtml() +"</td>" 150 html_str += "<P>" + self.skills.tohtml() +"</td>"
307 #a block for 1.6009 end
308 html_str += "</tr></table>" 151 html_str += "</tr></table>"
309 return html_str 152 return html_str
310 153
311 def about(self): 154 def about(self):
312 html_str = "<img src='" + dir_struct["icon"] 155 """html_str = "<img src='" + dir_struct["icon"]
313 html_str += "dnd3e_logo.gif' ><br><b>dnd3e Character Tool " 156 html_str += "dnd3e_logo.gif' ><br><b>dnd3e Character Tool "
314 html_str += self.Version+"</b>" #m 1.6000 was hard coded. 157 html_str += self.Version+"</b>"
315 html_str += "<br>by Dj Gilcrease<br>digitalxero@gmail.com" 158 html_str += "<br>by Dj Gilcrease<br>digitalxero@gmail.com"
316 return html_str 159 return html_str"""
160 text = 'dnd3e Character Tool' + self.Version +'\n'
161 text += 'by Dj Gilcrease digitalxero@gmail.com'
162 return text
317 163
318 ########Core Handlers are done now############ 164 ########Core Handlers are done now############
319 ########Onto the Sub Nodes######## 165 ########Onto the Sub Nodes########
320 ##Primary Sub Node## 166 ##Primary Sub Node##
321 167
340 self.char_hander = parent 186 self.char_hander = parent
341 self.drag = False 187 self.drag = False
342 self.frame = component.get('frame') 188 self.frame = component.get('frame')
343 self.myeditor = None 189 self.myeditor = None
344 190
345
346 def on_drop(self,evt): 191 def on_drop(self,evt):
347 pass 192 pass
348 193
349 def on_rclick(self,evt): 194 def on_rclick(self,evt):
350 pass 195 pass
373 """ Node Handler for how to instructions. This handler will be 218 """ Node Handler for how to instructions. This handler will be
374 created by dnd3echar_handler. 219 created by dnd3echar_handler.
375 """ 220 """
376 def __init__(self,xml_dom,tree_node,parent): 221 def __init__(self,xml_dom,tree_node,parent):
377 dnd3e_char_child.__init__(self,xml_dom,tree_node,parent) 222 dnd3e_char_child.__init__(self,xml_dom,tree_node,parent)
378 self.hparent = parent #a 1.5002 allow ability to run up tree. 223 self.hparent = parent
379 224
380 def get_design_panel(self,parent): 225 def get_design_panel(self,parent):
381 wnd = howto_panel(parent, self) 226 wnd = howto_panel(parent, self)
382 wnd.title = "How To" 227 wnd.title = "How To"
383 return wnd 228 return wnd
400 """ Node Handler for general information. This handler will be 245 """ Node Handler for general information. This handler will be
401 created by dnd3echar_handler. 246 created by dnd3echar_handler.
402 """ 247 """
403 def __init__(self,xml_dom,tree_node,parent): 248 def __init__(self,xml_dom,tree_node,parent):
404 dnd3e_char_child.__init__(self,xml_dom,tree_node,parent) 249 dnd3e_char_child.__init__(self,xml_dom,tree_node,parent)
405 self.hparent = parent #a 1.5002 allow ability to run up tree. 250 self.hparent = parent
406 self.root = getRoot(self) #a 1.5002 251 self.root = getRoot(self)
407 self.root.general = self #a 1.5002 252 self.root.general = self
408 self.charName = self.get_char_name() # a 1.5002 make getting name easier. 253 self.charName = self.get_char_name()
409 254
410 def get_design_panel(self,parent): 255 def get_design_panel(self,parent):
411 wnd = outline_panel(parent,self,gen_grid,"General Information") 256 wnd = outline_panel(parent,self,gen_grid,"General Information")
412 wnd.title = "General Info" 257 wnd.title = "General Info"
413 return wnd 258 return wnd
422 html_str = html_str[:len(html_str)-2] + "</td></tr></table>" 267 html_str = html_str[:len(html_str)-2] + "</td></tr></table>"
423 return html_str 268 return html_str
424 269
425 def on_name_change(self,name): 270 def on_name_change(self,name):
426 self.char_hander.rename(name) 271 self.char_hander.rename(name)
427 #o 1.5002 self.char_hander = parent in this case. 272 self.charName = name
428 self.charName = name #a 1.5002 make getting name easier.
429
430 273
431 def get_char_name( self ): 274 def get_char_name( self ):
432 node = self.xml.findall( 'name' )[0] 275 node = self.xml.findall( 'name' )[0]
433 return node.text 276 return node.text
434 277
435 class gen_grid(wx.grid.Grid): 278 class gen_grid(wx.grid.Grid):
436 """grid for gen info""" 279 """grid for gen info"""
437 def __init__(self, parent, handler): 280 def __init__(self, parent, handler):
438 pname = handler.xml.set("name", 'General') 281 pname = handler.xml.set("name", 'General')
439 self.hparent = handler #a 1.5002 allow ability to run up tree, needed 282 self.hparent = handler
440 # a 1.5002 parent is functional parent, not invoking parent.
441
442 283
443 wx.grid.Grid.__init__(self, parent, -1, style=wx.SUNKEN_BORDER | wx.WANTS_CHARS) 284 wx.grid.Grid.__init__(self, parent, -1, style=wx.SUNKEN_BORDER | wx.WANTS_CHARS)
444 #self.Bind(wx.EVT_SIZE, self.on_size)
445 self.Bind(wx.grid.EVT_GRID_CELL_CHANGE, self.on_cell_change) 285 self.Bind(wx.grid.EVT_GRID_CELL_CHANGE, self.on_cell_change)
446 self.handler = handler 286 self.handler = handler
447 n_list = handler.xml.getchildren() 287 n_list = handler.xml.getchildren()
448 self.CreateGrid(len(n_list),2) 288 self.CreateGrid(len(n_list),2)
449 self.SetRowLabelSize(0) 289 self.SetRowLabelSize(0)
450 self.SetColLabelSize(0) 290 self.SetColLabelSize(0)
451 self.n_list = n_list 291 self.n_list = n_list
452 i = 0 292 i = 0
453 for i in range(len(n_list)): 293 for i in range(len(n_list)): self.refresh_row(i)
454 self.refresh_row(i)
455 294
456 def on_cell_change(self,evt): 295 def on_cell_change(self,evt):
457 row = evt.GetRow() 296 row = evt.GetRow()
458 col = evt.GetCol() 297 col = evt.GetCol()
459 value = self.GetCellValue(row,col) 298 value = self.GetCellValue(row,col)
460 self.n_list[row].text = value 299 self.n_list[row].text = value
461 if row==0: 300 if row==0: self.handler.on_name_change(value)
462 self.handler.on_name_change(value)
463 #self.AutoSizeColumn(1)
464 301
465 def refresh_row(self,rowi): 302 def refresh_row(self,rowi):
466 self.SetCellValue(rowi,0,self.n_list[rowi].tag) 303 self.SetCellValue(rowi,0,self.n_list[rowi].tag)
467 self.SetReadOnly(rowi,0) 304 self.SetReadOnly(rowi,0)
468 self.SetCellValue(rowi,1,self.n_list[rowi].text) 305 self.SetCellValue(rowi,1,self.n_list[rowi].text)
472 """ Node Handler for general information. This handler will be 309 """ Node Handler for general information. This handler will be
473 created by dnd3echar_handler. 310 created by dnd3echar_handler.
474 """ 311 """
475 def __init__(self,xml_dom,tree_node,parent): 312 def __init__(self,xml_dom,tree_node,parent):
476 dnd3e_char_child.__init__(self,xml_dom,tree_node,parent) 313 dnd3e_char_child.__init__(self,xml_dom,tree_node,parent)
477 self.hparent = parent #a 1.5002 allow ability to run up tree. 314 self.hparent = parent
478 self.root = getRoot(self) #a 1.6009 315 self.root = getRoot(self)
479 self.root.inventory = self #a 1.6009 316 self.root.inventory = self
480 317
481 def get_design_panel(self,parent): 318 def get_design_panel(self,parent):
482 wnd = inventory_pane(parent, self) #outline_panel(parent,self,inventory_grid,"Inventory") 319 wnd = inventory_pane(parent, self) #outline_panel(parent,self,inventory_grid,"Inventory")
483 wnd.title = "General Info" 320 wnd.title = "Inventory"
484 return wnd 321 return wnd
485 322
486 def tohtml(self): 323 def tohtml(self):
487 n_list = self.xml.getchildren() 324 n_list = self.xml.getchildren()
488 html_str = "<table width=100% border=1 ><tr BGCOLOR=#E9E9E9 ><th>General Information</th></tr><tr><td>" 325 html_str = "<table width=100% border=1 ><tr BGCOLOR=#E9E9E9 ><th>General Information</th></tr><tr><td>"
489 for n in n_list: 326 for n in n_list:
490 debug((n)) 327 html_str += "<B>"+n.tag.capitalize()+":</B> "
491 html_str += "<B>"+n.tag.capitalize() +":</B> "
492 html_str += n.text + "<br>" 328 html_str += n.text + "<br>"
493 html_str = html_str[:len(html_str)-2] + "</td></tr></table>" 329 html_str = html_str[:len(html_str)-2] + "</td></tr></table>"
494 return html_str 330 return html_str
495 331
496 class inventory_pane(wx.Panel): 332 class inventory_pane(wx.Panel):
497 def __init__(self, parent, handler): 333 def __init__(self, parent, handler):
498 wx.Panel.__init__(self, parent, wx.ID_ANY) 334 wx.Panel.__init__(self, parent, wx.ID_ANY)
499 self.n_list = handler.xml.getchildren() 335 self.n_list = handler.xml.getchildren()
500 self.autosize = False 336 self.autosize = False
501 self.sizer = wx.StaticBoxSizer(wx.StaticBox(self, wx.ID_ANY, "Inventroy"), wx.VERTICAL) 337 self.sizer = wx.StaticBoxSizer(wx.StaticBox(self, wx.ID_ANY, "Inventory"), wx.VERTICAL)
502 self.lang = wx.TextCtrl(self, wx.ID_ANY, "", style=wx.TE_MULTILINE | wx.TE_BESTWRAP, name="Languages") 338 self.lang = wx.TextCtrl(self, wx.ID_ANY, "", style=wx.TE_MULTILINE | wx.TE_BESTWRAP, name="Languages")
503 self.gear = wx.TextCtrl(self, wx.ID_ANY, "", style=wx.TE_MULTILINE | wx.TE_BESTWRAP, name="Gear") 339 self.gear = wx.TextCtrl(self, wx.ID_ANY, "", style=wx.TE_MULTILINE | wx.TE_BESTWRAP, name="Gear")
504 self.magic = wx.TextCtrl(self, wx.ID_ANY, "", style=wx.TE_MULTILINE | wx.TE_BESTWRAP, name="Magic") 340 self.magic = wx.TextCtrl(self, wx.ID_ANY, "", style=wx.TE_MULTILINE | wx.TE_BESTWRAP, name="Magic")
505 self.grid = wx.grid.Grid(self, wx.ID_ANY, style=wx.SUNKEN_BORDER | wx.WANTS_CHARS) 341 self.grid = wx.grid.Grid(self, wx.ID_ANY, style=wx.SUNKEN_BORDER | wx.WANTS_CHARS)
506 self.grid.CreateGrid(len(self.n_list)-3,2) 342 self.grid.CreateGrid(len(self.n_list)-3,2)
507 self.grid.SetRowLabelSize(0) 343 self.grid.SetRowLabelSize(0)
508 self.grid.SetColLabelSize(0) 344 self.grid.SetColLabelSize(0)
509 for i in xrange(len(self.n_list)): 345 for i in xrange(len(self.n_list)): self.refresh_row(i)
510 self.refresh_row(i)
511 sizer1 = wx.BoxSizer(wx.HORIZONTAL) 346 sizer1 = wx.BoxSizer(wx.HORIZONTAL)
512 sizer1.Add(self.grid, 1, wx.EXPAND) 347 sizer1.Add(self.grid, 1, wx.EXPAND)
513 sizer1.Add(self.lang, 1, wx.EXPAND) 348 sizer1.Add(self.lang, 1, wx.EXPAND)
514 self.sizer.Add(sizer1, 0, wx.EXPAND) 349 self.sizer.Add(sizer1, 0, wx.EXPAND)
515 sizer2 = wx.BoxSizer(wx.HORIZONTAL) 350 sizer2 = wx.BoxSizer(wx.HORIZONTAL)
573 """ Node handler for a dnd3e charactor 408 """ Node handler for a dnd3e charactor
574 <nodehandler name='?' module='dnd3e' class='dnd3echar_handler2' /> 409 <nodehandler name='?' module='dnd3e' class='dnd3echar_handler2' />
575 """ 410 """
576 def __init__(self,xml_dom,tree_node,parent): 411 def __init__(self,xml_dom,tree_node,parent):
577 node_handler.__init__(self,xml_dom,tree_node) 412 node_handler.__init__(self,xml_dom,tree_node)
578 self.hparent = parent #a 1.5002 allow ability to run up tree. 413 self.hparent = parent
579 dnd3e_char_child.__init__(self,xml_dom,tree_node,parent) 414 dnd3e_char_child.__init__(self,xml_dom,tree_node,parent)
580 self.frame = component.get('frame') 415 self.frame = component.get('frame')
581 self.child_handlers = {} 416 self.child_handlers = {}
582 self.new_child_handler('abilities','Abilities Scores',dnd3eability,'gear') 417 self.new_child_handler('abilities','Abilities Scores',dnd3eability,'gear')
583 self.new_child_handler('classes','Classes',dnd3eclasses,'knight') 418 self.new_child_handler('classes','Classes',dnd3eclasses,'knight')
584 self.new_child_handler('saves','Saves',dnd3esaves,'skull') 419 self.new_child_handler('saves','Saves',dnd3esaves,'skull')
585 self.myeditor = None 420 self.myeditor = None
586
587 421
588 def new_child_handler(self,tag,text,handler_class,icon='gear'): 422 def new_child_handler(self,tag,text,handler_class,icon='gear'):
589 node_list = self.xml.findall(tag) 423 node_list = self.xml.findall(tag)
590 tree = self.tree 424 tree = self.tree
591 i = self.tree.icons[icon] 425 i = self.tree.icons[icon]
595 self.child_handlers[tag] = handler 429 self.child_handlers[tag] = handler
596 430
597 def get_design_panel(self,parent): 431 def get_design_panel(self,parent):
598 return tabbed_panel(parent,self,1) 432 return tabbed_panel(parent,self,1)
599 433
600
601 def get_use_panel(self,parent): 434 def get_use_panel(self,parent):
435 print 'here'
602 return tabbed_panel(parent,self,2) 436 return tabbed_panel(parent,self,2)
603 437
604 class class_char_child(node_handler): 438 class class_char_child(node_handler):
605 """ Node Handler for skill. This handler will be 439 """ Node Handler for skill. This handler will be
606 created by dnd3echar_handler. 440 created by dnd3echar_handler.
641 """ Node Handler for ability. This handler will be 475 """ Node Handler for ability. This handler will be
642 created by dnd3echar_handler. 476 created by dnd3echar_handler.
643 """ 477 """
644 def __init__(self,xml_dom,tree_node,parent): 478 def __init__(self,xml_dom,tree_node,parent):
645 class_char_child.__init__(self,xml_dom,tree_node,parent) 479 class_char_child.__init__(self,xml_dom,tree_node,parent)
646 self.hparent = parent #a 1.5002 allow ability to run up tree. 480 self.hparent = parent
647 self.root = getRoot(self) #a 1.5002 get top of our local function tree. 481 self.root = getRoot(self)
648 self.root.abilities = self #a 1.5002 let other classes find me. 482 self.root.abilities = self
649 self.abilities = {} 483 self.abilities = {}
650 node_list = self.xml.findall('stat') 484 node_list = self.xml.findall('stat')
651 tree = self.tree 485 tree = self.tree
652 icons = tree.icons 486 icons = tree.icons
653 for n in node_list: 487 for n in node_list:
654 name = n.get('abbr') 488 name = n.get('abbr')
655 self.abilities[name] = n 489 self.abilities[name] = n
656 new_tree_node = tree.AppendItem( self.mytree_node, name, icons['gear'], icons['gear'] ) 490 new_tree_node = tree.AppendItem( self.mytree_node, name, icons['gear'], icons['gear'] )
657 tree.SetPyData( new_tree_node, self ) 491 tree.SetPyData( new_tree_node, self )
658 #print "dnd3eability - init self.abilities",self.abilities #a (debug) 1.5002
659 492
660 def on_rclick( self, evt ): 493 def on_rclick( self, evt ):
661 item = self.tree.GetSelection() 494 item = self.tree.GetSelection()
662 name = self.tree.GetItemText( item ) 495 name = self.tree.GetItemText( item )
663 #if item == self.mytree_node: #d 1.6016 496 if not item == self.mytree_node:
664 # dnd3e_char_child.on_ldclick( self, evt ) #d 1.6016
665 if not item == self.mytree_node: #a 1.6016
666 #else: #d 1.6016
667 mod = self.get_mod( name ) 497 mod = self.get_mod( name )
668 if mod >= 0: 498 if mod >= 0: mod1 = "+"
669 mod1 = "+" 499 else: mod1 = ""
670 else:
671 mod1 = ""
672 chat = self.chat 500 chat = self.chat
673 txt = '%s check: [1d20%s%s]' % ( name, mod1, mod ) 501 txt = '%s check: [1d20%s%s]' % ( name, mod1, mod )
674 chat.ParsePost( txt, True, True ) 502 chat.ParsePost( txt, True, True )
675 503
676 def get_mod(self,abbr): 504 def get_mod(self,abbr):
695 for n in node_list: 523 for n in node_list:
696 name = n.get('name') 524 name = n.get('name')
697 abbr = n.get('abbr') 525 abbr = n.get('abbr')
698 base = n.get('base') 526 base = n.get('base')
699 mod = str(self.get_mod(abbr)) 527 mod = str(self.get_mod(abbr))
700 if int(mod) >= 0: #m 1.6013 added "int(" and ")" 528 if int(mod) >= 0: mod1 = "+"
701 mod1 = "+" 529 else: mod1 = ""
702 else:
703 mod1 = ""
704 html_str = (html_str + "<tr ALIGN='center'><td>"+ 530 html_str = (html_str + "<tr ALIGN='center'><td>"+
705 name+"</td><td>"+base+'</td><td>%s%s</td></tr>' % (mod1, mod)) 531 name+"</td><td>"+base+'</td><td>%s%s</td></tr>' % (mod1, mod))
706 html_str = html_str + "</table>" 532 html_str = html_str + "</table>"
707 return html_str 533 return html_str
708 534
709 class abil_grid(wx.grid.Grid): 535 class abil_grid(wx.grid.Grid):
710 """grid for abilities""" 536 """grid for abilities"""
711 def __init__(self, parent, handler): 537 def __init__(self, parent, handler):
712 pname = handler.xml.set("name", 'Stats') 538 pname = handler.xml.set("name", 'Stats')
713 self.hparent = handler #a 1.5002 allow ability to run up tree. 539 self.hparent = handler
714 self.root = getRoot(self) 540 self.root = getRoot(self)
715 #a 1.5002 in this case, we need the functional parent, not the invoking parent.
716 541
717 wx.grid.Grid.__init__(self, parent, -1, style=wx.SUNKEN_BORDER | wx.WANTS_CHARS) 542 wx.grid.Grid.__init__(self, parent, -1, style=wx.SUNKEN_BORDER | wx.WANTS_CHARS)
718 self.Bind(wx.EVT_SIZE, self.on_size) 543 self.Bind(wx.EVT_SIZE, self.on_size)
719 self.Bind(wx.grid.EVT_GRID_CELL_CHANGE, self.on_cell_change) 544 self.Bind(wx.grid.EVT_GRID_CELL_CHANGE, self.on_cell_change)
720 self.handler = handler 545 self.handler = handler
721 stats = handler.xml.findall('stat') 546 stats = handler.xml.findall('stat')
722 self.CreateGrid(len(stats),3) 547 self.CreateGrid(len(stats),3)
723 self.SetRowLabelSize(0) 548 self.SetRowLabelSize(0)
724 col_names = ['Ability','Score','Modifier'] 549 col_names = ['Ability','Score','Modifier']
725 for i in range(len(col_names)): 550 for i in range(len(col_names)): self.SetColLabelValue(i,col_names[i])
726 self.SetColLabelValue(i,col_names[i])
727 self.stats = stats 551 self.stats = stats
728 i = 0 552 i = 0
729 for i in range(len(stats)): 553 for i in range(len(stats)): self.refresh_row(i)
730 self.refresh_row(i)
731 self.char_wnd = None 554 self.char_wnd = None
732 555
733 def on_cell_change(self,evt): 556 def on_cell_change(self,evt):
734 row = evt.GetRow() 557 row = evt.GetRow()
735 col = evt.GetCol() 558 col = evt.GetCol()
736 value = self.GetCellValue(row,col) 559 value = self.GetCellValue(row,col)
737 #print value
738 try: 560 try:
739 int(value) 561 int(value)
740 self.stats[row].set('base',value) 562 self.stats[row].set('base',value)
741 self.refresh_row(row) 563 self.refresh_row(row)
742 except: 564 except:
743 self.SetCellValue(row,col,"0") 565 self.SetCellValue(row,col,"0")
744 if self.char_wnd: 566 if self.char_wnd: self.char_wnd.refresh_data()
745 self.char_wnd.refresh_data()
746 567
747 def refresh_row(self,rowi): 568 def refresh_row(self,rowi):
748 s = self.stats[rowi] 569 s = self.stats[rowi]
749
750 name = s.get('name') 570 name = s.get('name')
751 abbr = s.get('abbr') 571 abbr = s.get('abbr')
752 self.SetCellValue(rowi,0,name) 572 self.SetCellValue(rowi,0,name)
753 self.SetReadOnly(rowi,0) 573 self.SetReadOnly(rowi,0)
754 self.SetCellValue(rowi,1,s.get('base')) 574 self.SetCellValue(rowi,1,s.get('base'))
755 self.SetCellValue(rowi,2,str(self.handler.get_mod(abbr))) 575 self.SetCellValue(rowi,2,str(self.handler.get_mod(abbr)))
756 self.SetReadOnly(rowi,2) 576 self.SetReadOnly(rowi,2)
757 #if self.root.saves.saveGrid: #a 1.6018 d 1.9002 whole if clause 577 self.root.saves.refresh_data()
758 #print getmembers(self.root.saves.saveGrid) 578 self.root.attacks.refreshMRdata()
759 #self.root.saves.saveGrid.refresh_data() #a 1.6018
760 #print "skipping saving throw update, put back in later"
761 self.root.saves.refresh_data() #a 1.9002
762 self.root.attacks.refreshMRdata() #a 1.9001 `
763 579
764 def on_size(self,evt): 580 def on_size(self,evt):
765 (w,h) = self.GetClientSizeTuple() 581 (w,h) = self.GetClientSizeTuple()
766 cols = self.GetNumberCols() 582 cols = self.GetNumberCols()
767 col_w = w/(cols+2) 583 col_w = w/(cols+2)
768 self.SetColSize(0,col_w*3) 584 self.SetColSize(0,col_w*3)
769 for i in range(1,cols): 585 for i in range(1,cols): self.SetColSize(i,col_w)
770 self.SetColSize(i,col_w)
771 evt.Skip() 586 evt.Skip()
772 self.Refresh() 587 self.Refresh()
773 588
774 def refresh_data(self): 589 def refresh_data(self):
775 for r in range(self.GetNumberRows()-1): 590 for r in range(self.GetNumberRows()-1): self.refresh_row(r)
776 self.refresh_row(r)
777 591
778 class dnd3eclasses(class_char_child): 592 class dnd3eclasses(class_char_child):
779 """ Node Handler for classes. This handler will be 593 """ Node Handler for classes. This handler will be
780 created by dnd3echar_handler. 594 created by dnd3echar_handler.
781 """ 595 """
782 def __init__(self,xml_dom,tree_node,parent): 596 def __init__(self,xml_dom,tree_node,parent):
783 class_char_child.__init__(self,xml_dom,tree_node,parent) 597 class_char_child.__init__(self,xml_dom,tree_node,parent)
784 self.hparent = parent #a 1.5002 allow ability to run up tree. 598 self.hparent = parent
785 self.root = getRoot(self) 599 self.root = getRoot(self)
786 self.root.classes = self 600 self.root.classes = self
787 #a 1.5002 in this case, we need the functional parent, not the invoking parent.
788 601
789 def get_design_panel(self,parent): 602 def get_design_panel(self,parent):
790 wnd = outline_panel(parent,self,class_panel,"Classes") 603 wnd = outline_panel(parent,self,class_panel,"Classes")
791 wnd.title = "Classes" 604 wnd.title = "Classes"
792 return wnd 605 return wnd
793 606
794 def tohtml(self): 607 def tohtml(self):
795 html_str = "<table width=100% border=1 ><tr BGCOLOR=#E9E9E9 ><th>Classes</th></tr><tr><td>" 608 html_str = "<table width=100% border=1 ><tr BGCOLOR=#E9E9E9 ><th>Classes</th></tr><tr><td>"
796 n_list = self.xml.getchildren() 609 n_list = self.xml.getchildren()
797 for n in n_list: 610 for n in n_list: html_str += n.get('name') + " ("+n.get('level')+"), "
798 html_str += n.get('name') + " ("+n.get('level')+"), "
799 html_str = html_str[:len(html_str)-2] + "</td></tr></table>" 611 html_str = html_str[:len(html_str)-2] + "</td></tr></table>"
800 return html_str 612 return html_str
801 613
802 def get_char_lvl( self, attr ): 614 def get_char_lvl( self, attr ):
803 node_list = self.xml.findall('class') 615 node_list = self.xml.findall('class')
804 # print "eclasses - get_char_lvl node_list",node_list 616 tot = 0
805 tot = 0 #a 1.5009 actually, slipping in a quick enhancement ;-)
806 for n in node_list: 617 for n in node_list:
807 lvl = n.get('level') #o 1.5009 not sure of the value of this 618 lvl = n.get('level')
808 tot += int(lvl) #a 1.5009 619 tot += int(lvl)
809 type = n.get('name') #o 1.5009 not sure of the value of this 620 type = n.get('name')
810 #print type,lvl #a (debug) 1.5009 621 if attr == "level": return lvl
811 if attr == "level": 622 elif attr == "class": return type
812 return lvl #o 1.5009 this returns the level of someone's first class. ??? 623 if attr == "lvl": return tot
813 elif attr == "class": 624
814 return type #o 1.5009 this returns one of the char's classes. ??? 625 def get_class_lvl( self, classN ):
815 if attr == "lvl": #a 1.5009 this has value, adding this.
816 return tot #a 1.5009 return character's "overall" level.
817
818 def get_class_lvl( self, classN ): #a 1.5009 need to be able to get monk lvl
819 #a 1.5009 this function is new.
820 node_list = self.xml.findall('class') 626 node_list = self.xml.findall('class')
821 #print "eclasses - get_class_lvl node_list",node_list
822 for n in node_list: 627 for n in node_list:
823 lvl = n.get('level') 628 lvl = n.get('level')
824 type = n.get('name') 629 type = n.get('name')
825 if classN == type: 630 if classN == type: return lvl
826 return lvl
827 631
828 class class_panel(wx.Panel): 632 class class_panel(wx.Panel):
829 def __init__(self, parent, handler): 633 def __init__(self, parent, handler):
830 pname = handler.xml.set("name", 'Class') 634 pname = handler.xml.set("name", 'Class')
831 635
843 self.sizer = sizer 647 self.sizer = sizer
844 self.SetSizer(self.sizer) 648 self.SetSizer(self.sizer)
845 self.SetAutoLayout(True) 649 self.SetAutoLayout(True)
846 self.Fit() 650 self.Fit()
847 651
848 #self.Bind(wx.EVT_SIZE, self.on_size)
849 self.Bind(wx.EVT_BUTTON, self.on_remove, id=10) 652 self.Bind(wx.EVT_BUTTON, self.on_remove, id=10)
850 self.Bind(wx.EVT_BUTTON, self.on_add, id=20) 653 self.Bind(wx.EVT_BUTTON, self.on_add, id=20)
851 self.grid.Bind(wx.grid.EVT_GRID_CELL_CHANGE, self.on_cell_change) 654 self.grid.Bind(wx.grid.EVT_GRID_CELL_CHANGE, self.on_cell_change)
852 655
853 n_list = handler.xml.getchildren() 656 n_list = handler.xml.getchildren()
855 self.xml = handler.xml 658 self.xml = handler.xml
856 self.grid.CreateGrid(len(n_list),2,1) 659 self.grid.CreateGrid(len(n_list),2,1)
857 self.grid.SetRowLabelSize(0) 660 self.grid.SetRowLabelSize(0)
858 self.grid.SetColLabelValue(0,"Class") 661 self.grid.SetColLabelValue(0,"Class")
859 self.grid.SetColLabelValue(1,"Level") 662 self.grid.SetColLabelValue(1,"Level")
860 for i in range(len(n_list)): 663 for i in range(len(n_list)): self.refresh_row(i)
861 self.refresh_row(i)
862 self.temp_dom = None 664 self.temp_dom = None
863 665
864 def on_cell_change(self,evt): 666 def on_cell_change(self,evt):
865 row = evt.GetRow() 667 row = evt.GetRow()
866 col = evt.GetCol() 668 col = evt.GetCol()
875 name = n.get('name') 677 name = n.get('name')
876 level = n.get('level') 678 level = n.get('level')
877 self.grid.SetCellValue(i,0,name) 679 self.grid.SetCellValue(i,0,name)
878 self.grid.SetReadOnly(i,0) 680 self.grid.SetReadOnly(i,0)
879 self.grid.SetCellValue(i,1,level) 681 self.grid.SetCellValue(i,1,level)
880 #self.grid.SetReadOnly(i,1)
881 682
882 def on_remove(self,evt): 683 def on_remove(self,evt):
883 rows = self.grid.GetNumberRows() 684 rows = self.grid.GetNumberRows()
884 for i in range(rows): 685 for i in range(rows):
885 if self.grid.IsInSelection(i,0): 686 if self.grid.IsInSelection(i,0):
891 tree = parse(dir_struct["dnd3e"]+"dnd3eclasses.xml") 692 tree = parse(dir_struct["dnd3e"]+"dnd3eclasses.xml")
892 xml_dom = tree.getroot() 693 xml_dom = tree.getroot()
893 self.temp_dom = xml_dom 694 self.temp_dom = xml_dom
894 f_list = self.temp_dom.findall('class') 695 f_list = self.temp_dom.findall('class')
895 opts = [] 696 opts = []
896 for f in f_list: 697 for f in f_list: opts.append(f.get('name'))
897 opts.append(f.get('name'))
898 dlg = wx.SingleChoiceDialog(self,'Choose Class','Classes',opts) 698 dlg = wx.SingleChoiceDialog(self,'Choose Class','Classes',opts)
899 if dlg.ShowModal() == wx.ID_OK: 699 if dlg.ShowModal() == wx.ID_OK:
900 i = dlg.GetSelection() 700 i = dlg.GetSelection()
901 new_node = self.xml.append(f_list[i]) 701 new_node = self.xml.append(f_list[i])
902 self.grid.AppendRows(1) 702 self.grid.AppendRows(1)
908 self.grid.SetDimensions(0,0,s[0],s[1]-25) 708 self.grid.SetDimensions(0,0,s[0],s[1]-25)
909 self.sizer.SetDimension(0,s[1]-25,s[0],25) 709 self.sizer.SetDimension(0,s[1]-25,s[0],25)
910 (w,h) = self.grid.GetClientSizeTuple() 710 (w,h) = self.grid.GetClientSizeTuple()
911 cols = self.grid.GetNumberCols() 711 cols = self.grid.GetNumberCols()
912 col_w = w/(cols) 712 col_w = w/(cols)
913 for i in range(0,cols): 713 for i in range(0,cols): self.grid.SetColSize(i,col_w)
914 self.grid.SetColSize(i,col_w)
915 714
916 715
917 class dnd3esaves(class_char_child): 716 class dnd3esaves(class_char_child):
918 """ Node Handler for saves. This handler will be 717 """ Node Handler for saves. This handler will be
919 created by dnd3echar_handler. 718 created by dnd3echar_handler.
920 """ 719 """
921 def __init__(self,xml_dom,tree_node,parent): 720 def __init__(self,xml_dom,tree_node,parent):
922 class_char_child.__init__(self,xml_dom,tree_node,parent) 721 class_char_child.__init__(self,xml_dom,tree_node,parent)
923 self.hparent = parent #a 1.5002 allow ability to run up tree. 722 self.hparent = parent
924 #self.saveGrid = None #a 1.6018 d 1.9002 723 self.saveGridFrame = []
925 self.saveGridFrame = [] #a 1.9002 handle list, check frame for close.
926 724
927 tree = self.tree 725 tree = self.tree
928 icons = self.tree.icons 726 icons = self.tree.icons
929 727
930 self.root = getRoot(self) #a 1.5002 728 self.root = getRoot(self)
931 self.root.saves = self #a 1.6009 729 self.root.saves = self
932 node_list = self.xml.findall('save') 730 node_list = self.xml.findall('save')
933 self.saves={} 731 self.saves={}
934 for n in node_list: 732 for n in node_list:
935 name = n.get('name') 733 name = n.get('name')
936 self.saves[name] = n 734 self.saves[name] = n
937 new_tree_node = tree.AppendItem(self.mytree_node,name,icons['gear'],icons['gear']) 735 new_tree_node = tree.AppendItem(self.mytree_node,name,icons['gear'],icons['gear'])
938 tree.SetPyData(new_tree_node,self) 736 tree.SetPyData(new_tree_node,self)
939 737
940 #a 1.9002 this whole method 738
941 def refresh_data(self): # refresh the data in the melee/ranged section 739 def refresh_data(self):
942 # of the attack chart. 740 # of the attack chart.
943 # count backwards, maintains context despite "removes" 741 # count backwards, maintains context despite "removes"
944 for i in range(len(self.saveGridFrame)-1,-1,-1): 742 for i in range(len(self.saveGridFrame)-1,-1,-1):
945 x = self.saveGridFrame[i] 743 x = self.saveGridFrame[i]
946 if x == None: 744 if x == None: x.refresh_data()
947 x.refresh_data() 745 else: self.saveGridFrame.remove(x)
948 else:
949 self.saveGridFrame.remove(x)
950 746
951 def get_mod(self,name): 747 def get_mod(self,name):
952 save = self.saves[name] 748 save = self.saves[name]
953 stat = save.get('stat') 749 stat = save.get('stat')
954 #print "dnd3esaves, get_mod: self,root",self,self.root #a (debug) 1.5002 750 stat_mod = self.root.abilities.get_mod(stat)
955 #print "and abilities",self.root.abilities #a (debug) 1.5002
956 stat_mod = self.root.abilities.get_mod(stat) #a 1.5002
957 base = int(save.get('base')) 751 base = int(save.get('base'))
958 miscmod = int(save.get('miscmod')) 752 miscmod = int(save.get('miscmod'))
959 magmod = int(save.get('magmod')) 753 magmod = int(save.get('magmod'))
960 total = stat_mod + base + miscmod + magmod 754 total = stat_mod + base + miscmod + magmod
961 return total 755 return total
962 756
963 def on_rclick(self,evt): 757 def on_rclick(self,evt):
964 item = self.tree.GetSelection() 758 item = self.tree.GetSelection()
965 name = self.tree.GetItemText(item) 759 name = self.tree.GetItemText(item)
966 if item == self.mytree_node: 760 if item == self.mytree_node:
967 pass #a 1.5003 syntatic place holder 761 pass
968 return #a 1.5003 762 return
969 #print "failure mode!"
970 #dnd3e_char_child.on_ldclick(self,evt) #d 1.5003 this busted
971 #wnd = save_grid(self.frame.note,self)
972 #wnd.title = "Saves"
973 #self.frame.add_panel(wnd)
974 else: 763 else:
975 mod = self.get_mod(name) 764 mod = self.get_mod(name)
976 if mod >= 0: mod1 = "+" 765 if mod >= 0: mod1 = "+"
977 else: mod1 = "" 766 else: mod1 = ""
978 chat = self.chat 767 chat = self.chat
993 for n in node_list: 782 for n in node_list:
994 name = n.get('name') 783 name = n.get('name')
995 stat = n.get('stat') 784 stat = n.get('stat')
996 base = n.get('base') 785 base = n.get('base')
997 html_str = html_str + "<tr ALIGN='center'><td>"+name+"</td><td>"+stat+"</td><td>"+base+"</td>" 786 html_str = html_str + "<tr ALIGN='center'><td>"+name+"</td><td>"+stat+"</td><td>"+base+"</td>"
998 #stat_mod = str(dnd_globals["stats"][stat]) #d 1.5002 787 stat_mod = self.root.abilities.get_mod(stat)
999 stat_mod = self.root.abilities.get_mod(stat) #a 1.5002
1000 788
1001 mag = n.get('magmod') 789 mag = n.get('magmod')
1002 misc = n.get('miscmod') 790 misc = n.get('miscmod')
1003 mod = str(self.get_mod(name)) 791 mod = str(self.get_mod(name))
1004 if mod >= 0: 792 if mod >= 0: mod1 = "+"
1005 mod1 = "+" 793 else: mod1 = ""
1006 else:
1007 mod1 = ""
1008 #m 1.5009 next line. added str() around stat_mod
1009 html_str = html_str + "<td>"+str(stat_mod)+"</td><td>"+mag+"</td>" 794 html_str = html_str + "<td>"+str(stat_mod)+"</td><td>"+mag+"</td>"
1010 html_str = html_str + '<td>'+misc+'</td><td>%s%s</td></tr>' % (mod1, mod) 795 html_str = html_str + '<td>'+misc+'</td><td>%s%s</td></tr>' % (mod1, mod)
1011 html_str = html_str + "</table>" 796 html_str = html_str + "</table>"
1012 return html_str 797 return html_str
1013 798
1014 #mark6 799 #mark6
1015 class save_grid(wx.grid.Grid): 800 class save_grid(wx.grid.Grid):
1016 """grid for saves""" 801 """grid for saves"""
1017 def __init__(self, parent, handler): 802 def __init__(self, parent, handler):
1018 pname = handler.xml.set("name", 'Saves') 803 pname = handler.xml.set("name", 'Saves')
1019 self.hparent = handler #a 1.5002 allow ability to run up tree. 804 self.hparent = handler
1020 #a 1.5002 in this case, we need the functional parent, not the invoking parent.
1021 self.root = getRoot(self) 805 self.root = getRoot(self)
1022 #self.hparent.saveGrid = self #a 1.6018 d 1.9001
1023 wx.grid.Grid.__init__(self, parent, -1, style=wx.SUNKEN_BORDER | wx.WANTS_CHARS) 806 wx.grid.Grid.__init__(self, parent, -1, style=wx.SUNKEN_BORDER | wx.WANTS_CHARS)
1024 self.Bind(wx.EVT_SIZE, self.on_size) 807 self.Bind(wx.EVT_SIZE, self.on_size)
1025 self.Bind(wx.grid.EVT_GRID_CELL_CHANGE, self.on_cell_change) 808 self.Bind(wx.grid.EVT_GRID_CELL_CHANGE, self.on_cell_change)
1026 self.handler = handler 809 self.handler = handler
1027 saves = handler.xml.findall('save') 810 saves = handler.xml.findall('save')
1028 self.CreateGrid(len(saves),7) 811 self.CreateGrid(len(saves),7)
1029 self.SetRowLabelSize(0) 812 self.SetRowLabelSize(0)
1030 col_names = ['Save','Key','base','Abil','Magic','Misc','Total'] 813 col_names = ['Save','Key','base','Abil','Magic','Misc','Total']
1031 for i in range(len(col_names)): 814 for i in range(len(col_names)): self.SetColLabelValue(i,col_names[i])
1032 self.SetColLabelValue(i,col_names[i])
1033 self.saves = saves 815 self.saves = saves
1034 i = 0 816 i = 0
1035 for i in range(len(saves)): self.refresh_row(i) 817 for i in range(len(saves)): self.refresh_row(i)
1036 #a 1.9002 remainder of code in this method.
1037 climber = parent 818 climber = parent
1038 nameNode = climber.GetClassName() 819 nameNode = climber.GetClassName()
1039 while nameNode != 'wxFrame': 820 while nameNode != 'wxFrame':
1040 climber = climber.parent 821 climber = climber.parent
1041 nameNode = climber.GetClassName() 822 nameNode = climber.GetClassName()
1042 masterFrame=climber 823 masterFrame=climber
1043 masterFrame.refresh_data=self.refresh_data 824 masterFrame.refresh_data=self.refresh_data
1044 #print getmembers(masterFrame)
1045 handler.saveGridFrame.append(masterFrame) 825 handler.saveGridFrame.append(masterFrame)
1046 826
1047 def on_cell_change(self,evt): 827 def on_cell_change(self,evt):
1048 row = evt.GetRow() 828 row = evt.GetRow()
1049 col = evt.GetCol() 829 col = evt.GetCol()
1050 value = self.GetCellValue(row,col) 830 value = self.GetCellValue(row,col)
1051 try: 831 try:
1052 int(value) 832 int(value)
1053 if col == 2: 833 if col == 2: self.saves[row].set('base',value)
1054 self.saves[row].set('base',value) 834 elif col == 4: self.saves[row].set('magmod',value)
1055 elif col ==4: 835 elif col == 5: self.saves[row].set('miscmod',value)
1056 self.saves[row].set('magmod',value)
1057 elif col ==5: # 1.5001
1058 self.saves[row].set('miscmod',value)
1059 self.refresh_row(row) 836 self.refresh_row(row)
1060 except: 837 except: self.SetCellValue(row,col,"0")
1061 self.SetCellValue(row,col,"0")
1062 838
1063 def refresh_row(self,rowi): 839 def refresh_row(self,rowi):
1064 s = self.saves[rowi] 840 s = self.saves[rowi]
1065 name = s.get('name') 841 name = s.get('name')
1066 self.SetCellValue(rowi,0,name) 842 self.SetCellValue(rowi,0,name)
1080 def on_size(self,evt): 856 def on_size(self,evt):
1081 (w,h) = self.GetClientSizeTuple() 857 (w,h) = self.GetClientSizeTuple()
1082 cols = self.GetNumberCols() 858 cols = self.GetNumberCols()
1083 col_w = w/(cols+2) 859 col_w = w/(cols+2)
1084 self.SetColSize(0,col_w*3) 860 self.SetColSize(0,col_w*3)
1085 for i in range(1,cols): 861 for i in range(1,cols): self.SetColSize(i,col_w)
1086 self.SetColSize(i,col_w)
1087 evt.Skip() 862 evt.Skip()
1088 self.Refresh() 863 self.Refresh()
1089 864
1090 def refresh_data(self): 865 def refresh_data(self):
1091 for r in range(self.GetNumberRows()): 866 for r in range(self.GetNumberRows()): self.refresh_row(r)
1092 self.refresh_row(r)
1093 867
1094 class dnd3eskillsnfeats(dnd3e_char_child): 868 class dnd3eskillsnfeats(dnd3e_char_child):
1095 """ Node handler for a dnd3e charactor 869 """ Node handler for a dnd3e charactor
1096 <nodehandler name='?' module='dnd3e' class='dnd3echar_handler2' /> 870 <nodehandler name='?' module='dnd3e' class='dnd3echar_handler2' />
1097 """ 871 """
1098 def __init__(self,xml_dom,tree_node,parent): 872 def __init__(self,xml_dom,tree_node,parent):
1099 self.hparent = parent #a 1.5002 allow ability to run up tree. 873 self.hparent = parent
1100 self.root = getRoot(self) #a 1.6009 874 self.root = getRoot(self)
1101
1102 #print "dnd3eskillsnfeats - init, self ",self #a (debug) 1.5002
1103 #print "dnd3eskillsnfeats - init, parent ",self.hparent #a (debug) 1.5002
1104 #print "dnd3eskillsnfeats - init, parent ",parent.dnd3eclassnstats #a (debug) 1.5002
1105
1106 node_handler.__init__(self,xml_dom,tree_node) 875 node_handler.__init__(self,xml_dom,tree_node)
1107 dnd3e_char_child.__init__(self,xml_dom,tree_node,parent) 876 dnd3e_char_child.__init__(self,xml_dom,tree_node,parent)
1108 self.frame = component.get('frame') 877 self.frame = component.get('frame')
1109 self.child_handlers = {} 878 self.child_handlers = {}
1110 self.new_child_handler('skills','Skills',dnd3eskill,'book') 879 self.new_child_handler('skills','Skills',dnd3eskill,'book')
1111 self.new_child_handler('feats','Feats',dnd3efeats,'book') 880 self.new_child_handler('feats','Feats',dnd3efeats,'book')
1112 #wxMenuItem(self.tree.std_menu, dnd3e_EXPORT, "Export...", "Export")
1113 self.myeditor = None 881 self.myeditor = None
1114 882
1115 def new_child_handler(self,tag,text,handler_class,icon='gear'): 883 def new_child_handler(self,tag,text,handler_class,icon='gear'):
1116 node_list = self.xml.findall(tag) 884 node_list = self.xml.findall(tag)
1117 tree = self.tree 885 tree = self.tree
1166 class dnd3eskill(skills_char_child): 934 class dnd3eskill(skills_char_child):
1167 """ Node Handler for skill. This handler will be 935 """ Node Handler for skill. This handler will be
1168 created by dnd3echar_handler. 936 created by dnd3echar_handler.
1169 """ 937 """
1170 def __init__(self,xml_dom,tree_node,parent): 938 def __init__(self,xml_dom,tree_node,parent):
1171 self.hparent = parent #a 1.5002 allow ability to run up tree. 939 self.hparent = parent
1172 #a 1.5002 Need the functional parent, not the invoking parent. 940 self.root = getRoot(self)
1173 self.root = getRoot(self) #a 1.5002 941 self.root.skills = self
1174 self.root.skills = self #a 1.6009
1175 942
1176 skills_char_child.__init__(self,xml_dom,tree_node,parent) 943 skills_char_child.__init__(self,xml_dom,tree_node,parent)
1177 tree = self.tree 944 tree = self.tree
1178 icons = self.tree.icons 945 icons = self.tree.icons
1179 node_list = self.xml.findall('skill') 946 node_list = self.xml.findall('skill')
1180 947
1181 self.skills={} 948 self.skills={}
1182 #Adding code to not display skills you can not use -mgt
1183 for n in node_list: 949 for n in node_list:
1184 name = n.get('name') 950 name = n.get('name')
1185 self.skills[name] = n 951 self.skills[name] = n
1186 skill_check = self.skills[name] 952 skill_check = self.skills[name]
1187 ranks = int(skill_check.get('rank')) 953 ranks = int(skill_check.get('rank'))
1188 trained = int(skill_check.get('untrained')) 954 trained = int(skill_check.get('untrained'))
1189
1190 if ranks > 0 or trained == 1: 955 if ranks > 0 or trained == 1:
1191 new_tree_node = tree.AppendItem(self.mytree_node,name, 956 new_tree_node = tree.AppendItem(self.mytree_node,name,
1192 icons['gear'],icons['gear']) 957 icons['gear'],icons['gear'])
1193 else: continue 958 else: continue
1194 tree.SetPyData(new_tree_node,self) 959 tree.SetPyData(new_tree_node,self)
1199 #The change. -mgt 964 #The change. -mgt
1200 tree = self.tree 965 tree = self.tree
1201 icons = self.tree.icons 966 icons = self.tree.icons
1202 tree.CollapseAndReset(self.mytree_node) 967 tree.CollapseAndReset(self.mytree_node)
1203 node_list = self.xml.findall('skill') 968 node_list = self.xml.findall('skill')
1204
1205 self.skills={} 969 self.skills={}
1206 for n in node_list: 970 for n in node_list:
1207 name = n.get('name') 971 name = n.get('name')
1208 self.skills[name] = n 972 self.skills[name] = n
1209 skill_check = self.skills[name] 973 skill_check = self.skills[name]
1210 ranks = int(skill_check.get('rank')) 974 ranks = int(skill_check.get('rank'))
1211 trained = int(skill_check.get('untrained')) 975 trained = int(skill_check.get('untrained'))
1212
1213 if ranks > 0 or trained == 1: 976 if ranks > 0 or trained == 1:
1214 new_tree_node = tree.AppendItem(self.mytree_node,name, 977 new_tree_node = tree.AppendItem(self.mytree_node,name,
1215 icons['gear'],icons['gear']) 978 icons['gear'],icons['gear'])
1216 else: continue 979 else: continue
1217 tree.SetPyData(new_tree_node,self) 980 tree.SetPyData(new_tree_node,self)
1218 981
1219 def get_mod(self,name): 982 def get_mod(self,name):
1220 skill = self.skills[name] 983 skill = self.skills[name]
1221 stat = skill.get('stat') 984 stat = skill.get('stat')
1222 #stat_mod = int(dnd_globals["stats"][stat]) #d 1.5002 985 stat_mod = self.root.abilities.get_mod(stat)
1223 stat_mod = self.root.abilities.get_mod(stat) #a 1.5002
1224 rank = int(skill.get('rank')) 986 rank = int(skill.get('rank'))
1225 misc = int(skill.get('misc')) 987 misc = int(skill.get('misc'))
1226 total = stat_mod + rank + misc 988 total = stat_mod + rank + misc
1227 return total 989 return total
1228 990
1229 def on_rclick(self,evt): 991 def on_rclick(self,evt):
1230 item = self.tree.GetSelection() 992 item = self.tree.GetSelection()
1231 name = self.tree.GetItemText(item) 993 name = self.tree.GetItemText(item)
1232 #print "skill rc self",self #a 1.6004 994 if item == self.mytree_node: return
1233 #print "skill rc tree",self.mytree_node #a 1.6004 995 ac = self.root.ac.get_check_pen()
1234 #print "skill rc item",item #a 1.6004
1235 if item == self.mytree_node:
1236 return
1237 # following line fails,
1238 #dnd3e_char_child.on_ldclick(self,evt) #d 1.6014
1239 # it's what it used to try to do.
1240 ac = self.root.ac.get_check_pen() #a 1.5002 for 1.5004 verify fix.
1241 skill = self.skills[name] 996 skill = self.skills[name]
1242 untr = skill.get('untrained') #a 1.6004 997 untr = skill.get('untrained')
1243 rank = skill.get('rank') #a 1.6004 998 rank = skill.get('rank')
1244 if eval('%s == 0' % (untr)): #a 1.6004 999 if eval('%s == 0' % (untr)):
1245 if eval('%s == 0' % (rank)): #a 1.6004 1000 if eval('%s == 0' % (rank)):
1246 res = 'You fumble around, accomplishing nothing' #a 1.6004 1001 res = 'You fumble around, accomplishing nothing'
1247 txt = '%s Skill Check: %s' % (name, res) #a 1.6004 1002 txt = '%s Skill Check: %s' % (name, res)
1248 chat = self.chat #a 1.6004 1003 chat = self.chat
1249 chat.Post(txt,True,True) #a 1.6004 1004 chat.Post(txt,True,True)
1250 return #a 1.6004 1005 return
1251
1252 armor = '' 1006 armor = ''
1253 acCp = '' 1007 acCp = ''
1254 if ac < 0: #acCp >= 1 #m 1.5004 this is stored as negatives. 1008 if ac < 0:
1255 armorCheck = int(skill.get('armorcheck')) 1009 armorCheck = int(skill.get('armorcheck'))
1256 #print "ac,armorCheck",ac,armorCheck
1257 if armorCheck == 1: 1010 if armorCheck == 1:
1258 acCp=ac 1011 acCp=ac
1259 armor = '(includes Armor Penalty of %s)' % (acCp) 1012 armor = '(includes Armor Penalty of %s)' % (acCp)
1260 if item == self.mytree_node: 1013 if item == self.mytree_node:
1261 dnd3e_char_child.on_ldclick(self,evt) 1014 dnd3e_char_child.on_ldclick(self,evt)
1262 #wnd = skill_grid(self.frame.note,self)
1263 #wnd.title = "Skills"
1264 #self.frame.add_panel(wnd)
1265 else: 1015 else:
1266 mod = self.get_mod(name) 1016 mod = self.get_mod(name)
1267 if mod >= 0: mod1 = "+" 1017 if mod >= 0: mod1 = "+"
1268 else: mod1 = "" 1018 else: mod1 = ""
1269 chat = self.chat 1019 chat = self.chat
1284 1034
1285 for n in node_list: 1035 for n in node_list:
1286 name = n.get('name') 1036 name = n.get('name')
1287 stat = n.get('stat') 1037 stat = n.get('stat')
1288 rank = n.get('rank') 1038 rank = n.get('rank')
1289 untr = n.get('untrained') #a 1.6004 1039 untr = n.get('untrained')
1290 #Filter unsuable skills out of pretty print -mgt 1040 #Filter unsuable skills out of pretty print -mgt
1291 if eval('%s > 0' % (rank)) or eval('%s == 1' % (untr)): 1041 if eval('%s > 0' % (rank)) or eval('%s == 1' % (untr)):
1292 if eval('%s >=1' % (rank)): 1042 if eval('%s >=1' % (rank)):
1293 html_str += "<tr ALIGN='center' bgcolor='#CCCCFF'><td>" #a 1.6004 1043 html_str += "<tr ALIGN='center' bgcolor='#CCCCFF'><td>"
1294 #html_str += "<tr ALIGN='center' bgcolor='green'><td>" #d 1.6004
1295 html_str += name+"</td><td>"+stat+"</td><td>"+rank+"</td>" 1044 html_str += name+"</td><td>"+stat+"</td><td>"+rank+"</td>"
1296 elif eval('%s == 1' % (untr)): #a 1.6004 1045 elif eval('%s == 1' % (untr)):
1297 html_str += "<tr ALIGN='center' bgcolor='#C0FF40'><td>" #a 1.6004 1046 html_str += "<tr ALIGN='center' bgcolor='#C0FF40'><td>"
1298 html_str += name+"</td><td>"+stat+"</td><td>"+rank+"</td>" #a 1.6004 1047 html_str += name+"</td><td>"+stat+"</td><td>"+rank+"</td>"
1299 else: 1048 else:
1300 html_str += "<tr ALIGN='center'><td>"+name+"</td><td>" 1049 html_str += "<tr ALIGN='center'><td>"+name+"</td><td>"
1301 html_str += stat+"</td><td>"+rank+"</td>" 1050 html_str += stat+"</td><td>"+rank+"</td>"
1302 else: 1051 else: continue
1303 continue 1052 stat_mod = self.root.abilities.get_mod(stat)
1304 stat_mod = self.root.abilities.get_mod(stat) #a 1.5002
1305 #stat_mod = str(dnd_globals["stats"][stat]) #d 1.5002
1306 misc = n.get('misc') 1053 misc = n.get('misc')
1307 mod = str(self.get_mod(name)) 1054 mod = str(self.get_mod(name))
1308 if mod >= 0: 1055 if mod >= 0: mod1 = "+"
1309 mod1 = "+" 1056 else: mod1 = ""
1310 else:
1311 mod1 = ""
1312 html_str += "<td>"+str(stat_mod)+"</td><td>"+misc #m 1.6009 str() 1057 html_str += "<td>"+str(stat_mod)+"</td><td>"+misc #m 1.6009 str()
1313 html_str += '</td><td>%s%s</td></tr>' % (mod1, mod) 1058 html_str += '</td><td>%s%s</td></tr>' % (mod1, mod)
1314 html_str = html_str + "</table>" 1059 html_str = html_str + "</table>"
1315 return html_str 1060 return html_str
1316 1061
1317 1062
1318 class skill_grid(wx.grid.Grid): 1063 class skill_grid(wx.grid.Grid):
1319 """ panel for skills """ 1064 """ panel for skills """
1320 def __init__(self, parent, handler): 1065 def __init__(self, parent, handler):
1321 self.hparent = handler #a 1.5002 need function parent, not invoker 1066 self.hparent = handler
1322 self.root = getRoot(self) #a 1.5002 1067 self.root = getRoot(self)
1323 pname = handler.xml.set("name", 'Skills') 1068 pname = handler.xml.set("name", 'Skills')
1324 1069
1325 wx.grid.Grid.__init__(self, parent, -1, style=wx.SUNKEN_BORDER | wx.WANTS_CHARS) 1070 wx.grid.Grid.__init__(self, parent, -1, style=wx.SUNKEN_BORDER | wx.WANTS_CHARS)
1326 self.Bind(wx.EVT_SIZE, self.on_size) 1071 self.Bind(wx.EVT_SIZE, self.on_size)
1327 self.Bind(wx.grid.EVT_GRID_CELL_CHANGE, self.on_cell_change) 1072 self.Bind(wx.grid.EVT_GRID_CELL_CHANGE, self.on_cell_change)
1328 self.handler = handler 1073 self.handler = handler
1329 skills = handler.xml.findall('skill') 1074 skills = handler.xml.findall('skill')
1330 #xelf.stats = dnd_globals["stats"] #d 1.5002
1331 1075
1332 self.CreateGrid(len(skills),6) 1076 self.CreateGrid(len(skills),6)
1333 self.SetRowLabelSize(0) 1077 self.SetRowLabelSize(0)
1334 col_names = ['Skill','Key','Rank','Abil','Misc','Total'] 1078 col_names = ['Skill','Key','Rank','Abil','Misc','Total']
1335 for i in range(len(col_names)): 1079 for i in range(len(col_names)):
1336 self.SetColLabelValue(i,col_names[i]) 1080 self.SetColLabelValue(i,col_names[i])
1337 rowi = 0 1081 rowi = 0
1338 self.skills = skills 1082 self.skills = skills
1339 for i in range(len(skills)): 1083 for i in range(len(skills)): self.refresh_row(i)
1340 self.refresh_row(i)
1341 1084
1342 def on_cell_change(self,evt): 1085 def on_cell_change(self,evt):
1343 row = evt.GetRow() 1086 row = evt.GetRow()
1344 col = evt.GetCol() 1087 col = evt.GetCol()
1345 value = self.GetCellValue(row,col) 1088 value = self.GetCellValue(row,col)
1346 #print value
1347 try: 1089 try:
1348 int(value) 1090 int(value)
1349 if col == 2: 1091 if col == 2: self.skills[row].set('rank',value)
1350 self.skills[row].set('rank',value) 1092 elif col ==4: self.skills[row].set('misc',value)
1351 elif col ==4:
1352 self.skills[row].set('misc',value)
1353 self.refresh_row(row) 1093 self.refresh_row(row)
1354 except: 1094 except: self.SetCellValue(row,col,"0")
1355 self.SetCellValue(row,col,"0")
1356
1357 #call refresh_skills
1358 self.handler.refresh_skills() 1095 self.handler.refresh_skills()
1359 1096
1360 def refresh_row(self,rowi): 1097 def refresh_row(self,rowi):
1361 s = self.skills[rowi] 1098 s = self.skills[rowi]
1362 name = s.get('name') 1099 name = s.get('name')
1364 self.SetReadOnly(rowi,0) 1101 self.SetReadOnly(rowi,0)
1365 stat = s.get('stat') 1102 stat = s.get('stat')
1366 self.SetCellValue(rowi,1,stat) 1103 self.SetCellValue(rowi,1,stat)
1367 self.SetReadOnly(rowi,1) 1104 self.SetReadOnly(rowi,1)
1368 self.SetCellValue(rowi,2,s.get('rank')) 1105 self.SetCellValue(rowi,2,s.get('rank'))
1369 #self.SetCellValue(rowi,3,str(dnd_globals["stats"][stat])) #d 1.5002 1106 if self.root.abilities: stat_mod=self.root.abilities.get_mod(stat)
1370 if self.root.abilities: #a 1.5002 sanity check. 1107 else:
1371 stat_mod=self.root.abilities.get_mod(stat) #a 1.5002 1108 stat_mod = -6
1372 else: #a 1.5002
1373 stat_mod = -6 #a 1.5002 this can happen if code is changed so
1374 #a 1.5002 that abilities are not defined prior invokation of init.
1375 print "Please advise dnd3e maintainer alert 1.5002 raised" 1109 print "Please advise dnd3e maintainer alert 1.5002 raised"
1376 1110
1377 self.SetCellValue(rowi,3,str(stat_mod)) #a 1.5002 1111 self.SetCellValue(rowi,3,str(stat_mod))
1378 self.SetReadOnly(rowi,3) 1112 self.SetReadOnly(rowi,3)
1379 self.SetCellValue(rowi,4,s.get('misc')) 1113 self.SetCellValue(rowi,4,s.get('misc'))
1380 mod = str(self.handler.get_mod(name)) 1114 mod = str(self.handler.get_mod(name))
1381 self.SetCellValue(rowi,5,mod) 1115 self.SetCellValue(rowi,5,mod)
1382 self.SetReadOnly(rowi,5) 1116 self.SetReadOnly(rowi,5)
1384 def on_size(self,evt): 1118 def on_size(self,evt):
1385 (w,h) = self.GetClientSizeTuple() 1119 (w,h) = self.GetClientSizeTuple()
1386 cols = self.GetNumberCols() 1120 cols = self.GetNumberCols()
1387 col_w = w/(cols+2) 1121 col_w = w/(cols+2)
1388 self.SetColSize(0,col_w*3) 1122 self.SetColSize(0,col_w*3)
1389 for i in range(1,cols): 1123 for i in range(1,cols): self.SetColSize(i,col_w)
1390 self.SetColSize(i,col_w)
1391 evt.Skip() 1124 evt.Skip()
1392 self.Refresh() 1125 self.Refresh()
1393 1126
1394 def refresh_data(self): 1127 def refresh_data(self):
1395 1128 for r in range(self.GetNumberRows()): self.refresh_row(r)
1396 for r in range(self.GetNumberRows()):
1397 self.refresh_row(r)
1398
1399
1400 1129
1401 1130
1402 class dnd3efeats(skills_char_child): 1131 class dnd3efeats(skills_char_child):
1403 """ Node Handler for classes. This handler will be 1132 """ Node Handler for classes. This handler will be
1404 created by dnd3echar_handler. 1133 created by dnd3echar_handler.
1405 """ 1134 """
1406 def __init__(self,xml_dom,tree_node,parent): 1135 def __init__(self,xml_dom,tree_node,parent):
1407 skills_char_child.__init__(self,xml_dom,tree_node,parent) 1136 skills_char_child.__init__(self,xml_dom,tree_node,parent)
1408 self.hparent = parent #a 1.5002 allow ability to run up tree. 1137 self.hparent = parent
1409 self.root = getRoot(self) #a 1.5002 1138 self.root = getRoot(self)
1410 self.root.feats = self #a 1.6009 1139 self.root.feats = self
1411
1412 1140
1413 def get_design_panel(self,parent): 1141 def get_design_panel(self,parent):
1414 setTitle="Feats - " + self.root.general.charName #a 1.5010 1142 setTitle="Feats - " + self.root.general.charName
1415 wnd = outline_panel(parent,self,feat_panel,setTitle) #a 1.5010 1143 wnd = outline_panel(parent,self,feat_panel,setTitle)
1416 #wnd = outline_panel(parent,self,feat_panel,"Feats") #d 1.5010 1144 wnd.title = "Feats"
1417 wnd.title = "Feats" #d 1.5010
1418 #wnd.title = "Feats - " + self.charName
1419 return wnd 1145 return wnd
1420 1146
1421 def tohtml(self): 1147 def tohtml(self):
1422 html_str = "<table width=100% border=1 ><tr BGCOLOR=#E9E9E9 ><th>Feats</th></tr><tr><td>" 1148 html_str = "<table width=100% border=1 ><tr BGCOLOR=#E9E9E9 ><th>Feats</th></tr><tr><td>"
1423 n_list = self.xml.getchildren() 1149 n_list = self.xml.getchildren()
1427 return html_str 1153 return html_str
1428 1154
1429 class feat_panel(wx.Panel): 1155 class feat_panel(wx.Panel):
1430 def __init__(self, parent, handler): 1156 def __init__(self, parent, handler):
1431 1157
1432 self.hparent = handler #a 1.5002 allow ability to run up tree. 1158 self.hparent = handler
1433 #a 1.5002 in this case, we need the functional parent, not the invoking parent. 1159 self.root = getRoot(self)
1434 self.root = getRoot(self) #a 1.5002 1160 pname = handler.xml.set("name", 'Feats')
1435 #tempTitle= 'Feats - ' + self.root.general.charName #a 1.5010
1436 #pname = handler.xml.set("name", tempTitle) #a 1.5010
1437 pname = handler.xml.set("name", 'Feats') #d 1.5010
1438
1439 wx.Panel.__init__(self, parent, -1) 1161 wx.Panel.__init__(self, parent, -1)
1440 self.grid =wx.grid.Grid(self, -1, style=wx.SUNKEN_BORDER | wx.WANTS_CHARS) 1162 self.grid =wx.grid.Grid(self, -1, style=wx.SUNKEN_BORDER | wx.WANTS_CHARS)
1441 sizer = wx.BoxSizer(wx.VERTICAL) 1163 sizer = wx.BoxSizer(wx.VERTICAL)
1442 sizer.Add(self.grid, 1, wx.EXPAND) 1164 sizer.Add(self.grid, 1, wx.EXPAND)
1443
1444 sizer1 = wx.BoxSizer(wx.HORIZONTAL) 1165 sizer1 = wx.BoxSizer(wx.HORIZONTAL)
1445 sizer1.Add(wx.Button(self, 10, "Remove Feat"), 0, wx.EXPAND) 1166 sizer1.Add(wx.Button(self, 10, "Remove Feat"), 0, wx.EXPAND)
1446 sizer1.Add(wx.Size(10,10)) 1167 sizer1.Add(wx.Size(10,10))
1447 sizer1.Add(wx.Button(self, 20, "Add Feat"), 0, wx.EXPAND) 1168 sizer1.Add(wx.Button(self, 20, "Add Feat"), 0, wx.EXPAND)
1448
1449 sizer.Add(sizer1, 0, wx.EXPAND) 1169 sizer.Add(sizer1, 0, wx.EXPAND)
1450 self.sizer = sizer 1170 self.sizer = sizer
1451
1452 self.SetSizer(self.sizer) 1171 self.SetSizer(self.sizer)
1453 self.SetAutoLayout(True) 1172 self.SetAutoLayout(True)
1454 self.Fit() 1173 self.Fit()
1455
1456 #self.Bind(wx.EVT_SIZE, self.on_size)
1457 self.Bind(wx.EVT_BUTTON, self.on_remove, id=10) 1174 self.Bind(wx.EVT_BUTTON, self.on_remove, id=10)
1458 self.Bind(wx.EVT_BUTTON, self.on_add, id=20) 1175 self.Bind(wx.EVT_BUTTON, self.on_add, id=20)
1459
1460 n_list = handler.xml.getchildren() 1176 n_list = handler.xml.getchildren()
1461 self.n_list = n_list 1177 self.n_list = n_list
1462 self.xml = handler.xml 1178 self.xml = handler.xml
1463 self.grid.CreateGrid(len(n_list),3,1) 1179 self.grid.CreateGrid(len(n_list),3,1)
1464 self.grid.SetRowLabelSize(0) 1180 self.grid.SetRowLabelSize(0)
1465 self.grid.SetColLabelValue(0,"Feat") 1181 self.grid.SetColLabelValue(0,"Feat")
1466 self.grid.SetColLabelValue(1,"Type") 1182 self.grid.SetColLabelValue(1,"Type")
1467 self.grid.SetColLabelValue(2,"Reference") #m 1.6 typo correction. 1183 self.grid.SetColLabelValue(2,"Reference")
1468 for i in range(len(n_list)): 1184 for i in range(len(n_list)): self.refresh_row(i)
1469 self.refresh_row(i)
1470 self.temp_dom = None 1185 self.temp_dom = None
1471 1186
1472 def refresh_row(self,i): 1187 def refresh_row(self,i):
1473 feat = self.n_list[i] 1188 feat = self.n_list[i]
1474
1475 name = feat.get('name') 1189 name = feat.get('name')
1476 type = feat.get('type') 1190 type = feat.get('type')
1477 desc = feat.get('desc') #m 1.6 correct typo 1191 desc = feat.get('desc')
1478 self.grid.SetCellValue(i,0,name) 1192 self.grid.SetCellValue(i,0,name)
1479 self.grid.SetReadOnly(i,0) 1193 self.grid.SetReadOnly(i,0)
1480 self.grid.SetCellValue(i,1,type) 1194 self.grid.SetCellValue(i,1,type)
1481 self.grid.SetReadOnly(i,1) 1195 self.grid.SetReadOnly(i,1)
1482 self.grid.SetCellValue(i,2,desc) #m 1.6 correct typo 1196 self.grid.SetCellValue(i,2,desc)
1483 self.grid.SetReadOnly(i,2) 1197 self.grid.SetReadOnly(i,2)
1484 1198
1485 def on_remove(self,evt): 1199 def on_remove(self,evt):
1486 rows = self.grid.GetNumberRows() 1200 rows = self.grid.GetNumberRows()
1487 for i in range(rows): 1201 for i in range(rows):
1524 """ 1238 """
1525 def __init__(self,xml_dom,tree_node,parent): 1239 def __init__(self,xml_dom,tree_node,parent):
1526 1240
1527 node_handler.__init__(self,xml_dom,tree_node) 1241 node_handler.__init__(self,xml_dom,tree_node)
1528 1242
1529 self.hparent = parent #a 1.5002 allow ability to run up tree. 1243 self.hparent = parent
1530 self.root = getRoot(self) #a 1.5012 1244 self.root = getRoot(self)
1531
1532
1533
1534 #mark3
1535 dnd3e_char_child.__init__(self,xml_dom,tree_node,parent) 1245 dnd3e_char_child.__init__(self,xml_dom,tree_node,parent)
1536 self.frame = component.get('frame') 1246 self.frame = component.get('frame')
1537 self.child_handlers = {} 1247 self.child_handlers = {}
1538 self.new_child_handler('hp','Hit Points',dnd3ehp,'gear') 1248 self.new_child_handler('hp','Hit Points',dnd3ehp,'gear')
1539 self.new_child_handler('attacks','Attacks',dnd3eattacks,'spears') 1249 self.new_child_handler('attacks','Attacks',dnd3eattacks,'spears')
1540 self.new_child_handler('ac','Armor',dnd3earmor,'spears') 1250 self.new_child_handler('ac','Armor',dnd3earmor,'spears')
1541 #print "combat",self.child_handlers #a (debug) 1.5002
1542 #wxMenuItem(self.tree.std_menu, dnd3e_EXPORT, "Export...", "Export")
1543 self.myeditor = None 1251 self.myeditor = None
1544
1545 1252
1546 def new_child_handler(self,tag,text,handler_class,icon='gear'): 1253 def new_child_handler(self,tag,text,handler_class,icon='gear'):
1547 node_list = self.xml.findall(tag) 1254 node_list = self.xml.findall(tag)
1548 tree = self.tree 1255 tree = self.tree
1549 i = self.tree.icons[icon] 1256 i = self.tree.icons[icon]
1568 self.char_hander = parent 1275 self.char_hander = parent
1569 self.drag = False 1276 self.drag = False
1570 self.frame = component.get('frame') 1277 self.frame = component.get('frame')
1571 self.myeditor = None 1278 self.myeditor = None
1572 1279
1573
1574 def on_drop(self,evt): 1280 def on_drop(self,evt):
1575 pass 1281 pass
1576 1282
1577 def on_rclick(self,evt): 1283 def on_rclick(self,evt):
1578 pass 1284 pass
1600 """ Node Handler for hit points. This handler will be 1306 """ Node Handler for hit points. This handler will be
1601 created by dnd3echar_handler. 1307 created by dnd3echar_handler.
1602 """ 1308 """
1603 def __init__(self,xml_dom,tree_node,parent): 1309 def __init__(self,xml_dom,tree_node,parent):
1604 combat_char_child.__init__(self,xml_dom,tree_node,parent) 1310 combat_char_child.__init__(self,xml_dom,tree_node,parent)
1605 self.hparent = parent #a 1.5002 allow ability to run up tree. 1311 self.hparent = parent
1606 self.root = getRoot(self) #a 1.6009 1312 self.root = getRoot(self)
1607 self.root.hp = self #a 1.6009 1313 self.root.hp = self
1608 1314
1609 def get_design_panel(self,parent): 1315 def get_design_panel(self,parent):
1610 wnd = outline_panel(parent,self,hp_panel,"Hit Points") 1316 wnd = outline_panel(parent,self,hp_panel,"Hit Points")
1611 wnd.title = "Hit Points" 1317 wnd.title = "Hit Points"
1612 return wnd 1318 return wnd
1628 return html_str 1334 return html_str
1629 1335
1630 class hp_panel(wx.Panel): 1336 class hp_panel(wx.Panel):
1631 def __init__(self, parent, handler): 1337 def __init__(self, parent, handler):
1632 wx.Panel.__init__(self, parent, -1) 1338 wx.Panel.__init__(self, parent, -1)
1633 self.hparent = handler #a 1.5002 allow ability to run up tree. In this 1339 self.hparent = handler
1634 #a 1.5002 case, we need the functional parent, not the invoking parent.
1635
1636 pname = handler.xml.set("name", 'HitPoints') 1340 pname = handler.xml.set("name", 'HitPoints')
1637 self.sizer = wx.FlexGridSizer(2, 4, 2, 2) # rows, cols, hgap, vgap 1341 self.sizer = wx.FlexGridSizer(2, 4, 2, 2) # rows, cols, hgap, vgap
1638 self.xml = handler.xml 1342 self.xml = handler.xml
1639 self.sizer.AddMany([ (wx.StaticText(self, -1, "HP Current:"), 0, 1343 self.sizer.AddMany([ (wx.StaticText(self, -1, "HP Current:"), 0,
1640 wx.ALIGN_CENTER_VERTICAL), 1344 wx.ALIGN_CENTER_VERTICAL),
1646 ]) 1350 ])
1647 self.sizer.AddGrowableCol(1) 1351 self.sizer.AddGrowableCol(1)
1648 self.SetSizer(self.sizer) 1352 self.SetSizer(self.sizer)
1649 self.SetAutoLayout(True) 1353 self.SetAutoLayout(True)
1650 self.Fit() 1354 self.Fit()
1651
1652 #self.Bind(wx.EVT_SIZE, self.on_size)
1653 self.Bind(wx.EVT_TEXT, self.on_text, id=HP_MAX) 1355 self.Bind(wx.EVT_TEXT, self.on_text, id=HP_MAX)
1654 self.Bind(wx.EVT_TEXT, self.on_text, id=HP_CUR) 1356 self.Bind(wx.EVT_TEXT, self.on_text, id=HP_CUR)
1655 1357
1656 def on_text(self,evt): 1358 def on_text(self,evt):
1657 id = evt.GetId() 1359 id = evt.GetId()
1658 if id == HP_CUR: 1360 if id == HP_CUR: self.xml.set('current',evt.GetString())
1659 self.xml.set('current',evt.GetString()) 1361 elif id == HP_MAX: self.xml.set('max',evt.GetString())
1660 elif id == HP_MAX:
1661 self.xml.set('max',evt.GetString())
1662 1362
1663 def on_size(self,evt): 1363 def on_size(self,evt):
1664 s = self.GetClientSizeTuple() 1364 s = self.GetClientSizeTuple()
1665 self.sizer.SetDimension(0,0,s[0],s[1]) 1365 self.sizer.SetDimension(0,0,s[0],s[1])
1666 1366
1668 """ Node Handler for attacks. This handler will be 1368 """ Node Handler for attacks. This handler will be
1669 created by dnd3echar_handler. 1369 created by dnd3echar_handler.
1670 """ 1370 """
1671 def __init__(self,xml_dom,tree_node,parent): 1371 def __init__(self,xml_dom,tree_node,parent):
1672 combat_char_child.__init__(self,xml_dom,tree_node,parent) 1372 combat_char_child.__init__(self,xml_dom,tree_node,parent)
1673 self.hparent = parent #a 1.5002 allow ability to run up tree. 1373 self.hparent = parent
1674 self.root = getRoot(self) #a 1.5002 1374 self.root = getRoot(self)
1675 self.root.attacks = self #a 1.6009 so others can find me. 1375 self.root.attacks = self
1676 self.mrFrame = [] #a 1.9001 1376 self.mrFrame = []
1677
1678 #a 1.5012 start a1b
1679
1680 self.updateFootNotes = False 1377 self.updateFootNotes = False
1681 self.updateFootNotes = False 1378 self.updateFootNotes = False
1682 self.html_str = "<html><body>" 1379 self.html_str = "<html><body>"
1683 self.html_str += ("<br> This character has weapons with no "+ 1380 self.html_str += ("<br> This character has weapons with no "+
1684 "footnotes. This program will "+ 1381 "footnotes. This program will "+
1694 "<br><br>Update to character:"+self.root.general.charName+ 1391 "<br><br>Update to character:"+self.root.general.charName+
1695 "<br><br>"+ 1392 "<br><br>"+
1696 """<table border='1' width=100% ><tr BGCOLOR=#E9E9E9 > 1393 """<table border='1' width=100% ><tr BGCOLOR=#E9E9E9 >
1697 <th width='80%'>Weapon Name</th><th>Added Footnote</th></tr>\n""") 1394 <th width='80%'>Weapon Name</th><th>Added Footnote</th></tr>\n""")
1698 self.temp_dom={} 1395 self.temp_dom={}
1699 #a 1.5012 end a1b
1700
1701 node_list = self.xml.findall('melee') 1396 node_list = self.xml.findall('melee')
1702 self.melee = node_list[0] 1397 self.melee = node_list[0]
1703 node_list = self.xml.findall('ranged') 1398 node_list = self.xml.findall('ranged')
1704 self.ranged = node_list[0] 1399 self.ranged = node_list[0]
1705 self.refresh_weapons() # this causes self.weapons to be loaded. 1400 self.refresh_weapons()
1706
1707 #a 1.5012 this whole if clause.
1708 if self.updateFootNotes == True: 1401 if self.updateFootNotes == True:
1709 self.updateFootNotes = False 1402 self.updateFootNotes = False
1710 name = self.root.general.charName 1403 name = self.root.general.charName
1711 self.html_str += "</table>" 1404 self.html_str += "</table>"
1712 self.html_str += "</body> </html> " 1405 self.html_str += "</body> </html> "
1713 masterFrame = self.root.frame 1406 masterFrame = self.root.frame
1714
1715 title = name+"'s weapons' update to have footnotes" 1407 title = name+"'s weapons' update to have footnotes"
1716 fnFrame = wx.Frame(masterFrame, -1, title) 1408 fnFrame = wx.Frame(masterFrame, -1, title)
1717 fnFrame.panel = wx.html.HtmlWindow(fnFrame,-1) 1409 fnFrame.panel = wx.html.HtmlWindow(fnFrame,-1)
1718 fnFrame.panel.SetPage(self.html_str) 1410 fnFrame.panel.SetPage(self.html_str)
1719 fnFrame.Show() 1411 fnFrame.Show()
1720 1412
1721 #weaponsH = self.xml.findall('attacks') 1413
1722 #mark7 1414
1723 1415 def refreshMRdata(self):
1724 #a 1.9001 this whole method
1725 def refreshMRdata(self): # refresh the data in the melee/ranged section
1726 # of the attack chart. 1416 # of the attack chart.
1727 # count backwards, maintains context despite "removes" 1417 # count backwards, maintains context despite "removes"
1728 for i in range(len(self.mrFrame)-1,-1,-1): #a 1.9001 1418 for i in range(len(self.mrFrame)-1,-1,-1):
1729 x = self.mrFrame[i] 1419 x = self.mrFrame[i]
1730 if x == None: 1420 if x == None: x.refreshMRdata() #a 1.9001
1731 x.refreshMRdata() #a 1.9001 1421 else: self.mrFrame.remove(x)
1732 else:
1733 self.mrFrame.remove(x)
1734 1422
1735 def refresh_weapons(self): 1423 def refresh_weapons(self):
1736 self.weapons = {} 1424 self.weapons = {}
1737 1425
1738 tree = self.tree 1426 tree = self.tree
1739 icons = self.tree.icons 1427 icons = self.tree.icons
1740 tree.CollapseAndReset(self.mytree_node) 1428 tree.CollapseAndReset(self.mytree_node)
1741 node_list = self.xml.findall('weapon') 1429 node_list = self.xml.findall('weapon')
1742 for n in node_list: 1430 for n in node_list:
1743 name = n.get('name') 1431 name = n.get('name')
1744 fn = safeGetAttr(n,'fn') #a 1.5012 can be removed when 1432 fn = safeGetAttr(n,'fn')
1745 #a 1.5012 confident all characters in the world have footnotes. 1433 if fn == None:
1746 #if self.updateFootNotes:
1747 if fn == None:#a 1.5012
1748 self.updateFootNotes=True 1434 self.updateFootNotes=True
1749 self.updateFootN(n) #a 1.5012 1435 self.updateFootN(n)
1750 new_tree_node = tree.AppendItem( 1436 new_tree_node = tree.AppendItem(
1751 self.mytree_node,name,icons['sword'],icons['sword']) 1437 self.mytree_node,name,icons['sword'],icons['sword'])
1752 tree.SetPyData(new_tree_node,self) 1438 tree.SetPyData(new_tree_node,self)
1753 self.weapons[name]=n 1439 self.weapons[name]=n
1754 1440
1755 def updateFootN(self,n):#a 1.5012 this whole function 1441 def updateFootN(self,n):
1756 if not self.temp_dom: 1442 if not self.temp_dom:
1757 tree = parse(dir_struct["dnd3e"]+"dnd3eweapons.xml") 1443 tree = parse(dir_struct["dnd3e"]+"dnd3eweapons.xml")
1758 self.temp_dom = tree.getroot() 1444 self.temp_dom = tree.getroot()
1759 nameF = n.get('name') 1445 nameF = n.get('name')
1760 w_list = self.temp_dom.findall('weapon') 1446 w_list = self.temp_dom.findall('weapon')
1763 if nameF == w.get('name'): 1449 if nameF == w.get('name'):
1764 found = True 1450 found = True
1765 fnN = safeGetAttr(n,'fn') 1451 fnN = safeGetAttr(n,'fn')
1766 if fnN == None or fnN == 'None': 1452 if fnN == None or fnN == 'None':
1767 fnW = w.get('fn') 1453 fnW = w.get('fn')
1768 #print "weapon",nameF,"footnotes are updated to",fnW
1769 self.html_str += ("<tr ALIGN='center'><td>"+nameF+"</td>"+ 1454 self.html_str += ("<tr ALIGN='center'><td>"+nameF+"</td>"+
1770 "<td>"+fnW+"</td></tr>\n") 1455 "<td>"+fnW+"</td></tr>\n")
1771 n.set('fn',fnW) 1456 n.set('fn',fnW)
1772 break 1457 break
1773 if not found: 1458 if not found:
1775 "Weapon, research "+ 1460 "Weapon, research "+
1776 "and update manually; setting footnote to indicate custom</td>"+ 1461 "and update manually; setting footnote to indicate custom</td>"+
1777 "<td>"+'X'+"</td></tr>\n") 1462 "<td>"+'X'+"</td></tr>\n")
1778 n.set('fn','X') 1463 n.set('fn','X')
1779 1464
1780
1781 def get_mod(self,type='m'): 1465 def get_mod(self,type='m'):
1782 (base, base2, base3, base4, base5, base6, stat_mod, misc) \ 1466 (base, base2, base3, base4, base5, base6, stat_mod, misc) \
1783 = self.get_attack_data(type) 1467 = self.get_attack_data(type)
1784 return int(base + misc + int(stat_mod)) 1468 return int(base + misc + int(stat_mod))
1785 1469
1786 def get_attack_data(self,type='m'): 1470 def get_attack_data(self,type='m'):
1787 if type=='m' or type=='0': 1471 if type=='m' or type=='0':
1788 stat = 'Str' #m was dnd_globals["stats"]['Str'] 1.5002 1472 stat = 'Str'
1789 temp = self.melee 1473 temp = self.melee
1790 else: 1474 else:
1791 stat = 'Dex' #m was dnd_globals["stats"]['Dex'] 1.5002 1475 stat = 'Dex'
1792 temp = self.ranged 1476 temp = self.ranged
1793 stat_mod = -7 1477 stat_mod = -7
1794 stat_mod = self.root.abilities.get_mod(stat) #a 1.5002 1478 stat_mod = self.root.abilities.get_mod(stat)
1795 #print "Big test - stat_mod",stat_mod #a (debug) 1.6000
1796 base = int(temp.get('base')) 1479 base = int(temp.get('base'))
1797 base2 = int(temp.get('second')) 1480 base2 = int(temp.get('second'))
1798 base3 = int(temp.get('third')) 1481 base3 = int(temp.get('third'))
1799 base4 = int(temp.get('forth')) 1482 base4 = int(temp.get('forth'))
1800 base5 = int(temp.get('fifth')) 1483 base5 = int(temp.get('fifth'))
1805 def on_rclick(self,evt): 1488 def on_rclick(self,evt):
1806 item = self.tree.GetSelection() 1489 item = self.tree.GetSelection()
1807 1490
1808 name = self.tree.GetItemText(item) 1491 name = self.tree.GetItemText(item)
1809 if item == self.mytree_node: 1492 if item == self.mytree_node:
1810 #print "bail due to FUD" 1493 return
1811 return #a 1.6015
1812 #dnd3e_char_child.on_ldclick(self,evt)#d 1.6015
1813 #self.frame.add_panel(self.get_design_panel(self.frame.note))
1814 else: 1494 else:
1815 #print "entering attack phase" 1495
1816 mod = int(self.weapons[name].get('mod')) 1496 mod = int(self.weapons[name].get('mod'))
1817 wepMod = mod #a 1.5008 1497 wepMod = mod #a 1.5008
1818 footNotes = safeGetAttr(self.weapons[name],'fn','') 1498 footNotes = safeGetAttr(self.weapons[name],'fn','')
1819 cat = self.weapons[name].get('category') #a1.6001 1499 cat = self.weapons[name].get('category') #a1.6001
1820 result = split(cat,"-",2) #a 1.6001 1500 result = split(cat,"-",2) #a 1.6001
1824 print "the hyphen. Assuming Melee" 1504 print "the hyphen. Assuming Melee"
1825 print "weapon name: ",name 1505 print "weapon name: ",name
1826 tres="Melee" 1506 tres="Melee"
1827 else: 1507 else:
1828 tres=result[1] 1508 tres=result[1]
1829 #print "print FootNotes,tres",footNotes,tres
1830 if tres == 'Melee': #a 1.6001 #m 1.6022 use of tres here and... 1509 if tres == 'Melee': #a 1.6001 #m 1.6022 use of tres here and...
1831 #if self.weapons[name].get('range') == '0':#d 1.6001
1832 rangeOrMelee = 'm' #a 1.5008 code demote for next comment block 1510 rangeOrMelee = 'm' #a 1.5008 code demote for next comment block
1833 elif tres == 'Ranged': #m 1.6001 (was just else) #m 1.6022 here 1511 elif tres == 'Ranged': #m 1.6001 (was just else) #m 1.6022 here
1834 rangeOrMelee = 'r' #a 1.5008 1512 rangeOrMelee = 'r' #a 1.5008
1835 else:#a 1.6001 add this whole else clause. 1513 else:#a 1.6001 add this whole else clause.
1836 print "warning: 1.6001 unable to interpret weapon category" 1514 print "warning: 1.6001 unable to interpret weapon category"
1842 dmg = self.weapons[name].get('damage') 1520 dmg = self.weapons[name].get('damage')
1843 1521
1844 #a 1.6003 start code fix instance a 1522 #a 1.6003 start code fix instance a
1845 result = split(dmg,"/",2) 1523 result = split(dmg,"/",2)
1846 dmg = result[0] 1524 dmg = result[0]
1847 #print "1.6003 check:dmg",dmg,";result",result
1848 #o currently, only picking out dmg; rest are simply ignored.
1849 #o May be usefull
1850 #o later for two weapon attack correction.
1851 #a 1.6003 end code fix instance a
1852
1853 monkLvl = self.root.classes.get_class_lvl('Monk') # a 1.5002 1525 monkLvl = self.root.classes.get_class_lvl('Monk') # a 1.5002
1854 #print "monkLvl",monkLvl #a (debug) 1.5002
1855 # monkLvl = dnd_globals["class"]["lvl"] #d 1.5002
1856 if dmg == "Monk Med": 1526 if dmg == "Monk Med":
1857 if monkLvl == None: #a 1.5009 1527 if monkLvl == None: #a 1.5009
1858 txt = 'Attempting to use monk attack, but has no monk ' 1528 txt = 'Attempting to use monk attack, but has no monk '
1859 txt += 'levels, please choose a different attack.' 1529 txt += 'levels, please choose a different attack.'
1860 chat.ParsePost( txt, True, True ) #a 1.5009 1530 chat.ParsePost( txt, True, True ) #a 1.5009
1861 return #a 1.5009 1531 return #a 1.5009
1862 else: #a 1.5009 1532 else: #a 1.5009
1863 lvl=int(monkLvl) 1533 lvl=int(monkLvl)
1864 if lvl <= 3: #m 1.6022 reversed the order of checks. 1534 if lvl <= 3: dmg = "1d6"
1865 dmg = "1d6" 1535 elif lvl <= 7: dmg = "1d8"
1866 elif lvl <= 7: 1536 elif lvl <= 11: dmg = "1d10"
1867 dmg = "1d8" 1537 elif lvl <= 15: dmg = "2d6"
1868 elif lvl <= 11: 1538 elif lvl <= 19: dmg = "2d8"
1869 dmg = "1d10" 1539 elif lvl <= 20: dmg = "2d10"
1870 elif lvl <= 15:
1871 dmg = "2d6"
1872 elif lvl <= 19:
1873 dmg = "2d8"
1874 elif lvl <= 20:
1875 dmg = "2d10"
1876 if dmg == "Monk Small": 1540 if dmg == "Monk Small":
1877 if monkLvl == None: #a 1.5009 1541 if monkLvl == None:
1878 txt = 'Attempting to use monk attack, but has no monk ' 1542 txt = 'Attempting to use monk attack, but has no monk '
1879 txt += 'levels, please choose a different attack.' 1543 txt += 'levels, please choose a different attack.'
1880 chat.ParsePost( txt, True, True ) #a 1.5009 1544 chat.ParsePost( txt, True, True )
1881 return #a 1.5009 1545 return
1882 else: #a 1.5009 1546 else:
1883 lvl=int(monkLvl) 1547 lvl=int(monkLvl)
1884 if lvl <= 3: #m 1.6022 reversed the order of the checks 1548 if lvl <= 3: dmg = "1d4"
1885 dmg = "1d4" 1549 elif lvl <= 7: dmg = "1d6"
1886 elif lvl <= 7: 1550 elif lvl <= 11: dmg = "1d8"
1887 dmg = "1d6" 1551 elif lvl <= 15: dmg = "1d10"
1888 elif lvl <= 11: 1552 elif lvl <= 20: dmg = "2d6"
1889 dmg = "1d8"
1890 elif lvl <= 15:
1891 dmg = "1d10"
1892 elif lvl <= 20:
1893 dmg = "2d6"
1894 flu = '' 1553 flu = ''
1895 #print "adjusted weapon damage is:",dmg
1896 #o 1.5007 str bow
1897 #o 1.5011 start looking about here str dam bonus missed for thrown?
1898 #o 1.5012 start looking about here str penalty missed for bow/sling?
1899 #o 1.5013 off-hand attacks.? dam and all affects?
1900 str_mod = self.root.abilities.get_mod('Str') #a 1.5007,11,12,13 1554 str_mod = self.root.abilities.get_mod('Str') #a 1.5007,11,12,13
1901 if rangeOrMelee == 'r': #a 1.5008 1555 if rangeOrMelee == 'r': #a 1.5008
1902 #if off_hand == True then stat_mod = stat_mod/2 #o 1.5013 1556
1903 #c 1.5007 ranged weapons normally get no str mod 1557 if find(footNotes,'b') > -1:
1904 if find(footNotes,'b') > -1:#a 1.5012 if it's a bow 1558 if str_mod >= 0: str_mod = 0
1905 if str_mod >= 0: #a 1.5012 never a str bonus 1559 else: str_mod = 0
1906 str_mod = 0 #a 1.5012 penalty, 1560 mod2 = ""
1907 else: #a 1.5012 if appropriate 1561 if str_mod >= 0: mod2 = "+"
1908 str_mod = 0
1909 # c 1.5007 (must adjust for str bows later and thown weapons)
1910 #o 1.5007 include + for str bows
1911 #o 1.5012 include any str penalty for bows/slings.
1912 mod2 = "" #a 1.5007,11-13
1913 if str_mod >= 0: #1.6 tidy up code.
1914 mod2 = "+" #1.6 tidy up code.
1915 aStrengthMod = mod2 + str(str_mod) #a 1.5008 applicable strength mod 1562 aStrengthMod = mod2 + str(str_mod) #a 1.5008 applicable strength mod
1916
1917 #if name == "Flurry of Blows(Monk Med)": #d 1.6012
1918 if find(name ,"Flurry of Blows") > -1: #a 1.6012 1563 if find(name ,"Flurry of Blows") > -1: #a 1.6012
1919 flu = '-2' 1564 flu = '-2'
1920
1921 (base, base2, base3, base4, base5, base6, stat_mod, misc)\ 1565 (base, base2, base3, base4, base5, base6, stat_mod, misc)\
1922 = self.get_attack_data(rangeOrMelee) #a 1.5008 1566 = self.get_attack_data(rangeOrMelee) #a 1.5008
1923 self.sendRoll(base ,stat_mod,misc,wepMod,name,flu,dmg, 1567 self.sendRoll(base ,stat_mod,misc,wepMod,name,flu,dmg,
1924 aStrengthMod,'',True,rollAnyWay=True) 1568 aStrengthMod,'',True,rollAnyWay=True)
1925 if flu != '': 1569 if flu != '':
1935 1579
1936 def sendRoll(self,base,stat_mod,misc,wepMod,name,flu,dmg,aStrengthMod, 1580 def sendRoll(self,base,stat_mod,misc,wepMod,name,flu,dmg,aStrengthMod,
1937 spacer="",pname=False,rollAnyWay=False): 1581 spacer="",pname=False,rollAnyWay=False):
1938 if base != 0 or rollAnyWay: 1582 if base != 0 or rollAnyWay:
1939 base = base + int(stat_mod) + misc + wepMod #m 1.5008 1583 base = base + int(stat_mod) + misc + wepMod #m 1.5008
1940 if base >= 0: 1584 if base >= 0: mod1 = "+"
1941 mod1 = "+" 1585 else: mod1 = ""
1942 else:
1943 mod1 = ""
1944 txt = '%s ' % (spacer) 1586 txt = '%s ' % (spacer)
1945 txt += '%s Attack Roll: <b>[1d20%s%s%s]</b>' % (name, mod1, base, flu) 1587 txt += '%s Attack Roll: <b>[1d20%s%s%s]</b>' % (name, mod1, base, flu)
1946 txt += ' ===> Damage: <b>[%s%s]</b>' % (dmg, aStrengthMod) 1588 txt += ' ===> Damage: <b>[%s%s]</b>' % (dmg, aStrengthMod)
1947 self.chat.ParsePost( txt, True, True ) 1589 self.chat.ParsePost( txt, True, True )
1948 1590
1970 html_str += "<td>"+str(ranged[2])+"</td></tr></table>" 1612 html_str += "<td>"+str(ranged[2])+"</td></tr></table>"
1971 1613
1972 n_list = self.xml.findall('weapon') 1614 n_list = self.xml.findall('weapon')
1973 for n in n_list: 1615 for n in n_list:
1974 mod = n.get('mod') 1616 mod = n.get('mod')
1975 if mod >= 0: 1617 if mod >= 0: mod1 = "+"
1976 mod1 = "+" 1618 else: mod1 = ""
1977 else:
1978 mod1 = ""
1979 ran = n.get('range') 1619 ran = n.get('range')
1980 total = str(int(mod) + self.get_mod(ran)) 1620 total = str(int(mod) + self.get_mod(ran))
1981 html_str += """<P><table width=100% border=1 ><tr BGCOLOR=#E9E9E9 > 1621 html_str += """<P><table width=100% border=1 ><tr BGCOLOR=#E9E9E9 >
1982 <th colspan=2>Weapon</th> 1622 <th colspan=2>Weapon</th>
1983 <th>Attack</th><th >Damage</th><th>Critical</th></tr>""" 1623 <th>Attack</th><th >Damage</th><th>Critical</th></tr>"""
1990 html_str += "<tr ALIGN='center'><td>"+ran+"</td><td>" 1630 html_str += "<tr ALIGN='center'><td>"+ran+"</td><td>"
1991 html_str += n.get('weight')+"</td>" 1631 html_str += n.get('weight')+"</td>"
1992 html_str += "<td>"+n.get('type')+"</td><td>" 1632 html_str += "<td>"+n.get('type')+"</td><td>"
1993 html_str += n.get('size')+"</td>" 1633 html_str += n.get('size')+"</td>"
1994 html_str += '<td>%s%s</td></tr>' % (mod1, mod) 1634 html_str += '<td>%s%s</td></tr>' % (mod1, mod)
1995 #a 1.5012 add next two lines to pretty print footnotes.
1996 html_str += """<tr><th BGCOLOR=#E9E9E9 colspan=2>Footnotes:</th>""" 1635 html_str += """<tr><th BGCOLOR=#E9E9E9 colspan=2>Footnotes:</th>"""
1997 html_str += "<th colspan=3>"+safeGetAttr(n,'fn','')+"</th></tr>" 1636 html_str += "<th colspan=3>"+safeGetAttr(n,'fn','')+"</th></tr>"
1998 html_str += '</table>' 1637 html_str += '</table>'
1999 return html_str 1638 return html_str
2000 1639
2001 class attack_grid(wx.grid.Grid): 1640 class attack_grid(wx.grid.Grid):
2002 """grid for attacks""" 1641 """grid for attacks"""
2003 def __init__(self, parent, handler): 1642 def __init__(self, parent, handler):
2004 pname = handler.xml.set("name", 'Melee') 1643 pname = handler.xml.set("name", 'Melee')
2005 self.hparent = handler #a 1.5002 allow ability to run up tree. 1644 self.hparent = handler
2006 #a 1.5002 we need the functional parent, not the invoking parent.
2007
2008 wx.grid.Grid.__init__(self, parent, -1, style=wx.SUNKEN_BORDER | wx.WANTS_CHARS) 1645 wx.grid.Grid.__init__(self, parent, -1, style=wx.SUNKEN_BORDER | wx.WANTS_CHARS)
2009 1646
2010 self.root = getRoot(self) #a 1.9001 1647 self.root = getRoot(self) #a 1.9001
2011 self.parent = parent 1648 self.parent = parent
2012 self.handler = handler 1649 self.handler = handler
2013 self.rows = (self.handler.melee,self.handler.ranged) 1650 self.rows = (self.handler.melee,self.handler.ranged)
2014 self.CreateGrid(2,10) 1651 self.CreateGrid(2,10)
2015 self.SetRowLabelSize(0) 1652 self.SetRowLabelSize(0)
2016 col_names = ['Type','base','base 2','base 3','base 4','base 5', 1653 col_names = ['Type','base','base 2','base 3','base 4','base 5',
2017 'base 6','abil','misc','Total'] 1654 'base 6','abil','misc','Total']
2018 for i in range(len(col_names)): 1655 for i in range(len(col_names)): self.SetColLabelValue(i,col_names[i])
2019 self.SetColLabelValue(i,col_names[i])
2020 self.SetCellValue(0,0,"Melee") 1656 self.SetCellValue(0,0,"Melee")
2021 self.SetCellValue(1,0,"Ranged") 1657 self.SetCellValue(1,0,"Ranged")
2022 self.refresh_data() 1658 self.refresh_data()
2023 self.Bind(wx.EVT_SIZE, self.on_size) 1659 self.Bind(wx.EVT_SIZE, self.on_size)
2024 self.Bind(wx.grid.EVT_GRID_CELL_CHANGE, self.on_cell_change) 1660 self.Bind(wx.grid.EVT_GRID_CELL_CHANGE, self.on_cell_change)
2025 #print "looking for containing frame"
2026
2027 #a 1.9001 remainder of code in this method.
2028 climber = parent 1661 climber = parent
2029 nameNode = climber.GetClassName() 1662 nameNode = climber.GetClassName()
2030 while nameNode != 'wxFrame': 1663 while nameNode != 'wxFrame':
2031 climber = climber.parent 1664 climber = climber.parent
2032 nameNode = climber.GetClassName() 1665 nameNode = climber.GetClassName()
2033 masterFrame=climber 1666 masterFrame=climber
2034 masterFrame.refreshMRdata=self.refresh_data 1667 masterFrame.refreshMRdata=self.refresh_data
2035 #print getmembers(masterFrame)
2036
2037 handler.mrFrame.append(masterFrame) 1668 handler.mrFrame.append(masterFrame)
2038
2039 #print "masterFrame=",masterFrame
2040 #print "mr.Show=",masterFrame.Show()
2041 #print "mf.GetName",masterFrame.GetName()
2042 #print "mf.GetClassName",masterFrame.GetClassName()
2043 #print "mf.GetId",masterFrame.GetId()
2044 #print "mf.GetLabel",masterFrame.GetLabel()
2045 #print "mf.GetHandle",masterFrame.GetHandle()
2046 #print "mf.GetParent",masterFrame.GetParent()
2047 # here, GetParent consistent returns the master frame of the app.
2048 #print "mf.GetGParent",masterFrame.GetGrandParent() #here, always None
2049 #print "mf.GetTitle",masterFrame.GetTitle()
2050 #print "mf.IsEnabled",masterFrame.IsEnabled()
2051 #print "mf.IsShown",masterFrame.IsShown()
2052 #print "mf.IsTopLevel",masterFrame.IsTopLevel()
2053 #print "self.frame=",self.frame
2054 1669
2055 1670
2056 def on_cell_change(self,evt): 1671 def on_cell_change(self,evt):
2057 row = evt.GetRow() 1672 row = evt.GetRow()
2058 col = evt.GetCol() 1673 col = evt.GetCol()
2059 value = self.GetCellValue(row,col) 1674 value = self.GetCellValue(row,col)
2060 try: 1675 try:
2061 int(value) 1676 int(value)
2062 if col==1: 1677 if col==1: self.rows[row].set('base',value)
2063 self.rows[row].set('base',value) 1678 elif col==2: self.rows[row].set('second',value)
2064 elif col==2: 1679 elif col==3: self.rows[row].set('third',value)
2065 self.rows[row].set('second',value) 1680 elif col==4: self.rows[row].set('forth',value)
2066 elif col==3: 1681 elif col==5: self.rows[row].set('fifth',value)
2067 self.rows[row].set('third',value) 1682 elif col==6: self.rows[row].set('sixth',value)
2068 elif col==4: 1683 elif col==8: self.rows[row].set('misc',value)
2069 self.rows[row].set('forth',value)
2070 elif col==5:
2071 self.rows[row].set('fifth',value)
2072 elif col==6:
2073 self.rows[row].set('sixth',value)
2074 elif col==8:
2075 self.rows[row].set('misc',value)
2076 #print "row:",row,"value",value,self.rows[row]
2077 self.parent.refresh_data() 1684 self.parent.refresh_data()
2078 except: 1685 except: self.SetCellValue(row,col,"0")
2079 self.SetCellValue(row,col,"0")
2080 1686
2081 def refresh_data(self): 1687 def refresh_data(self):
2082
2083 melee = self.handler.get_attack_data('m') 1688 melee = self.handler.get_attack_data('m')
2084 ranged = self.handler.get_attack_data('r') 1689 ranged = self.handler.get_attack_data('r')
2085 tmelee = int(melee[0]) + int(melee[6]) + int(melee[7]) 1690 tmelee = int(melee[0]) + int(melee[6]) + int(melee[7])
2086 tranged = int(ranged[0]) + int(ranged[6]) + int(ranged[7]) 1691 tranged = int(ranged[0]) + int(ranged[6]) + int(ranged[7])
2087 # for i in range(0,7): #d 1.5005
2088 for i in range(0,8): #a 1.5005 1692 for i in range(0,8): #a 1.5005
2089 self.SetCellValue(0,i+1,str(melee[i])) 1693 self.SetCellValue(0,i+1,str(melee[i]))
2090 self.SetCellValue(1,i+1,str(ranged[i])) 1694 self.SetCellValue(1,i+1,str(ranged[i]))
2091 self.SetCellValue(0,9,str(tmelee)) 1695 self.SetCellValue(0,9,str(tmelee))
2092 self.SetCellValue(1,9,str(tranged)) 1696 self.SetCellValue(1,9,str(tranged))
2095 self.SetReadOnly(0,7) 1699 self.SetReadOnly(0,7)
2096 self.SetReadOnly(1,7) 1700 self.SetReadOnly(1,7)
2097 self.SetReadOnly(0,9) 1701 self.SetReadOnly(0,9)
2098 self.SetReadOnly(1,9) 1702 self.SetReadOnly(1,9)
2099 1703
2100
2101 def on_size(self,evt): 1704 def on_size(self,evt):
2102 (w,h) = self.GetClientSizeTuple() 1705 (w,h) = self.GetClientSizeTuple()
2103 cols = self.GetNumberCols() 1706 cols = self.GetNumberCols()
2104 col_w = w/(cols+1) 1707 col_w = w/(cols+1)
2105 self.SetColSize(0,col_w*2) 1708 self.SetColSize(0,col_w*2)
2106 for i in range(1,cols): 1709 for i in range(1,cols): self.SetColSize(i,col_w)
2107 self.SetColSize(i,col_w)
2108 evt.Skip() 1710 evt.Skip()
2109 self.Refresh() 1711 self.Refresh()
2110 1712
2111 class weapon_panel(wx.Panel): 1713 class weapon_panel(wx.Panel):
2112 def __init__(self, parent, handler): 1714 def __init__(self, parent, handler):
2113 self.hparent = handler #a 1.5012 1715 self.hparent = handler
2114 self.root = getRoot(self) 1716 self.root = getRoot(self)
2115
2116 pname = handler.xml.set("name", 'Weapons') 1717 pname = handler.xml.set("name", 'Weapons')
2117
2118 wx.Panel.__init__(self, parent, -1) 1718 wx.Panel.__init__(self, parent, -1)
2119 self.grid =wx.grid.Grid(self, -1, style=wx.SUNKEN_BORDER | wx.WANTS_CHARS) 1719 self.grid =wx.grid.Grid(self, -1, style=wx.SUNKEN_BORDER | wx.WANTS_CHARS)
2120 sizer = wx.BoxSizer(wx.VERTICAL) 1720 sizer = wx.BoxSizer(wx.VERTICAL)
2121 sizer.Add(self.grid, 1, wx.EXPAND) 1721 sizer.Add(self.grid, 1, wx.EXPAND)
2122
2123 sizer2 = wx.BoxSizer(wx.HORIZONTAL) 1722 sizer2 = wx.BoxSizer(wx.HORIZONTAL)
2124 sizer2.Add(wx.Button(self, 10, "Remove Weapon"), 0, wx.EXPAND) 1723 sizer2.Add(wx.Button(self, 10, "Remove Weapon"), 0, wx.EXPAND)
2125 sizer2.Add(wx.Size(10,10)) 1724 sizer2.Add(wx.Size(10,10))
2126 sizer2.Add(wx.Button(self, 20, "Add Weapon"), 0, wx.EXPAND) 1725 sizer2.Add(wx.Button(self, 20, "Add Weapon"), 0, wx.EXPAND)
2127
2128 sizer.Add(sizer2, 0, wx.EXPAND) 1726 sizer.Add(sizer2, 0, wx.EXPAND)
2129 sizer.Add(wx.StaticText(self, -1, "Right click a weapon's footnote to see what the footnotes mean."),0, wx.EXPAND)#a 1.5012 1727 sizer.Add(wx.StaticText(self, -1, "Right click a weapon's footnote to see what the footnotes mean."),0, wx.EXPAND)#a 1.5012
2130 self.sizer = sizer 1728 self.sizer = sizer
2131 self.SetSizer(self.sizer) 1729 self.SetSizer(self.sizer)
2132 self.SetAutoLayout(True) 1730 self.SetAutoLayout(True)
2133 self.Fit() 1731 self.Fit()
2134
2135 self.sizer2 = sizer2 1732 self.sizer2 = sizer2
2136 #self.Bind(wx.EVT_SIZE, self.on_size)
2137 self.Bind(wx.EVT_BUTTON, self.on_remove, id=10) 1733 self.Bind(wx.EVT_BUTTON, self.on_remove, id=10)
2138 self.Bind(wx.EVT_BUTTON, self.on_add, id=20) 1734 self.Bind(wx.EVT_BUTTON, self.on_add, id=20)
2139 self.grid.Bind(wx.grid.EVT_GRID_CELL_CHANGE, self.on_cell_change) 1735 self.grid.Bind(wx.grid.EVT_GRID_CELL_CHANGE, self.on_cell_change)
2140 self.grid.Bind(wx.grid.EVT_GRID_CELL_RIGHT_CLICK, self.on_gridRclick)#a 1.5012 1736 self.grid.Bind(wx.grid.EVT_GRID_CELL_RIGHT_CLICK, self.on_gridRclick)#a 1.5012
2141 1737
2142 n_list = handler.xml.findall('weapon') 1738 n_list = handler.xml.findall('weapon')
2143 self.n_list = n_list 1739 self.n_list = n_list
2144 self.xml = handler.xml 1740 self.xml = handler.xml
2145 self.handler = handler 1741 self.handler = handler
2146 #trash=input("weapon panel init colnames")
2147 self.colAttr = ['name','damage','mod','critical','type','weight', 1742 self.colAttr = ['name','damage','mod','critical','type','weight',
2148 'range','size','Total','fn', 'comment'] #a 1.5012 1743 'range','size','Total','fn', 'comment']
2149 col_names = ['Name','Damage','To hit\nmod','Critical','Type','Weight', 1744 col_names = ['Name','Damage','To hit\nmod','Critical','Type','Weight',
2150 'Range','Size','Total','Foot\nnotes','Comment'] #a 1.5012 1745 'Range','Size','Total','Foot\nnotes','Comment']
2151 gridColCount=len(col_names)#a 1.5012 1746 gridColCount=len(col_names)
2152 self.grid.CreateGrid(len(n_list),gridColCount,1) #a 1.5012 1747 self.grid.CreateGrid(len(n_list),gridColCount,1)
2153 #self.grid.CreateGrid(len(n_list),9,1) #d 1.5012
2154 self.grid.SetRowLabelSize(0) 1748 self.grid.SetRowLabelSize(0)
2155 #col_names = ['Name','damage','mod','critical','type','weight','range', 'size','Total'] #d 1.5012 1749 for i in range(gridColCount): self.grid.SetColLabelValue(i,col_names[i])
2156 #for i in range(len(col_names)): #d 1.5012
2157 for i in range(gridColCount): #a 1.5012
2158 self.grid.SetColLabelValue(i,col_names[i])
2159 self.refresh_data() 1750 self.refresh_data()
2160 self.temp_dom = None 1751 self.temp_dom = None
2161 1752
2162 1753
2163 #mark4 1754 #mark4
2164 #a 1.5012 add entire method. 1755 #a 1.5012 add entire method.
2165 def on_gridRclick(self,evt): 1756 def on_gridRclick(self,evt):
2166 #print "weapon_panel, on_rclick: self,evt",self,evt
2167 row = evt.GetRow() 1757 row = evt.GetRow()
2168 col = evt.GetCol() 1758 col = evt.GetCol()
2169 value = self.grid.GetCellValue(row,col) 1759 value = self.grid.GetCellValue(row,col)
2170 #print "wp, on rclick,grid row,col,value",row,col,value
2171 if col == 9 and value != 'None': 1760 if col == 9 and value != 'None':
2172 n = self.n_list[row] 1761 n = self.n_list[row]
2173 name = n.get('name') 1762 name = n.get('name')
2174 #print "we want a panel!"
2175 handler = self.hparent 1763 handler = self.hparent
2176 #print "handler:",handler
2177 # A handler is a node, and nodes have a reference to 1764 # A handler is a node, and nodes have a reference to
2178 # the master frame 1765 # the master frame
2179 masterFrame = handler.frame 1766 masterFrame = handler.frame
2180 #print "masterFrame:",masterFrame
2181 title = name+"'s Special Weapon Characteristics" 1767 title = name+"'s Special Weapon Characteristics"
2182 fnFrame = wx.Frame(masterFrame, -1, title) 1768 fnFrame = wx.Frame(masterFrame, -1, title)
2183 fnFrame.panel = wx.html.HtmlWindow(fnFrame,-1) 1769 fnFrame.panel = wx.html.HtmlWindow(fnFrame,-1)
2184 if not self.temp_dom: 1770 if not self.temp_dom:
2185 tree = parse(dir_struct["dnd3e"]+"dnd3eweapons.xml") 1771 tree = parse(dir_struct["dnd3e"]+"dnd3eweapons.xml")
2186 xml_dom = tree.getroot() 1772 xml_dom = tree.getroot()
2187 self.temp_dom = xml_dom 1773 self.temp_dom = xml_dom
2188 f_list = self.temp_dom.findall('f') # the footnotes 1774 f_list = self.temp_dom.findall('f') # the footnotes
2189 #print "weapon_panel - on_rclick f_list",f_list#a 1.6
2190 n = self.n_list[row] 1775 n = self.n_list[row]
2191 name = n.get('name') 1776 name = n.get('name')
2192 footnotes = n.get('fn') 1777 footnotes = n.get('fn')
2193 html_str = "<html><body>" 1778 html_str = "<html><body>"
2194 html_str += """<table border='1' width=100% ><tr BGCOLOR=#E9E9E9 > 1779 html_str += """<table border='1' width=100% ><tr BGCOLOR=#E9E9E9 >
2195 <th width='10%'>Note</th><th>Description</th></tr>\n""" 1780 <th width='10%'>Note</th><th>Description</th></tr>\n"""
2196 #print "rclick,name,fn",name,footnotes
2197 if footnotes == "": 1781 if footnotes == "":
2198 html_str += "<tr ALIGN='center'><td></td>" 1782 html_str += "<tr ALIGN='center'><td></td>"
2199 html_str += " <td>This weapon has no footnotes</td></tr>" 1783 html_str += " <td>This weapon has no footnotes</td></tr>"
2200 for i in range(len(footnotes)): 1784 for i in range(len(footnotes)):
2201 aNote=footnotes[i] 1785 aNote=footnotes[i]
2210 html_str += ("<tr ALIGN='center'><td>"+aNote+"</td>"+ 1794 html_str += ("<tr ALIGN='center'><td>"+aNote+"</td>"+
2211 "<td>is not a recognized footnote</td></tr>\n") 1795 "<td>is not a recognized footnote</td></tr>\n")
2212 1796
2213 html_str += "</table>" 1797 html_str += "</table>"
2214 html_str += "</body> </html> " 1798 html_str += "</body> </html> "
2215
2216 #print html_str
2217 fnFrame.panel.SetPage(html_str) 1799 fnFrame.panel.SetPage(html_str)
2218 fnFrame.Show() 1800 fnFrame.Show()
2219 return 1801 return
2220 pass 1802 pass
2221
2222 1803
2223 1804
2224 def on_cell_change(self,evt): 1805 def on_cell_change(self,evt):
2225 row = evt.GetRow() 1806 row = evt.GetRow()
2226 col = evt.GetCol() 1807 col = evt.GetCol()
2230 self.n_list[row].set('mod',value) # a 5.012 demoted 1811 self.n_list[row].set('mod',value) # a 5.012 demoted
2231 if not (col == 9 and value == "None" and 1812 if not (col == 9 and value == "None" and
2232 self.n_list[row].get('fn') == "None" 1813 self.n_list[row].get('fn') == "None"
2233 ): #a 5.012 special case for footnotes 1814 ): #a 5.012 special case for footnotes
2234 self.n_list[row].set(self.colAttr[col],value)#a 5.012 1815 self.n_list[row].set(self.colAttr[col],value)#a 5.012
2235 #print "cell change",row,col,value
2236 #if col == 0:#d 5.012 use of colAttr removed need for this.
2237 # self.n_list[row].set('name',value) #d 5.012
2238 #elif col == 2: #d 5.012
2239 # try:#d 5.012 simplifying... remove this block.
2240 # int(value)
2241 # self.n_list[row].set('mod',value)
2242 # #self.refresh_row(row) #d 5.012 did nothing.
2243 # except:
2244 # value = "0"
2245 # self.n_list[row].set('mod',value)
2246 #else: #d 5.012 demoted self.n set.
2247 # self.n_list[row].set(self.grid.GetColLabelValue(col),value)
2248 1816
2249 1817
2250 def refresh_row(self,i): 1818 def refresh_row(self,i):
2251 n = self.n_list[i] 1819 n = self.n_list[i]
2252 fn = n.get('fn') 1820 fn = n.get('fn')
2253 #print "fn=",fn
2254 name = n.get('name') 1821 name = n.get('name')
2255 mod = n.get('mod') 1822 mod = n.get('mod')
2256 ran = n.get('range') 1823 ran = n.get('range')
2257 total = str(int(mod) + self.handler.get_mod(ran)) 1824 total = str(int(mod) + self.handler.get_mod(ran))
2258 self.grid.SetCellValue(i,0,name) 1825 self.grid.SetCellValue(i,0,name)
2264 self.grid.SetCellValue(i,6,ran) 1831 self.grid.SetCellValue(i,6,ran)
2265 self.grid.SetCellValue(i,7,n.get('size') ) 1832 self.grid.SetCellValue(i,7,n.get('size') )
2266 self.grid.SetCellValue(i,8,total) 1833 self.grid.SetCellValue(i,8,total)
2267 self.grid.SetCellValue(i,9,safeGetAttr(n,'fn','None')) #a 1.5012 1834 self.grid.SetCellValue(i,9,safeGetAttr(n,'fn','None')) #a 1.5012
2268 self.grid.SetCellValue(i,10,safeGetAttr(n,'comment','')) #a 1.5012 1835 self.grid.SetCellValue(i,10,safeGetAttr(n,'comment','')) #a 1.5012
2269 #fn=safeGetAttr(n,'fn','None') #a (debug) 1.5012
2270 #print "fn ",fn,"<" #a (debug) 1.5012
2271 #o 1.5012 original damage vs what someone has changed it to.
2272
2273 self.grid.SetReadOnly(i,8) 1836 self.grid.SetReadOnly(i,8)
2274 1837
2275 def on_remove(self,evt): #o 1.6011 correcting wrongful deletion 1838 def on_remove(self,evt): #o 1.6011 correcting wrongful deletion
2276 rows = self.grid.GetNumberRows() 1839 rows = self.grid.GetNumberRows()
2277 #for i in range(rows): #d 1.6011 do it backwards,
2278 for i in range(rows-1,-1,-1): #a 1.6011 or you lose context 1840 for i in range(rows-1,-1,-1): #a 1.6011 or you lose context
2279 if self.grid.IsInSelection(i,0): 1841 if self.grid.IsInSelection(i,0):
2280 self.grid.DeleteRows(i) 1842 self.grid.DeleteRows(i)
2281 self.xml.remove(self.n_list[i]) 1843 self.xml.remove(self.n_list[i])
2282 self.n_list = self.xml.findall('weapon') 1844 self.n_list = self.xml.findall('weapon')
2287 tree = parse(dir_struct["dnd3e"]+"dnd3eweapons.xml") 1849 tree = parse(dir_struct["dnd3e"]+"dnd3eweapons.xml")
2288 xml_dom = tree.getroot() 1850 xml_dom = tree.getroot()
2289 self.temp_dom = xml_dom 1851 self.temp_dom = xml_dom
2290 f_list = self.temp_dom.findall('weapon') 1852 f_list = self.temp_dom.findall('weapon')
2291 opts = [] 1853 opts = []
2292 #print "weapon_panel - on_add f_list",f_list#a 1.6
2293 for f in f_list: 1854 for f in f_list:
2294 opts.append(f.get('name')) 1855 opts.append(f.get('name'))
2295 dlg = wx.SingleChoiceDialog(self,'Choose Weapon','Weapon List',opts) 1856 dlg = wx.SingleChoiceDialog(self,'Choose Weapon','Weapon List',opts)
2296 if dlg.ShowModal() == wx.ID_OK: 1857 if dlg.ShowModal() == wx.ID_OK:
2297 i = dlg.GetSelection() 1858 i = dlg.GetSelection()
2298 #print f_list[i] # DOM Element: weapon.
2299 new_node = self.xml.append(f_list[i]) 1859 new_node = self.xml.append(f_list[i])
2300 #print self.grid.AppendRows # a bound method of wxGrid
2301 self.grid.AppendRows(1) 1860 self.grid.AppendRows(1)
2302 self.n_list = self.xml.findall('weapon') 1861 self.n_list = self.xml.findall('weapon')
2303 #print "self.n_list",self.n_list # list of DOM weapons
2304 self.refresh_row(self.grid.GetNumberRows()-1) 1862 self.refresh_row(self.grid.GetNumberRows()-1)
2305 self.handler.refresh_weapons() 1863 self.handler.refresh_weapons()
2306 dlg.Destroy() 1864 dlg.Destroy()
2307 1865
2308 def on_size(self,event): 1866 def on_size(self,event):
2312 self.sizer2.SetDimension(0,s[1]-15,s[0],15) 1870 self.sizer2.SetDimension(0,s[1]-15,s[0],15)
2313 (w,h) = self.grid.GetClientSizeTuple() 1871 (w,h) = self.grid.GetClientSizeTuple()
2314 cols = self.grid.GetNumberCols() 1872 cols = self.grid.GetNumberCols()
2315 col_w = w/(cols+1) 1873 col_w = w/(cols+1)
2316 self.grid.SetColSize(0,col_w*2) 1874 self.grid.SetColSize(0,col_w*2)
2317 for i in range(1,cols): 1875 for i in range(1,cols): self.grid.SetColSize(i,col_w)
2318 self.grid.SetColSize(i,col_w)
2319 1876
2320 def refresh_data(self): 1877 def refresh_data(self):
2321 1878 for i in range(len(self.n_list)): self.refresh_row(i)
2322 for i in range(len(self.n_list)):
2323 self.refresh_row(i)
2324 1879
2325 1880
2326 class attack_panel(wx.Panel): 1881 class attack_panel(wx.Panel):
2327 def __init__(self, parent, handler): 1882 def __init__(self, parent, handler):
2328 pname = handler.xml.set("name", 'Melee') 1883 pname = handler.xml.set("name", 'Melee')
2329 self.parent = parent #a 1.9001 1884 self.parent = parent #a 1.9001
2330
2331 wx.Panel.__init__(self, parent, -1) 1885 wx.Panel.__init__(self, parent, -1)
2332
2333 self.a_grid = attack_grid(self, handler) 1886 self.a_grid = attack_grid(self, handler)
2334 self.w_panel = weapon_panel(self, handler) 1887 self.w_panel = weapon_panel(self, handler)
2335 self.sizer = wx.BoxSizer(wx.VERTICAL) 1888 self.sizer = wx.BoxSizer(wx.VERTICAL)
2336 self.sizer.Add(self.a_grid, 1, wx.EXPAND) 1889 self.sizer.Add(self.a_grid, 1, wx.EXPAND)
2337 self.sizer.Add(self.w_panel, 2, wx.EXPAND) 1890 self.sizer.Add(self.w_panel, 2, wx.EXPAND)
2338 self.Bind(wx.EVT_SIZE, self.on_size) 1891 self.Bind(wx.EVT_SIZE, self.on_size)
2339 1892
2340
2341 def on_size(self,event): 1893 def on_size(self,event):
2342 s = self.GetClientSizeTuple() 1894 s = self.GetClientSizeTuple()
2343 self.sizer.SetDimension(0,0,s[0],s[1]) 1895 self.sizer.SetDimension(0,0,s[0],s[1])
2344 1896
2345 def refresh_data(self): 1897 def refresh_data(self):
2346
2347 self.w_panel.refresh_data() 1898 self.w_panel.refresh_data()
2348 self.a_grid.refresh_data() 1899 self.a_grid.refresh_data()
2349 1900
2350 1901
2351 class dnd3earmor(combat_char_child): 1902 class dnd3earmor(combat_char_child):
2352 """ Node Handler for ac. This handler will be 1903 """ Node Handler for ac. This handler will be
2353 created by dnd3echar_handler. 1904 created by dnd3echar_handler.
2354 """ 1905 """
2355 def __init__(self,xml_dom,tree_node,parent): 1906 def __init__(self,xml_dom,tree_node,parent):
2356 combat_char_child.__init__(self,xml_dom,tree_node,parent) 1907 combat_char_child.__init__(self,xml_dom,tree_node,parent)
2357 self.hparent = parent #a 1.5002 allow ability to run up tree. 1908 self.hparent = parent
2358 self.root = getRoot(self) #a 1.5002 1909 self.root = getRoot(self)
2359 self.root.ac = self #a 1.6009 1910 self.root.ac = self
2360 1911
2361 def get_spell_failure(self): 1912 def get_spell_failure(self):
2362 return self.get_total('spellfailure') 1913 return self.get_total('spellfailure')
2363 1914
2364 def get_total_weight(self): 1915 def get_total_weight(self):
2369 1920
2370 def get_armor_class(self): 1921 def get_armor_class(self):
2371 ac_total = 10 1922 ac_total = 10
2372 1923
2373 ac_total += self.get_total('bonus') 1924 ac_total += self.get_total('bonus')
2374 #m 1.5009 change to hardcode dex, was incorrect gv "stat" 1925 dex_mod = self.root.abilities.get_mod('Dex')
2375 dex_mod = self.root.abilities.get_mod('Dex')#m 1.5009 hardcode dex
2376 max_dex = self.get_max_dex() 1926 max_dex = self.get_max_dex()
2377 if dex_mod < max_dex: 1927 if dex_mod < max_dex: ac_total += dex_mod
2378 ac_total += dex_mod 1928 else: ac_total += max_dex
2379 else:
2380 ac_total += max_dex
2381 return ac_total 1929 return ac_total
2382 1930
2383 def get_max_dex(self): 1931 def get_max_dex(self):
2384 armor_list = self.xml.findall('armor') 1932 armor_list = self.xml.findall('armor')
2385 dex = 10 1933 dex = 10
2386 for a in armor_list: 1934 for a in armor_list:
2387 temp = int(a.get("maxdex")) 1935 temp = int(a.get("maxdex"))
2388 if temp < dex: 1936 if temp < dex: dex = temp
2389 dex = temp
2390 return dex 1937 return dex
2391 1938
2392 def get_total(self,attr): 1939 def get_total(self,attr):
2393 armor_list = self.xml.findall('armor') 1940 armor_list = self.xml.findall('armor')
2394 total = 0 1941 total = 0
2395 for a in armor_list: 1942 for a in armor_list: total += int(a.get(attr))
2396 total += int(a.get(attr))
2397 return total 1943 return total
2398 1944
2399 def get_design_panel(self,parent): 1945 def get_design_panel(self,parent):
2400 wnd = outline_panel(parent,self,ac_panel,"Armor") 1946 wnd = outline_panel(parent,self,ac_panel,"Armor")
2401 wnd.title = "Armor" 1947 wnd.title = "Armor"
2402 return wnd 1948 return wnd
2403 1949
2404 def on_rclick( self, evt ): 1950 def on_rclick( self, evt ):
2405 ac = self.get_armor_class() 1951 ac = self.get_armor_class()
2406 fac = (int(ac)-(self.root.abilities.get_mod('Dex'))) 1952 fac = (int(ac)-(self.root.abilities.get_mod('Dex')))
2407
2408 txt = '((AC: %s Normal, %s Flatfoot))' % ( ac, fac ) #a 1.5002 1953 txt = '((AC: %s Normal, %s Flatfoot))' % ( ac, fac ) #a 1.5002
2409 self.chat.ParsePost( txt, True, True ) 1954 self.chat.ParsePost( txt, True, True )
2410 1955
2411 def tohtml(self): 1956 def tohtml(self):
2412 html_str = """<table width=100% border=1 ><tr BGCOLOR=#E9E9E9 > 1957 html_str = """<table width=100% border=1 ><tr BGCOLOR=#E9E9E9 >
2439 1984
2440 1985
2441 class ac_panel(wx.Panel): 1986 class ac_panel(wx.Panel):
2442 def __init__(self, parent, handler): 1987 def __init__(self, parent, handler):
2443 pname = handler.xml.set("name", 'Armor') 1988 pname = handler.xml.set("name", 'Armor')
2444 self.hparent = handler #a 1.5002 allow ability to run up tree. 1989 self.hparent = handler
2445 #a 1.5002 we need the functional parent, not the invoking parent.
2446
2447 wx.Panel.__init__(self, parent, -1) 1990 wx.Panel.__init__(self, parent, -1)
2448 self.grid =wx.grid.Grid(self, -1, style=wx.SUNKEN_BORDER | wx.WANTS_CHARS) 1991 self.grid =wx.grid.Grid(self, -1, style=wx.SUNKEN_BORDER | wx.WANTS_CHARS)
2449 sizer = wx.BoxSizer(wx.VERTICAL) 1992 sizer = wx.BoxSizer(wx.VERTICAL)
2450 sizer.Add(self.grid, 1, wx.EXPAND) 1993 sizer.Add(self.grid, 1, wx.EXPAND)
2451
2452 sizer1 = wx.BoxSizer(wx.HORIZONTAL) 1994 sizer1 = wx.BoxSizer(wx.HORIZONTAL)
2453 sizer1.Add(wx.Button(self, 10, "Remove Armor"), 1, wx.EXPAND) 1995 sizer1.Add(wx.Button(self, 10, "Remove Armor"), 1, wx.EXPAND)
2454 sizer1.Add(wx.Size(10,10)) 1996 sizer1.Add(wx.Size(10,10))
2455 sizer1.Add(wx.Button(self, 20, "Add Armor"), 1, wx.EXPAND) 1997 sizer1.Add(wx.Button(self, 20, "Add Armor"), 1, wx.EXPAND)
2456
2457 sizer.Add(sizer1, 0, wx.EXPAND) 1998 sizer.Add(sizer1, 0, wx.EXPAND)
2458
2459 self.sizer = sizer 1999 self.sizer = sizer
2460 self.SetSizer(self.sizer) 2000 self.SetSizer(self.sizer)
2461 self.SetAutoLayout(True) 2001 self.SetAutoLayout(True)
2462 self.Fit() 2002 self.Fit()
2463
2464 #self.Bind(wx.EVT_SIZE, self.on_size)
2465 self.Bind(wx.EVT_BUTTON, self.on_remove, id=10) 2003 self.Bind(wx.EVT_BUTTON, self.on_remove, id=10)
2466 self.Bind(wx.EVT_BUTTON, self.on_add, id=20) 2004 self.Bind(wx.EVT_BUTTON, self.on_add, id=20)
2467 self.grid.Bind(wx.grid.EVT_GRID_CELL_CHANGE, self.on_cell_change) 2005 self.grid.Bind(wx.grid.EVT_GRID_CELL_CHANGE, self.on_cell_change)
2468 self.xml = handler.xml 2006 self.xml = handler.xml
2469 n_list = handler.xml.getchildren() 2007 n_list = handler.xml.getchildren()
2470 self.n_list = n_list 2008 self.n_list = n_list
2471 col_names = ['Armor','bonus','maxdex','cp','sf','weight','speed','type'] 2009 col_names = ['Armor','bonus','maxdex','cp','sf','weight','speed','type']
2472 self.grid.CreateGrid(len(n_list),len(col_names),1) 2010 self.grid.CreateGrid(len(n_list),len(col_names),1)
2473 self.grid.SetRowLabelSize(0) 2011 self.grid.SetRowLabelSize(0)
2474 for i in range(len(col_names)): 2012 for i in range(len(col_names)): self.grid.SetColLabelValue(i,col_names[i])
2475 self.grid.SetColLabelValue(i,col_names[i])
2476 self.atts =['name','bonus','maxdex','checkpenalty', 2013 self.atts =['name','bonus','maxdex','checkpenalty',
2477 'spellfailure','weight','speed','type'] 2014 'spellfailure','weight','speed','type']
2478 for i in range(len(n_list)): 2015 for i in range(len(n_list)): self.refresh_row(i)
2479 self.refresh_row(i)
2480 self.temp_dom = None 2016 self.temp_dom = None
2481 2017
2482 2018
2483 def on_cell_change(self,evt): 2019 def on_cell_change(self,evt):
2484 row = evt.GetRow() 2020 row = evt.GetRow()
2486 value = self.grid.GetCellValue(row,col) 2022 value = self.grid.GetCellValue(row,col)
2487 if col >= 1 and col <= 5: 2023 if col >= 1 and col <= 5:
2488 try: 2024 try:
2489 int(value) 2025 int(value)
2490 self.n_list[row].set(self.atts[col],value) 2026 self.n_list[row].set(self.atts[col],value)
2491 except: 2027 except: self.grid.SetCellValue(row,col,"0")
2492 self.grid.SetCellValue(row,col,"0") 2028 else: self.n_list[row].set(self.atts[col],value)
2493 else:
2494 self.n_list[row].set(self.atts[col],value)
2495 2029
2496 def refresh_row(self,i): 2030 def refresh_row(self,i):
2497 n = self.n_list[i] 2031 n = self.n_list[i]
2498 2032 for y in range(len(self.atts)): self.grid.SetCellValue(i,y,n.get(self.atts[y]))
2499 for y in range(len(self.atts)):
2500 self.grid.SetCellValue(i,y,n.get(self.atts[y]))
2501 2033
2502 def on_remove(self,evt): 2034 def on_remove(self,evt):
2503 rows = self.grid.GetNumberRows() 2035 rows = self.grid.GetNumberRows()
2504 for i in range(rows): 2036 for i in range(rows):
2505 if self.grid.IsInSelection(i,0): 2037 if self.grid.IsInSelection(i,0):
2511 tree = parse(dir_struct["dnd3e"]+"dnd3earmor.xml") 2043 tree = parse(dir_struct["dnd3e"]+"dnd3earmor.xml")
2512 xml_dom = tree.getroot() 2044 xml_dom = tree.getroot()
2513 self.temp_dom = xml_dom 2045 self.temp_dom = xml_dom
2514 f_list = self.temp_dom.findall('armor') 2046 f_list = self.temp_dom.findall('armor')
2515 opts = [] 2047 opts = []
2516 for f in f_list: 2048 for f in f_list: opts.append(f.get('name'))
2517 opts.append(f.get('name'))
2518 dlg = wx.SingleChoiceDialog(self,'Choose Armor:','Armor List',opts) 2049 dlg = wx.SingleChoiceDialog(self,'Choose Armor:','Armor List',opts)
2519 if dlg.ShowModal() == wx.ID_OK: 2050 if dlg.ShowModal() == wx.ID_OK:
2520 i = dlg.GetSelection() 2051 i = dlg.GetSelection()
2521 new_node = self.xml.append(f_list[i]) 2052 new_node = self.xml.append(f_list[i])
2522 self.grid.AppendRows(1) 2053 self.grid.AppendRows(1)
2529 self.sizer.SetDimension(0,s[1]-25,s[0],25) 2060 self.sizer.SetDimension(0,s[1]-25,s[0],25)
2530 (w,h) = self.grid.GetClientSizeTuple() 2061 (w,h) = self.grid.GetClientSizeTuple()
2531 cols = self.grid.GetNumberCols() 2062 cols = self.grid.GetNumberCols()
2532 col_w = w/(cols+2) 2063 col_w = w/(cols+2)
2533 self.grid.SetColSize(0,col_w*3) 2064 self.grid.SetColSize(0,col_w*3)
2534 for i in range(1,cols): 2065 for i in range(1,cols): self.grid.SetColSize(i,col_w)
2535 self.grid.SetColSize(i,col_w)
2536 2066
2537 2067
2538 class dnd3esnp(dnd3e_char_child): 2068 class dnd3esnp(dnd3e_char_child):
2539 """ Node Handler for power points. This handler will be 2069 """ Node Handler for power points. This handler will be
2540 created by dnd3echar_handler. 2070 created by dnd3echar_handler.
2541 """ 2071 """
2542 def __init__(self,xml_dom,tree_node,parent): 2072 def __init__(self,xml_dom,tree_node,parent):
2543 node_handler.__init__(self,xml_dom,tree_node) 2073 node_handler.__init__(self,xml_dom,tree_node)
2544 dnd3e_char_child.__init__(self,xml_dom,tree_node,parent) 2074 dnd3e_char_child.__init__(self,xml_dom,tree_node,parent)
2545 self.hparent = parent #a 1.5002 allow ability to run up tree. 2075 self.hparent = parent
2546
2547
2548 self.frame = component.get('frame') 2076 self.frame = component.get('frame')
2549 self.child_handlers = {} 2077 self.child_handlers = {}
2550 self.new_child_handler('spells','Spells',dnd3espells,'book') 2078 self.new_child_handler('spells','Spells',dnd3espells,'book')
2551 self.new_child_handler('divine','Divine Spells',dnd3edivine,'book') 2079 self.new_child_handler('divine','Divine Spells',dnd3edivine,'book')
2552 self.new_child_handler('powers','Powers',dnd3epowers,'book') 2080 self.new_child_handler('powers','Powers',dnd3epowers,'book')
2566 return tabbed_panel(parent,self,1) 2094 return tabbed_panel(parent,self,1)
2567 2095
2568 def get_use_panel(self,parent): 2096 def get_use_panel(self,parent):
2569 return tabbed_panel(parent,self,2) 2097 return tabbed_panel(parent,self,2)
2570 2098
2571 # def set_char_pp(self,attr,evl): #d 1.5002 doesn't seem to be used, but
2572 # dnd_globals["pp"][attr] = evl #d 1.5002 uses dnd_globals, so tossing.
2573
2574
2575 # def get_char_pp( self, attr ): #d 1.5002 doesn't seem to be used, but
2576 # return dnd_globals["pp"][attr] #d 1.5002 doesn't seem to be used, but
2577 2099
2578 class snp_char_child(node_handler): 2100 class snp_char_child(node_handler):
2579 """ Node Handler for skill. This handler will be 2101 """ Node Handler for skill. This handler will be
2580 created by dnd3echar_handler. 2102 created by dnd3echar_handler.
2581 """ 2103 """
2583 node_handler.__init__(self,xml_dom,tree_node) 2105 node_handler.__init__(self,xml_dom,tree_node)
2584 self.char_hander = parent 2106 self.char_hander = parent
2585 self.drag = False 2107 self.drag = False
2586 self.frame = component.get('frame') 2108 self.frame = component.get('frame')
2587 self.myeditor = None 2109 self.myeditor = None
2588
2589
2590 2110
2591 def on_drop(self,evt): 2111 def on_drop(self,evt):
2592 pass 2112 pass
2593 2113
2594 def on_rclick(self,evt): 2114 def on_rclick(self,evt):
2648 use += '+1' 2168 use += '+1'
2649 charNameL=self.root.general.charName #a 1.5002 2169 charNameL=self.root.general.charName #a 1.5002
2650 left = eval( '%s - ( %s )' % ( memrz, use ) ) 2170 left = eval( '%s - ( %s )' % ( memrz, use ) )
2651 if left < 0: 2171 if left < 0:
2652 txt = '%s Tried to cast %s but has used all of them for today,' 2172 txt = '%s Tried to cast %s but has used all of them for today,'
2653 #txt +='"Please rest so I can cast more."' % ( dnd_globals["gen"]["Name"], name )##d 1.5002
2654 txt +='"Please rest so I can cast more."' % ( charNameL, name ) #a 1.5002 2173 txt +='"Please rest so I can cast more."' % ( charNameL, name ) #a 1.5002
2655 self.chat.ParsePost( txt, True, False ) 2174 self.chat.ParsePost( txt, True, False )
2656 else: 2175 else:
2657 #txt = '%s casts %s ( level %s, "%s" )' % ( dnd_globals["gen"]["Name"], name, level, descr )#d 1.5002
2658 txt = '%s casts %s ( level %s, "%s" )' % ( charNameL, name, level, descr )#a f 1.5002 2176 txt = '%s casts %s ( level %s, "%s" )' % ( charNameL, name, level, descr )#a f 1.5002
2659 self.chat.ParsePost( txt, True, False ) 2177 self.chat.ParsePost( txt, True, False )
2660 s = '' 2178 s = ''
2661 if left != 1: 2179 if left != 1: s = 's'
2662 s = 's'
2663 #txt = '%s can cast %s %d more time%s' % ( dnd_globals["gen"]["Name"], name, left, s )#d 1.5002
2664 txt = '%s can cast %s %d more time%s' % ( charNameL, name, left, s ) #a 1.5002 2180 txt = '%s can cast %s %d more time%s' % ( charNameL, name, left, s ) #a 1.5002
2665 self.chat.ParsePost( txt, False, False ) 2181 self.chat.ParsePost( txt, False, False )
2666 self.spells[ name ].set( 'used', `eval( use )` ) 2182 self.spells[ name ].set( 'used', `eval( use )` )
2667 2183
2668 def refresh_spells(self): 2184 def refresh_spells(self):
2683 return wnd 2199 return wnd
2684 2200
2685 def tohtml(self): 2201 def tohtml(self):
2686 html_str = "<table width=100% border=1 ><tr BGCOLOR=#E9E9E9 ><th>Arcane Spells</th></tr><tr><td><br>" 2202 html_str = "<table width=100% border=1 ><tr BGCOLOR=#E9E9E9 ><th>Arcane Spells</th></tr><tr><td><br>"
2687 n_list = self.xml.getchildren() 2203 n_list = self.xml.getchildren()
2688 for n in n_list: 2204 for n in n_list: html_str += "(" + n.get('level') + ") " + n.get('name')+ ", "
2689 html_str += "(" + n.get('level') + ") " + n.get('name')+ ", "
2690 html_str = html_str[:len(html_str)-2] + "</td></tr></table>" 2205 html_str = html_str[:len(html_str)-2] + "</td></tr></table>"
2691 return html_str 2206 return html_str
2692 2207
2693 def get_char_lvl( self, attr ): 2208 def get_char_lvl( self, attr ):
2694 return self.char_hander.get_char_lvl(attr) 2209 return self.char_hander.get_char_lvl(attr)
2695 2210
2696 class spells_panel(wx.Panel): 2211 class spells_panel(wx.Panel):
2697 def __init__(self, parent, handler): 2212 def __init__(self, parent, handler):
2698 pname = handler.xml.set("name", 'Arcane Spells') 2213 pname = handler.xml.set("name", 'Arcane Spells')
2699 self.hparent = handler #a 1.5002 allow ability to run up tree. 2214 self.hparent = handler #a 1.5002 allow ability to run up tree.
2700 #a 1.5002 in this case, we need the functional parent, not the invoking parent.
2701
2702 wx.Panel.__init__(self, parent, -1) 2215 wx.Panel.__init__(self, parent, -1)
2703 self.grid =wx.grid.Grid(self, -1, style=wx.SUNKEN_BORDER | wx.WANTS_CHARS) 2216 self.grid =wx.grid.Grid(self, -1, style=wx.SUNKEN_BORDER | wx.WANTS_CHARS)
2704 self.handler = handler 2217 self.handler = handler
2705 sizer = wx.BoxSizer(wx.VERTICAL) 2218 sizer = wx.BoxSizer(wx.VERTICAL)
2706 sizer.Add(self.grid, 1, wx.EXPAND) 2219 sizer.Add(self.grid, 1, wx.EXPAND)
2707
2708 sizer1 = wx.BoxSizer(wx.HORIZONTAL) 2220 sizer1 = wx.BoxSizer(wx.HORIZONTAL)
2709 sizer1.Add(wx.Button(self, 10, "Remove Spell"), 1, wx.EXPAND) 2221 sizer1.Add(wx.Button(self, 10, "Remove Spell"), 1, wx.EXPAND)
2710 sizer1.Add(wx.Size(10,10)) 2222 sizer1.Add(wx.Size(10,10))
2711 sizer1.Add(wx.Button(self, 20, "Add Spell"), 1, wx.EXPAND) 2223 sizer1.Add(wx.Button(self, 20, "Add Spell"), 1, wx.EXPAND)
2712 sizer1.Add(wx.Size(10,10)) 2224 sizer1.Add(wx.Size(10,10))
2713 sizer1.Add(wx.Button(self, 30, "Refresh Spells"), 1, wx.EXPAND) 2225 sizer1.Add(wx.Button(self, 30, "Refresh Spells"), 1, wx.EXPAND)
2714
2715 sizer.Add(sizer1, 0, wx.EXPAND) 2226 sizer.Add(sizer1, 0, wx.EXPAND)
2716 self.sizer = sizer 2227 self.sizer = sizer
2717 self.SetSizer(self.sizer) 2228 self.SetSizer(self.sizer)
2718 self.SetAutoLayout(True) 2229 self.SetAutoLayout(True)
2719 self.Fit() 2230 self.Fit()
2720
2721 #self.Bind(wx.EVT_SIZE, self.on_size)
2722 self.Bind(wx.EVT_BUTTON, self.on_remove, id=10) 2231 self.Bind(wx.EVT_BUTTON, self.on_remove, id=10)
2723 self.Bind(wx.EVT_BUTTON, self.on_add, id=20) 2232 self.Bind(wx.EVT_BUTTON, self.on_add, id=20)
2724 self.Bind(wx.EVT_BUTTON, self.on_refresh_spells, id=30) 2233 self.Bind(wx.EVT_BUTTON, self.on_refresh_spells, id=30)
2725 self.grid.Bind(wx.grid.EVT_GRID_CELL_CHANGE, self.on_cell_change) 2234 self.grid.Bind(wx.grid.EVT_GRID_CELL_CHANGE, self.on_cell_change)
2726 n_list = handler.xml.getchildren() 2235 n_list = handler.xml.getchildren()
2730 self.grid.SetRowLabelSize(0) 2239 self.grid.SetRowLabelSize(0)
2731 self.grid.SetColLabelValue(0,"No.") 2240 self.grid.SetColLabelValue(0,"No.")
2732 self.grid.SetColLabelValue(1,"Lvl") 2241 self.grid.SetColLabelValue(1,"Lvl")
2733 self.grid.SetColLabelValue(2,"Spell") 2242 self.grid.SetColLabelValue(2,"Spell")
2734 self.grid.SetColLabelValue(3,"Desc") 2243 self.grid.SetColLabelValue(3,"Desc")
2735 for i in range(len(n_list)): 2244 for i in range(len(n_list)): self.refresh_row(i)
2736 self.refresh_row(i)
2737 self.temp_dom = None 2245 self.temp_dom = None
2738 2246
2739 def on_cell_change(self,evt): 2247 def on_cell_change(self,evt):
2740 row = evt.GetRow() 2248 row = evt.GetRow()
2741 col = evt.GetCol() 2249 col = evt.GetCol()
2742 value = self.grid.GetCellValue(row,col) 2250 value = self.grid.GetCellValue(row,col)
2743 if col == 0: 2251 if col == 0: self.n_list[row].set('memrz',value)
2744 self.n_list[row].set('memrz',value)
2745
2746 2252
2747 def refresh_row(self,i): 2253 def refresh_row(self,i):
2748 spell = self.n_list[i] 2254 spell = self.n_list[i]
2749
2750 memrz = spell.get('memrz') 2255 memrz = spell.get('memrz')
2751 name = spell.get('name') 2256 name = spell.get('name')
2752 type = spell.get('desc') 2257 type = spell.get('desc')
2753 level = spell.get('level') 2258 level = spell.get('level')
2754 self.grid.SetCellValue(i,0,memrz) 2259 self.grid.SetCellValue(i,0,memrz)
2777 opts = [] 2282 opts = []
2778 #lvl = int(dnd3e_char_child.get_char_lvl('level')) 2283 #lvl = int(dnd3e_char_child.get_char_lvl('level'))
2779 #castlvl = eval('%s/2' % (lvl)) 2284 #castlvl = eval('%s/2' % (lvl))
2780 for f in f_list: 2285 for f in f_list:
2781 spelllvl = f.get('level') 2286 spelllvl = f.get('level')
2782 #if spelllvl <= "1":
2783 # opts.append("(" + f.get('level') + ")" + f.get('name'))
2784 #else:
2785 # if eval('%d >= %s' %(castlvl, spelllvl)):
2786 opts.append("(" + f.get('level') + ")" + f.get('name')) 2287 opts.append("(" + f.get('level') + ")" + f.get('name'))
2787 dlg = wx.SingleChoiceDialog(self,'Choose Spell','Spells',opts) 2288 dlg = wx.SingleChoiceDialog(self,'Choose Spell','Spells',opts)
2788 if dlg.ShowModal() == wx.ID_OK: 2289 if dlg.ShowModal() == wx.ID_OK:
2789 i = dlg.GetSelection() 2290 i = dlg.GetSelection()
2790 new_node = self.xml.append(f_list[i]) 2291 new_node = self.xml.append(f_list[i])
2794 self.handler.refresh_spells() 2295 self.handler.refresh_spells()
2795 dlg.Destroy() 2296 dlg.Destroy()
2796 2297
2797 def on_refresh_spells( self, evt ): 2298 def on_refresh_spells( self, evt ):
2798 f_list = self.xml.findall('spell') 2299 f_list = self.xml.findall('spell')
2799 2300 for spell in f_list: spell.set( 'used', '0' )
2800 for spell in f_list:
2801 spell.set( 'used', '0' )
2802 2301
2803 def on_size(self,event): 2302 def on_size(self,event):
2804 s = self.GetClientSizeTuple() 2303 s = self.GetClientSizeTuple()
2805 self.grid.SetDimensions(0,0,s[0],s[1]-25) 2304 self.grid.SetDimensions(0,0,s[0],s[1]-25)
2806 self.sizer.SetDimension(0,s[1]-25,s[0],25) 2305 self.sizer.SetDimension(0,s[1]-25,s[0],25)
2807 (w,h) = self.grid.GetClientSizeTuple() 2306 (w,h) = self.grid.GetClientSizeTuple()
2808 cols = self.grid.GetNumberCols() 2307 cols = self.grid.GetNumberCols()
2809 col_w = w/(cols) 2308 col_w = w/(cols)
2810 for i in range(0,cols): 2309 for i in range(0,cols): self.grid.SetColSize(i,col_w)
2811 self.grid.SetColSize(i,col_w)
2812 self.grid.SetColSize(0,w * 0.10) 2310 self.grid.SetColSize(0,w * 0.10)
2813 self.grid.SetColSize(1,w * 0.10) 2311 self.grid.SetColSize(1,w * 0.10)
2814 self.grid.SetColSize(2,w * 0.30) 2312 self.grid.SetColSize(2,w * 0.30)
2815 self.grid.SetColSize(3,w * 0.50) 2313 self.grid.SetColSize(3,w * 0.50)
2816 2314
2817 def refresh_data(self): 2315 def refresh_data(self):
2818 for i in range(len(self.n_list)): 2316 for i in range(len(self.n_list)): self.refresh_row(i)
2819 self.refresh_row(i)
2820 2317
2821 class dnd3edivine(snp_char_child): 2318 class dnd3edivine(snp_char_child):
2822 """ Node Handler for classes. This handler will be 2319 """ Node Handler for classes. This handler will be
2823 created by dnd3echar_handler. 2320 created by dnd3echar_handler.
2824 """ 2321 """
2825 def __init__(self,xml_dom,tree_node,parent): 2322 def __init__(self,xml_dom,tree_node,parent):
2826 snp_char_child.__init__(self,xml_dom,tree_node,parent) 2323 snp_char_child.__init__(self,xml_dom,tree_node,parent)
2827 self.hparent = parent #a 1.5002 allow ability to run up tree. 2324 self.hparent = parent #a 1.5002 allow ability to run up tree.
2828 self.root = getRoot(self) #a 1.5002 2325 self.root = getRoot(self) #a 1.5002
2829 self.root.divine = self #a 1.6009 2326 self.root.divine = self #a 1.6009
2830
2831
2832 node_list = self.xml.findall( 'gift' ) 2327 node_list = self.xml.findall( 'gift' )
2833 self.spells = {} 2328 self.spells = {}
2834 tree = self.tree 2329 tree = self.tree
2835 icons = self.tree.icons 2330 icons = self.tree.icons
2836 for n in node_list: 2331 for n in node_list:
2853 use += '+1' 2348 use += '+1'
2854 left = eval( '%s - ( %s )' % ( memrz, use ) ) 2349 left = eval( '%s - ( %s )' % ( memrz, use ) )
2855 if left < 0: 2350 if left < 0:
2856 txt = '%s Tried to cast %s but has used all of them for today,' #m 1.5002 break in 2. 2351 txt = '%s Tried to cast %s but has used all of them for today,' #m 1.5002 break in 2.
2857 txt += "Please rest so I can cast more."' % ( charNameL, name )' #a 1.5002 2352 txt += "Please rest so I can cast more."' % ( charNameL, name )' #a 1.5002
2858 #txt += "Please rest so I can cast more."' % ( dnd_globals["gen"]["Name"], name ) #d 1.5002
2859 self.chat.ParsePost( txt, True, False ) 2353 self.chat.ParsePost( txt, True, False )
2860 else: 2354 else:
2861 #txt = '%s casts %s ( level %s, "%s" )' % ( dnd_globals["gen"]["Name"], name, level, descr ) #d 1.5002
2862 txt = '%s casts %s ( level %s, "%s" )' % ( charNameL, name, level, descr ) #a 5002 2355 txt = '%s casts %s ( level %s, "%s" )' % ( charNameL, name, level, descr ) #a 5002
2863 self.chat.ParsePost( txt, True, False ) 2356 self.chat.ParsePost( txt, True, False )
2864 s = '' 2357 s = ''
2865 if left != 1: 2358 if left != 1: s = 's'
2866 s = 's'
2867 #txt = '%s can cast %s %d more time%s' % ( dnd_globals["gen"]["Name"], name, left, s ) #d 1.5002
2868 txt = '%s can cast %s %d more time%s' % ( charNameL, name, left, s ) #a 1.5002 2359 txt = '%s can cast %s %d more time%s' % ( charNameL, name, left, s ) #a 1.5002
2869 self.chat.ParsePost( txt, False, False ) 2360 self.chat.ParsePost( txt, False, False )
2870 self.spells[ name ].set( 'used', `eval( use )` ) 2361 self.spells[ name ].set( 'used', `eval( use )` )
2871 2362
2872 def refresh_spells(self): 2363 def refresh_spells(self):
2873 self.spells = {} 2364 self.spells = {}
2874 tree = self.tree 2365 tree = self.tree
2875 icons = self.tree.icons 2366 icons = self.tree.icons
2876 tree.CollapseAndReset(self.mytree_node) 2367 tree.CollapseAndReset(self.mytree_node)
2877
2878 node_list = self.xml.findall('gift') 2368 node_list = self.xml.findall('gift')
2879 for n in node_list: 2369 for n in node_list:
2880 name = n.get('name') 2370 name = n.get('name')
2881 new_tree_node = tree.AppendItem(self.mytree_node,name,icons['flask'],icons['flask']) 2371 new_tree_node = tree.AppendItem(self.mytree_node,name,icons['flask'],icons['flask'])
2882 tree.SetPyData(new_tree_node,self) 2372 tree.SetPyData(new_tree_node,self)
2888 return wnd 2378 return wnd
2889 2379
2890 def tohtml(self): 2380 def tohtml(self):
2891 html_str = "<table width=100% border=1 ><tr BGCOLOR=#E9E9E9 ><th>Divine Spells</th></tr><tr><td><br>" 2381 html_str = "<table width=100% border=1 ><tr BGCOLOR=#E9E9E9 ><th>Divine Spells</th></tr><tr><td><br>"
2892 n_list = self.xml.getchildren() 2382 n_list = self.xml.getchildren()
2893 for n in n_list: 2383 for n in n_list: html_str += "(" + n.get('level') + ") " + n.get('name')+ ", "
2894 html_str += "(" + n.get('level') + ") " + n.get('name')+ ", "
2895 html_str = html_str[:len(html_str)-2] + "</td></tr></table>" 2384 html_str = html_str[:len(html_str)-2] + "</td></tr></table>"
2896 return html_str 2385 return html_str
2897 2386
2898 def get_char_lvl( self, attr ): 2387 def get_char_lvl( self, attr ):
2899 return self.char_hander.get_char_lvl(attr) 2388 return self.char_hander.get_char_lvl(attr)
2900 2389
2901 class divine_panel(wx.Panel): 2390 class divine_panel(wx.Panel):
2902 def __init__(self, parent, handler): 2391 def __init__(self, parent, handler):
2903 pname = handler.xml.set("name", 'Divine Spells') 2392 pname = handler.xml.set("name", 'Divine Spells')
2904 self.hparent = handler #a 1.5002 allow ability to run up tree. 2393 self.hparent = handler
2905 #a 1.5002 in this case, we need the functional parent, not the invoking parent.
2906
2907 wx.Panel.__init__(self, parent, -1) 2394 wx.Panel.__init__(self, parent, -1)
2908 self.grid =wx.grid.Grid(self, -1, style=wx.SUNKEN_BORDER | wx.WANTS_CHARS) 2395 self.grid =wx.grid.Grid(self, -1, style=wx.SUNKEN_BORDER | wx.WANTS_CHARS)
2909 self.handler = handler 2396 self.handler = handler
2910 sizer = wx.BoxSizer(wx.VERTICAL) 2397 sizer = wx.BoxSizer(wx.VERTICAL)
2911 sizer.Add(self.grid, 1, wx.EXPAND) 2398 sizer.Add(self.grid, 1, wx.EXPAND)
2912
2913 sizer1 = wx.BoxSizer(wx.HORIZONTAL) 2399 sizer1 = wx.BoxSizer(wx.HORIZONTAL)
2914 sizer1.Add(wx.Button(self, 10, "Remove Spell"), 1, wx.EXPAND) 2400 sizer1.Add(wx.Button(self, 10, "Remove Spell"), 1, wx.EXPAND)
2915 sizer1.Add(wx.Size(10,10)) 2401 sizer1.Add(wx.Size(10,10))
2916 sizer1.Add(wx.Button(self, 20, "Add Spell"), 1, wx.EXPAND) 2402 sizer1.Add(wx.Button(self, 20, "Add Spell"), 1, wx.EXPAND)
2917 sizer1.Add(wx.Size(10,10)) 2403 sizer1.Add(wx.Size(10,10))
2918 sizer1.Add(wx.Button(self, 30, "Refresh Spells"), 1, wx.EXPAND) 2404 sizer1.Add(wx.Button(self, 30, "Refresh Spells"), 1, wx.EXPAND)
2919
2920 sizer.Add(sizer1, 0, wx.EXPAND) 2405 sizer.Add(sizer1, 0, wx.EXPAND)
2921 self.sizer = sizer 2406 self.sizer = sizer
2922 self.SetSizer(self.sizer) 2407 self.SetSizer(self.sizer)
2923 self.SetAutoLayout(True) 2408 self.SetAutoLayout(True)
2924 self.Fit() 2409 self.Fit()
2925 2410
2926 #self.Bind(wx.EVT_SIZE, self.on_size)
2927 self.Bind(wx.EVT_BUTTON, self.on_remove, id=10) 2411 self.Bind(wx.EVT_BUTTON, self.on_remove, id=10)
2928 self.Bind(wx.EVT_BUTTON, self.on_add, id=20) 2412 self.Bind(wx.EVT_BUTTON, self.on_add, id=20)
2929 self.Bind(wx.EVT_BUTTON, self.on_refresh_spells, id=30) 2413 self.Bind(wx.EVT_BUTTON, self.on_refresh_spells, id=30)
2930 self.grid.Bind(wx.grid.EVT_GRID_CELL_CHANGE, self.on_cell_change) 2414 self.grid.Bind(wx.grid.EVT_GRID_CELL_CHANGE, self.on_cell_change)
2931 2415
2936 self.grid.SetRowLabelSize(0) 2420 self.grid.SetRowLabelSize(0)
2937 self.grid.SetColLabelValue(0,"No.") 2421 self.grid.SetColLabelValue(0,"No.")
2938 self.grid.SetColLabelValue(1,"Lvl") 2422 self.grid.SetColLabelValue(1,"Lvl")
2939 self.grid.SetColLabelValue(2,"Spell") 2423 self.grid.SetColLabelValue(2,"Spell")
2940 self.grid.SetColLabelValue(3,"Desc") 2424 self.grid.SetColLabelValue(3,"Desc")
2941 for i in range(len(n_list)): 2425 for i in range(len(n_list)): self.refresh_row(i)
2942 self.refresh_row(i)
2943 self.temp_dom = None 2426 self.temp_dom = None
2944 2427
2945 def on_cell_change(self,evt): 2428 def on_cell_change(self,evt):
2946 row = evt.GetRow() 2429 row = evt.GetRow()
2947
2948 col = evt.GetCol() 2430 col = evt.GetCol()
2949 value = self.grid.GetCellValue(row,col) 2431 value = self.grid.GetCellValue(row,col)
2950 if col == 0: 2432 if col == 0: self.n_list[row].set('memrz',value)
2951 self.n_list[row].set('memrz',value)
2952
2953 2433
2954 def refresh_row(self,i): 2434 def refresh_row(self,i):
2955 spell = self.n_list[i] 2435 spell = self.n_list[i]
2956
2957 memrz = spell.get('memrz') 2436 memrz = spell.get('memrz')
2958 name = spell.get('name') 2437 name = spell.get('name')
2959 type = spell.get('desc') 2438 type = spell.get('desc')
2960 level = spell.get('level') 2439 level = spell.get('level')
2961 self.grid.SetCellValue(i,0,memrz) 2440 self.grid.SetCellValue(i,0,memrz)
2978 tree = parse(dir_struct["dnd3e"]+"dnd3edivine.xml") 2457 tree = parse(dir_struct["dnd3e"]+"dnd3edivine.xml")
2979 xml_dom = tree.getroot() 2458 xml_dom = tree.getroot()
2980 self.temp_dom = xml_dom 2459 self.temp_dom = xml_dom
2981 f_list = self.temp_dom.findall('gift') 2460 f_list = self.temp_dom.findall('gift')
2982 opts = [] 2461 opts = []
2983 #lvl = int(dnd3e_char_child.get_char_lvl('level'))
2984 #castlvl = lvl / 2
2985 for f in f_list: 2462 for f in f_list:
2986 spelllvl = f.get('level') 2463 spelllvl = f.get('level')
2987 #if spelllvl <= "1":
2988 # opts.append("(" + f.get('level') + ")" + f.get('name'))
2989 #else:
2990 # if eval('%d >= %s' %(castlvl, spelllvl)):
2991 opts.append("(" + f.get('level') + ")" + f.get('name')) 2464 opts.append("(" + f.get('level') + ")" + f.get('name'))
2992 dlg = wx.SingleChoiceDialog(self,'Choose Spell','Spells',opts) 2465 dlg = wx.SingleChoiceDialog(self,'Choose Spell','Spells',opts)
2993 if dlg.ShowModal() == wx.ID_OK: 2466 if dlg.ShowModal() == wx.ID_OK:
2994 i = dlg.GetSelection() 2467 i = dlg.GetSelection()
2995 new_node = self.xml.append(f_list[i]) 2468 new_node = self.xml.append(f_list[i])
2999 self.handler.refresh_spells() 2472 self.handler.refresh_spells()
3000 dlg.Destroy() 2473 dlg.Destroy()
3001 2474
3002 def on_refresh_spells( self, evt ): 2475 def on_refresh_spells( self, evt ):
3003 f_list = self.xml.findall('gift') 2476 f_list = self.xml.findall('gift')
3004 for spell in f_list: 2477 for spell in f_list: spell.set( 'used', '0' )
3005 spell.set( 'used', '0' )
3006 2478
3007 def on_size(self,event): 2479 def on_size(self,event):
3008 s = self.GetClientSizeTuple() 2480 s = self.GetClientSizeTuple()
3009 self.grid.SetDimensions(0,0,s[0],s[1]-25) 2481 self.grid.SetDimensions(0,0,s[0],s[1]-25)
3010 self.sizer.SetDimension(0,s[1]-25,s[0],25) 2482 self.sizer.SetDimension(0,s[1]-25,s[0],25)
3011 (w,h) = self.grid.GetClientSizeTuple() 2483 (w,h) = self.grid.GetClientSizeTuple()
3012 cols = self.grid.GetNumberCols() 2484 cols = self.grid.GetNumberCols()
3013 col_w = w/(cols) 2485 col_w = w/(cols)
3014 for i in range(0,cols): 2486 for i in range(0,cols): self.grid.SetColSize(i,col_w)
3015 self.grid.SetColSize(i,col_w)
3016 self.grid.SetColSize(0,w * 0.10) 2487 self.grid.SetColSize(0,w * 0.10)
3017 self.grid.SetColSize(1,w * 0.10) 2488 self.grid.SetColSize(1,w * 0.10)
3018 self.grid.SetColSize(2,w * 0.30) 2489 self.grid.SetColSize(2,w * 0.30)
3019 self.grid.SetColSize(3,w * 0.50) 2490 self.grid.SetColSize(3,w * 0.50)
3020 2491
3021 def refresh_data(self): 2492 def refresh_data(self):
3022 2493 for i in range(len(self.n_list)): self.refresh_row(i)
3023 for i in range(len(self.n_list)):
3024 self.refresh_row(i)
3025 2494
3026 2495
3027 class dnd3epowers(snp_char_child): 2496 class dnd3epowers(snp_char_child):
3028 """ Node Handler for classes. This handler will be 2497 """ Node Handler for classes. This handler will be
3029 created by dnd3echar_handler. 2498 created by dnd3echar_handler.
3073 else: 2542 else:
3074 txt = ('%s uses %s as a Free Talent ( level %s, "%s" )' 2543 txt = ('%s uses %s as a Free Talent ( level %s, "%s" )'
3075 % ( charNameL, name, level, descr )) #a 1.5002 2544 % ( charNameL, name, level, descr )) #a 1.5002
3076 self.chat.ParsePost( txt, True, False ) 2545 self.chat.ParsePost( txt, True, False )
3077 s = '' 2546 s = ''
3078 if left != 1: 2547 if left != 1: s = 's'
3079 s = 's'
3080 txt = '%s has %d Free Talent%s left' % ( charNameL, numcast, s ) #a 1.5002 2548 txt = '%s has %d Free Talent%s left' % ( charNameL, numcast, s ) #a 1.5002
3081 self.chat.ParsePost( txt, False, False ) 2549 self.chat.ParsePost( txt, False, False )
3082 self.root.pp.set_char_pp('free',left) #a 1.5002 2550 self.root.pp.set_char_pp('free',left) #a 1.5002
3083 else: 2551 else:
3084 left = eval('%s - ( %s )' % ( cpp, points )) 2552 left = eval('%s - ( %s )' % ( cpp, points ))
3099 self.chat.ParsePost( txt, False, False ) 2567 self.chat.ParsePost( txt, False, False )
3100 self.root.pp.set_char_pp('current1',left) #a 1.5002 2568 self.root.pp.set_char_pp('current1',left) #a 1.5002
3101 2569
3102 def refresh_powers(self): 2570 def refresh_powers(self):
3103 self.powers = {} 2571 self.powers = {}
3104
3105 tree = self.tree 2572 tree = self.tree
3106 icons = self.tree.icons 2573 icons = self.tree.icons
3107 tree.CollapseAndReset(self.mytree_node) 2574 tree.CollapseAndReset(self.mytree_node)
3108 node_list = self.xml.findall('power') 2575 node_list = self.xml.findall('power')
3109 for n in node_list: 2576 for n in node_list:
3128 2595
3129 class power_panel(wx.Panel): 2596 class power_panel(wx.Panel):
3130 def __init__(self, parent, handler): 2597 def __init__(self, parent, handler):
3131 #m 1.5015 corrected typo, was Pionic. 2598 #m 1.5015 corrected typo, was Pionic.
3132 pname = handler.xml.set("name", 'Psionic Powers') 2599 pname = handler.xml.set("name", 'Psionic Powers')
3133 self.hparent = handler #a 1.5002 allow ability to run up tree. In this 2600 self.hparent = handler
3134 #a 1.5002 case, we need the functional parent, not the invoking parent.
3135 self.root = getRoot(self) #a (debug) 1.5002,1.5014 2601 self.root = getRoot(self) #a (debug) 1.5002,1.5014
3136 2602
3137 wx.Panel.__init__(self, parent, -1) 2603 wx.Panel.__init__(self, parent, -1)
3138 self.grid = wx.grid.Grid(self, -1, style=wx.SUNKEN_BORDER | wx.WANTS_CHARS) 2604 self.grid = wx.grid.Grid(self, -1, style=wx.SUNKEN_BORDER | wx.WANTS_CHARS)
3139 self.handler = handler 2605 self.handler = handler
3166 self.grid.SetColLabelValue(0,"PP") 2632 self.grid.SetColLabelValue(0,"PP")
3167 self.grid.SetColLabelValue(1,"Lvl") 2633 self.grid.SetColLabelValue(1,"Lvl")
3168 self.grid.SetColLabelValue(2,"Power") 2634 self.grid.SetColLabelValue(2,"Power")
3169 self.grid.SetColLabelValue(3,"Desc") 2635 self.grid.SetColLabelValue(3,"Desc")
3170 self.grid.SetColLabelValue(4,"Type") 2636 self.grid.SetColLabelValue(4,"Type")
3171 for i in range(len(n_list)): 2637 for i in range(len(n_list)): self.refresh_row(i)
3172 self.refresh_row(i)
3173 self.refresh_data() 2638 self.refresh_data()
3174 self.temp_dom = None 2639 self.temp_dom = None
3175 2640
3176 def on_cell_change(self,evt): 2641 def on_cell_change(self,evt):
3177 row = evt.GetRow() 2642 row = evt.GetRow()
3178 col = evt.GetCol() 2643 col = evt.GetCol()
3179 value = self.grid.GetCellValue(row,col) 2644 value = self.grid.GetCellValue(row,col)
3180 """if col == 0:
3181 self.n_list[row].set('memrz',value)"""
3182
3183 2645
3184 def refresh_row(self,i): 2646 def refresh_row(self,i):
3185 power = self.n_list[i] 2647 power = self.n_list[i]
3186
3187 point = power.get('point') 2648 point = power.get('point')
3188 name = power.get('name') 2649 name = power.get('name')
3189 type = power.get('desc') 2650 type = power.get('desc')
3190 test = power.get('test') 2651 test = power.get('test')
3191 level = power.get('level') 2652 level = power.get('level')
3214 xml_dom = tree.getroot() 2675 xml_dom = tree.getroot()
3215 self.temp_dom = xml_dom 2676 self.temp_dom = xml_dom
3216 debug(self.temp) 2677 debug(self.temp)
3217 f_list = self.temp_dom.findall('power') 2678 f_list = self.temp_dom.findall('power')
3218 opts = [] 2679 opts = []
3219 #lvl = int(dnd3e_char_child.get_char_lvl('level'))
3220 #castlvl = lvl / 2
3221 for f in f_list: 2680 for f in f_list:
3222 spelllvl = f.get('level') 2681 spelllvl = f.get('level')
3223 #if spelllvl <= "1":
3224 # opts.append("(" + f.get('level') + ") - " + f.get('name') + " - " + f.get('test'))
3225 #else:
3226 # if eval('%d >= %s' %(castlvl, spelllvl)):
3227 opts.append("(" + f.get('level') + ") - " + 2682 opts.append("(" + f.get('level') + ") - " +
3228 f.get('name') + " - " + f.get('test')) 2683 f.get('name') + " - " + f.get('test'))
3229 dlg = wx.SingleChoiceDialog(self,'Choose Power','Powers',opts) 2684 dlg = wx.SingleChoiceDialog(self,'Choose Power','Powers',opts)
3230 if dlg.ShowModal() == wx.ID_OK: 2685 if dlg.ShowModal() == wx.ID_OK:
3231 i = dlg.GetSelection() 2686 i = dlg.GetSelection()
3244 self.xml.remove(self.n_list[i]) 2699 self.xml.remove(self.n_list[i])
3245 self.n_list = self.xml.findall('weapon') 2700 self.n_list = self.xml.findall('weapon')
3246 self.handler.refresh_powers() 2701 self.handler.refresh_powers()
3247 2702
3248 def on_refresh_powers( self, evt ): 2703 def on_refresh_powers( self, evt ):
3249 #a 1.5002,1.5014 s
3250 self.root.pp.set_char_pp('current1',self.root.pp.get_char_pp('max1')) 2704 self.root.pp.set_char_pp('current1',self.root.pp.get_char_pp('max1'))
3251 self.root.pp.set_char_pp('free',self.root.pp.get_char_pp('maxfree')) 2705 self.root.pp.set_char_pp('free',self.root.pp.get_char_pp('maxfree'))
3252 #a 1.5002,1.5014 e
3253
3254
3255 2706
3256 def on_size(self,event): 2707 def on_size(self,event):
3257 s = self.GetClientSizeTuple() 2708 s = self.GetClientSizeTuple()
3258 self.grid.SetDimensions(0,0,s[0],s[1]-25) 2709 self.grid.SetDimensions(0,0,s[0],s[1]-25)
3259 self.sizer.SetDimension(0,s[1]-25,s[0],25) 2710 self.sizer.SetDimension(0,s[1]-25,s[0],25)
3260 (w,h) = self.grid.GetClientSizeTuple() 2711 (w,h) = self.grid.GetClientSizeTuple()
3261 cols = self.grid.GetNumberCols() 2712 cols = self.grid.GetNumberCols()
3262 col_w = w/(cols) 2713 col_w = w/(cols)
3263 for i in range(0,cols): 2714 for i in range(0,cols): self.grid.SetColSize(i,col_w)
3264 self.grid.SetColSize(i,col_w)
3265 self.grid.SetColSize(0,w * 0.05) 2715 self.grid.SetColSize(0,w * 0.05)
3266 self.grid.SetColSize(1,w * 0.05) 2716 self.grid.SetColSize(1,w * 0.05)
3267 self.grid.SetColSize(2,w * 0.30) 2717 self.grid.SetColSize(2,w * 0.30)
3268 self.grid.SetColSize(3,w * 0.30) 2718 self.grid.SetColSize(3,w * 0.30)
3269 self.grid.SetColSize(4,w * 0.30) 2719 self.grid.SetColSize(4,w * 0.30)
3270 2720
3271 def refresh_data(self): 2721 def refresh_data(self):
3272 2722 for i in range(len(self.n_list)): self.refresh_row(i)
3273 for i in range(len(self.n_list)):
3274 self.refresh_row(i)
3275 2723
3276 class dnd3epp(snp_char_child): 2724 class dnd3epp(snp_char_child):
3277 """ Node Handler for power points. This handler will be 2725 """ Node Handler for power points. This handler will be
3278 created by dnd3echar_handler. 2726 created by dnd3echar_handler.
3279 """ 2727 """
3282 self.hparent = parent #a 1.5002 allow ability to run up tree. 2730 self.hparent = parent #a 1.5002 allow ability to run up tree.
3283 self.root = getRoot(self) 2731 self.root = getRoot(self)
3284 self.root.pp = self 2732 self.root.pp = self
3285 self.ppPanel=None 2733 self.ppPanel=None
3286 2734
3287
3288 def get_design_panel(self,parent): 2735 def get_design_panel(self,parent):
3289 wnd = outline_panel(parent,self,pp_panel,"Power Points") 2736 wnd = outline_panel(parent,self,pp_panel,"Power Points")
3290 wnd.title = "Power Points" 2737 wnd.title = "Power Points"
3291 return wnd 2738 return wnd
3292 2739
3293 2740
3294 def tohtml(self): 2741 def tohtml(self):
3295 html_str = "<table width=100% border=1 ><tr BGCOLOR=#E9E9E9 >" 2742 html_str = "<table width=100% border=1 ><tr BGCOLOR=#E9E9E9 >"
3296 #html_str += "<th colspan=8>Power Points</th></tr>" #d 1.6010
3297 html_str += "<th colspan=7>Power Points</th>" #a 1.6010 2743 html_str += "<th colspan=7>Power Points</th>" #a 1.6010
3298 #m 1.6010 rearanged everything below to "return html_str"
3299 html_str += "</tr><tr>" 2744 html_str += "</tr><tr>"
3300 html_str += "<th colspan=2>Max:</th>" 2745 html_str += "<th colspan=2>Max:</th>"
3301 html_str += "<td>"+self.xml.get('max1')+"</td>" 2746 html_str += "<td>"+self.xml.get('max1')+"</td>"
3302 html_str += "<th colspan=3>Max Talents/day:</th>" 2747 html_str += "<th colspan=3>Max Talents/day:</th>"
3303 html_str += "<td>"+self.xml.get('maxfree')+"</td>" 2748 html_str += "<td>"+self.xml.get('maxfree')+"</td>"
3309 html_str += "</tr></table>" 2754 html_str += "</tr></table>"
3310 return html_str 2755 return html_str
3311 2756
3312 def get_char_pp( self, attr ): 2757 def get_char_pp( self, attr ):
3313 pp = self.xml.get(attr) 2758 pp = self.xml.get(attr)
3314 #print "dnd3epp -get_char_pp: attr,pp",attr,pp
3315 return pp 2759 return pp
3316 2760
3317 def set_char_pp( self, attr, evl ): 2761 def set_char_pp( self, attr, evl ):
3318 qSub = str(evl) #a 1.5014 must force it to be a string for next call. 2762 qSub = str(evl) #a 1.5014 must force it to be a string for next call.
3319 self.xml.set(attr, qSub) 2763 self.xml.set(attr, qSub)
3320 #This function needs to be looked at the idea is to refresh the power panel
3321 #But it causes a seg fault when you refresh from powers -mgt
3322 #if self.ppPanel: #a 1.5015
3323 # self.ppPanel.on_refresh(attr,qSub) #a 1.5015
3324
3325 2764
3326 class pp_panel(wx.Panel): 2765 class pp_panel(wx.Panel):
3327 def __init__(self, parent, handler): 2766 def __init__(self, parent, handler):
3328 wx.Panel.__init__(self, parent, -1) 2767 wx.Panel.__init__(self, parent, -1)
3329 self.hparent = handler #a 1.5002 allow ability to run up tree. 2768 self.hparent = handler #a 1.5002 allow ability to run up tree.
3330 #a 1.5002 we need the functional parent, not the invoking parent.
3331 self.hparent.ppPanel=self #a 1.5xx 2769 self.hparent.ppPanel=self #a 1.5xx
3332 2770
3333 pname = handler.xml.set("name", 'PowerPoints') 2771 pname = handler.xml.set("name", 'PowerPoints')
3334 self.sizer = wx.FlexGridSizer(2, 4, 2, 2) # rows, cols, hgap, vgap 2772 self.sizer = wx.FlexGridSizer(2, 4, 2, 2) # rows, cols, hgap, vgap
3335 self.xml = handler.xml 2773 self.xml = handler.xml
3337 self.static1= wx.StaticText(self, -1, "PP Current:") #a 1.5015 2775 self.static1= wx.StaticText(self, -1, "PP Current:") #a 1.5015
3338 self.dyn1= wx.TextCtrl(self, PP_CUR, 2776 self.dyn1= wx.TextCtrl(self, PP_CUR,
3339 self.xml.get('current1')) #a 1.5015 2777 self.xml.get('current1')) #a 1.5015
3340 self.dyn3= wx.TextCtrl(self, PP_FRE, 2778 self.dyn3= wx.TextCtrl(self, PP_FRE,
3341 self.xml.get('free')) #a 1.5015 2779 self.xml.get('free')) #a 1.5015
3342 # self.sizer.AddMany([ (wx.StaticText(self, -1, "PP Current:"), #d 1.5015
3343 # 0, wx.ALIGN_CENTER_VERTICAL),
3344 # (wx.TextCtrl(self, PP_CUR, #d 1.5015
3345 # self.xml.get('current1')), 0, wx.EXPAND),
3346 self.sizer.AddMany([ (self.static1, 0, wx.ALIGN_CENTER_VERTICAL), 2780 self.sizer.AddMany([ (self.static1, 0, wx.ALIGN_CENTER_VERTICAL),
3347 (self.dyn1, 0, wx.EXPAND), 2781 (self.dyn1, 0, wx.EXPAND),
3348 (wx.StaticText(self, -1, "PP Max:"), 0, wx.ALIGN_CENTER_VERTICAL), 2782 (wx.StaticText(self, -1, "PP Max:"), 0, wx.ALIGN_CENTER_VERTICAL),
3349 (wx.TextCtrl(self, PP_MAX, 2783 (wx.TextCtrl(self, PP_MAX,
3350 self.xml.get('max1')), 0, wx.EXPAND), 2784 self.xml.get('max1')), 0, wx.EXPAND),
3351 (wx.StaticText(self, -1, "Current Free Talants per day:"), 2785 (wx.StaticText(self, -1, "Current Free Talants per day:"),
3352 0, wx.ALIGN_CENTER_VERTICAL), 2786 0, wx.ALIGN_CENTER_VERTICAL),
3353 (self.dyn3, 0, wx.EXPAND), #a 1.5015 2787 (self.dyn3, 0, wx.EXPAND), #a 1.5015
3354 # (wx.TextCtrl(self, PP_FRE,
3355 # self.xml.get('free')), 0, wx.EXPAND),#d 1.5015
3356 (wx.StaticText(self, -1, "Max Free Talants per day:"), 2788 (wx.StaticText(self, -1, "Max Free Talants per day:"),
3357 0, wx.ALIGN_CENTER_VERTICAL), 2789 0, wx.ALIGN_CENTER_VERTICAL),
3358 (wx.TextCtrl(self, PP_MFRE, 2790 (wx.TextCtrl(self, PP_MFRE,
3359 self.xml.get('maxfree')), 0, wx.EXPAND), 2791 self.xml.get('maxfree')), 0, wx.EXPAND),
3360 ]) 2792 ])
3361 2793
3362 self.sizer.AddGrowableCol(1) 2794 self.sizer.AddGrowableCol(1)
3363 self.SetSizer(self.sizer) 2795 self.SetSizer(self.sizer)
3364 self.SetAutoLayout(True) 2796 self.SetAutoLayout(True)
3365 self.Fit() 2797 self.Fit()
3366
3367 #self.Bind(wx.EVT_SIZE, self.on_size)
3368 self.Bind(wx.EVT_TEXT, self.on_text, id=PP_MAX) 2798 self.Bind(wx.EVT_TEXT, self.on_text, id=PP_MAX)
3369 self.Bind(wx.EVT_TEXT, self.on_text, id=PP_CUR) 2799 self.Bind(wx.EVT_TEXT, self.on_text, id=PP_CUR)
3370 self.Bind(wx.EVT_TEXT, self.on_text, id=PP_FRE) 2800 self.Bind(wx.EVT_TEXT, self.on_text, id=PP_FRE)
3371 self.Bind(wx.EVT_TEXT, self.on_text, id=PP_MFRE) 2801 self.Bind(wx.EVT_TEXT, self.on_text, id=PP_MFRE)
3372 2802
3373 def on_text(self,evt): 2803 def on_text(self,evt):
3374 id = evt.GetId() 2804 id = evt.GetId()
3375 if id == PP_CUR: 2805 if id == PP_CUR: self.xml.set('current1',evt.GetString())
3376 self.xml.set('current1',evt.GetString()) 2806 elif id == PP_MAX: self.xml.set('max1',evt.GetString())
3377 elif id == PP_MAX: 2807 elif id == PP_FRE: self.xml.set('free',evt.GetString())
3378 self.xml.set('max1',evt.GetString()) 2808 elif id == PP_MFRE: self.xml.set('maxfree',evt.GetString())
3379 elif id == PP_FRE:
3380 self.xml.set('free',evt.GetString())
3381 elif id == PP_MFRE:
3382 self.xml.set('maxfree',evt.GetString())
3383 2809
3384 def on_size(self,evt): 2810 def on_size(self,evt):
3385 s = self.GetClientSizeTuple() 2811 s = self.GetClientSizeTuple()
3386 self.sizer.SetDimension(0,0,s[0],s[1]) 2812 self.sizer.SetDimension(0,0,s[0],s[1])
3387 2813
3388 #a 5.015 this whole function. 2814 #a 5.015 this whole function.
3389 def on_refresh(self,attr,value): 2815 def on_refresh(self,attr,value):
3390 if attr == 'current1': 2816 if attr == 'current1': self.dyn1.SetValue(value)
3391 self.dyn1.SetValue(value) 2817 else: self.dyn3.SetValue(value)
3392 else:
3393 self.dyn3.SetValue(value)