comparison orpg/gametree/nodehandlers/d20.py @ 0:4385a7d0efd1 grumpy-goblin

Deleted and repushed it with the 'grumpy-goblin' branch. I forgot a y
author sirebral
date Tue, 14 Jul 2009 16:41:58 -0500
parents
children c54768cffbd4
comparison
equal deleted inserted replaced
-1:000000000000 0:4385a7d0efd1
1 # Copyright (C) 2000-2001 The OpenRPG Project
2 #
3 # openrpg-dev@lists.sourceforge.net
4 #
5 # This program is free software; you can redistribute it and/or modify
6 # it under the terms of the GNU General Public License as published by
7 # the Free Software Foundation; either version 2 of the License, or
8 # (at your option) any later version.
9 #
10 # This program is distributed in the hope that it will be useful,
11 # but WITHOUT ANY WARRANTY; without even the implied warranty of
12 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 # GNU General Public License for more details.
14 #
15 # You should have received a copy of the GNU General Public License
16 # along with this program; if not, write to the Free Software
17 # Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
18 # --
19 #
20 # File: d20.py
21 # Author: Chris Davis
22 # Maintainer:
23 # Version:
24 # $Id: d20.py,v 1.30 2007/05/22 00:50:57 digitalxero Exp $
25 #
26 # Description: The file contains code for the d20 nodehanlers
27 #
28
29 __version__ = "$Id: d20.py,v 1.30 2007/05/22 00:50:57 digitalxero Exp $"
30
31 from core import *
32 import re
33
34 D20_EXPORT = wx.NewId()
35 ############################
36 ## d20 character node handler
37 ############################
38 ## Spells code - added by Dragonstar
39 ##Powers, Divine spells, inventory, howto, power points by Digitalxero
40 ##The whole look and easy of use redone by Digitalxero
41 class container_handler(node_handler):
42 """ should not be used! only a base class!
43 <nodehandler name='?' module='core' class='container_handler' />
44 """
45 def __init__(self,xml_dom,tree_node):
46 node_handler.__init__(self,xml_dom,tree_node)
47 self.load_children()
48
49 def load_children(self):
50 children = self.master_dom._get_childNodes()
51 for c in children:
52 self.tree.load_xml(c,self.mytree_node)
53
54
55 def on_drop(self,evt):
56 drag_obj = self.tree.drag_obj
57 #if self.is_my_child(self.mytree_node,drag_obj.mytree_node):
58 # return
59 if drag_obj == self:
60 return
61 opt = wx.MessageBox("Add node as child?","Container Node",wx.YES_NO|wx.CANCEL)
62 if opt == wx.YES:
63 xml_dom = self.tree.drag_obj.delete()
64 xml_dom = self.master_dom.insertBefore(xml_dom,None)
65 self.tree.load_xml(xml_dom, self.mytree_node)
66 self.tree.Expand(self.mytree_node)
67 elif opt == wx.NO:
68 node_handler.on_drop(self,evt)
69
70 def tohtml(self):
71 cookie = 0
72 html_str = "<table border=\"1\" ><tr><td>"
73 html_str += "<b>"+self.master_dom.getAttribute("name") + "</b>"
74 html_str += "</td></tr>\n"
75 html_str += "<tr><td>"
76
77 max = tree.GetChildrenCount(handler.mytree_node,0)
78 try:
79 (child,cookie)=self.tree.GetFirstChild(self.mytree_node,cookie)
80 except: # If this happens we probably have a newer version of wxPython
81 (child,cookie)=self.tree.GetFirstChild(self.mytree_node)
82 obj = self.tree.GetPyData(child)
83 for m in range(max):
84 html_str += "<p>" + obj.tohtml()
85 if m < max-1:
86 child = self.tree.GetNextSibling(child)
87 if child.IsOk():
88 obj = self.tree.GetPyData(child)
89 html_str += "</td></tr></table>"
90 return html_str
91
92 def get_size_constraint(self):
93 return 1
94
95 def get_char_name( self ):
96 return self.child_handlers['general'].get_char_name()
97
98 def set_char_pp(self,attr,evl):
99 return self.child_handlers['pp'].set_char_pp(attr,evl)
100
101 def get_char_pp( self, attr ):
102 return self.child_handlers['pp'].get_char_pp(attr)
103
104 def get_char_lvl( self, attr ):
105 return self.child_handlers['classes'].get_char_lvl(attr)
106
107
108
109 class d20char_handler(node_handler):
110 """ Node handler for a d20 charactor
111 <nodehandler name='?' module='d20' class='d20char_handler2' />
112 """
113 def __init__(self,xml_dom,tree_node):
114 node_handler.__init__(self,xml_dom,tree_node)
115 self.frame = open_rpg.get_component('frame')
116 self.child_handlers = {}
117 self.new_child_handler('howtouse','HowTO use this tool',d20howto,'note')
118 self.new_child_handler('general','General Information',d20general,'gear')
119 self.new_child_handler('inventory','Money and Inventory',d20inventory,'money')
120 self.new_child_handler('abilities','Abilities Scores',d20ability,'gear')
121 self.new_child_handler('classes','Classes',d20classes,'knight')
122 self.new_child_handler('saves','Saves',d20saves,'skull')
123 self.new_child_handler('skills','Skills',d20skill,'book')
124 self.new_child_handler('feats','Feats',d20feats,'book')
125 self.new_child_handler('spells','Spells',d20spells,'book')
126 self.new_child_handler('divine','Divine Spells',d20divine,'book')
127 self.new_child_handler('powers','Powers',d20powers,'questionhead')
128 self.new_child_handler('hp','Hit Points',d20hp,'gear')
129 self.new_child_handler('pp','Power Points',d20pp,'gear')
130 self.new_child_handler('attacks','Attacks',d20attacks,'spears')
131 self.new_child_handler('ac','Armor',d20armor,'spears')
132 #wxMenuItem(self.tree.std_menu, D20_EXPORT, "Export...", "Export")
133 self.myeditor = None
134
135
136 def on_version(self,old_version):
137 node_handler.on_version(self,old_version)
138 if old_version == "":
139 tmp = open(orpg.dirpath.dir_struct["nodes"]+"d20character.xml","r")
140 xml_dom = parseXml_with_dlg(self.tree,tmp.read())
141 xml_dom = xml_dom._get_firstChild()
142 tmp.close()
143 ## add new nodes
144 for tag in ("howtouse","inventory","powers","divine","pp"):
145 node_list = xml_dom.getElementsByTagName(tag)
146 self.master_dom.appendChild(node_list[0])
147
148 ## add new atts
149 melee_attack = self.master_dom.getElementsByTagName('melee')[0]
150 melee_attack.setAttribute("second","0")
151 melee_attack.setAttribute("third","0")
152 melee_attack.setAttribute("forth","0")
153 melee_attack.setAttribute("fifth","0")
154 melee_attack.setAttribute("sixth","0")
155 range_attack = self.master_dom.getElementsByTagName('ranged')[0]
156 range_attack.setAttribute("second","0")
157 range_attack.setAttribute("third","0")
158 range_attack.setAttribute("forth","0")
159 range_attack.setAttribute("fifth","0")
160 range_attack.setAttribute("sixth","0")
161
162 gen_list = self.master_dom.getElementsByTagName('general')[0]
163
164 for tag in ("currentxp","xptolevel"):
165 node_list = xml_dom.getElementsByTagName(tag)
166 gen_list.appendChild(node_list[0])
167 ## temp fix
168 #parent = self.master_dom._get_parentNode()
169 #old_dom = parent.replaceChild(xml_dom,self.master_dom)
170 #self.master_dom = xml_dom
171 print old_version
172
173
174 def get_char_name( self ):
175 return self.child_handlers['general'].get_char_name()
176
177 def set_char_pp(self,attr,evl):
178 return self.child_handlers['pp'].set_char_pp(attr,evl)
179
180 def get_char_pp( self, attr ):
181 return self.child_handlers['pp'].get_char_pp(attr)
182
183 def get_char_lvl( self, attr ):
184 return self.child_handlers['classes'].get_char_lvl(attr)
185
186
187 def new_child_handler(self,tag,text,handler_class,icon='gear'):
188 node_list = self.master_dom.getElementsByTagName(tag)
189 tree = self.tree
190 i = self.tree.icons[icon]
191 new_tree_node = tree.AppendItem(self.mytree_node,text,i,i)
192 handler = handler_class(node_list[0],new_tree_node,self)
193 tree.SetPyData(new_tree_node,handler)
194 self.child_handlers[tag] = handler
195
196 def get_design_panel(self,parent):
197 return tabbed_panel(parent,self,1)
198
199
200 def get_use_panel(self,parent):
201 return tabbed_panel(parent,self,2)
202
203
204 def tohtml(self):
205 html_str = "<table><tr><td colspan=2 >"+self.child_handlers['general'].tohtml()+"</td></tr>"
206 html_str += "<tr><td width='50%' valign=top >"+self.child_handlers['abilities'].tohtml()
207 html_str += "<P>" + self.child_handlers['saves'].tohtml()
208 html_str += "<P>" + self.child_handlers['attacks'].tohtml()
209 html_str += "<P>" + self.child_handlers['ac'].tohtml()
210 html_str += "<P>" + self.child_handlers['feats'].tohtml()
211 html_str += "<P>" + self.child_handlers['spells'].tohtml()
212 html_str += "<P>" + self.child_handlers['divine'].tohtml()
213 html_str += "<P>" + self.child_handlers['powers'].tohtml()
214 html_str += "<P>" + self.child_handlers['inventory'].tohtml() +"</td>"
215 html_str += "<td width='50%' valign=top >"+self.child_handlers['classes'].tohtml()
216 html_str += "<P>" + self.child_handlers['hp'].tohtml()
217 html_str += "<P>" + self.child_handlers['pp'].tohtml()
218 html_str += "<P>" + self.child_handlers['skills'].tohtml() +"</td>"
219 html_str += "</tr></table>"
220 return html_str
221
222 def about(self):
223 html_str = "<img src='" + orpg.dirpath.dir_struct["icon"]+'d20_logo.gif' "><br /><b>d20 Character Tool v0.7 beta</b>"
224 html_str += "<br />by Chris Davis<br />chris@rpgarchive.com"
225 return html_str
226
227 def get_char_name( self ):
228 return self.child_handlers['general'].get_char_name()
229 def get_armor_class( self ):
230 return self.child_handlers['ac'].get_armor_class()
231 def get_max_hp( self ):
232 return self.child_handlers['hp'].get_max_hp()
233 def get_current_hp( self ):
234 return self.child_handlers['hp'].get_current_hp()
235
236 def set_char_pp(self,attr,evl):
237 return self.child_handlers['pp'].set_char_pp(attr,evl)
238
239 def get_char_pp( self, attr ):
240 return self.child_handlers['pp'].get_char_pp(attr)
241
242 def get_char_lvl( self, attr ):
243 return self.child_handlers['classes'].get_char_lvl(attr)
244
245 class tabbed_panel(wx.Notebook):
246 def __init__(self, parent, handler, mode):
247 wx.Notebook.__init__(self, parent, -1, size=(1200,800))
248 self.handler = handler
249 self.parent = parent
250 tree = self.handler.tree
251 max = tree.GetChildrenCount(handler.mytree_node)
252
253 cookie = 0
254
255 try:
256 (child,cookie)=tree.GetFirstChild(handler.mytree_node,cookie)
257 except: # If this happens we probably have a newer version of wxPython
258 (child,cookie)=tree.GetFirstChild(handler.mytree_node)
259 if not child.IsOk():
260 return
261 obj = tree.GetPyData(child)
262 for m in range(max):
263 if mode == 1:
264 panel = obj.get_design_panel(self)
265 else:
266 panel = obj.get_use_panel(self)
267 name = obj.master_dom.getAttribute("name")
268
269 if panel:
270 self.AddPage(panel,name)
271 if m < max-1:
272 child = tree.GetNextSibling(child)
273 if child.IsOk():
274 obj = tree.GetPyData(child)
275 else:
276 break
277
278
279 def about(self):
280 html_str = "<img src='" + orpg.dirpath.dir_struct["icon"]+'d20_logo.gif' "><br /><b>d20 Character Tool v0.7 beta</b>"
281 html_str += "<br />by Chris Davis<br />chris@rpgarchive.com"
282 return html_str
283
284 def get_char_name( self ):
285 return self.child_handlers['general'].get_char_name()
286
287 def set_char_pp(self,attr,evl):
288 return self.child_handlers['pp'].set_char_pp(attr,evl)
289
290 def get_char_pp( self, attr ):
291 return self.child_handlers['pp'].get_char_pp(attr)
292
293 def get_char_lvl( self, attr ):
294 return self.child_handlers['classes'].get_char_lvl(attr)
295
296 class d20_char_child(node_handler):
297 """ Node Handler for skill. This handler will be
298 created by d20char_handler.
299 """
300 def __init__(self,xml_dom,tree_node,parent):
301 node_handler.__init__(self,xml_dom,tree_node)
302 self.char_hander = parent
303 self.drag = False
304 self.frame = open_rpg.get_component('frame')
305 self.myeditor = None
306
307
308 def on_drop(self,evt):
309 pass
310
311 def on_rclick(self,evt):
312 pass
313
314 def on_ldclick(self,evt):
315 return
316 if self.myeditor == None or self.myeditor.destroyed:
317 title = self.master_dom.getAttribute('name') + " Editor"
318 self.myeditor = wx.Frame(self.frame, -1, title)
319 if wx.Platform == '__WXMSW__':
320 icon = wx.Icon(orpg.dirpath.dir_struct["icon"]+'grid.ico', wx.BITMAP_TYPE_ICO)
321 self.myeditor.SetIcon(icon)
322 del icon
323 wnd = self.get_design_panel(self.myeditor)
324 self.myeditor.panel = wnd
325 self.wnd = wnd
326 self.myeditor.Show(1)
327 else:
328 self.myeditor.Raise()
329
330 def on_html(self,evt):
331 html_str = self.tohtml()
332 wnd = http_html_window(self.frame.note,-1)
333 wnd.title = self.master_dom.getAttribute('name')
334 self.frame.add_panel(wnd)
335 wnd.SetPage(html_str)
336
337 def get_design_panel(self,parent):
338 pass
339
340 def get_use_panel(self,parent):
341 return self.get_design_panel(parent)
342
343 def delete(self):
344 pass
345
346
347 class d20skill(d20_char_child):
348 """ Node Handler for skill. This handler will be
349 created by d20char_handler.
350 """
351 def __init__(self,xml_dom,tree_node,parent):
352 d20_char_child.__init__(self,xml_dom,tree_node,parent)
353 tree = self.tree
354 icons = self.tree.icons
355 node_list = self.master_dom.getElementsByTagName('skill')
356 self.skills={}
357 for n in node_list:
358 name = n.getAttribute('name')
359 self.skills[name] = n
360 new_tree_node = tree.AppendItem(self.mytree_node,name,icons['gear'],icons['gear'])
361 tree.SetPyData(new_tree_node,self)
362
363 def get_mod(self,name):
364 skill = self.skills[name]
365 stat = skill.getAttribute('stat')
366 ac = int(skill.getAttribute('armorcheck'))
367 if ac:
368 ac = self.char_hander.child_handlers['ac'].get_check_pen()
369 stat_mod = self.char_hander.child_handlers['abilities'].get_mod(stat)
370 rank = int(skill.getAttribute('rank'))
371 misc = int(skill.getAttribute('misc'))
372 total = stat_mod + rank + misc + ac
373 return total
374
375 def on_rclick(self,evt):
376 item = self.tree.GetSelection()
377 name = self.tree.GetItemText(item)
378 if item == self.mytree_node:
379 d20_char_child.on_ldclick(self,evt)
380 #wnd = skill_grid(self.frame.note,self)
381 #wnd.title = "Skills
382 #self.frame.add_panel(wnd)
383 else:
384 skill = self.skills[name];
385 untrained = skill.getAttribute('untrained');
386 rank = skill.getAttribute('rank');
387 if untrained == "0" and rank == "0":
388 txt = '%s Skill Check: Untrained' % (name)
389 else:
390 mod = self.get_mod(name)
391 if mod >= 0:
392 mod1 = "+"
393 else:
394 mod1 = ""
395 txt = '%s Skill Check: [1d20%s%s]' % (name, mod1, mod)
396 chat = self.chat
397 chat.ParsePost(txt,True,True)
398
399 def get_design_panel(self,parent):
400 wnd = outline_panel(parent,self,skill_grid,"Skills")
401 wnd.title = "Skills (edit)"
402 return wnd
403
404 def tohtml(self):
405 html_str = """<table border='1' width=100% ><tr BGCOLOR=#E9E9E9 ><th width='30%'>Skill</th><th>Key</th>
406 <th>Rank</th><th>Abil</th><th>Misc</th><th>Total</th></tr>"""
407 node_list = self.master_dom.getElementsByTagName('skill')
408 for n in node_list:
409 name = n.getAttribute('name')
410 stat = n.getAttribute('stat')
411 rank = n.getAttribute('rank')
412 html_str = html_str + "<tr ALIGN='center'><td>"+name+"</td><td>"+stat+"</td><td>"+rank+"</td>"
413 stat_mod = str(self.char_hander.child_handlers['abilities'].get_mod(stat))
414 misc = n.getAttribute('misc')
415 mod = str(self.get_mod(name))
416 if mod >= 0:
417 mod1 = "+"
418 else:
419 mod1 = ""
420 html_str = html_str + "<td>"+stat_mod+"</td><td>"+misc+'</td><td>%s%s</td></tr>' % (mod1, mod)
421 html_str = html_str + "</table>"
422 return html_str
423
424
425 class d20ability(d20_char_child):
426 """ Node Handler for ability. This handler will be
427 created by d20char_handler.
428 """
429 def __init__(self,xml_dom,tree_node,parent):
430 d20_char_child.__init__(self,xml_dom,tree_node,parent)
431 self.abilities = {}
432 node_list = self.master_dom.getElementsByTagName('stat')
433 tree = self.tree
434 icons = tree.icons
435 for n in node_list:
436 name = n.getAttribute('abbr')
437 self.abilities[name] = n
438 new_tree_node = tree.AppendItem( self.mytree_node, name, icons['gear'], icons['gear'] )
439 tree.SetPyData( new_tree_node, self )
440
441 def on_rclick( self, evt ):
442 item = self.tree.GetSelection()
443 name = self.tree.GetItemText( item )
444 if item == self.mytree_node:
445 d20_char_child.on_ldclick( self, evt )
446 else:
447 mod = self.get_mod( name )
448 if mod >= 0:
449 mod1 = "+"
450 else:
451 mod1 = ""
452 chat = self.chat
453 txt = '%s check: [1d20%s%s]' % ( name, mod1, mod )
454 chat.ParsePost( txt, True, True )
455
456 def get_mod(self,abbr):
457 score = int(self.abilities[abbr].getAttribute('base'))
458 mod = (score - 10) / 2
459 return mod
460
461 def set_score(self,abbr,score):
462 if score >= 0:
463 self.abilities[abbr].setAttribute("base",str(score))
464
465 def get_design_panel(self,parent):
466 wnd = outline_panel(parent,self,abil_grid,"Abilities")
467 wnd.title = "Abilities (edit)"
468 return wnd
469
470 def tohtml(self):
471 html_str = """<table border='1' width=100%><tr BGCOLOR=#E9E9E9 ><th width='50%'>Ability</th>
472 <th>Base</th><th>Modifier</th></tr>"""
473 node_list = self.master_dom.getElementsByTagName('stat')
474 for n in node_list:
475 name = n.getAttribute('name')
476 abbr = n.getAttribute('abbr')
477 base = n.getAttribute('base')
478 mod = str(self.get_mod(abbr))
479 if mod >= 0:
480 mod1 = "+"
481 else:
482 mod1 = ""
483 html_str = html_str + "<tr ALIGN='center'><td>"+name+"</td><td>"+base+'</td><td>%s%s</td></tr>' % (mod1, mod)
484 html_str = html_str + "</table>"
485 return html_str
486
487 class d20saves(d20_char_child):
488 """ Node Handler for saves. This handler will be
489 created by d20char_handler.
490 """
491 def __init__(self,xml_dom,tree_node,parent):
492 d20_char_child.__init__(self,xml_dom,tree_node,parent)
493 tree = self.tree
494 icons = self.tree.icons
495 node_list = self.master_dom.getElementsByTagName('save')
496 self.saves={}
497 for n in node_list:
498 name = n.getAttribute('name')
499 self.saves[name] = n
500 new_tree_node = tree.AppendItem(self.mytree_node,name,icons['gear'],icons['gear'])
501 tree.SetPyData(new_tree_node,self)
502
503 def get_mod(self,name):
504 save = self.saves[name]
505 stat = save.getAttribute('stat')
506 stat_mod = self.char_hander.child_handlers['abilities'].get_mod(stat)
507 base = int(save.getAttribute('base'))
508 miscmod = int(save.getAttribute('miscmod'))
509 magmod = int(save.getAttribute('magmod'))
510 total = stat_mod + base + miscmod + magmod
511 return total
512
513 def on_rclick(self,evt):
514 item = self.tree.GetSelection()
515 name = self.tree.GetItemText(item)
516 if item == self.mytree_node:
517 d20_char_child.on_ldclick(self,evt)
518 #wnd = save_grid(self.frame.note,self)
519 #wnd.title = "Saves"
520 #self.frame.add_panel(wnd)
521 else:
522 mod = self.get_mod(name)
523 if mod >= 0:
524 mod1 = "+"
525 else:
526 mod1 = ""
527 chat = self.chat
528 txt = '%s save: [1d20%s%s]' % (name, mod1, mod)
529 chat.ParsePost( txt, True, True )
530
531 def get_design_panel(self,parent):
532 wnd = outline_panel(parent,self,save_grid,"Saves")
533 wnd.title = "Saves"
534 return wnd
535
536 def tohtml(self):
537 html_str = """<table border='1' width=100% ><tr BGCOLOR=#E9E9E9 ><th width='30%'>Save</th>
538 <th>Key</th><th>Base</th><th>Abil</th><th>Magic</th>
539 <th>Misc</th><th>Total</th></tr>"""
540 node_list = self.master_dom.getElementsByTagName('save')
541 for n in node_list:
542 name = n.getAttribute('name')
543 stat = n.getAttribute('stat')
544 base = n.getAttribute('base')
545 html_str = html_str + "<tr ALIGN='center'><td>"+name+"</td><td>"+stat+"</td><td>"+base+"</td>"
546 stat_mod = str(self.char_hander.child_handlers['abilities'].get_mod(stat))
547 mag = n.getAttribute('magmod')
548 misc = n.getAttribute('miscmod')
549 mod = str(self.get_mod(name))
550 if mod >= 0:
551 mod1 = "+"
552 else:
553 mod1 = ""
554 html_str = html_str + "<td>"+stat_mod+"</td><td>"+mag+"</td>"
555 html_str = html_str + '<td>'+misc+'</td><td>%s%s</td></tr>' % (mod1, mod)
556 html_str = html_str + "</table>"
557 return html_str
558
559
560 class d20general(d20_char_child):
561 """ Node Handler for general information. This handler will be
562 created by d20char_handler.
563 """
564 def __init__(self,xml_dom,tree_node,parent):
565 d20_char_child.__init__(self,xml_dom,tree_node,parent)
566
567 def get_design_panel(self,parent):
568 wnd = outline_panel(parent,self,gen_grid,"General Information")
569 wnd.title = "General Info"
570 return wnd
571
572 def tohtml(self):
573 n_list = self.master_dom._get_childNodes()
574 html_str = "<table width=100% border=1 ><tr BGCOLOR=#E9E9E9 ><th>General Information</th></tr><tr><td>"
575 for n in n_list:
576 t_node = safe_get_text_node(n)
577 html_str += "<B>"+n._get_tagName().capitalize() +":</B> "
578 html_str += t_node._get_nodeValue() + ", "
579 html_str = html_str[:len(html_str)-2] + "</td></tr></table>"
580 return html_str
581
582 def on_name_change(self,name):
583 self.char_hander.rename(name)
584
585 def get_char_name( self ):
586 node = self.master_dom.getElementsByTagName( 'name' )[0]
587 t_node = safe_get_text_node( node )
588 return t_node._get_nodeValue()
589
590
591 class d20classes(d20_char_child):
592 """ Node Handler for classes. This handler will be
593 created by d20char_handler.
594 """
595 def __init__(self,xml_dom,tree_node,parent):
596 d20_char_child.__init__(self,xml_dom,tree_node,parent)
597
598 def get_design_panel(self,parent):
599 wnd = outline_panel(parent,self,class_panel,"Classes")
600 wnd.title = "Classes"
601 return wnd
602
603 def tohtml(self):
604 html_str = "<table width=100% border=1 ><tr BGCOLOR=#E9E9E9 ><th>Classes</th></tr><tr><td>"
605 n_list = self.master_dom._get_childNodes()
606 for n in n_list:
607 html_str += n.getAttribute('name') + " ("+n.getAttribute('level')+"), "
608 html_str = html_str[:len(html_str)-2] + "</td></tr></table>"
609 return html_str
610
611 def get_char_lvl( self, attr ):
612 node_list = self.master_dom.getElementsByTagName('class')
613 for n in node_list:
614 lvl = n.getAttribute('level')
615 type = n.getAttribute('name')
616 if attr == "level":
617 return lvl
618 elif attr == "class":
619 return type
620
621
622 class d20feats(d20_char_child):
623 """ Node Handler for classes. This handler will be
624 created by d20char_handler.
625 """
626 def __init__(self,xml_dom,tree_node,parent):
627 d20_char_child.__init__(self,xml_dom,tree_node,parent)
628
629 def get_design_panel(self,parent):
630 wnd = outline_panel(parent,self,feat_panel,"Feats")
631 wnd.title = "Feats"
632 return wnd
633
634 def tohtml(self):
635 html_str = "<table width=100% border=1 ><tr BGCOLOR=#E9E9E9 ><th>Feats</th></tr><tr><td>"
636 n_list = self.master_dom._get_childNodes()
637 for n in n_list:
638 html_str += n.getAttribute('name')+ ", "
639 html_str = html_str[:len(html_str)-2] + "</td></tr></table>"
640 return html_str
641
642 class d20spells(d20_char_child):
643 """ Node Handler for classes. This handler will be
644 created by d20char_handler.
645 """
646 def __init__(self,xml_dom,tree_node,parent):
647 d20_char_child.__init__(self,xml_dom,tree_node,parent)
648 node_list = self.master_dom.getElementsByTagName( 'spell' )
649 self.spells = {}
650 tree = self.tree
651 icons = self.tree.icons
652 for n in node_list:
653 name = n.getAttribute('name')
654 self.spells[ name ] = n
655 new_tree_node = tree.AppendItem( self.mytree_node, name, icons['gear'], icons['gear'] )
656 tree.SetPyData( new_tree_node, self )
657
658 def on_rclick( self, evt ):
659 item = self.tree.GetSelection()
660 name = self.tree.GetItemText( item )
661 if item == self.mytree_node:
662 d20_char_child.on_ldclick( self, evt )
663 else:
664 level = self.spells[ name ].getAttribute( 'level' )
665 descr = self.spells[ name ].getAttribute( 'desc' )
666 use = self.spells[ name ].getAttribute( 'used' )
667 memrz = self.spells[ name ].getAttribute( 'memrz' )
668 cname = self.char_hander.get_char_name()
669 use += '+1'
670 left = eval( '%s - ( %s )' % ( memrz, use ) )
671 if left < 0:
672 txt = '%s Tried to cast %s but has used all of them for today, "Please rest so I can cast more."' % ( cname, name )
673 self.chat.ParsePost( txt, True, False )
674 else:
675 txt = '%s casts %s ( level %s, "%s" )' % ( cname, name, level, descr )
676 self.chat.ParsePost( txt, True, False )
677 s = ''
678 if left != 1:
679 s = 's'
680 txt = '%s can cast %s %d more time%s' % ( cname, name, left, s )
681 self.chat.ParsePost( txt, False, False )
682 self.spells[ name ].setAttribute( 'used', `eval( use )` )
683
684 def refresh_spells(self):
685 self.spells = {}
686 tree = self.tree
687 icons = self.tree.icons
688 tree.CollapseAndReset(self.mytree_node)
689 node_list = self.master_dom.getElementsByTagName('spell')
690 for n in node_list:
691 name = n.getAttribute('name')
692 new_tree_node = tree.AppendItem(self.mytree_node,name,icons['gear'],icons['gear'])
693 tree.SetPyData(new_tree_node,self)
694 self.spells[name]=n
695
696 def get_design_panel(self,parent):
697 wnd = outline_panel(parent,self,spell_panel,"Spells")
698 wnd.title = "Spells"
699 return wnd
700
701 def tohtml(self):
702 html_str = "<table width=100% border=1 ><tr BGCOLOR=#E9E9E9 ><th>Arcane Spells</th></tr><tr><td><br />"
703 n_list = self.master_dom._get_childNodes()
704 for n in n_list:
705 html_str += "(" + n.getAttribute('level') + ") " + n.getAttribute('name')+ ", "
706 html_str = html_str[:len(html_str)-2] + "</td></tr></table>"
707 return html_str
708
709 def get_char_lvl( self, attr ):
710 return self.char_hander.get_char_lvl(attr)
711
712 class d20divine(d20_char_child):
713 """ Node Handler for classes. This handler will be
714 created by d20char_handler.
715 """
716 def __init__(self,xml_dom,tree_node,parent):
717 d20_char_child.__init__(self,xml_dom,tree_node,openrpg,parent)
718 node_list = self.master_dom.getElementsByTagName( 'gift' )
719 self.spells = {}
720 tree = self.tree
721 icons = self.tree.icons
722 for n in node_list:
723 name = n.getAttribute('name')
724 self.spells[ name ] = n
725 new_tree_node = tree.AppendItem( self.mytree_node, name, icons['flask'], icons['flask'] )
726 tree.SetPyData( new_tree_node, self )
727
728 def on_rclick( self, evt ):
729 item = self.tree.GetSelection()
730 name = self.tree.GetItemText( item )
731 if item == self.mytree_node:
732 d20_char_child.on_ldclick( self, evt )
733 else:
734 level = self.spells[ name ].getAttribute( 'level' )
735 descr = self.spells[ name ].getAttribute( 'desc' )
736 use = self.spells[ name ].getAttribute( 'used' )
737 memrz = self.spells[ name ].getAttribute( 'memrz' )
738 cname = self.char_hander.get_char_name()
739 use += '+1'
740 left = eval( '%s - ( %s )' % ( memrz, use ) )
741 if left < 0:
742 txt = '%s Tried to cast %s but has used all of them for today, "Please rest so I can cast more."' % ( cname, name )
743 self.chat.ParsePost( txt, True, False )
744 else:
745 txt = '%s casts %s ( level %s, "%s" )' % ( cname, name, level, descr )
746 self.chat.ParsePost( txt, True, False )
747 s = ''
748 if left != 1:
749 s = 's'
750 txt = '%s can cast %s %d more time%s' % ( cname, name, left, s )
751 self.chat.ParsePost( txt, False, False )
752 self.spells[ name ].setAttribute( 'used', `eval( use )` )
753
754 def refresh_spells(self):
755 self.spells = {}
756 tree = self.tree
757 icons = self.tree.icons
758 tree.CollapseAndReset(self.mytree_node)
759 node_list = self.master_dom.getElementsByTagName('gift')
760 for n in node_list:
761 name = n.getAttribute('name')
762 new_tree_node = tree.AppendItem(self.mytree_node,name,icons['flask'],icons['flask'])
763 tree.SetPyData(new_tree_node,self)
764 self.spells[name]=n
765
766 def get_design_panel(self,parent):
767 wnd = outline_panel(parent,self,divine_panel,"Spells")
768 wnd.title = "Spells"
769 return wnd
770
771 def tohtml(self):
772 html_str = "<table width=100% border=1 ><tr BGCOLOR=#E9E9E9 ><th>Divine Spells</th></tr><tr><td><br />"
773 n_list = self.master_dom._get_childNodes()
774 for n in n_list:
775 html_str += "(" + n.getAttribute('level') + ") " + n.getAttribute('name')+ ", "
776 html_str = html_str[:len(html_str)-2] + "</td></tr></table>"
777 return html_str
778
779 def get_char_lvl( self, attr ):
780 return self.char_hander.get_char_lvl(attr)
781
782 class d20powers(d20_char_child):
783 """ Node Handler for classes. This handler will be
784 created by d20char_handler.
785 """
786 def __init__(self,xml_dom,tree_node,parent):
787 d20_char_child.__init__(self,xml_dom,tree_node,parent)
788 node_list = self.master_dom.getElementsByTagName( 'power' )
789 #cpp = self.master_dom.getElementsByTagName( 'pp' ).getAttribute('current1')
790 self.powers = {}
791 tree = self.tree
792 icons = self.tree.icons
793 for n in node_list:
794 name = n.getAttribute('name')
795 self.powers[ name ] = n
796 new_tree_node = tree.AppendItem( self.mytree_node, name, icons['gear'], icons['gear'] )
797 tree.SetPyData( new_tree_node, self )
798
799 def on_rclick( self, evt ):
800 item = self.tree.GetSelection()
801 name = self.tree.GetItemText( item )
802 if item == self.mytree_node:
803 d20_char_child.on_ldclick( self, evt )
804 else:
805 level = self.powers[ name ].getAttribute( 'level' )
806 descr = self.powers[ name ].getAttribute( 'desc' )
807 use = self.powers[ name ].getAttribute( 'used' )
808 points = self.powers[ name ].getAttribute( 'point' )
809 cpp = self.char_hander.get_char_pp('current1')
810 fre = self.char_hander.get_char_pp('free')
811 cname = self.char_hander.get_char_name()
812 if level == "0" and fre != "0":
813 left = eval('%s - ( %s )' % ( fre, points ))
814 numcast = eval('%s / %s' % (left, points))
815 if left < 0:
816 txt = '%s doesnt have enough PowerPoints to use %s' % ( cname, name )
817 self.chat.ParsePost( txt, True, False )
818 else:
819 txt = '%s uses %s as a Free Talent ( level %s, "%s" )' % ( cname, name, level, descr )
820 self.chat.ParsePost( txt, True, False )
821 s = ''
822 if left != 1:
823 s = 's'
824 txt = '%s can use %s %d more time%s' % ( cname, name, numcast, s )
825 self.chat.ParsePost( txt, False, False )
826 self.char_hander.set_char_pp('free', left)
827 else:
828 left = eval('%s - ( %s )' % ( cpp, points ))
829 numcast = eval('%s / %s' % (left, points))
830 if left < 0:
831 txt = '%s doesnt have enough PowerPoints to use %s' % ( cname, name )
832 self.chat.ParsePost( txt, True, False )
833 else:
834 txt = '%s uses %s ( level %s, "%s" )' % ( cname, name, level, descr )
835 self.chat.ParsePost( txt, True, False )
836 s = ''
837 if left != 1:
838 s = 's'
839 txt = '%s can use %s %d more time%s' % ( cname, name, numcast, s )
840 txt += ' - And has %d more PowerpointsP left' % (left)
841 self.chat.ParsePost( txt, False, False )
842 self.char_hander.set_char_pp('current1', left)
843
844 def refresh_powers(self):
845 self.powers = {}
846 tree = self.tree
847 icons = self.tree.icons
848 tree.CollapseAndReset(self.mytree_node)
849 node_list = self.master_dom.getElementsByTagName('power')
850 for n in node_list:
851 name = n.getAttribute('name')
852 new_tree_node = tree.AppendItem(self.mytree_node,name,icons['questionhead'],icons['questionhead'])
853 tree.SetPyData(new_tree_node,self)
854 self.powers[name]=n
855
856 def get_design_panel(self,parent):
857 wnd = outline_panel(parent,self,power_panel,"Powers")
858 wnd.title = "Powers"
859 return wnd
860
861 def tohtml(self):
862 html_str = "<table width=100% border=1 ><tr BGCOLOR=#E9E9E9 ><th>Powers</th></tr><tr><td><br />"
863 n_list = self.master_dom._get_childNodes()
864 for n in n_list:
865 html_str += "(" + n.getAttribute('level') + ") " + n.getAttribute('name')+ ", "
866 html_str = html_str[:len(html_str)-2] + "</td></tr></table>"
867 return html_str
868
869 def get_char_lvl( self, attr ):
870 return self.char_hander.get_char_lvl(attr)
871
872 def set_char_pp(self,attr,evl):
873 return self.char_hander.set_char_pp(attr,evl)
874
875 def get_char_pp( self, attr ):
876 return self.char_hander.get_char_pp(attr)
877
878 class d20howto(d20_char_child):
879 """ Node Handler for hit points. This handler will be
880 created by d20char_handler.
881 """
882 def __init__(self,xml_dom,tree_node,parent):
883 d20_char_child.__init__(self,xml_dom,tree_node,parent)
884
885 def get_design_panel(self,parent):
886 wnd = outline_panel(parent,self,howto_panel,"How To")
887 wnd.title = "How To"
888 return wnd
889
890 class d20inventory(d20_char_child):
891 """ Node Handler for general information. This handler will be
892 created by d20char_handler.
893 """
894 def __init__(self,xml_dom,tree_node,parent):
895 d20_char_child.__init__(self,xml_dom,tree_node,parent)
896
897 def get_design_panel(self,parent):
898 wnd = outline_panel(parent,self,inventory_grid,"Inventory")
899 wnd.title = "General Info"
900 return wnd
901
902 def tohtml(self):
903 n_list = self.master_dom._get_childNodes()
904 html_str = "<table width=100% border=1 ><tr BGCOLOR=#E9E9E9 ><th>General Information</th></tr><tr><td>"
905 for n in n_list:
906 t_node = safe_get_text_node(n)
907 html_str += "<B>"+n._get_tagName().capitalize() +":</B> "
908 html_str += t_node._get_nodeValue() + "<br />"
909 html_str = html_str[:len(html_str)-2] + "</td></tr></table>"
910 return html_str
911
912 def on_name_change(self,name):
913 self.char_hander.rename(name)
914
915 def get_char_name( self ):
916 node = self.master_dom.getElementsByTagName( 'name' )[0]
917 t_node = safe_get_text_node( node )
918 return t_node._get_nodeValue()
919
920 class d20hp(d20_char_child):
921 """ Node Handler for hit points. This handler will be
922 created by d20char_handler.
923 """
924 def __init__(self,xml_dom,tree_node,parent):
925 d20_char_child.__init__(self,xml_dom,tree_node,parent)
926
927 def get_design_panel(self,parent):
928 wnd = outline_panel(parent,self,hp_panel,"Hit Points")
929 wnd.title = "Hit Points"
930 return wnd
931
932 def tohtml(self):
933 html_str = "<table width=100% border=1 ><tr BGCOLOR=#E9E9E9 ><th colspan=4>Hit Points</th></tr>"
934 html_str += "<tr><th>Max:</th><td>"+self.master_dom.getAttribute('max')+"</td>"
935 html_str += "<th>Current:</th><td>"+self.master_dom.getAttribute('current')+"</td>"
936 html_str += "</tr></table>"
937 return html_str
938
939 def get_max_hp( self ):
940 try:
941 return eval( self.master_dom.getAttribute( 'max' ) )
942 except:
943 return 0
944 def get_current_hp( self ):
945 try:
946 return eval( self.master_dom.getAttribute( 'current' ) )
947 except:
948 return 0
949
950 class d20pp(d20_char_child):
951 """ Node Handler for power points. This handler will be
952 created by d20char_handler.
953 """
954 def __init__(self,xml_dom,tree_node,parent):
955 d20_char_child.__init__(self,xml_dom,tree_node,parent)
956
957 def get_design_panel(self,parent):
958 wnd = outline_panel(parent,self,pp_panel,"Power Points")
959 wnd.title = "Power Points"
960 return wnd
961
962 def tohtml(self):
963 html_str = "<table width=100% border=1 ><tr BGCOLOR=#E9E9E9 ><th colspan=8>Power Points</th></tr>"
964 html_str += "<tr><th>Max:</th><td>"+self.master_dom.getAttribute('max1')+"</td>"
965 html_str += "<th>Current:</th><td>"+self.master_dom.getAttribute('current1')+"</td>"
966 html_str += "<th>Current Talents/day:</th><td>"+self.master_dom.getAttribute('free')+"</td>"
967 html_str += "<th>Max Talents/day:</th><td>"+self.master_dom.getAttribute('maxfree')+"</td>"
968 html_str += "</tr></table>"
969 return html_str
970
971 def get_char_pp( self, attr ):
972 pp = self.master_dom.getAttribute(attr)
973 return pp
974
975 def set_char_pp( self, attr, evl ):
976 pp = self.master_dom.setAttribute(attr, evl)
977 return pp
978
979 class d20attacks(d20_char_child):
980 """ Node Handler for attacks. This handler will be
981 created by d20char_handler.
982 """
983 def __init__(self,xml_dom,tree_node,parent):
984 d20_char_child.__init__(self,xml_dom,tree_node,parent)
985 node_list = self.master_dom.getElementsByTagName('melee')
986 self.melee = node_list[0]
987 node_list = self.master_dom.getElementsByTagName('ranged')
988 self.ranged = node_list[0]
989 self.refresh_weapons()
990
991 def refresh_weapons(self):
992 self.weapons = {}
993 tree = self.tree
994 icons = self.tree.icons
995 tree.CollapseAndReset(self.mytree_node)
996 node_list = self.master_dom.getElementsByTagName('weapon')
997 for n in node_list:
998 name = n.getAttribute('name')
999 new_tree_node = tree.AppendItem(self.mytree_node,name,icons['sword'],icons['sword'])
1000 tree.SetPyData(new_tree_node,self)
1001 self.weapons[name]=n
1002
1003 def get_attack_data(self):
1004 temp = self.melee
1005 base = int(temp.getAttribute('base'))
1006 base2 = int(temp.getAttribute('second'))
1007 base3 = int(temp.getAttribute('third'))
1008 base4 = int(temp.getAttribute('forth'))
1009 base5 = int(temp.getAttribute('fifth'))
1010 base6 = int(temp.getAttribute('sixth'))
1011 misc = int(temp.getAttribute('misc'))
1012 return (base, base2, base3, base4, base5, base6, misc)
1013
1014 # Replace any 'S' and 'D' in an attack modifier and damage modifier with the
1015 # strength bonus or dexterity bonus respectively.
1016 def process_mod_codes( self, attack, damage ):
1017 str_mod = self.char_hander.child_handlers['abilities'].get_mod( 'Str' )
1018 dex_mod = self.char_hander.child_handlers['abilities'].get_mod( 'Dex' )
1019 str_re = re.compile('S')
1020 dex_re = re.compile('D')
1021 attack = str_re.sub( str( str_mod ), attack )
1022 attack = dex_re.sub( str( dex_mod ), attack )
1023 damage = str_re.sub( str( str_mod ), damage );
1024 damage = dex_re.sub( str( dex_mod ), damage );
1025 return (attack, damage)
1026
1027 # Decompose a damage string (e.g. longsword +1 sneak attack "1d8+S+1+1d6")
1028 # into it's 4 seperate components <n>d<s>+<mods>+<extra dice>
1029 def decompose_damage( self, damage ):
1030 m = re.match( r"(?P<n>\d+)d(?P<s>\d+)(?P<mods>(\s*(\+|-|/|\*)\s*(\d+|D|S)*)*)(?P<extra>(\s*(\+|-)\s*\d+d\d+)?)\s*$", damage )
1031 return (int(m.group('n')), int(m.group('s')), m.group('mods'), m.group('extra'))
1032
1033 def on_rclick(self,evt):
1034 item = self.tree.GetSelection()
1035 name = self.tree.GetItemText(item)
1036 if item == self.mytree_node:
1037 d20_char_child.on_ldclick(self,evt)
1038 #self.frame.add_panel(self.get_design_panel(self.frame.note))
1039 else:
1040 # Weapon/attack specific attack modifier (e.g. "S+1" for a longsword+1).
1041 attack_mod_str = self.weapons[name].getAttribute('mod')
1042
1043 # Weapon/attack specific damage (e.g. "1d8+S+1" for a longsword+1).
1044 damage_str = self.weapons[name].getAttribute('damage')
1045 (num_damage_dice, damage_die, damage_mods, extra_damage) = self.decompose_damage( damage_str )
1046
1047 # Replace any 'S' and 'D' in attack_mod_str and damage_str with the
1048 # strength bonus or dexterity bonus respectively.
1049 (attack_mod_str, damage_mods) = self.process_mod_codes( attack_mod_str, damage_mods )
1050
1051 # Base attack bonuses for up to six attacks.
1052 bab_attributes = ['base', 'second', 'third', 'forth', 'fifth', 'sixth']
1053 bab = []
1054 for b in bab_attributes:
1055 bab.append( int(self.melee.getAttribute( b )) )
1056
1057 # Misc. attack modifier to be applied to *all* attacks.
1058 misc_mod = int(self.melee.getAttribute( 'misc' ));
1059
1060 # Attack modifier (except BAB)
1061 attack_mod = misc_mod + eval( attack_mod_str )
1062
1063 # Total damage mod (except extra dice)
1064 if damage_mods != '':
1065 damage_mod = eval( damage_mods )
1066 else:
1067 damage_mod = 0
1068
1069 # Determine critical hit range and multiplier.
1070 critical_str = self.weapons[name].getAttribute( 'critical' )
1071 m = re.match( r"(((?P<min>\d+)-)?\d+/)?x(?P<mult>\d+)", critical_str )
1072 crit_min = m.group( 'min' )
1073 crit_mult = m.group( 'mult' )
1074 if crit_min == None:
1075 crit_min = 20
1076 else:
1077 crit_min = int( crit_min )
1078 if crit_mult == None:
1079 crit_mult = 2
1080 else:
1081 crit_mult = int( crit_mult )
1082
1083 # Simple matter to output all the attack/damage lines to the chat buffer.
1084 for i in range( 0, len( bab ) ):
1085 if bab[i] > 0 or i == 0:
1086 attack_roll_str = '[1d20%+d]' % (bab[i] + attack_mod)
1087 attack_roll_parsed = self.chat.ParseDice( attack_roll_str )
1088 damage_roll_str = '[%dd%d%+d%s]' % (num_damage_dice, damage_die, damage_mod, extra_damage)
1089 damage_roll_parsed = self.chat.ParseDice( damage_roll_str )
1090 txt = '%s (%s): %s ===> Damage: %s' \
1091 % (name, bab_attributes[i], attack_roll_parsed, damage_roll_parsed)
1092 self.chat.Post( txt, True, True )
1093
1094 # Check for a critical hit
1095 d20_roll = int(re.match( r".*\[(\d+),.*", attack_roll_parsed ).group(1));
1096 dmg = damage_str
1097 if d20_roll >= crit_min:
1098 for j in range(1,crit_mult):
1099 dmg += '+%s' % damage_str
1100 txt = 'Critical hit? [1d20%+d] ===> Damage: [%dd%d%+d%s]' \
1101 % (bab[i] + attack_mod, crit_mult*num_damage_dice, \
1102 damage_die, crit_mult*damage_mod, extra_damage)
1103 self.chat.ParsePost( txt, True, True )
1104
1105 def get_design_panel(self,parent):
1106 wnd = outline_panel(parent,self,attack_panel,"Attacks")
1107 wnd.title = "Attacks"
1108 return wnd
1109
1110 def get_char_lvl( self, attr ):
1111 return self.char_hander.get_char_lvl(attr)
1112
1113 def tohtml(self):
1114 babs = self.get_attack_data()
1115 html_str = "<table width=100% border=1 ><tr ALIGN='center'><th BGCOLOR=#E9E9E9>Base Attack Bonus</th>"
1116 html_str += '<td>%+d' % babs[0]
1117 for i in range(1,6):
1118 if babs[i] > 0:
1119 html_str += '/%+d' % babs[i]
1120 html_str += "</td></tr><tr ALIGN='center' ><th BGCOLOR=#E9E9E9>Misc. Attack Bonus</th>"
1121 html_str += '<td>%+d</td></tr></table>' % babs[6]
1122
1123 n_list = self.master_dom.getElementsByTagName('weapon')
1124 for n in n_list:
1125 (attack_mod, damage_mod) = self.process_mod_codes( n.getAttribute( 'mod' ), \
1126 n.getAttribute( 'damage' ) )
1127 attack_mod = eval( attack_mod )
1128 html_str += """<P><table width=100% border=1><tr BGCOLOR=#E9E9E9><th colspan=3>Weapon</th>
1129 <th>Attack</th><th >Damage</th></tr>""" \
1130 + "<tr ALIGN='center'><td colspan=3>" \
1131 + n.getAttribute('name') + "</td><td>"
1132 html_str += '%+d</td><td>%s</td></tr>' % (attack_mod, damage_mod)
1133 html_str += """<tr BGCOLOR=#E9E9E9 ><th>Critical</th><th>Range</th><th>Weight</th>
1134 <th>Type</th><th>Size</th></tr>""" \
1135 + "<tr ALIGN='center'><td>" \
1136 + n.getAttribute( 'critical' ) + "</td><td>" \
1137 + n.getAttribute( 'range' ) + "</td><td>" \
1138 + n.getAttribute( 'weight' )+"</td><td>" \
1139 + n.getAttribute( 'type' ) + "</td><td>" \
1140 + n.getAttribute( 'size' ) + "</td></tr></table>"
1141 return html_str
1142
1143 class d20armor(d20_char_child):
1144 """ Node Handler for ac. This handler will be
1145 created by d20char_handler.
1146 """
1147 def __init__(self,xml_dom,tree_node,parent):
1148 d20_char_child.__init__(self,xml_dom,tree_node,parent)
1149
1150 def get_spell_failure(self):
1151 return self.get_total('spellfailure')
1152
1153 def get_total_weight(self):
1154 return self.get_total('weight')
1155
1156 def get_check_pen(self):
1157 return self.get_total('checkpenalty')
1158
1159 def get_armor_class(self):
1160 ac_total = 10
1161 ac_total += self.get_total('bonus')
1162 dex_mod = self.char_hander.child_handlers['abilities'].get_mod('Dex')
1163 max_dex = self.get_max_dex()
1164 if dex_mod < max_dex:
1165 ac_total += dex_mod
1166 else:
1167 ac_total += max_dex
1168 return ac_total
1169
1170 def get_max_dex(self):
1171 armor_list = self.master_dom.getElementsByTagName('armor')
1172 dex = 10
1173 for a in armor_list:
1174 temp = int(a.getAttribute("maxdex"))
1175 if temp < dex:
1176 dex = temp
1177 return dex
1178
1179 def get_total(self,attr):
1180 armor_list = self.master_dom.getElementsByTagName('armor')
1181 total = 0
1182 for a in armor_list:
1183 total += int(a.getAttribute(attr))
1184 return total
1185
1186 def get_design_panel(self,parent):
1187 wnd = outline_panel(parent,self,ac_panel,"Armor")
1188 wnd.title = "Armor"
1189 return wnd
1190
1191 def tohtml(self):
1192 html_str = """<table width=100% border=1 ><tr BGCOLOR=#E9E9E9 ><th>AC</th>
1193 <th>Check Penalty</th><th >Spell Failure</th><th>Max Dex</th><th>Total Weight</th></tr>"""
1194 html_str += "<tr ALIGN='center' ><td>"+str(self.get_armor_class())+"</td>"
1195 html_str += "<td>"+str(self.get_check_pen())+"</td>"
1196 html_str += "<td>"+str(self.get_spell_failure())+"</td>"
1197 html_str += "<td>"+str(self.get_max_dex())+"</td>"
1198 html_str += "<td>"+str(self.get_total_weight())+"</td></tr></table>"
1199 n_list = self.master_dom._get_childNodes()
1200 for n in n_list:
1201 html_str += """<P><table width=100% border=1 ><tr BGCOLOR=#E9E9E9 ><th colspan=3>Armor</th>
1202 <th>Type</th><th >Bonus</th></tr>"""
1203 html_str += "<tr ALIGN='center' ><td colspan=3>"+n.getAttribute('name')+"</td>"
1204 html_str += "<td>"+n.getAttribute('type')+"</td>"
1205 html_str += "<td>"+n.getAttribute('bonus')+"</td></tr>"
1206 html_str += """<tr BGCOLOR=#E9E9E9 ><th>Check Penalty</th><th>Spell Failure</th>
1207 <th>Max Dex</th><th>Speed</th><th>Weight</th></tr>"""
1208 html_str += "<tr ALIGN='center'><td>"+n.getAttribute('checkpenalty')+"</td>"
1209 html_str += "<td>"+n.getAttribute('spellfailure')+"</td>"
1210 html_str += "<td>"+n.getAttribute('maxdex')+"</td>"
1211 html_str += "<td>"+n.getAttribute('speed')+"</td>"
1212 html_str += "<td>"+n.getAttribute('weight')+"</td></tr></table>"
1213 return html_str
1214
1215
1216 ########################
1217 ## d20 char windows
1218 ########################
1219
1220 class base_panel(wx.Panel):
1221 def __init__(self, parent):
1222 wx.Panel.__init__(self, parent, -1)
1223
1224 #self.build_ctrls()
1225 self.Bind(wx.EVT_SIZE, self.on_size)
1226
1227 def on_size(self,event):
1228 s = self.GetClientSizeTuple()
1229 #self.splitter.SetDimensions(0,0,s[0],s[1])
1230
1231 class outline_panel(wx.Panel):
1232 def __init__(self, parent, handler, wnd, txt,):
1233 wx.Panel.__init__(self, parent, -1)
1234 self.panel = wnd(self,handler)
1235 self.outline = wx.StaticBox(self,-1,txt)
1236 self.Bind(wx.EVT_SIZE, self.on_size)
1237
1238 def on_size(self,event):
1239 s = self.GetClientSizeTuple()
1240 self.panel.SetDimensions(20,20,s[0]-40,s[1]-40)
1241 self.outline.SetDimensions(5,5,s[0]-10,s[1]-10)
1242
1243 class char_panel(wx.ScrolledWindow):
1244 def __init__(self, parent, handler):
1245 pname = handler.master_dom.setAttribute("name", 'TWO')
1246 wx.ScrolledWindow.__init__(self, parent, -1,style=wx.VSCROLL | wx.SUNKEN_BORDER )
1247 self.height = 1200
1248 self.SetScrollbars(10, 10,80, self.height/10)
1249 self.main_sizer = wx.BoxSizer(wx.HORIZONTAL)
1250 self.panels = {}
1251 keys = handler.child_handlers.keys()
1252 for k in keys:
1253 self.panels[k] = handler.child_handlers[k].get_design_panel(self, [k])
1254 self.sub_sizer = wx.BoxSizer(wx.VERTICAL)
1255 self.sub_sizer2 = wx.BoxSizer(wx.VERTICAL)
1256 self.sub_sizer.Add(self.panels['general'], 1, wx.EXPAND)
1257 self.sub_sizer.Add(self.panels['abilities'], 1, wx.EXPAND)
1258
1259 self.sub_sizer.Add(self.panels['attacks'], 2, wx.EXPAND)
1260 self.sub_sizer.Add(self.panels['ac'], 1, wx.EXPAND)
1261 self.sub_sizer.Add(self.panels['spells'], 1, wx.EXPAND)
1262
1263 self.sub_sizer2.Add(self.panels['classes'], 2, wx.EXPAND)
1264 self.sub_sizer2.Add(self.panels['hp'], 1, wx.EXPAND)
1265 self.sub_sizer2.Add(self.panels['pp'], 1, wx.EXPAND)
1266 self.sub_sizer2.Add(self.panels['saves'], 2, wx.EXPAND)
1267
1268 self.sub_sizer2.Add(self.panels['feats'], 2, wx.EXPAND)
1269 self.sub_sizer2.Add(self.panels['powers'], 2, wx.EXPAND)
1270 self.sub_sizer2.Add(self.panels['skills'], 3, wx.EXPAND)
1271
1272 self.main_sizer.Add(self.sub_sizer, 1, wx.EXPAND)
1273 self.main_sizer.Add(self.sub_sizer2, 1, wx.EXPAND)
1274 self.panels['abilities'].panel.char_wnd = self
1275 self.SetSizer(self.main_sizer)
1276 self.Bind(wx.EVT_SIZE, self.on_size)
1277
1278
1279 def on_size(self,evt):
1280 s = self.GetClientSizeTuple()
1281 self.SetScrollbars(10, 10,s[0]/10, self.height/10)
1282 dc = wx.ClientDC(self)
1283 x = dc.DeviceToLogicalX(0)
1284 y = dc.DeviceToLogicalY(0)
1285 self.main_sizer.SetDimension(x,y,s[0],self.height)
1286 evt.Skip()
1287
1288 def refresh_data(self):
1289 self.panels['saves'].panel.refresh_data()
1290 self.panels['skills'].panel.refresh_data()
1291 self.panels['attacks'].panel.refresh_data()
1292 self.panels['powers'].panel.refresh_data()
1293 self.panels['spells'].panel.refresh_data()
1294
1295 HOWTO_MAX = wx.NewId()
1296
1297 class howto_panel(wx.Panel):
1298 def __init__(self, parent, handler):
1299 wx.Panel.__init__(self, parent, -1)
1300 pname = handler.master_dom.setAttribute("name", 'How To')
1301 self.sizer = wx.FlexGridSizer(2, 4, 2, 2) # rows, cols, hgap, vgap
1302 self.master_dom = handler.master_dom
1303 n_list = self.master_dom._get_childNodes()
1304 for n in n_list:
1305 t_node = safe_get_text_node(n)
1306 self.sizer.AddMany([ (wx.StaticText(self, -1, t_node._get_nodeValue()), 0, wx.ALIGN_CENTER_VERTICAL),
1307 ])
1308 self.sizer.AddGrowableCol(1)
1309 self.SetSizer(self.sizer)
1310
1311
1312 HP_CUR = wx.NewId()
1313 HP_MAX = wx.NewId()
1314
1315 class hp_panel(wx.Panel):
1316 def __init__(self, parent, handler):
1317 wx.Panel.__init__(self, parent, -1)
1318 pname = handler.master_dom.setAttribute("name", 'HitPoints')
1319 self.sizer = wx.FlexGridSizer(2, 4, 2, 2) # rows, cols, hgap, vgap
1320 self.master_dom = handler.master_dom
1321 self.sizer.AddMany([ (wx.StaticText(self, -1, "HP Current:"), 0, wx.ALIGN_CENTER_VERTICAL),
1322 (wx.TextCtrl(self, HP_CUR, self.master_dom.getAttribute('current')), 0, wx.EXPAND),
1323 (wx.StaticText(self, -1, "HP Max:"), 0, wx.ALIGN_CENTER_VERTICAL),
1324 (wx.TextCtrl(self, HP_MAX, self.master_dom.getAttribute('max')), 0, wx.EXPAND),
1325 ])
1326 self.sizer.AddGrowableCol(1)
1327 self.SetSizer(self.sizer)
1328 self.Bind(wx.EVT_SIZE, self.on_size)
1329 self.Bind(wx.EVT_TEXT, self.on_text, id=HP_MAX)
1330 self.Bind(wx.EVT_TEXT, self.on_text, id=HP_CUR)
1331
1332 def on_text(self,evt):
1333 id = evt.GetId()
1334 if id == HP_CUR:
1335 self.master_dom.setAttribute('current',evt.GetString())
1336 elif id == HP_MAX:
1337 self.master_dom.setAttribute('max',evt.GetString())
1338
1339 def on_size(self,evt):
1340 s = self.GetClientSizeTuple()
1341 self.sizer.SetDimension(0,0,s[0],s[1])
1342
1343 PP_CUR = wx.NewId()
1344 PP_MAX = wx.NewId()
1345 PP_FRE = wx.NewId()
1346 PP_MFRE = wx.NewId()
1347
1348 class pp_panel(wx.Panel):
1349 def __init__(self, parent, handler):
1350 wx.Panel.__init__(self, parent, -1)
1351 pname = handler.master_dom.setAttribute("name", 'PowerPoints')
1352 self.sizer = wx.FlexGridSizer(2, 4, 2, 2) # rows, cols, hgap, vgap
1353 self.master_dom = handler.master_dom
1354
1355 self.sizer.AddMany([ (wx.StaticText(self, -1, "PP Current:"), 0, wx.ALIGN_CENTER_VERTICAL),
1356 (wx.TextCtrl(self, PP_CUR, self.master_dom.getAttribute('current1')), 0, wx.EXPAND),
1357 (wx.StaticText(self, -1, "PP Max:"), 0, wx.ALIGN_CENTER_VERTICAL),
1358 (wx.TextCtrl(self, PP_MAX, self.master_dom.getAttribute('max1')), 0, wx.EXPAND),
1359 (wx.StaticText(self, -1, "Current Free Talants per day:"), 0, wx.ALIGN_CENTER_VERTICAL),
1360 (wx.TextCtrl(self, PP_FRE, self.master_dom.getAttribute('free')), 0, wx.EXPAND),
1361 (wx.StaticText(self, -1, "Max Free Talants per day:"), 0, wx.ALIGN_CENTER_VERTICAL),
1362 (wx.TextCtrl(self, PP_MFRE, self.master_dom.getAttribute('maxfree')), 0, wx.EXPAND),
1363 ])
1364 self.sizer.AddGrowableCol(1)
1365 self.SetSizer(self.sizer)
1366 self.Bind(wx.EVT_SIZE, self.on_size)
1367 self.Bind(wx.EVT_TEXT, self.on_text, id=PP_MAX)
1368 self.Bind(wx.EVT_TEXT, self.on_text, id=PP_CUR)
1369 self.Bind(wx.EVT_TEXT, self.on_text, id=PP_FRE)
1370 self.Bind(wx.EVT_TEXT, self.on_text, id=PP_MFRE)
1371
1372 def on_text(self,evt):
1373 id = evt.GetId()
1374 if id == PP_CUR:
1375 self.master_dom.setAttribute('current1',evt.GetString())
1376 elif id == PP_MAX:
1377 self.master_dom.setAttribute('max1',evt.GetString())
1378 elif id == PP_FRE:
1379 self.master_dom.setAttribute('free',evt.GetString())
1380 elif id == PP_MFRE:
1381 self.master_dom.setAttribute('maxfree',evt.GetString())
1382
1383 def on_size(self,evt):
1384 s = self.GetClientSizeTuple()
1385 self.sizer.SetDimension(0,0,s[0],s[1])
1386
1387
1388 class gen_grid(wx.grid.Grid):
1389 """grid for gen info"""
1390 def __init__(self, parent, handler):
1391 pname = handler.master_dom.setAttribute("name", 'General')
1392 wx.grid.Grid.__init__(self, parent, -1, style=wx.SUNKEN_BORDER | wx.WANTS_CHARS)
1393 self.Bind(wx.EVT_SIZE, self.on_size)
1394 self.Bind(wx.grid.EVT_GRID_CELL_CHANGE, self.on_cell_change)
1395 self.handler = handler
1396 n_list = handler.master_dom._get_childNodes()
1397 self.CreateGrid(len(n_list),2)
1398 self.SetRowLabelSize(0)
1399 self.SetColLabelSize(0)
1400 self.n_list = n_list
1401 i = 0
1402 for i in range(len(n_list)):
1403 self.refresh_row(i)
1404
1405 def on_cell_change(self,evt):
1406 row = evt.GetRow()
1407 col = evt.GetCol()
1408 value = self.GetCellValue(row,col)
1409 t_node = self.n_list[row]._get_firstChild()
1410 t_node._set_nodeValue(value)
1411 if row==0: self.handler.on_name_change(value)
1412
1413 def refresh_row(self,rowi):
1414 t_node = safe_get_text_node(self.n_list[rowi])
1415 self.SetCellValue(rowi,0,self.n_list[rowi]._get_tagName())
1416 self.SetReadOnly(rowi,0)
1417 self.SetCellValue(rowi,1,t_node._get_nodeValue())
1418
1419 def on_size(self,evt):
1420 (w,h) = self.GetClientSizeTuple()
1421 cols = self.GetNumberCols()
1422 col_w = w/(cols)
1423 for i in range(0,cols):
1424 self.SetColSize(i,col_w)
1425 evt.Skip()
1426 self.Refresh()
1427
1428 class inventory_grid(wx.grid.Grid):
1429 """grid for gen info"""
1430 def __init__(self, parent, handler):
1431 pname = handler.master_dom.setAttribute("name", 'Money and Inventory')
1432 wx.grid.Grid.__init__(self, parent, -1, style=wx.SUNKEN_BORDER | wx.WANTS_CHARS)
1433 self.Bind(wx.EVT_SIZE, self.on_size)
1434 self.Bind(wx.grid.EVT_GRID_CELL_CHANGE, self.on_cell_change)
1435 self.handler = handler
1436 n_list = handler.master_dom._get_childNodes()
1437 self.CreateGrid(len(n_list),2)
1438 self.SetRowLabelSize(0)
1439 self.SetColLabelSize(0)
1440 self.n_list = n_list
1441 i = 0
1442 for i in range(len(n_list)):
1443 self.refresh_row(i)
1444
1445 def on_cell_change(self,evt):
1446 row = evt.GetRow()
1447 col = evt.GetCol()
1448 value = self.GetCellValue(row,col)
1449 t_node = self.n_list[row]._get_firstChild()
1450 t_node._set_nodeValue(value)
1451 if row==0: self.handler.on_name_change(value)
1452
1453 def refresh_row(self,rowi):
1454 t_node = safe_get_text_node(self.n_list[rowi])
1455 self.SetCellValue(rowi,0,self.n_list[rowi]._get_tagName())
1456 self.SetReadOnly(rowi,0)
1457 self.SetCellValue(rowi,1,t_node._get_nodeValue())
1458
1459 def on_size(self,evt):
1460 (w,h) = self.GetClientSizeTuple()
1461 cols = self.GetNumberCols()
1462 col_w = w/(cols)
1463 for i in range(0,cols):
1464 self.SetColSize(i,col_w)
1465 evt.Skip()
1466 self.Refresh()
1467
1468 class abil_grid(wx.grid.Grid):
1469 """grid for abilities"""
1470 def __init__(self, parent, handler):
1471 pname = handler.master_dom.setAttribute("name", 'Stats')
1472 wx.grid.Grid.__init__(self, parent, -1, style=wx.SUNKEN_BORDER | wx.WANTS_CHARS)
1473 self.Bind(wx.EVT_SIZE, self.on_size)
1474 self.Bind(wx.grid.EVT_GRID_CELL_CHANGE, self.on_cell_change)
1475 self.handler = handler
1476 stats = handler.master_dom.getElementsByTagName('stat')
1477 self.CreateGrid(len(stats),3)
1478 self.SetRowLabelSize(0)
1479 col_names = ['Ability','Score','Modifier']
1480 for i in range(len(col_names)):
1481 self.SetColLabelValue(i,col_names[i])
1482 self.stats = stats
1483 i = 0
1484 for i in range(len(stats)):
1485 self.refresh_row(i)
1486 self.char_wnd = None
1487
1488 def on_cell_change(self,evt):
1489 row = evt.GetRow()
1490 col = evt.GetCol()
1491 value = self.GetCellValue(row,col)
1492 try:
1493 int(value)
1494 self.stats[row].setAttribute('base',value)
1495 self.refresh_row(row)
1496 except:
1497 self.SetCellValue(row,col,"0")
1498 if self.char_wnd:
1499 self.char_wnd.refresh_data()
1500
1501 def refresh_row(self,rowi):
1502 s = self.stats[rowi]
1503 name = s.getAttribute('name')
1504 abbr = s.getAttribute('abbr')
1505 self.SetCellValue(rowi,0,name)
1506 self.SetReadOnly(rowi,0)
1507 self.SetCellValue(rowi,1,s.getAttribute('base'))
1508 self.SetCellValue(rowi,2,str(self.handler.get_mod(abbr)))
1509 self.SetReadOnly(rowi,2)
1510
1511 def on_size(self,evt):
1512 (w,h) = self.GetClientSizeTuple()
1513 cols = self.GetNumberCols()
1514 col_w = w/(cols+2)
1515 self.SetColSize(0,col_w*3)
1516 for i in range(1,cols):
1517 self.SetColSize(i,col_w)
1518 evt.Skip()
1519 self.Refresh()
1520
1521 def refresh_data(self):
1522 for r in range(self.GetNumberRows()-1):
1523 self.refresh_row(r)
1524
1525
1526 class save_grid(wx.grid.Grid):
1527 """grid for saves"""
1528 def __init__(self, parent, handler):
1529 pname = handler.master_dom.setAttribute("name", 'Saves')
1530 wx.grid.Grid.__init__(self, parent, -1, style=wx.SUNKEN_BORDER | wx.WANTS_CHARS)
1531 self.Bind(wx.EVT_SIZE, self.on_size)
1532 self.Bind(wx.grid.EVT_GRID_CELL_CHANGE, self.on_cell_change)
1533 self.handler = handler
1534 saves = handler.master_dom.getElementsByTagName('save')
1535 self.stats = handler.char_hander.child_handlers['abilities']
1536 self.CreateGrid(len(saves),7)
1537 self.SetRowLabelSize(0)
1538 col_names = ['Save','Key','base','Abil','Magic','Misc','Total']
1539 for i in range(len(col_names)):
1540 self.SetColLabelValue(i,col_names[i])
1541 self.saves = saves
1542 i = 0
1543 for i in range(len(saves)):
1544 self.refresh_row(i)
1545
1546 def on_cell_change(self,evt):
1547 row = evt.GetRow()
1548 col = evt.GetCol()
1549 value = self.GetCellValue(row,col)
1550 try:
1551 int(value)
1552 if col == 2:
1553 self.saves[row].setAttribute('base',value)
1554 elif col ==4:
1555 self.saves[row].setAttribute('magmod',value)
1556 elif col ==4:
1557 self.saves[row].setAttribute('miscmod',value)
1558 self.refresh_row(row)
1559 except:
1560 self.SetCellValue(row,col,"0")
1561
1562 def refresh_row(self,rowi):
1563 s = self.saves[rowi]
1564 name = s.getAttribute('name')
1565 self.SetCellValue(rowi,0,name)
1566 self.SetReadOnly(rowi,0)
1567 stat = s.getAttribute('stat')
1568 self.SetCellValue(rowi,1,stat)
1569 self.SetReadOnly(rowi,1)
1570 self.SetCellValue(rowi,2,s.getAttribute('base'))
1571 self.SetCellValue(rowi,3,str(self.stats.get_mod(stat)))
1572 self.SetReadOnly(rowi,3)
1573 self.SetCellValue(rowi,4,s.getAttribute('magmod'))
1574 self.SetCellValue(rowi,5,s.getAttribute('miscmod'))
1575 mod = str(self.handler.get_mod(name))
1576 self.SetCellValue(rowi,6,mod)
1577 self.SetReadOnly(rowi,6)
1578
1579 def on_size(self,evt):
1580 (w,h) = self.GetClientSizeTuple()
1581 cols = self.GetNumberCols()
1582 col_w = w/(cols+2)
1583 self.SetColSize(0,col_w*3)
1584 for i in range(1,cols):
1585 self.SetColSize(i,col_w)
1586 evt.Skip()
1587 self.Refresh()
1588
1589 def refresh_data(self):
1590 for r in range(self.GetNumberRows()):
1591 self.refresh_row(r)
1592
1593
1594 class skill_grid(wx.grid.Grid):
1595 """ panel for skills """
1596 def __init__(self, parent, handler):
1597 pname = handler.master_dom.setAttribute("name", 'Skills')
1598 wx.grid.Grid.__init__(self, parent, -1, style=wx.SUNKEN_BORDER | wx.WANTS_CHARS)
1599 self.Bind(wx.EVT_SIZE, self.on_size)
1600 self.Bind(wx.grid.EVT_GRID_CELL_CHANGE, self.on_cell_change)
1601 self.handler = handler
1602 skills = handler.master_dom.getElementsByTagName('skill')
1603 self.stats = handler.char_hander.child_handlers['abilities']
1604 self.CreateGrid(len(skills),6)
1605 self.SetRowLabelSize(0)
1606 col_names = ['Skill','Key','Rank','Abil','Misc','Total']
1607 for i in range(len(col_names)):
1608 self.SetColLabelValue(i,col_names[i])
1609 rowi = 0
1610 self.skills = skills
1611 for i in range(len(skills)):
1612 self.refresh_row(i)
1613
1614 def on_cell_change(self,evt):
1615 row = evt.GetRow()
1616 col = evt.GetCol()
1617 value = self.GetCellValue(row,col)
1618 try:
1619 int(value)
1620 if col == 2:
1621 self.skills[row].setAttribute('rank',value)
1622 elif col ==4:
1623 self.skills[row].setAttribute('misc',value)
1624 self.refresh_row(row)
1625 except:
1626 self.SetCellValue(row,col,"0")
1627
1628 def refresh_row(self,rowi):
1629 s = self.skills[rowi]
1630 name = s.getAttribute('name')
1631 self.SetCellValue(rowi,0,name)
1632 self.SetReadOnly(rowi,0)
1633 stat = s.getAttribute('stat')
1634 self.SetCellValue(rowi,1,stat)
1635 self.SetReadOnly(rowi,1)
1636 self.SetCellValue(rowi,2,s.getAttribute('rank'))
1637 self.SetCellValue(rowi,3,str(self.stats.get_mod(stat)))
1638 self.SetReadOnly(rowi,3)
1639 self.SetCellValue(rowi,4,s.getAttribute('misc'))
1640 mod = str(self.handler.get_mod(name))
1641 self.SetCellValue(rowi,5,mod)
1642 self.SetReadOnly(rowi,5)
1643
1644 def on_size(self,evt):
1645 (w,h) = self.GetClientSizeTuple()
1646 cols = self.GetNumberCols()
1647 col_w = w/(cols+2)
1648 self.SetColSize(0,col_w*3)
1649 for i in range(1,cols):
1650 self.SetColSize(i,col_w)
1651 evt.Skip()
1652 self.Refresh()
1653
1654 def refresh_data(self):
1655 for r in range(self.GetNumberRows()):
1656 self.refresh_row(r)
1657
1658
1659
1660 class feat_panel(wx.Panel):
1661 def __init__(self, parent, handler):
1662 pname = handler.master_dom.setAttribute("name", 'Feats')
1663 wx.Panel.__init__(self, parent, -1)
1664 self.grid =wx.grid.Grid(self, -1, style=wx.SUNKEN_BORDER | wx.WANTS_CHARS)
1665 sizer = wx.BoxSizer(wx.HORIZONTAL)
1666 sizer.Add(wx.Button(self, 10, "Remove Feat"), 1, wx.EXPAND)
1667 sizer.Add(wx.Size(10,10))
1668 sizer.Add(wx.Button(self, 20, "Add Feat"), 1, wx.EXPAND)
1669 self.sizer = sizer
1670 self.Bind(wx.EVT_SIZE, self.on_size)
1671 self.Bind(wx.EVT_BUTTON, self.on_remove, id=10)
1672 self.Bind(wx.EVT_BUTTON, self.on_add, id=20)
1673
1674 n_list = handler.master_dom._get_childNodes()
1675 self.n_list = n_list
1676 self.master_dom = handler.master_dom
1677 self.grid.CreateGrid(len(n_list),2,1)
1678 self.grid.SetRowLabelSize(0)
1679 self.grid.SetColLabelValue(0,"Feat")
1680 self.grid.SetColLabelValue(1,"Type")
1681 for i in range(len(n_list)):
1682 self.refresh_row(i)
1683 self.temp_dom = None
1684 self.SetSizer(self.sizer)
1685
1686 def refresh_row(self,i):
1687 feat = self.n_list[i]
1688 name = feat.getAttribute('name')
1689 type = feat.getAttribute('type')
1690 self.grid.SetCellValue(i,0,name)
1691 self.grid.SetReadOnly(i,0)
1692 self.grid.SetCellValue(i,1,type)
1693 self.grid.SetReadOnly(i,1)
1694
1695 def on_remove(self,evt):
1696 rows = self.grid.GetNumberRows()
1697 for i in range(rows):
1698 if self.grid.IsInSelection(i,0):
1699 self.grid.DeleteRows(i)
1700 self.master_dom.removeChild(self.n_list[i])
1701
1702 def on_add(self,evt):
1703 if not self.temp_dom:
1704 tmp = open(orpg.dirpath.dir_struct["d20"]+"d20feats.xml","r")
1705 xml_dom = parseXml_with_dlg(self,tmp.read())
1706 xml_dom = xml_dom._get_firstChild()
1707 tmp.close()
1708 self.temp_dom = xml_dom
1709 f_list = self.temp_dom.getElementsByTagName('feat')
1710 opts = []
1711 for f in f_list:
1712 opts.append(f.getAttribute('name'))
1713 dlg = wx.SingleChoiceDialog(self,'Choose Feat','Feats',opts)
1714 if dlg.ShowModal() == wx.ID_OK:
1715 i = dlg.GetSelection()
1716 new_node = self.master_dom.appendChild(f_list[i].cloneNode(False))
1717 self.grid.AppendRows(1)
1718 self.refresh_row(self.grid.GetNumberRows()-1)
1719 dlg.Destroy()
1720
1721
1722 def on_size(self,event):
1723 s = self.GetClientSizeTuple()
1724 self.grid.SetDimensions(0,0,s[0],s[1]-25)
1725 self.sizer.SetDimension(0,s[1]-25,s[0],25)
1726 (w,h) = self.grid.GetClientSizeTuple()
1727 cols = self.grid.GetNumberCols()
1728 col_w = w/(cols)
1729 for i in range(0,cols):
1730 self.grid.SetColSize(i,col_w)
1731
1732 class spell_panel(wx.Panel):
1733 def __init__(self, parent, handler):
1734 pname = handler.master_dom.setAttribute("name", 'Arcane Spells')
1735 wx.Panel.__init__(self, parent, -1)
1736 self.grid =wx.grid.Grid(self, -1, style=wx.SUNKEN_BORDER | wx.WANTS_CHARS)
1737 self.handler = handler
1738 sizer = wx.BoxSizer(wx.HORIZONTAL)
1739 sizer.Add(wx.Button(self, 10, "Remove Spell"), 1, wx.EXPAND)
1740 sizer.Add(wx.Size(10,10))
1741 sizer.Add(wx.Button(self, 20, "Add Spell"), 1, wx.EXPAND)
1742 sizer.Add(wx.Size(10,10))
1743 sizer.Add(wx.Button(self, 30, "Refresh Spells"), 1, wx.EXPAND)
1744 self.sizer = sizer
1745 self.SetSizer(self.sizer)
1746 self.Bind(wx.EVT_SIZE, self.on_size)
1747 self.Bind(wx.EVT_BUTTON, self.on_remove, id=10)
1748 self.Bind(wx.EVT_BUTTON, self.on_add, id=20)
1749 self.Bind(wx.EVT_BUTTON, self.on_refresh_spells, id=30)
1750 self.grid.Bind(wx.grid.EVT_GRID_CELL_CHANGE, self.on_cell_change)
1751 n_list = handler.master_dom._get_childNodes()
1752 self.n_list = n_list
1753 self.master_dom = handler.master_dom
1754 self.grid.CreateGrid(len(n_list),4,1)
1755 self.grid.SetRowLabelSize(0)
1756 self.grid.SetColLabelValue(0,"No.")
1757 self.grid.SetColLabelValue(1,"Lvl")
1758 self.grid.SetColLabelValue(2,"Spell")
1759 self.grid.SetColLabelValue(3,"Desc")
1760 for i in range(len(n_list)):
1761 self.refresh_row(i)
1762 self.temp_dom = None
1763
1764 def on_cell_change(self,evt):
1765 row = evt.GetRow()
1766 col = evt.GetCol()
1767 value = self.grid.GetCellValue(row,col)
1768 if col == 0:
1769 self.n_list[row].setAttribute('memrz',value)
1770
1771
1772 def refresh_row(self,i):
1773 spell = self.n_list[i]
1774 memrz = spell.getAttribute('memrz')
1775 name = spell.getAttribute('name')
1776 type = spell.getAttribute('desc')
1777 level = spell.getAttribute('level')
1778 self.grid.SetCellValue(i,0,memrz)
1779 self.grid.SetCellValue(i,2,name)
1780 self.grid.SetReadOnly(i,2)
1781 self.grid.SetCellValue(i,3,type)
1782 self.grid.SetReadOnly(i,3)
1783 self.grid.SetCellValue(i,1,level)
1784 self.grid.SetReadOnly(i,1)
1785
1786 def on_remove(self,evt):
1787 rows = self.grid.GetNumberRows()
1788 for i in range(rows):
1789 if self.grid.IsInSelection(i,0):
1790 self.grid.DeleteRows(i)
1791 self.master_dom.removeChild(self.n_list[i])
1792 self.handler.refresh_spells()
1793
1794 def on_add(self,evt):
1795 if not self.temp_dom:
1796 tmp = open(orpg.dirpath.dir_struct["d20"]+"d20spells.xml","r")
1797 xml_dom = parseXml_with_dlg(self,tmp.read())
1798 xml_dom = xml_dom._get_firstChild()
1799 tmp.close()
1800 self.temp_dom = xml_dom
1801 f_list = self.temp_dom.getElementsByTagName('spell')
1802 opts = []
1803 # lvl = int(self.handler.get_char_lvl('level'))
1804 # castlvl = lvl / 2
1805 for f in f_list:
1806 opts.append("(" + f.getAttribute('level') + ")" + f.getAttribute('name'))
1807 # spelllvl = f.getAttribute('level')
1808 # if spelllvl <= "1":
1809 # opts.append("(" + f.getAttribute('level') + ")" + f.getAttribute('name'))
1810 # else:
1811 # if eval('%d >= %s' %(castlvl, spelllvl)):
1812 # opts.append("(" + f.getAttribute('level') + ")" + f.getAttribute('name'))
1813 dlg = wx.SingleChoiceDialog(self,'Choose Spell','Spells',opts)
1814 if dlg.ShowModal() == wx.ID_OK:
1815 i = dlg.GetSelection()
1816 new_node = self.master_dom.appendChild(f_list[i].cloneNode(False))
1817 self.grid.AppendRows(1)
1818 self.n_list = self.master_dom.getElementsByTagName('spell')
1819 self.refresh_row(self.grid.GetNumberRows()-1)
1820 self.handler.refresh_spells()
1821 dlg.Destroy()
1822
1823 def on_refresh_spells( self, evt ):
1824 f_list = self.master_dom.getElementsByTagName('spell')
1825 for spell in f_list:
1826 spell.setAttribute( 'used', '0' )
1827
1828 def on_size(self,event):
1829 s = self.GetClientSizeTuple()
1830 self.grid.SetDimensions(0,0,s[0],s[1]-25)
1831 self.sizer.SetDimension(0,s[1]-25,s[0],25)
1832 (w,h) = self.grid.GetClientSizeTuple()
1833 cols = self.grid.GetNumberCols()
1834 col_w = w/(cols)
1835 for i in range(0,cols):
1836 self.grid.SetColSize(i,col_w)
1837 self.grid.SetColSize(0,w * 0.10)
1838 self.grid.SetColSize(1,w * 0.10)
1839 self.grid.SetColSize(2,w * 0.30)
1840 self.grid.SetColSize(3,w * 0.50)
1841
1842 def refresh_data(self):
1843 for i in range(len(self.n_list)):
1844 self.refresh_row(i)
1845
1846 class divine_panel(wx.Panel):
1847 def __init__(self, parent, handler):
1848 pname = handler.master_dom.setAttribute("name", 'Divine Spells')
1849 wx.Panel.__init__(self, parent, -1)
1850 self.grid =wx.grid.Grid(self, -1, style=wx.SUNKEN_BORDER | wx.WANTS_CHARS)
1851 self.handler = handler
1852 sizer = wx.BoxSizer(wx.HORIZONTAL)
1853 sizer.Add(wx.Button(self, 10, "Remove Spell"), 1, wx.EXPAND)
1854 sizer.Add(wx.Size(10,10))
1855 sizer.Add(wx.Button(self, 20, "Add Spell"), 1, wx.EXPAND)
1856 sizer.Add(wx.Size(10,10))
1857 sizer.Add(wx.Button(self, 30, "Refresh Spells"), 1, wx.EXPAND)
1858 self.sizer = sizer
1859 self.SetSizer(self.sizer)
1860 self.Bind(wx.EVT_SIZE, self.on_size)
1861 self.Bind(wx.EVT_BUTTON, self.on_remove, id=10)
1862 self.Bind(wx.EVT_BUTTON, self.on_add, id=20)
1863 self.Bind(wx.EVT_BUTTON, self.on_refresh_spells, id=30)
1864 self.grid.Bind(wx.grid.EVT_GRID_CELL_CHANGE, self.on_cell_change)
1865 n_list = handler.master_dom._get_childNodes()
1866 self.n_list = n_list
1867 self.master_dom = handler.master_dom
1868 self.grid.CreateGrid(len(n_list),4,1)
1869 self.grid.SetRowLabelSize(0)
1870 self.grid.SetColLabelValue(0,"No.")
1871 self.grid.SetColLabelValue(1,"Lvl")
1872 self.grid.SetColLabelValue(2,"Spell")
1873 self.grid.SetColLabelValue(3,"Desc")
1874 for i in range(len(n_list)):
1875 self.refresh_row(i)
1876 self.temp_dom = None
1877
1878 def on_cell_change(self,evt):
1879 row = evt.GetRow()
1880 col = evt.GetCol()
1881 value = self.grid.GetCellValue(row,col)
1882 if col == 0:
1883 self.n_list[row].setAttribute('memrz',value)
1884
1885
1886 def refresh_row(self,i):
1887 spell = self.n_list[i]
1888 memrz = spell.getAttribute('memrz')
1889 name = spell.getAttribute('name')
1890 type = spell.getAttribute('desc')
1891 level = spell.getAttribute('level')
1892 self.grid.SetCellValue(i,0,memrz)
1893 self.grid.SetCellValue(i,2,name)
1894 self.grid.SetReadOnly(i,2)
1895 self.grid.SetCellValue(i,3,type)
1896 self.grid.SetReadOnly(i,3)
1897 self.grid.SetCellValue(i,1,level)
1898 self.grid.SetReadOnly(i,1)
1899
1900 def on_remove(self,evt):
1901 rows = self.grid.GetNumberRows()
1902 for i in range(rows):
1903 if self.grid.IsInSelection(i,0):
1904 self.grid.DeleteRows(i)
1905 self.master_dom.removeChild(self.n_list[i])
1906 self.handler.refresh_spells()
1907
1908 def on_add(self,evt):
1909 if not self.temp_dom:
1910 tmp = open(orpg.dirpath.dir_struct["d20"]+"d20divine.xml","r")
1911 xml_dom = parseXml_with_dlg(self,tmp.read())
1912 xml_dom = xml_dom._get_firstChild()
1913 tmp.close()
1914 self.temp_dom = xml_dom
1915 f_list = self.temp_dom.getElementsByTagName('gift')
1916 opts = []
1917 # lvl = int(self.handler.get_char_lvl('level'))
1918 # castlvl = lvl / 2
1919 for f in f_list:
1920 opts.append("(" + f.getAttribute('level') + ")" + f.getAttribute('name'))
1921 # spelllvl = f.getAttribute('level')
1922 # if spelllvl <= "1":
1923 # opts.append("(" + f.getAttribute('level') + ")" + f.getAttribute('name'))
1924 # else:
1925 # if eval('%d >= %s' %(castlvl, spelllvl)):
1926 # opts.append("(" + f.getAttribute('level') + ")" + f.getAttribute('name'))
1927 dlg = wx.SingleChoiceDialog(self,'Choose Spell','Spells',opts)
1928 if dlg.ShowModal() == wx.ID_OK:
1929 i = dlg.GetSelection()
1930 new_node = self.master_dom.appendChild(f_list[i].cloneNode(False))
1931 self.grid.AppendRows(1)
1932 self.n_list = self.master_dom.getElementsByTagName('gift')
1933 self.refresh_row(self.grid.GetNumberRows()-1)
1934 self.handler.refresh_spells()
1935 dlg.Destroy()
1936
1937 def on_refresh_spells( self, evt ):
1938 f_list = self.master_dom.getElementsByTagName('gift')
1939 for spell in f_list:
1940 spell.setAttribute( 'used', '0' )
1941
1942 def on_size(self,event):
1943 s = self.GetClientSizeTuple()
1944 self.grid.SetDimensions(0,0,s[0],s[1]-25)
1945 self.sizer.SetDimension(0,s[1]-25,s[0],25)
1946 (w,h) = self.grid.GetClientSizeTuple()
1947 cols = self.grid.GetNumberCols()
1948 col_w = w/(cols)
1949 for i in range(0,cols):
1950 self.grid.SetColSize(i,col_w)
1951 self.grid.SetColSize(0,w * 0.10)
1952 self.grid.SetColSize(1,w * 0.10)
1953 self.grid.SetColSize(2,w * 0.30)
1954 self.grid.SetColSize(3,w * 0.50)
1955
1956 def refresh_data(self):
1957 for i in range(len(self.n_list)):
1958 self.refresh_row(i)
1959
1960
1961 class power_panel(wx.Panel):
1962 def __init__(self, parent, handler):
1963 pname = handler.master_dom.setAttribute("name", 'Pionic Powers')
1964 wx.Panel.__init__(self, parent, -1)
1965 self.grid =wx.grid.Grid(self, -1, style=wx.SUNKEN_BORDER | wx.WANTS_CHARS)
1966 self.handler = handler
1967 sizer = wx.BoxSizer(wx.HORIZONTAL)
1968 sizer.Add(wx.Button(self, 10, "Remove Power"), 1, wx.EXPAND)
1969 sizer.Add(wx.Size(10,10))
1970 sizer.Add(wx.Button(self, 20, "Add Power"), 1, wx.EXPAND)
1971 sizer.Add(wx.Size(10,10))
1972 sizer.Add(wx.Button(self, 30, "Refresh Powers"), 1, wx.EXPAND)
1973 self.sizer = sizer
1974 self.Bind(wx.EVT_SIZE, self.on_size)
1975 self.Bind(wx.EVT_BUTTON, self.on_remove, id=10)
1976 self.Bind(wx.EVT_BUTTON, self.on_add, id=20)
1977 self.Bind(wx.EVT_BUTTON, self.on_refresh_powers, id=30)
1978 self.grid.Bind(wx.grid.EVT_GRID_CELL_CHANGE, self.on_cell_change)
1979 n_list = handler.master_dom._get_childNodes()
1980 self.n_list = n_list
1981 self.master_dom = handler.master_dom
1982 self.grid.CreateGrid(len(n_list),5,1)
1983 self.grid.SetRowLabelSize(0)
1984 self.grid.SetColLabelValue(0,"PP")
1985 self.grid.SetColLabelValue(1,"Lvl")
1986 self.grid.SetColLabelValue(2,"Power")
1987 self.grid.SetColLabelValue(3,"Desc")
1988 self.grid.SetColLabelValue(4,"Type")
1989 for i in range(len(n_list)):
1990 self.refresh_row(i)
1991 self.refresh_data()
1992 self.temp_dom = None
1993 self.SetSizer(self.sizer)
1994
1995 def on_cell_change(self,evt):
1996 row = evt.GetRow()
1997 col = evt.GetCol()
1998 value = self.grid.GetCellValue(row,col)
1999 """if col == 0:
2000 self.n_list[row].setAttribute('memrz',value)"""
2001
2002
2003 def refresh_row(self,i):
2004 power = self.n_list[i]
2005 point = power.getAttribute('point')
2006 name = power.getAttribute('name')
2007 type = power.getAttribute('desc')
2008 test = power.getAttribute('test')
2009 level = power.getAttribute('level')
2010 self.grid.SetCellValue(i,0,point)
2011 self.grid.SetReadOnly(i,0)
2012 self.grid.SetCellValue(i,1,level)
2013 self.grid.SetReadOnly(i,1)
2014 self.grid.SetCellValue(i,2,name)
2015 self.grid.SetReadOnly(i,2)
2016 self.grid.SetCellValue(i,3,type)
2017 self.grid.SetReadOnly(i,3)
2018 self.grid.SetCellValue(i,4,test)
2019 self.grid.SetReadOnly(i,4)
2020
2021 def on_remove(self,evt):
2022 rows = self.grid.GetNumberRows()
2023 for i in range(rows):
2024 if self.grid.IsInSelection(i,0):
2025 self.grid.DeleteRows(i)
2026 self.master_dom.removeChild(self.n_list[i])
2027 self.handler.refresh_powers()
2028
2029 def on_add(self,evt):
2030 if not self.temp_dom:
2031 tmp = open(orpg.dirpath.dir_struct["d20"]+"d20powers.xml","r")
2032 xml_dom = parseXml_with_dlg(self,tmp.read())
2033 xml_dom = xml_dom._get_firstChild()
2034 tmp.close()
2035 self.temp_dom = xml_dom
2036 f_list = self.temp_dom.getElementsByTagName('power')
2037 opts = []
2038 # lvl = int(self.handler.get_char_lvl('level'))
2039 # castlvl = lvl / 2
2040 for f in f_list:
2041 opts.append("(" + f.getAttribute('level') + ") - " + f.getAttribute('name') + " - " + f.getAttribute('test'))
2042 # spelllvl = f.getAttribute('level')
2043 # if spelllvl <= "1":
2044 # opts.append("(" + f.getAttribute('level') + ") - " + f.getAttribute('name') + " - " + f.getAttribute('test'))
2045 # else:
2046 # if eval('%d >= %s' %(castlvl, spelllvl)):
2047 # opts.append("(" + f.getAttribute('level') + ") - " + f.getAttribute('name') + " - " + f.getAttribute('test'))
2048 dlg = wx.SingleChoiceDialog(self,'Choose Power','Powers',opts)
2049 if dlg.ShowModal() == wx.ID_OK:
2050 i = dlg.GetSelection()
2051 new_node = self.master_dom.appendChild(f_list[i].cloneNode(False))
2052 self.grid.AppendRows(1)
2053 self.n_list = self.master_dom.getElementsByTagName('power')
2054 self.refresh_row(self.grid.GetNumberRows()-1)
2055 self.handler.refresh_powers()
2056 dlg.Destroy()
2057
2058 def on_remove(self,evt):
2059 rows = self.grid.GetNumberRows()
2060 for i in range(rows):
2061 if self.grid.IsInSelection(i,0):
2062 self.grid.DeleteRows(i)
2063 self.master_dom.removeChild(self.n_list[i])
2064 self.n_list = self.master_dom.getElementsByTagName('weapon')
2065 self.handler.refresh_weapons()
2066
2067
2068 def on_refresh_powers( self, evt ):
2069 mfre = self.handler.get_char_pp('maxfree')
2070 mpp = self.handler.get_char_pp('max1')
2071 self.handler.set_char_pp( 'free', mfre )
2072 self.handler.set_char_pp( 'current1', mpp )
2073
2074 def on_size(self,event):
2075 s = self.GetClientSizeTuple()
2076 self.grid.SetDimensions(0,0,s[0],s[1]-25)
2077 self.sizer.SetDimension(0,s[1]-25,s[0],25)
2078 (w,h) = self.grid.GetClientSizeTuple()
2079 cols = self.grid.GetNumberCols()
2080 col_w = w/(cols)
2081 for i in range(0,cols):
2082 self.grid.SetColSize(i,col_w)
2083 self.grid.SetColSize(0,w * 0.05)
2084 self.grid.SetColSize(1,w * 0.05)
2085 self.grid.SetColSize(2,w * 0.30)
2086 self.grid.SetColSize(3,w * 0.30)
2087 self.grid.SetColSize(4,w * 0.30)
2088
2089 def refresh_data(self):
2090 for i in range(len(self.n_list)):
2091 self.refresh_row(i)
2092
2093 class attack_grid(wx.grid.Grid):
2094 """grid for attacks"""
2095 def __init__(self, parent, handler):
2096 pname = handler.master_dom.setAttribute("name", 'Melee')
2097 wx.grid.Grid.__init__(self, parent, -1, style=wx.SUNKEN_BORDER | wx.WANTS_CHARS)
2098 self.parent = parent
2099 self.handler = handler
2100 self.babs = self.handler.melee
2101 self.CreateGrid(1,7)
2102 self.SetRowLabelSize(0)
2103 col_names = ['base','base 2','base 3','base 4','base 5','base 6','misc']
2104 for i in range(len(col_names)):
2105 self.SetColLabelValue(i,col_names[i])
2106 self.refresh_data()
2107 self.Bind(wx.EVT_SIZE, self.on_size)
2108 self.Bind(wx.grid.EVT_GRID_CELL_CHANGE, self.on_cell_change)
2109
2110 def on_cell_change(self,evt):
2111 row = evt.GetRow()
2112 col = evt.GetCol()
2113 value = self.GetCellValue(row,col)
2114 try:
2115 int(value)
2116 except:
2117 value = "0"
2118 self.SetCellValue( row, col, value )
2119 attribs = ['base','second','third','forth','fifth','sixth','misc']
2120 self.babs.setAttribute( attribs[col], value )
2121 self.parent.refresh_data()
2122
2123 def refresh_data(self):
2124 attack_mods = self.handler.get_attack_data()
2125 for i in range(0,7):
2126 self.SetCellValue( 0, i, str(attack_mods[i]) )
2127
2128 def on_size(self,evt):
2129 (w,h) = self.GetClientSizeTuple()
2130 cols = self.GetNumberCols()
2131 col_w = w/cols
2132 for i in range(0,cols):
2133 self.SetColSize(i,col_w)
2134 evt.Skip()
2135 self.Refresh()
2136
2137 class weapon_panel(wx.Panel):
2138 def __init__(self, parent, handler):
2139 pname = handler.master_dom.setAttribute("name", 'Weapons')
2140 wx.Panel.__init__(self, parent, -1)
2141 self.grid =wx.grid.Grid(self, -1, style=wx.SUNKEN_BORDER | wx.WANTS_CHARS)
2142 sizer = wx.BoxSizer(wx.HORIZONTAL)
2143 sizer.Add(wx.Button(self, 10, "Remove Weapon"), 1, wx.EXPAND)
2144 sizer.Add(wx.Size(10,10))
2145 sizer.Add(wx.Button(self, 20, "Add Weapon"), 1, wx.EXPAND)
2146 self.sizer = sizer
2147 self.Bind(wx.EVT_SIZE, self.on_size)
2148 self.Bind(wx.EVT_BUTTON, self.on_remove, id=10)
2149 self.Bind(wx.EVT_BUTTON, self.on_add, id=20)
2150 self.grid.Bind(wx.grid.EVT_GRID_CELL_CHANGE, self.on_cell_change)
2151 n_list = handler.master_dom.getElementsByTagName('weapon')
2152 self.n_list = n_list
2153 self.master_dom = handler.master_dom
2154 self.handler = handler
2155 self.grid.CreateGrid(len(n_list),8,1)
2156 self.grid.SetRowLabelSize(0)
2157 col_names = ['Name','damage','mod','critical','type','weight','range','size']
2158 for i in range(len(col_names)):
2159 self.grid.SetColLabelValue(i,col_names[i])
2160 self.refresh_data()
2161 self.temp_dom = None
2162 self.SetSizer(self.sizer)
2163
2164 def on_cell_change(self,evt):
2165 row = evt.GetRow()
2166 col = evt.GetCol()
2167 value = self.grid.GetCellValue(row,col)
2168 if col == 0:
2169 self.n_list[row].setAttribute('name',value)
2170 self.handler.refresh_weapons();
2171 else:
2172 self.n_list[row].setAttribute(self.grid.GetColLabelValue(col),value)
2173
2174 def refresh_row(self,i):
2175 n = self.n_list[i]
2176 name = n.getAttribute('name')
2177 mod = n.getAttribute('mod')
2178 ran = n.getAttribute('range')
2179 self.grid.SetCellValue(i,0,name)
2180 self.grid.SetCellValue(i,1,n.getAttribute('damage'))
2181 self.grid.SetCellValue(i,2,mod)
2182 self.grid.SetCellValue(i,3,n.getAttribute('critical'))
2183 self.grid.SetCellValue(i,4,n.getAttribute('type'))
2184 self.grid.SetCellValue(i,5,n.getAttribute('weight'))
2185 self.grid.SetCellValue(i,6,ran)
2186 self.grid.SetCellValue(i,7,n.getAttribute('size') )
2187
2188 def on_remove(self,evt):
2189 rows = self.grid.GetNumberRows()
2190 for i in range(rows):
2191 if self.grid.IsInSelection(i,0):
2192 self.grid.DeleteRows(i)
2193 self.master_dom.removeChild(self.n_list[i])
2194 self.n_list = self.master_dom.getElementsByTagName('weapon')
2195 self.handler.refresh_weapons()
2196
2197 def on_add(self,evt):
2198 if not self.temp_dom:
2199 tmp = open(orpg.dirpath.dir_struct["d20"]+"d20weapons.xml","r")
2200 xml_dom = parseXml_with_dlg(self,tmp.read())
2201 xml_dom = xml_dom._get_firstChild()
2202 tmp.close()
2203 self.temp_dom = xml_dom
2204 f_list = self.temp_dom.getElementsByTagName('weapon')
2205 opts = []
2206 for f in f_list:
2207 opts.append(f.getAttribute('name'))
2208 dlg = wx.SingleChoiceDialog(self,'Choose Weapon','Weapon List',opts)
2209 if dlg.ShowModal() == wx.ID_OK:
2210 i = dlg.GetSelection()
2211 new_node = self.master_dom.appendChild(f_list[i].cloneNode(False))
2212 self.grid.AppendRows(1)
2213 self.n_list = self.master_dom.getElementsByTagName('weapon')
2214 self.refresh_row(self.grid.GetNumberRows()-1)
2215 self.handler.refresh_weapons()
2216 dlg.Destroy()
2217
2218 def on_size(self,event):
2219 s = self.GetClientSizeTuple()
2220 self.grid.SetDimensions(0,0,s[0],s[1]-25)
2221 self.sizer.SetDimension(0,s[1]-25,s[0],25)
2222 (w,h) = self.grid.GetClientSizeTuple()
2223 cols = self.grid.GetNumberCols()
2224 col_w = w/(cols+1)
2225 self.grid.SetColSize(0,col_w*2)
2226 for i in range(1,cols):
2227 self.grid.SetColSize(i,col_w)
2228
2229 def refresh_data(self):
2230 for i in range(len(self.n_list)):
2231 self.refresh_row(i)
2232
2233
2234 class attack_panel(wx.Panel):
2235 def __init__(self, parent, handler):
2236 pname = handler.master_dom.setAttribute("name", 'Melee')
2237 wx.Panel.__init__(self, parent, -1)
2238
2239 self.a_grid = attack_grid(self, handler)
2240 self.w_panel = weapon_panel(self, handler)
2241 self.sizer = wx.BoxSizer(wx.VERTICAL)
2242 self.sizer.Add(self.a_grid, 1, wx.EXPAND)
2243 self.sizer.Add(self.w_panel, 2, wx.EXPAND)
2244 self.Bind(wx.EVT_SIZE, self.on_size)
2245 self.SetSizer(self.sizer)
2246
2247 def on_size(self,event):
2248 s = self.GetClientSizeTuple()
2249 self.sizer.SetDimension(0,0,s[0],s[1])
2250
2251 def refresh_data(self):
2252 self.w_panel.refresh_data()
2253 self.a_grid.refresh_data()
2254
2255
2256 class ac_panel(wx.Panel):
2257 def __init__(self, parent, handler):
2258 pname = handler.master_dom.setAttribute("name", 'Armor')
2259 wx.Panel.__init__(self, parent, -1)
2260 self.grid =wx.grid.Grid(self, -1, style=wx.SUNKEN_BORDER | wx.WANTS_CHARS)
2261 sizer = wx.BoxSizer(wx.HORIZONTAL)
2262 sizer.Add(wx.Button(self, 10, "Remove Armor"), 1, wx.EXPAND)
2263 sizer.Add(wx.Size(10,10))
2264 sizer.Add(wx.Button(self, 20, "Add Armor"), 1, wx.EXPAND)
2265 self.sizer = sizer
2266 self.Bind(wx.EVT_SIZE, self.on_size)
2267 self.Bind(wx.EVT_BUTTON, self.on_remove, id=10)
2268 self.Bind(wx.EVT_BUTTON, self.on_add, id=20)
2269 self.grid.Bind(wx.grid.EVT_GRID_CELL_CHANGE, self.on_cell_change)
2270 self.master_dom = handler.master_dom
2271 n_list = handler.master_dom._get_childNodes()
2272 self.n_list = n_list
2273 col_names = ['Armor','bonus','maxdex','cp','sf','weight','speed','type']
2274 self.grid.CreateGrid(len(n_list),len(col_names),1)
2275 self.grid.SetRowLabelSize(0)
2276 for i in range(len(col_names)):
2277 self.grid.SetColLabelValue(i,col_names[i])
2278 self.atts =['name','bonus','maxdex','checkpenalty','spellfailure','weight','speed','type']
2279 for i in range(len(n_list)):
2280 self.refresh_row(i)
2281 self.temp_dom = None
2282 self.SetSizer(self.sizer)
2283
2284 def on_cell_change(self,evt):
2285 row = evt.GetRow()
2286 col = evt.GetCol()
2287 value = self.grid.GetCellValue(row,col)
2288 if col >= 1 and col <= 5:
2289 try:
2290 int(value)
2291 self.n_list[row].setAttribute(self.atts[col],value)
2292 except:
2293 self.grid.SetCellValue(row,col,"0")
2294 else:
2295 self.n_list[row].setAttribute(self.atts[col],value)
2296
2297 def refresh_row(self,i):
2298 n = self.n_list[i]
2299 for y in range(len(self.atts)):
2300 self.grid.SetCellValue(i,y,n.getAttribute(self.atts[y]))
2301
2302 def on_remove(self,evt):
2303 rows = self.grid.GetNumberRows()
2304 for i in range(rows):
2305 if self.grid.IsInSelection(i,0):
2306 self.grid.DeleteRows(i)
2307 self.master_dom.removeChild(self.n_list[i])
2308
2309 def on_add(self,evt):
2310 if not self.temp_dom:
2311 tmp = open(orpg.dirpath.dir_struct["d20"]+"d20armor.xml","r")
2312 xml_dom = parseXml_with_dlg(self,tmp.read())
2313 xml_dom = xml_dom._get_firstChild()
2314 tmp.close()
2315 self.temp_dom = xml_dom
2316 f_list = self.temp_dom.getElementsByTagName('armor')
2317 opts = []
2318 for f in f_list:
2319 opts.append(f.getAttribute('name'))
2320 dlg = wx.SingleChoiceDialog(self,'Choose Armor:','Armor List',opts)
2321 if dlg.ShowModal() == wx.ID_OK:
2322 i = dlg.GetSelection()
2323 new_node = self.master_dom.appendChild(f_list[i].cloneNode(False))
2324 self.grid.AppendRows(1)
2325 self.refresh_row(self.grid.GetNumberRows()-1)
2326 dlg.Destroy()
2327
2328 def on_size(self,event):
2329 s = self.GetClientSizeTuple()
2330 self.grid.SetDimensions(0,0,s[0],s[1]-25)
2331 self.sizer.SetDimension(0,s[1]-25,s[0],25)
2332 (w,h) = self.grid.GetClientSizeTuple()
2333 cols = self.grid.GetNumberCols()
2334 col_w = w/(cols+2)
2335 self.grid.SetColSize(0,col_w*3)
2336 for i in range(1,cols):
2337 self.grid.SetColSize(i,col_w)
2338
2339
2340 class class_panel(wx.Panel):
2341 def __init__(self, parent, handler):
2342 pname = handler.master_dom.setAttribute("name", 'Class')
2343 wx.Panel.__init__(self, parent, -1)
2344 self.grid =wx.grid.Grid(self, -1, style=wx.SUNKEN_BORDER | wx.WANTS_CHARS)
2345 sizer = wx.BoxSizer(wx.HORIZONTAL)
2346 sizer.Add(wx.Button(self, 10, "Remove Class"), 1, wx.EXPAND)
2347 sizer.Add(wx.Size(10,10))
2348 sizer.Add(wx.Button(self, 20, "Add Class"), 1, wx.EXPAND)
2349 self.sizer = sizer
2350 self.SetSizer(self.sizer)
2351 self.Bind(wx.EVT_SIZE, self.on_size)
2352 self.Bind(wx.EVT_BUTTON, self.on_remove, id=10)
2353 self.Bind(wx.EVT_BUTTON, self.on_add, id=20)
2354 self.grid.Bind(wx.grid.EVT_GRID_CELL_CHANGE, self.on_cell_change)
2355
2356 n_list = handler.master_dom._get_childNodes()
2357 self.n_list = n_list
2358 self.master_dom = handler.master_dom
2359 self.grid.CreateGrid(len(n_list),2,1)
2360 self.grid.SetRowLabelSize(0)
2361 self.grid.SetColLabelValue(0,"Class")
2362 self.grid.SetColLabelValue(1,"Level")
2363 for i in range(len(n_list)):
2364 self.refresh_row(i)
2365 self.temp_dom = None
2366
2367 def on_cell_change(self,evt):
2368 row = evt.GetRow()
2369 col = evt.GetCol()
2370 value = self.grid.GetCellValue(row,col)
2371 try:
2372 int(value)
2373 self.n_list[row].setAttribute('level',value)
2374 except:
2375 self.grid.SetCellValue(row,col,"1")
2376
2377
2378 def refresh_row(self,i):
2379 n = self.n_list[i]
2380 name = n.getAttribute('name')
2381 level = n.getAttribute('level')
2382 self.grid.SetCellValue(i,0,name)
2383 self.grid.SetReadOnly(i,0)
2384 self.grid.SetCellValue(i,1,level)
2385 #self.grid.SetReadOnly(i,1)
2386
2387 def on_remove(self,evt):
2388 rows = self.grid.GetNumberRows()
2389 for i in range(rows):
2390 if self.grid.IsInSelection(i,0):
2391 self.grid.DeleteRows(i)
2392 self.master_dom.removeChild(self.n_list[i])
2393
2394 def on_add(self,evt):
2395 if not self.temp_dom:
2396 tmp = open(orpg.dirpath.dir_struct["d20"]+"d20classes.xml","r")
2397 xml_dom = parseXml_with_dlg(self,tmp.read())
2398 xml_dom = xml_dom._get_firstChild()
2399 tmp.close()
2400 self.temp_dom = xml_dom
2401 f_list = self.temp_dom.getElementsByTagName('class')
2402 opts = []
2403 for f in f_list:
2404 opts.append(f.getAttribute('name'))
2405 dlg = wx.SingleChoiceDialog(self,'Choose Class','Classes',opts)
2406 if dlg.ShowModal() == wx.ID_OK:
2407 i = dlg.GetSelection()
2408 new_node = self.master_dom.appendChild(f_list[i].cloneNode(False))
2409 self.grid.AppendRows(1)
2410 self.refresh_row(self.grid.GetNumberRows()-1)
2411 dlg.Destroy()
2412
2413
2414 def on_size(self,event):
2415 s = self.GetClientSizeTuple()
2416 self.grid.SetDimensions(0,0,s[0],s[1]-25)
2417 self.sizer.SetDimension(0,s[1]-25,s[0],25)
2418 (w,h) = self.grid.GetClientSizeTuple()
2419 cols = self.grid.GetNumberCols()
2420 col_w = w/(cols)
2421 for i in range(0,cols):
2422 self.grid.SetColSize(i,col_w)