changeset 136:b4e02e8cd314 alpha

Traipse Alpha 'OpenRPG' {091016-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 (Cleaning up for Beta) Added Bookmarks Fix to Remote Admin Commands Minor fix to text based Server Fix to Pretty Print, from Core Fix to Splitter Nodes not being created Fix to massive amounts of images loading, from Core Added 'boot' command to remote admin Added confirmation window for sent nodes Minor changes to allow for portability to an OpenSUSE linux OS Miniatures Layer pop up box allows users to turn off Mini labels, from FlexiRPG Zoom Mouse plugin added Images added to Plugin UI Switching to Element Tree Map efficiency, from FlexiRPG Added Status Bar to Update Manager default_manifest.xml renamed to default_upmana.xml Cleaner clode for saved repositories New TrueDebug Class in orpg_log (See documentation for usage) Mercurial's hgweb folder is ported to upmana **Pretty important update that can help remove thousands of dead children from your gametree. **Children, <forms />, <group_atts />, <horizontal />, <cols />, <rows />, <height />, etc... are all tags now. Check your gametree and look for dead children!! **New Gametree Recusion method, mapping, and context sensitivity. !!Alpha - Watch out for infinite loops!!
author sirebral
date Mon, 16 Nov 2009 19:13:41 -0600
parents 82c47d583493
children 54446a995007
files images/8ball.gif images/WAmisc7.ico images/WAmisc9.ico images/add_filter.gif images/apoc.gif images/arc.png images/b_d10.gif images/b_d100.gif images/b_d12.gif images/b_d20.gif images/b_d4.gif images/b_d6.gif images/b_d8.gif images/bold.gif images/book.gif images/bricktile.gif images/browser.gif images/bullet.gif images/car.gif images/ccmap.gif images/chess.gif images/circle.png images/clear.gif images/close_wnd.bmp images/compass.gif images/compass.ico images/connect.gif images/crosshair.gif images/cyborg.gif images/d10.gif images/d20.gif images/d20.ico images/d20.xpm images/d20_logo.gif images/d4.gif images/d8.gif images/dash.png images/defaultmap.png images/delete_filter.gif images/dice.bmp images/die.gif images/divider.png images/draw.gif images/drugs.gif images/earth.gif images/edit_filter.gif images/fetching.png images/flask.gif images/flask.ico images/fogoff.png images/fogon.png images/folder.gif images/form.png images/frame.bmp images/gear.gif images/goblin.gif images/goblin.ico images/grenade.gif images/grid.gif images/grid.ico images/gun1.gif images/gun2.gif images/help.gif images/hidefog.png images/html.gif images/html.ico images/icons.xml images/img.gif images/install.gif images/italic.gif images/knight.gif images/labtop.gif images/money.gif images/mouse.gif images/move.gif images/ninja.gif images/noplayer.gif images/note.gif images/note.ico images/open.bmp images/orc.gif images/oriental.gif images/pin.gif images/planet.gif images/player-whisper.gif images/player.gif images/python55.gif images/questionhead.gif images/r2d2.gif images/rectangle.png images/rome.gif images/save.bmp images/sflogo.png images/shades.gif images/showfog.png images/skull.gif images/skull_16.gif images/smsword2.gif images/spears.gif images/splash.gif images/splash.jpg images/splash1.jpg images/splash13.jpg images/splitwin.bmp images/spotlight.png images/startrek.gif images/sword.gif images/tab.bmp images/tab_close.png images/tab_on.png images/tabber.png images/tank1.gif images/tank2.gif images/tape.gif images/text.png images/thief.gif images/tiefighter.gif images/underlined.gif images/wizard1.gif images/wxPyButton.png images/wxWinButton.png images/zoom_in.gif images/zoom_out.gif myfiles/webfiles/Textures/Copyright Notice.txt myfiles/webfiles/Textures/grass-natural.jpg myfiles/webfiles/Textures/grass11.jpg myfiles/webfiles/Textures/sandwave.jpg myfiles/webfiles/Textures/steelpops11.jpg myfiles/webfiles/Textures/versa_anigre.jpg myfiles/webfiles/Textures/water06.jpg myfiles/webfiles/Textures/water20.jpg orpg/chat/chatwnd.py orpg/gametree/gametree.py orpg/networking/gsclient.py orpg/networking/mplay_client.py orpg/orpg_version.py orpg/templates/feature.xml plugins/xxmouse-zoom.py
diffstat 6 files changed, 269 insertions(+), 145 deletions(-) [+]
line wrap: on
line diff
--- a/orpg/chat/chatwnd.py	Tue Nov 10 13:32:07 2009 -0600
+++ b/orpg/chat/chatwnd.py	Mon Nov 16 19:13:41 2009 -0600
@@ -915,7 +915,6 @@
 
         if self.settings.get_setting('AliasTool_On') == '0': self.toggle_alias('0')
         else: self.toggle_alias('1')
-
     
     def toggle_alias(self, act):
         if act == '0': self.toolbar_sizer.Show(self.aliasSizer, False)
@@ -926,79 +925,62 @@
         self.textpop_lock = createMaskedButton(self, dir_struct["icon"]+'note.gif', 'Open Text View Of Chat Session', wx.ID_ANY, '#bdbdbd')
 
     
-    def build_dice(self):
-        self.numDieText = wx.TextCtrl( self, wx.ID_ANY, "1", size= wx.Size(25, 25), validator=orpg.tools.inputValidator.MathOnlyValidator() )
-        self.dieModText = wx.TextCtrl( self, wx.ID_ANY, "", size= wx.Size(50, 25), validator=orpg.tools.inputValidator.MathOnlyValidator() )
+    def build_dice(self):
+        self.diceSizer = wx.BoxSizer(wx.HORIZONTAL)
+        self.numDieText = wx.TextCtrl( self, wx.ID_ANY, "1", 
+                                    size= wx.Size(25, 25), validator=orpg.tools.inputValidator.MathOnlyValidator() )
+        self.dieModText = wx.TextCtrl( self, wx.ID_ANY, "", 
+                                    size= wx.Size(50, 25), validator=orpg.tools.inputValidator.MathOnlyValidator() )
         self.d4Button = createMaskedButton(self, dir_struct["icon"]+'b_d4.gif', 'Roll d4', wx.ID_ANY)
         self.d6Button = createMaskedButton(self, dir_struct["icon"]+'b_d6.gif', 'Roll d6', wx.ID_ANY)
         self.d8Button = createMaskedButton(self, dir_struct["icon"]+'b_d8.gif', 'Roll d8', wx.ID_ANY)
         self.d10Button = createMaskedButton(self, dir_struct["icon"]+'b_d10.gif', 'Roll d10', wx.ID_ANY)
         self.d12Button = createMaskedButton(self, dir_struct["icon"]+'b_d12.gif', 'Roll d12', wx.ID_ANY)
         self.d20Button = createMaskedButton(self, dir_struct["icon"]+'b_d20.gif', 'Roll d20', wx.ID_ANY)
-        self.d100Button = createMaskedButton(self, dir_struct["icon"]+'b_d100.gif', 'Roll d100', wx.ID_ANY)
-        self.toolbar_sizer.Add( self.numDieText, 0, wx.ALIGN_CENTER | wx.EXPAND)
-        self.toolbar_sizer.Add( self.d4Button, 0 ,wx.EXPAND)
-        self.toolbar_sizer.Add( self.d6Button, 0 ,wx.EXPAND)
-        self.toolbar_sizer.Add( self.d8Button, 0 ,wx.EXPAND)
-        self.toolbar_sizer.Add( self.d10Button, 0 ,wx.EXPAND)
-        self.toolbar_sizer.Add( self.d12Button, 0 ,wx.EXPAND)
-        self.toolbar_sizer.Add( self.d20Button, 0 ,wx.EXPAND)
-        self.toolbar_sizer.Add( self.d100Button, 0 ,wx.EXPAND)
-        self.toolbar_sizer.Add( self.dieModText, 0, wx.ALIGN_CENTER, 5 )
+        self.d100Button = createMaskedButton(self, dir_struct["icon"]+'b_d100.gif', 'Roll d100', wx.ID_ANY)
+
+        self.diceSizer.Add( self.numDieText, 0, wx.ALIGN_CENTER | wx.EXPAND)
+        self.diceSizer.Add( self.d4Button, 0 ,wx.EXPAND)
+        self.diceSizer.Add( self.d6Button, 0 ,wx.EXPAND)
+        self.diceSizer.Add( self.d8Button, 0 ,wx.EXPAND)
+        self.diceSizer.Add( self.d10Button, 0 ,wx.EXPAND)
+        self.diceSizer.Add( self.d12Button, 0 ,wx.EXPAND)
+        self.diceSizer.Add( self.d20Button, 0 ,wx.EXPAND)
+        self.diceSizer.Add( self.d100Button, 0 ,wx.EXPAND)
+        self.diceSizer.Add( self.dieModText, 0, wx.ALIGN_CENTER, 5 )
+
+        self.toolbar_sizer.Add( self.diceSizer, 0, wx.EXPAND)
         if self.settings.get_setting('DiceButtons_On') == '0': self.toggle_dice('0')
         else: self.toggle_dice('1')
 
     
     def toggle_dice(self, act):
-        if act == '0':
-            self.toolbar_sizer.Show(self.numDieText, False)
-            self.toolbar_sizer.Show(self.d4Button, False)
-            self.toolbar_sizer.Show(self.d6Button, False)
-            self.toolbar_sizer.Show(self.d8Button, False)
-            self.toolbar_sizer.Show(self.d10Button, False)
-            self.toolbar_sizer.Show(self.d12Button, False)
-            self.toolbar_sizer.Show(self.d20Button, False)
-            self.toolbar_sizer.Show(self.d100Button, False)
-            self.toolbar_sizer.Show(self.dieModText, False)
-            self.toolbar_sizer.Layout()
-        else:
-            self.toolbar_sizer.Show(self.numDieText, True)
-            self.toolbar_sizer.Show(self.d4Button, True)
-            self.toolbar_sizer.Show(self.d6Button, True)
-            self.toolbar_sizer.Show(self.d8Button, True)
-            self.toolbar_sizer.Show(self.d10Button, True)
-            self.toolbar_sizer.Show(self.d12Button, True)
-            self.toolbar_sizer.Show(self.d20Button, True)
-            self.toolbar_sizer.Show(self.d100Button, True)
-            self.toolbar_sizer.Show(self.dieModText, True)
-            self.toolbar_sizer.Layout()
+        if act == '0': self.toolbar_sizer.Show(self.diceSizer, False)
+        else: self.toolbar_sizer.Show(self.diceSizer, True)
+        self.toolbar_sizer.Layout()
 
     
-    def build_formating(self):
+    def build_formating(self):
+        self.formatSizer = wx.BoxSizer(wx.HORIZONTAL)
         self.boldButton = createMaskedButton( self, dir_struct["icon"]+'bold.gif', 
                                                             'Make the selected text Bold', wx.ID_ANY, '#bdbdbd')
         self.italicButton = createMaskedButton( self, dir_struct["icon"]+'italic.gif', 
                                                             'Italicize the selected text', wx.ID_ANY, '#bdbdbd' )
         self.underlineButton = createMaskedButton( self, dir_struct["icon"]+'underlined.gif', 
-                                                            'Underline the selected text', wx.ID_ANY, '#bdbdbd' )
-        self.toolbar_sizer.Add( self.boldButton, 0, wx.EXPAND )
-        self.toolbar_sizer.Add( self.italicButton, 0, wx.EXPAND )
-        self.toolbar_sizer.Add( self.underlineButton, 0, wx.EXPAND )
+                                                            'Underline the selected text', wx.ID_ANY, '#bdbdbd' )
+
+        self.formatSizer.Add( self.boldButton, 0, wx.EXPAND )
+        self.formatSizer.Add( self.italicButton, 0, wx.EXPAND )
+        self.formatSizer.Add( self.underlineButton, 0, wx.EXPAND )
+        self.toolbar_sizer.Add( self.formatSizer, 0, wx.EXPAND )
         if self.settings.get_setting('FormattingButtons_On') == '0': self.toggle_formating('0')
         else: self.toggle_formating('1')
 
     
     def toggle_formating(self, act):
