Mercurial > traipse
comparison orpg/tools/InterParse.py @ 28:ff154cf3350c ornery-orc
Traipse 'OpenRPG' {100203-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 (Stable)
New Features:
New Bookmarks Feature
New 'boot' command to remote admin
New confirmation window for sent nodes
Miniatures Layer pop up box allows users to turn off Mini labels, from
FlexiRPG
New Zoom Mouse plugin added
New Images added to Plugin UI
Switching to Element Tree
New Map efficiency, from FlexiRPG
New Status Bar to Update Manager
New TrueDebug Class in orpg_log (See documentation for usage)
New Portable Mercurial
New Tip of the Day, from Core and community
New Reference Syntax added for custom PC sheets
New Child Reference for gametree
New Parent Reference for gametree
New Gametree Recursion method, mapping, context sensitivity, and
effeciency..
New Features node with bonus nodes and Node Referencing help added
New Dieroller structure from Core
New DieRoller portability for odd Dice
New 7th Sea die roller; ie [7k3] = [7d10.takeHighest(3).open(10)]
New 'Mythos' System die roller added
New vs. die roller method for WoD; ie [3v3] = [3d10.vs(3)]. Included for
Mythos roller also
New Warhammer FRPG Die Roller (Special thanks to Puu-san for the
support)
New EZ_Tree Reference system. Push a button, Traipse the tree, get a
reference (Beta!)
New Grids act more like Spreadsheets in Use mode, with Auto Calc
Fixes:
Fix to allow for portability to an OpenSUSE linux OS
Fix to mplay_client for Fedora and OpenSUSE
Fix to Text based Server
Fix to Remote Admin Commands
Fix to Pretty Print, from Core
Fix to Splitter Nodes not being created
Fix to massive amounts of images loading, from Core
Fix to Map from gametree not showing to all clients
Fix to gametree about menus
Fix to Password Manager check on startup
Fix to PC Sheets from tool nodes. They now use the tabber_panel
Fix to Whiteboard ID to prevent random line or text deleting.
Fixes to Server, Remote Server, and Server GUI
Fix to Update Manager; cleaner clode for saved repositories
Fixes made to Settings Panel and now reactive settings when Ok is
pressed
Fixes to Alternity roller's attack roll. Uses a simple Tuple instead of
a Splice
Fix to Use panel of Forms and Tabbers. Now longer enters design mode
Fix made Image Fetching. New fetching image and new failed image
Fix to whiteboard ID's to prevent non updated clients from ruining the
fix.
default_manifest.xml renamed to default_upmana.xml
author | sirebral |
---|---|
date | Wed, 03 Feb 2010 22:16:49 -0600 |
parents | |
children | 8e77f169f324 |
comparison
equal
deleted
inserted
replaced
27:51428d30c59e | 28:ff154cf3350c |
---|---|
1 from orpg.orpgCore import component | |
2 import re | |
3 from orpg.tools.orpg_log import logger | |
4 from wx import TextEntryDialog, ID_OK | |
5 | |
6 class InterParse(): | |
7 | |
8 def __init__(self): | |
9 pass | |
10 | |
11 def Post(self, s, send=False, myself=False): | |
12 s = self.Normalize(s) | |
13 component.get('chat').set_colors() | |
14 component.get('chat').Post(s, send, myself) | |
15 | |
16 def Normalize(self, s): | |
17 for plugin_fname in component.get('chat').activeplugins.keys(): | |
18 plugin = component.get('chat').activeplugins[plugin_fname] | |
19 try: s = plugin.pre_parse(s) | |
20 except Exception, e: | |
21 if str(e) != "'module' object has no attribute 'post_msg'": | |
22 logger.general(traceback.format_exc()) | |
23 logger.general("EXCEPTION: " + str(e)) | |
24 if component.get('chat').parsed == 0: | |
25 s = self.Node(s) | |
26 s = self.Dice(s) | |
27 s = self.Filter(s) | |
28 component.get('chat').parsed = 1 | |
29 return s | |
30 | |
31 def Filter(self, s): | |
32 s = component.get('chat').GetFilteredText(s) | |
33 return s | |
34 | |
35 def Node(self, s): | |
36 """Parses player input for embedded nodes rolls""" | |
37 cur_loc = 0 | |
38 #[a-zA-Z0-9 _\-\.] | |
39 reg = re.compile("(!@(.*?)@!)") | |
40 matches = reg.findall(s) | |
41 for i in xrange(0,len(matches)): | |
42 newstr = self.Node(self.resolve_nodes(matches[i][1])) | |
43 s = s.replace(matches[i][0], newstr, 1) | |
44 return s | |
45 | |
46 def Dice(self, s): | |
47 """Parses player input for embedded dice rolls""" | |
48 reg = re.compile("\[([^]]*?)\]") | |
49 matches = reg.findall(s) | |
50 for i in xrange(0,len(matches)): | |
51 newstr = self.Unknown(matches[i]) | |
52 qmode = 0 | |
53 newstr1 = newstr | |
54 if newstr[0].lower() == 'q': | |
55 newstr = newstr[1:] | |
56 qmode = 1 | |
57 if newstr[0].lower() == '#': | |
58 newstr = newstr[1:] | |
59 qmode = 2 | |
60 try: newstr = component.get('DiceManager').proccessRoll(newstr) | |
61 except: pass | |
62 if qmode == 1: | |
63 s = s.replace("[" + matches[i] + "]", | |
64 "<!-- Official Roll [" + newstr1 + "] => " + newstr + "-->" + newstr, 1) | |
65 elif qmode == 2: | |
66 s = s.replace("[" + matches[i] + "]", newstr[len(newstr)-2:-1], 1) | |
67 else: s = s.replace("[" + matches[i] + "]", | |
68 "[" + newstr1 + "<!-- Official Roll -->] => " + newstr, 1) | |
69 return s | |
70 | |
71 def Unknown(self, s): | |
72 # Uses a tuple. Usage: ?Label}dY. If no Label is assigned then use ?}DY | |
73 newstr = "0" | |
74 reg = re.compile("(\?\{*)([a-zA-Z ]*)(\}*)") | |
75 matches = reg.findall(s) | |
76 for i in xrange(0,len(matches)): | |
77 lb = "Replace '?' with: " | |
78 if len(matches[i][0]): | |
79 lb = matches[i][1] + "?: " | |
80 dlg = TextEntryDialog(self, lb, "Missing Value?") | |
81 dlg.SetValue('') | |
82 if matches[i][0] != '': | |
83 dlg.SetTitle("Enter Value for " + matches[i][1]) | |
84 if dlg.ShowModal() == ID_OK: newstr = dlg.GetValue() | |
85 if newstr == '': newstr = '0' | |
86 s = s.replace(matches[i][0], newstr, 1).replace(matches[i][1], '', 1).replace(matches[i][2], '', 1) | |
87 dlg.Destroy() | |
88 return s | |
89 | |
90 def NodeMap(self, s, node): | |
91 """Parses player input for embedded nodes rolls""" | |
92 cur_loc = 0 | |
93 reg = re.compile("(!!(.*?)!!)") | |
94 matches = reg.findall(s) | |
95 for i in xrange(0,len(matches)): | |
96 tree_map = node.get('map') | |
97 tree_map = tree_map + '::' + matches[i][1] | |
98 newstr = '!@'+ tree_map +'@!' | |
99 s = s.replace(matches[i][0], newstr, 1) | |
100 s = self.Node(s) | |
101 s = self.NodeParent(s, tree_map) | |
102 return s | |
103 | |
104 def NodeParent(self, s, tree_map): | |
105 """Parses player input for embedded nodes rolls""" | |
106 cur_loc = 0 | |
107 reg = re.compile("(!#(.*?)#!)") | |
108 matches = reg.findall(s) | |
109 for i in xrange(0,len(matches)): | |
110 ## Build the new tree_map | |
111 new_map = tree_map.split('::') | |
112 del new_map[len(new_map)-1] | |
113 parent_map = matches[i][1].split('::') | |
114 ## Backwards Reference the Parent Children | |
115 child_node = self.get_node('::'.join(new_map)) | |
116 newstr = self.get_root(child_node, tree_map, new_map, parent_map) | |
117 s = s.replace(matches[i][0], newstr, 1) | |
118 s = self.Node(s) | |
119 return s | |
120 | |
121 def get_root(self, child_node, tree_map, new_map, parent_map): | |
122 if child_node == 'Invalid Reference!': return child_node | |
123 roots = child_node.getchildren(); tr = tree_map.split('::') | |
124 newstr = '' | |
125 for root in roots: | |
126 try: t = new_map.index(root.get('name')) | |
127 except: t = 1 | |
128 if parent_map[0] == root.get('name'): | |
129 newstr = '!@' + '::'.join(new_map[:len(tr)-t]) + '::' + '::'.join(parent_map) + '@!' | |
130 if newstr != '': return newstr | |
131 else: | |
132 del new_map[len(new_map)-1] | |
133 child_node = self.get_node('::'.join(new_map)) | |
134 newstr = self.get_root(child_node, tree_map, new_map, parent_map) | |
135 return newstr | |
136 | |
137 def get_node(self, s): | |
138 return_node = 'Invalid Reference!' | |
139 value = "" | |
140 path = s.split('::') | |
141 depth = len(path) | |
142 try: node = component.get('tree').tree_map[path[0]]['node'] | |
143 except Exception, e: return return_node | |
144 return_node = self.resolve_get_loop(node, path, 1, depth) | |
145 return return_node | |
146 | |
147 def resolve_get_loop(self, node, path, step, depth): | |
148 if step == depth: return node | |
149 else: | |
150 child_list = node.findall('nodehandler') | |
151 for child in child_list: | |
152 if step == depth: break | |
153 if child.get('name') == path[step]: | |
154 node = self.resolve_get_loop(child, path, step+1, depth) | |
155 return node | |
156 | |
157 def resolve_nodes(self, s): | |
158 self.passed = False | |
159 string = 'Invalid Reference!' | |
160 value = "" | |
161 path = s.split('::') | |
162 depth = len(path) | |
163 try: node = component.get('tree').tree_map[path[0]]['node'] | |
164 except Exception, e: return string | |
165 if node.get('class') in ('dnd35char_handler', | |
166 "SWd20char_handler", | |
167 "d20char_handler", | |
168 "dnd3echar_handler"): string = self.resolve_cust_loop(node, path, 1, depth) | |
169 elif node.get('class') == 'rpg_grid_handler': self.resolve_grid(node, path, 1, depth) | |
170 else: string = self.resolve_loop(node, path, 1, depth) | |
171 return string | |
172 | |
173 def resolve_loop(self, node, path, step, depth): | |
174 if step == depth: return self.resolution(node) | |
175 else: | |
176 child_list = node.findall('nodehandler') | |
177 for child in child_list: | |
178 if step == depth: break | |
179 if child.get('name') == path[step]: | |
180 node = child | |
181 step += 1 | |
182 if node.get('class') in ('dnd35char_handler', | |
183 "SWd20char_handler", | |
184 "d20char_handler", | |
185 "dnd3echar_handler"): | |
186 string = self.resolve_cust_loop(node, path, step, depth) | |
187 elif node.get('class') == 'rpg_grid_handler': | |
188 string = self.resolve_grid(node, path, step, depth) | |
189 else: string = self.resolve_loop(node, path, step, depth) | |
190 return string | |
191 | |
192 def resolution(self, node): | |
193 if self.passed == False: | |
194 self.passed = True | |
195 if node.get('class') == 'textctrl_handler': | |
196 s = str(node.find('text').text) | |
197 else: s = 'Nodehandler for '+ node.get('class') + ' not done!' or 'Invalid Reference!' | |
198 else: | |
199 s = '' | |
200 s = self.NodeMap(s, node) | |
201 s = self.NodeParent(s, node.get('map')) | |
202 return s | |
203 | |
204 def resolve_grid(self, node, path, step, depth): | |
205 if step == depth: | |
206 return 'Invalid Grid Reference!' | |
207 cell = tuple(path[step].strip('(').strip(')').split(',')) | |
208 grid = node.find('grid') | |
209 rows = grid.findall('row') | |
210 col = rows[int(self.Dice(cell[0]))-1].findall('cell') | |
211 try: s = self.NodeMap(col[int(self.Dice(cell[1]))-1].text, node) or 'No Cell Data' | |
212 except: s = 'Invalid Grid Reference!' | |
213 return s | |
214 | |
215 def resolve_cust_loop(self, node, path, step, depth): | |
216 s = 'Invalid Reference!' | |
217 node_class = node.get('class') | |
218 ## Code needs clean up. Either choose .lower() or .title(), then reset the path list's content ## | |
219 if step == depth: self.resolution(node) | |
220 ##Build Abilities dictionary## | |
221 if node_class not in ('d20char_handler', "SWd20char_handler"): ab = node.find('character').find('abilities') | |
222 else: ab = node.find('abilities') | |
223 ab_list = ab.findall('stat'); pc_stats = {} | |
224 | |
225 for ability in ab_list: | |
226 pc_stats[ability.get('name')] = ( | |
227 str(ability.get('base')), | |
228 str((int(ability.get('base'))-10)/2) ) | |
229 pc_stats[ability.get('abbr')] = ( | |
230 str(ability.get('base')), | |
231 str((int(ability.get('base'))-10)/2) ) | |
232 | |
233 if node_class not in ('d20char_handler', "SWd20char_handler"): ab = node.find('character').find('saves') | |
234 else: ab = node.find('saves') | |
235 ab_list = ab.findall('save') | |
236 for save in ab_list: | |
237 pc_stats[save.get('name')] = (str(save.get('base')), str(int(save.get('magmod')) + int(save.get('miscmod')) + int(pc_stats[save.get('stat')][1]) ) ) | |
238 if save.get('name') == 'Fortitude': abbr = 'Fort' | |
239 if save.get('name') == 'Reflex': abbr = 'Ref' | |
240 if save.get('name') == 'Will': abbr = 'Will' | |
241 pc_stats[abbr] = ( str(save.get('base')), str(int(save.get('magmod')) + int(save.get('miscmod')) + int(pc_stats[save.get('stat')][1]) ) ) | |
242 | |
243 if path[step].lower() == 'skill': | |
244 if node_class not in ('d20char_handler', "SWd20char_handler"): node = node.find('snf') | |
245 node = node.find('skills') | |
246 child_list = node.findall('skill') | |
247 for child in child_list: | |
248 if path[step+1].lower() == child.get('name').lower(): | |
249 if step+2 == depth: s = child.get('rank') | |
250 elif path[step+2].lower() == 'check': | |
251 s = '<b>Skill Check:</b> ' + child.get('name') + ' [1d20+'+str( int(child.get('rank')) + int(pc_stats[child.get('stat')][1]) )+']' | |
252 return s | |
253 | |
254 if path[step].lower() == 'feat': | |
255 if node_class not in ('d20char_handler', "SWd20char_handler"): node = node.find('snf') | |
256 node = node.find('feats') | |
257 child_list = node.findall('feat') | |
258 for child in child_list: | |
259 if path[step+1].lower() == child.get('name').lower(): | |
260 if step+2 == depth: s = '<b>'+child.get('name')+'</b>'+': '+child.get('desc') | |
261 return s | |
262 if path[step].lower() == 'cast': | |
263 if node_class not in ('d20char_handler', "SWd20char_handler"): node = node.find('snp') | |
264 node = node.find('spells') | |
265 child_list = node.findall('spell') | |
266 for child in child_list: | |
267 if path[step+1].lower() == child.get('name').lower(): | |
268 if step+2 == depth: s = '<b>'+child.get('name')+'</b>'+': '+child.get('desc') | |
269 return s | |
270 if path[step].lower() == 'attack': | |
271 if node_class not in ('d20char_handler', "SWd20char_handler"): node = node.find('combat') | |
272 if path[step+1].lower() == 'melee' or path[step+1].lower() == 'm': | |
273 bonus_text = '(Melee)' | |
274 bonus = node.find('attacks') | |
275 bonus = bonus.find('melee') | |
276 bonus = bonus.attrib; d = int(pc_stats['Str'][1]) | |
277 elif path[step+1].lower() == 'ranged' or path[step+1].lower() == 'r': | |
278 bonus_text = '(Ranged)' | |
279 bonus = node.find('attacks') | |
280 bonus = bonus.find('ranged') | |
281 bonus = bonus.attrib; d = int(pc_stats['Dex'][1]) | |
282 for b in bonus: | |
283 d += int(bonus[b]) | |
284 bonus = str(d) | |
285 if path[step+2] == None: s= bonus | |
286 else: | |
287 weapons = node.find('attacks') | |
288 weapons = weapons.findall('weapon') | |
289 for child in weapons: | |
290 if path[step+2].lower() == child.get('name').lower(): | |
291 s = '<b>Attack: '+bonus_text+'</b> '+child.get('name')+' [1d20+'+bonus+'] ' + 'Damage: ['+child.get('damage')+']' | |
292 return s | |
293 elif pc_stats.has_key(path[step].title()): | |
294 if step+1 == depth: s = pc_stats[path[step].title()][0] + ' +('+pc_stats[path[step].title()][1]+')' | |
295 elif path[step+1].title() == 'Mod': s = pc_stats[path[step].title()][1] | |
296 elif path[step+1].title() == 'Check': s = '<b>'+path[step].title()+' Check:</b> [1d20+'+str(pc_stats[path[step].title()][1])+']' | |
297 return s | |
298 return s | |
299 | |
300 Parse = InterParse() |