-        if act == '0':
-            self.toolbar_sizer.Show(self.boldButton, False)
-            self.toolbar_sizer.Show(self.italicButton, False)
-            self.toolbar_sizer.Show(self.underlineButton, False)
-            self.toolbar_sizer.Layout()
-        else:
-            self.toolbar_sizer.Show(self.boldButton, True)
-            self.toolbar_sizer.Show(self.italicButton, True)
-            self.toolbar_sizer.Show(self.underlineButton, True)
-            self.toolbar_sizer.Layout()
+        if act == '0': self.toolbar_sizer.Show(self.formatSizer, False)
+        else: self.toolbar_sizer.Show(self.formatSizer, True)
+        self.toolbar_sizer.Layout()
 
     # Heroman - Ideally, we would use static labels...
     
@@ -1075,7 +1057,7 @@
         if self.lastSend:                          #  This will be zero when not typing, so equiv to if is_typing
             thisTime = time.time()                 #  thisTime is a local temp variable
             if (thisTime - self.lastPress) > 4:    #  Check to see if it's been 5 seconds since our last keystroke
-                                               #    If we're not already typing, then self.lastSend will be 0
+                                                   #  If we're not already typing, then self.lastSend will be 0
 
                 self.sendTyping(0)                 #  send a typing event here (0 for False)
     #  This subroutine actually takes care of sending the messages for typing/not_typing events
@@ -1926,15 +1908,100 @@
             for child in child_list:
                 if step == depth: break
                 if child.get('name') == path[step]:
-                    node = child
-                    step += 1
-                    self.resolve_loop(node, path, step, depth)
+                    node = child
+                    step += 1
+                    if node.get('class') in ('dnd35char_handler', "SWd20char_handler", "d20char_handler", "dnd3echar_handler"): self.resolve_cust_loop(node, path, step, depth)
+                    else: self.resolve_loop(node, path, step, depth)
+
+    def resolve_cust_loop(self, node, path, step, depth):
+        node_class = node.get('class')
+        if step == depth:
+            self.resolution(node)
+
+        ##Build Abilities dictionary##
+        if node_class not in ('d20char_handler', "SWd20char_handler"): ab = node.find('character').find('abilities')
+        else: ab = node.find('abilities')
+        ab_list = ab.findall('stat'); pc_stats = {}
+
+        for ability in ab_list:
+            pc_stats[ability.get('name')] = ( str(ability.get('base')), str((int(ability.get('base'))-10)/2) )
+            pc_stats[ability.get('abbr')] = ( str(ability.get('base')), str((int(ability.get('base'))-10)/2) )
+
+        if node_class not in ('d20char_handler', "SWd20char_handler"): ab = node.find('character').find('saves')
+        else: ab = node.find('saves')
+        ab_list = ab.findall('save')
+
+        for save in ab_list:
+            pc_stats[save.get('name')] = ( str(save.get('base')), str(int(save.get('magmod')) + int(save.get('miscmod')) + int(pc_stats[save.get('stat')][1]) ) )
+            if save.get('name') == 'Fortitude': abbr = 'Fort'
+            if save.get('name') == 'Reflex': abbr = 'Ref'
+            if save.get('name') == 'Will': abbr = 'Will'
+            pc_stats[abbr] = ( str(save.get('base')), str(int(save.get('magmod')) + int(save.get('miscmod')) + int(pc_stats[save.get('stat')][1]) ) )
+
+        if path[step] == 'Skill':
+            if node_class not in ('d20char_handler', "SWd20char_handler"): node = node.find('snf')
+            node = node.find('skills')
+            child_list = node.findall('skill')
+            for child in child_list:
+                if path[step+1] == child.get('name'):
+                    if step+2 == depth: self.data = child.get('rank')
+                    elif path[step+2] == 'Check':
+                        self.data = 'Skill Check: ' + child.get('name') + ' [1d20+'+str( int(child.get('rank')) + int(pc_stats[child.get('stat')][1]) )+']'
+            return
+
+        if path[step] == 'Feat':
+            if node_class not in ('d20char_handler', "SWd20char_handler"): node = node.find('snf')
+            node = node.find('feats')
+            child_list = node.findall('feat')
+            for child in child_list:
+                if path[step+1] == child.get('name'):
+                    if step+2 == depth: self.data = child.get('name') + ': ' + child.get('desc')
+            return
+
+        if path[step] == 'Cast':
+            if node_class not in ('d20char_handler', "SWd20char_handler"): node = node.find('snp')
+            node = node.find('spells')
+            child_list = node.findall('spell')
+            for child in child_list:
+                if path[step+1] == child.get('name'):
+                    if step+2 == depth: self.data = child.get('name') + ': ' + child.get('desc')
+            return
+
+        if path[step] == 'Attack':
+            if node_class not in ('d20char_handler', "SWd20char_handler"): node = node.find('combat')
+            if path[step+1] == 'Melee' or path[step+1] == 'M':
+                bonus = node.find('attacks')
+                bonus = bonus.find('melee')
+                bonus = bonus.attrib; d = 0
+            elif path[step+1] == 'Ranged' or path[step+1] == 'R':
+                bonus = node.find('attacks')
+                bonus = bonus.find('ranged')
+                bonus = bonus.attrib; d = 0
+            for b in bonus:
+                d += int(bonus[b])
+            bonus = str(d)
+            if path[step+2] == None:
+                self.data = bonus
+            else:
+                weapons = node.find('attacks')
+                weapons = weapons.findall('weapon')
+                for child in weapons:
+                    if path[step+2] == child.get('name'):
+                        self.data = 'Attack: '+child.get('name')+' [1d20+'+bonus+'] ' + 'Damage: ['+child.get('damage')+']'
+            return
+
+        elif pc_stats.has_key(path[step]):
+            if step+1 == depth: self.data = pc_stats[path[step]][0] + ' +('+pc_stats[path[step]][1]+')'
+            elif path[step+1] == 'Mod': self.data = pc_stats[path[step]][1]
+            elif path[step+1] == 'Check': self.data = path[step] + ' Check: [1d20+' + str(pc_stats[path[step]][1]) +']'
+            return
+
 
     def resolution(self, node):
         if self.passed == False:
             self.passed = True
             if node.get('class') == 'textctrl_handler': self.data = str(node.find('text').text)
-            else: self.data = 'Nodehandler for '+ node.get('class') + ' not done!' or 'No Data!'
+            else: self.data = 'Nodehandler for '+ node.get('class') + ' not done!' or 'Invalid Reference!'
         else:
             self.data = ''
             pass
@@ -1945,7 +2012,6 @@
         cur_loc = 0
         reg = re.compile("(!!(.*?)!!)")
         matches = reg.findall(s)
-        print matches
         for i in xrange(0,len(matches)):
             newstr = txt = '!@' + node.get('map') + '::' + matches[i][1] + '@!'
             s = s.replace(matches[i][0], newstr, 1)
@@ -1954,13 +2020,12 @@
 
     def resolve_nodes(self, s):
         self.passed = False
-        self.data = 'No Data!'
+        self.data = 'Invalid Reference!'
         value = ""
         path = s.split('::')
         depth = len(path)
-        self.gametree = component.get('tree')
-        dom = self.gametree.xml_root.getchildren()
-        for node in dom:
-            if node.get('name') == path[0]:
-                self.resolve_loop(node, path, 1, len(path))
+        self.gametree = component.get('tree')
+        node = self.gametree.tree_map[path[0]]['node']
+        if node.get('class') in ('dnd35char_handler', "SWd20char_handler", "d20char_handler", "dnd3echar_handler"): self.resolve_cust_loop(node, path, 1, depth)
+        else: self.resolve_loop(node, path, 1, depth)
         return self.data
--- a/orpg/gametree/gametree.py	Tue Nov 10 13:32:07 2009 -0600
+++ b/orpg/gametree/gametree.py	Mon Nov 16 19:13:41 2009 -0600
@@ -109,7 +109,7 @@
         self.id = 1
         self.dragging = False
         self.last_save_dir = dir_struct["user"]
-        self.tree_map = []
+        self.tree_map = {}
 
         #Create tree from default if it does not exist
         validate.config_file("tree.xml","default_tree.xml")
@@ -409,7 +409,7 @@
             type = f.GetFilterIndex()
             with open(f.GetPath(),"w") as f:
                 data = "<html><head><title>"+obj.xml.get("name")+"</title></head>"
-                data += "<body bgcolor=\"#FFFFFF\" >"+obj.tohtml()+"</body></html>"
+                data += "<body bgcolor='#FFFFFF' >"+obj.tohtml()+"</body></html>"
                 for tag in ("</tr>","</td>","</th>","</table>","</html>","</body>"):
                     data = data.replace(tag,tag+"\n")
                 f.write(data)
@@ -479,7 +479,7 @@
         obj = self.GetPyData(item)
         name = "New " + obj.xml_root.get("name")
         icon = obj.xml_root.get("icon")
-        xml_data = "<nodehandler name=\""+name+"\" icon=\"" + icon + "\" module=\"core\" class=\"node_loader\" >"
+        xml_data = "<nodehandler name='"+name+"' icon='" + icon + "' module='core' class='node_loader' >"
         xml_data += xml.toxml(obj)
         xml_data += "</nodehandler>"
         self.insert_xml(xml_data)
@@ -687,6 +687,9 @@
         return family_tree
     
     def load_xml(self, xml_element, parent_node, prev_node=None):
+        if parent_node == self.root:
+            self.tree_map[xml_element.get('name')] = {}
+            self.tree_map[xml_element.get('name')]['node'] = xml_element
         if parent_node != self.root:
             ## Loading XML seems to lag on Grids and Images need a cache for load speed ##
             family_tree = self.get_tree_map(parent_node)
--- a/orpg/networking/gsclient.py	Tue Nov 10 13:32:07 2009 -0600
+++ b/orpg/networking/gsclient.py	Mon Nov 16 19:13:41 2009 -0600
@@ -30,7 +30,6 @@
 __version__ = "$Id: gsclient.py,v 1.53 2007/10/25 21:49:34 digitalxero Exp $"
 
 import meta_server_lib
-#import orpg.tools.orpg_settings
 import orpg.tools.rgbhex
 import traceback
 
--- a/orpg/networking/mplay_client.py	Tue Nov 10 13:32:07 2009 -0600
+++ b/orpg/networking/mplay_client.py	Mon Nov 16 19:13:41 2009 -0600
@@ -122,7 +122,8 @@
         self.ROLE_PLAYER = "Player"
         self.ROLE_LURKER = "Lurker"
         ## --TaS
-        self.ip = socket.gethostbyname(socket.gethostname())
+        try: self.ip = socket.gethostbyname(socket.gethostname())
+	except: self.ip = socket.gethostbyname('localhost')
         self.remote_ip = None
         self.version = VERSION
         self.protocol_version = PROTOCOL_VERSION
@@ -733,7 +734,7 @@
     def on_group(self, id, msg, etreeEl):
         act = etreeEl.get("action")
         group_data = (id, etreeEl.get("name"), etreeEl.get("pwd"), etreeEl.get("players"))
-        if act == ('new' or 'update'):
+        if act == 'new' or act == 'update':
             self.groups[id] = group_data
             if act == 'update': self.on_group_event(mplay_event(GROUP_UPDATE, group_data))
             elif act == 'new': self.on_group_event(mplay_event(GROUP_NEW, group_data))
--- a/orpg/orpg_version.py	Tue Nov 10 13:32:07 2009 -0600
+++ b/orpg/orpg_version.py	Mon Nov 16 19:13:41 2009 -0600
@@ -4,7 +4,7 @@
 #BUILD NUMBER FORMAT: "YYMMDD-##" where ## is the incremental daily build index (if needed)
 DISTRO = "Traipse Alpha"
 DIS_VER = "Ornery Orc"
-BUILD = "091010-01"
+BUILD = "091016-00"
 
 # This version is for network capability.
 PROTOCOL_VERSION = "1.2"
--- a/orpg/templates/feature.xml	Tue Nov 10 13:32:07 2009 -0600
+++ b/orpg/templates/feature.xml	Mon Nov 16 19:13:41 2009 -0600
@@ -1,108 +1,164 @@
+<nodehandler class="tabber_handler" icon="help" module="containers" name="Traipse OpenRPG" version="1.0">
+  <nodehandler class="textctrl_handler" frame="400,400,139,110" icon="note" map="Traipse OpenRPG" module="forms" name="Node Referencing" version="1.0"><text hide_title="0" multiline="1" raw_mode="0" send_button="0">Traipse node referencing is unlike other distributions of OpenRPG.  The gametree mapping is a fluid map that changes with the location of your nodes.  This allows you to create a reference node that will stay with your character sheet, and if you change the location of your character sheet the reference will still work.
 
-<nodehandler class="tabber_handler" icon="help" module="containers" name="OpenRPG+ 1.7.1" version="1.0">
-  <nodehandler class="link_handler" icon="html" module="forms" name="Release Notes" version="1.0">
-    <link href="http://openrpg.digitalxero.net/wiki/index.php?page=Release+Notes"/>
-  </nodehandler>
-  <nodehandler class="link_handler" icon="html" module="forms" name="OpenRPG User Guide" version="1.0">
-    <link href="http://openrpg.digitalxero.net"/>
-  </nodehandler>
-  <nodehandler class="file_loader" icon="help" module="core" name="Load Die Roller Notes" version="1.0">
-    <file name="die_roller_notes.xml"/>
+There are two ways of references node data. A Root Reference and a Child Reference.
+
+A Root Reference uses this syntax:
+!@Node::Child::Data@!
+
+Root References find the data within the node first by looking at the nodes in the tree.  The location of the node must be exact or you will return an Invalid Reference!
+
+A Child Reference uses this syntax:
+!!Node::Child::Data!!
+
+Child References work from within a container.  Child References obtain the map from a child node and then look for the node data using an appended Root Reference.  As long as the Child Reference node remains in in the same location relative to the reference, you can move the nodes around and never need to change your references again.
+
+Child Referencing works from within a PC Sheet node as well.
+
+Syntax for Special PC Sheet Nodes:
+The nodes for the specialized PC Sheets now have a new syntax.
+
+Abilities:
+To reference an Ability, use the name or abbreviation of the Ability.
+Example: !@Mikael::Strength@!
+
+This will return the Ability, the Ability Score, and it's Modifier.
+
+Mod Referencing:
+If you want to find the Ability Modifier only, use Ability::Mod
+Example: !@Mikael::Strength::Mod@!
+
+Ability Checks:
+Ability Checks are simplified as well.  Simply add Check to the reference.
+Example: !@Mikael::Strength::Check@!
+
+The new referencing features are useful if you want to refence the ability modifier in other nodes.
+
+Skills:
+Skills work the similar to Abilities.  To refence a skill's ranks use the Skill syntax
+Example: !@Jonethan::Skill::Jump@!
+
+This will return the ranks you have in Jump.  Skill Checks are made by appending Check to the statement.
+Example: !@Jonethan::Skill::Jump::Check@!
+
+If you want to reference the skills modifier, use the Mod syntax
+Example: !@Jonethan::Skill::Jump::Mod@!
+
+Combat:
+You can now reference your attacks easily with the gametree.  Using the Attack syntax you can select modifier type, and a weapon to attack with.
+Example: !@Kammen-Pai::Attack::M::Dagger@!
+
+Modifier Type:
+There are two modifier types Melee (M) or Ranged(R) You will see I added can use the long word or the short hand.
+
+Spells:
+If the PC Sheet you are using has Spells and Powers, you can use the Cast syntax to cast a spell or use a power.
+Example: !@Kammen-Pai::Cast::Ray of Frost@!
+
+The data returned is the description of the spells actions.  Spell actions are difficult to remember, and even harder to code, so this will at least work as an emoteable reference and a reminder of how the spell works.
+
+Feats:
+Feats will work the same way as spells.  Because Feats and Spells have rulings that require such finesse it is not very easy to code them.  However you will receive an easy to use reference point for what your Feat does.
+Using the Feat syntax you can the description of the Feat.
+Example: !@Kammen-Pai::Feat::Ability Focus@!
+
+</text></nodehandler><nodehandler class="link_handler" icon="html" map="Traipse OpenRPG" module="forms" name="Release Notes" version="1.0">
+    <link href="http://www.assembla.com/wiki/show/traipse" />
   </nodehandler>
-  <nodehandler class="group_handler" icon="gear" module="containers" name="Templates" status="useful" version="1.0">
-    <group_atts border="1" cols="1"/>
-    <nodehandler class="group_handler" icon="flask" module="containers" name="Nodes" status="useful" version="1.0">
-      <group_atts border="1" cols="1"/>
-      <nodehandler class="file_loader" icon="note" module="core" name="Create New Text Box" version="1.0">
-        <file name="textctrl.xml"/>
+  <nodehandler class="link_handler" icon="html" map="Traipse OpenRPG" module="forms" name="Traipse User Guide" version="1.0">
+    <link href="http://www.assembla.com/wiki/show/traipse/User_Manual" />
+  </nodehandler>
+  <nodehandler class="file_loader" icon="help" map="Traipse OpenRPG" module="core" name="Load Die Roller Notes" version="1.0">
+    <file name="die_roller_notes.xml" />
+  </nodehandler>
+  <nodehandler border="1" class="group_handler" cols="1" icon="gear" map="Traipse OpenRPG" module="containers" name="Templates" status="useful" version="1.0">
+    <group_atts border="1" cols="1" />
+    <nodehandler border="1" class="group_handler" cols="1" icon="flask" map="Traipse OpenRPG::Templates" module="containers" name="Nodes" status="useful" version="1.0">
+      <group_atts border="1" cols="1" />
+      <nodehandler class="file_loader" icon="note" map="Traipse OpenRPG::Templates::Nodes" module="core" name="Create New Text Box" version="1.0">
+        <file name="textctrl.xml" />
       </nodehandler>
-      <nodehandler class="file_loader" icon="gear" module="core" name="Create New List Box" version="1.0">
-        <file name="listbox.xml"/>
+      <nodehandler class="file_loader" icon="gear" map="Traipse OpenRPG::Templates::Nodes" module="core" name="Create New List Box" version="1.0">
+        <file name="listbox.xml" />
       </nodehandler>
-      <nodehandler class="file_loader" icon="grid" module="core" name="Create New Grid" version="1.0">
-        <file name="grid.xml"/>
+      <nodehandler class="file_loader" icon="grid" map="Traipse OpenRPG::Templates::Nodes" module="core" name="Create New Grid" version="1.0">
+        <file name="grid.xml" />
       </nodehandler>
-      <nodehandler class="file_loader" icon="html" module="core" name="Create New Web Link" version="1.0">
-        <file name="link.xml"/>
+      <nodehandler class="file_loader" icon="html" map="Traipse OpenRPG::Templates::Nodes" module="core" name="Create New Web Link" version="1.0">
+        <file name="link.xml" />
       </nodehandler>
-      <nodehandler class="file_loader" icon="image" module="core" name="Create New Web Image" version="1.0">
-        <file name="image.xml"/>
+      <nodehandler class="file_loader" icon="image" map="Traipse OpenRPG::Templates::Nodes" module="core" name="Create New Web Image" version="1.0">
+        <file name="image.xml" />
       </nodehandler>
     </nodehandler>
-    <nodehandler class="group_handler" module="containers" name="Containers" status="useful" version="1.0">
-      <group_atts border="1" cols="1"/>
-      <nodehandler class="file_loader" module="core" name="Create New Folder" version="1.0">
-        <file name="group.xml"/>
+    <nodehandler border="1" class="group_handler" cols="1" map="Traipse OpenRPG::Templates" module="containers" name="Containers" status="useful" version="1.0">
+      <group_atts border="1" cols="1" />
+      <nodehandler class="file_loader" map="Traipse OpenRPG::Templates::Containers" module="core" name="Create New Folder" version="1.0">
+        <file name="group.xml" />
       </nodehandler>
-      <nodehandler class="file_loader" icon="tabber" module="core" name="Create New Tabber" version="1.0">
-        <file name="tabber.xml"/>
+      <nodehandler class="file_loader" icon="tabber" map="Traipse OpenRPG::Templates::Containers" module="core" name="Create New Tabber" version="1.0">
+        <file name="tabber.xml" />
       </nodehandler>
-      <nodehandler class="file_loader" icon="divider" module="core" name="Create New Splitter" version="1.0">
-        <file name="split.xml"/>
+      <nodehandler class="file_loader" icon="divider" map="Traipse OpenRPG::Templates::Containers" module="core" name="Create New Splitter" version="1.0">
+        <file name="split.xml" />
       </nodehandler>
-      <nodehandler class="file_loader" icon="form" module="core" name="Create New Form" version="1.0">
-        <file name="form.xml"/>
+      <nodehandler class="file_loader" icon="form" map="Traipse OpenRPG::Templates::Containers" module="core" name="Create New Form" version="1.0">
+        <file name="form.xml" />
       </nodehandler>
     </nodehandler>
-    <nodehandler class="group_handler" icon="gear" module="containers" name="Tools" status="useful" version="1.0">
-      <group_atts border="1" cols="1"/>
-      <nodehandler class="file_loader" icon="gear" module="core" name="Create New Chat Macro" version="1.0">
-        <file name="macro.xml"/>
+    <nodehandler border="1" class="group_handler" cols="1" icon="gear" map="Traipse OpenRPG::Templates" module="containers" name="Tools" status="useful" version="1.0">
+      <group_atts border="1" cols="1" />
+      <nodehandler class="file_loader" icon="gear" map="Traipse OpenRPG::Templates::Tools" module="core" name="Create New Chat Macro" version="1.0">
+        <file name="macro.xml" />
       </nodehandler>
-      <nodehandler class="file_loader" icon="gear" module="core" name="Create New Miniature Library Tool" version="1.0">
-        <file name="minlib.xml"/>
+      <nodehandler class="file_loader" icon="gear" map="Traipse OpenRPG::Templates::Tools" module="core" name="Create New Miniature Library Tool" version="1.0">
+        <file name="minlib.xml" />
       </nodehandler>
-      <nodehandler class="file_loader" icon="gear" module="core" name="Create remote node loader" version="1.0">
-        <file name="urloader.xml"/>
+      <nodehandler class="file_loader" icon="gear" map="Traipse OpenRPG::Templates::Tools" module="core" name="Create remote node loader" version="1.0">
+        <file name="urloader.xml" />
       </nodehandler>
-      <nodehandler class="file_loader" icon="d20" module="core" name="Create New d20 Character Tool" version="1.0">
-        <file name="d20character.xml"/>
+      <nodehandler class="file_loader" icon="d20" map="Traipse OpenRPG::Templates::Tools" module="core" name="Create New d20 Character Tool" version="1.0">
+        <file name="d20character.xml" />
       </nodehandler>
-      <nodehandler class="file_loader" icon="d20" module="core" name="Create New St*r W*rs Character Tool" version="1.0">
-        <file name="StarWars_d20character.xml"/>
+      <nodehandler class="file_loader" icon="d20" map="Traipse OpenRPG::Templates::Tools" module="core" name="Create New St*r W*rs Character Tool" version="1.0">
+        <file name="StarWars_d20character.xml" />
       </nodehandler>
-      <nodehandler class="file_loader" icon="d20" module="core" name="3rd Edition Character Tool" version="1.0">
-        <file name="dnd3e.xml"/>
+      <nodehandler class="file_loader" icon="d20" map="Traipse OpenRPG::Templates::Tools" module="core" name="3rd Edition Character Tool" version="1.0">
+        <file name="dnd3e.xml" />
       </nodehandler>
-      <nodehandler class="file_loader" icon="d20" module="core" name="3.5 Tool" version="1.0">
-        <file name="dnd3.5.xml"/>
+      <nodehandler class="file_loader" icon="d20" map="Traipse OpenRPG::Templates::Tools" module="core" name="3.5 Tool" version="1.0">
+        <file name="dnd3.5.xml" />
       </nodehandler>
     </nodehandler>
   </nodehandler>
-  <nodehandler class="group_handler" icon="browser" module="containers" name="OpenRPG+ Resources" version="1.0">
-    <group_atts border="1" cols="1"/>
-    <nodehandler class="link_handler" icon="html" module="forms" name="OpenRPG+ Home Page" version="1.0">
-      <link href="http://openrpg.digitalxero.net"/>
+  <nodehandler border="1" class="group_handler" cols="1" icon="browser" map="Traipse OpenRPG" module="containers" name="OpenRPG+ Resources" version="1.0">
+    <group_atts border="1" cols="1" />
+    <nodehandler class="link_handler" icon="html" map="Traipse OpenRPG::OpenRPG+ Resources" module="forms" name="OpenRPG+ Home Page" version="1.0">
+      <link href="http://www.openrpg.com" />
     </nodehandler>
-    <nodehandler class="link_handler" icon="html" module="forms" name="OpenRPG Project Page" version="1.0">
-      <link href="http://openrpg.digitalxero.net"/>
-    </nodehandler>
-    <nodehandler class="link_handler" icon="html" module="forms" name="OpenRPG Forums" version="1.0">
-      <link href="http://forums.rpghost.com/forumdisplay.php?s=&amp;forumid=118"/>
+    <nodehandler class="link_handler" icon="html" map="Traipse OpenRPG::OpenRPG+ Resources" module="forms" name="OpenRPG Forums" version="1.0">
+      <link href="http://forums.rpghost.com/forumdisplay.php?s=&amp;forumid=118" />
     </nodehandler>
-    <nodehandler class="link_handler" icon="html" module="forms" name="Submit A Bug Report" version="1.0">
-      <link href="http://openrpg.digitalxero.net/phpbb/viewtopic.php?t=10"/>
+    <nodehandler class="link_handler" icon="html" map="Traipse OpenRPG::OpenRPG+ Resources" module="forms" name="OpenRPG Plugin HQ" version="1.0">
+      <link href="http://openrpg.mduo13.com/plugins.php" />
     </nodehandler>
-    <nodehandler class="link_handler" icon="html" module="forms" name="OpenRPG Plugin HQ" version="1.0">
-      <link href="http://openrpg.mduo13.com/plugins.php"/>
+    <nodehandler class="link_handler" icon="html" map="Traipse OpenRPG::OpenRPG+ Resources" module="forms" name="OpenRPG Web Ring" version="1.0">
+      <link href="http://www.ringsurf.com/netring?ring=OpenRPG;action=home" />
     </nodehandler>
-    <nodehandler class="link_handler" icon="html" module="forms" name="OpenRPG Web Ring" version="1.0">
-      <link href="http://www.ringsurf.com/netring?ring=OpenRPG;action=home"/>
+    <nodehandler class="link_handler" icon="html" map="Traipse OpenRPG::OpenRPG+ Resources" module="forms" name="AutoRealm" version="1.0">
+      <link href="http://www.gryc.ws/autorealm.htm" />
     </nodehandler>
-    <nodehandler class="link_handler" icon="html" module="forms" name="AutoRealm" version="1.0">
-      <link href="http://www.gryc.ws/autorealm.htm"/>
-    </nodehandler>
-    <nodehandler class="link_handler" icon="html" module="forms" name="PCGen" version="1.0">
-      <link href="http://pcgen.sourceforge.net/01_overview.php"/>
+    <nodehandler class="link_handler" icon="html" map="Traipse OpenRPG::OpenRPG+ Resources" module="forms" name="PCGen" version="1.0">
+      <link href="http://pcgen.sourceforge.net/01_overview.php" />
     </nodehandler>
   </nodehandler>
-  <nodehandler class="group_handler" module="containers" name="Examples (Adventures)" version="1.0">
-    <group_atts border="1" cols="1"/>
-    <nodehandler class="file_loader" icon="d20" module="core" name="Bastion Press d20 Adventure" version="1.0">
-      <file name="Bastion_adventure.xml"/>
+  <nodehandler border="1" class="group_handler" cols="1" map="Traipse OpenRPG" module="containers" name="Examples (Adventures)" version="1.0">
+    <group_atts border="1" cols="1" />
+    <nodehandler class="file_loader" icon="d20" map="Traipse OpenRPG::Examples (Adventures)" module="core" name="Bastion Press d20 Adventure" version="1.0">
+      <file name="Bastion_adventure.xml" />
     </nodehandler>
-    <nodehandler class="file_loader" icon="d20" module="core" name="Darwin's World d20 Adventure" version="1.0">
-      <file name="Darwin_adventure.xml"/>
+    <nodehandler class="file_loader" icon="d20" map="Traipse OpenRPG::Examples (Adventures)" module="core" name="Darwin&apos;s World d20 Adventure" version="1.0">
+      <file name="Darwin_adventure.xml" />
     </nodehandler>
   </nodehandler>
 </nodehandler>