View Single Post
Duggan
Senior Member
Volunteer Data File Contributor
 
Join Date: Nov 2009
Posts: 1,502

Old September 5th, 2017, 04:42 PM
Still working on Planet Mercenary. I'm back to the Skill Specializations. Almost every skill has a series of Specializations that can be bootstrapped, bought by the user at creation, or bought during advancement. There's some overlap in specializations (Beam can be applied to six of the gun skills. Projectile applies to five of them, for example). A user may buy as many specialties associated with a skill as he has ranks in that skill (so someone with Pistols 2 could buy Beam and Projectile, but not also Non-Lethal). Most specialties are unique, but a few (which require one to apply a custom domain) repeat.

Initially, based on TCArknight's work on Doctor Who, I assumed that I'd need Gizmos, with the Specialties associated with the Skills, but the Specialties are really on the Hero, right? Or do I still need the Gizmo, since I want to be able to click on a button on the Skill and bring up the dialog to add specialties particular to that Skill?

What I have right now brings up a list of all specialties with the button (with an error message of "Attempt to retrieve candidate tagexpr from non-existent pick 'SpecHelp'" every time I bring up the form or confirm a choice), but it does add the specialty to the Hero such that I can display it in the listing. And I am able to bootstrap the specialty as part of the various Background choices. Still, I'd like to restrict the list to only specialties associated with the skill, not display the dialog if there are no choices that can be made, and at least flag if there are more specialties than ranks. Here is what I believe is the relevant code:

Procedures.dat
Code:
<!-- Script used to set up Specialty selection
  -->
  <procedure id="SetSpcExpr" context="pick"><![CDATA[
    ~make sure there's a gizmo to travel to
    doneif (isgizmo = 0)
    
    ~set up our tag expression for selecting appropriate specialty
    var expr as string
    var myId as string

    expr = "component.Specialty & (User.CustSkill |  "
    expr &= myId & ")"

    gizmo.childfound[SpecHelp].field[SpecExpr].text = expr
    ]]></procedure>
traits.str (I think maybe only eval 4 and eval 10 are relevant in Skill. Also, I've only included relevant components and compsets)
Code:
<!-- Skill component
        Each skill derives from this component
  -->
  <component
    id="Skill"
    name="Skill"
    autocompset="no"
    panellink="skills">

  <!-- Net final roll that includes the value of the linked attribute -->
    <field
      id="sklRoll"
      name="Net Skill Roll"
      type="derived">
      <calculate phase="Final" priority="5000">
        <after name="Calc trtFinal"/><![CDATA[
        ~only access the linkage if the skill is directly on the hero; if not, it is
        ~likely within an advancement gizmo and no linkage will exist there
        if (container.ishero <> 0) then
          @value = field[trtFinal].value
          endif
        ]]></calculate>
      </field>

	  <!-- Each skill needs its own identity tag so existing skills can be identified during advancement -->
    <identity group="Skill"/>
    
    <!-- Each skill can also be selected as a background/command package/race bonus.
         This bonus does count against the maximum at character creation.    -->
    <identity group="SkillBonus"/>

    <!-- Every skill is shown on the "Rolls" mouse-over on the Dashboard/TacCon -->
    <tag group="DashTacCon" tag="Rolls"/>
 
    <eval index="1" phase="Initialize" priority="3000"><![CDATA[
      field[trtMinimum].value = 0
      field[trtMaximum].value = 9
      ]]></eval>      
    
    <!-- Track the skill on the actor -->
    <eval index="2" phase="Setup" priority="5000"><![CDATA[
      perform forward[Skill.?]
      ]]></eval>
    
    <!-- Each skill point that is allocated by the user costs 1 CP -->
    <eval index="3" phase="Traits" priority="10000">
      <before name="Calc resLeft"/>
      <after name="Bound trtUser"/><![CDATA[
      ~if this skill is not added directly to the hero (i.e. an advance), skip it entirely
      doneif (origin.ishero = 0)

      ~adjust the resource appropriately
      hero.child[resCP].field[resSpent].value += field[trtUser].value
    ]]></eval>
    
    <!-- set the appropriate candidate expression -->
    <eval index="4" phase="Final" priority="1000" name="SpecHelp Expr">
      <![CDATA[
      
      var myId as string
      myId = tagids[Skill.sk?," & "]
      
      call SetSpcExpr
      ]]></eval>
      
    <eval index="10" phase="Initialize" priority="10000"><![CDATA[
      ~copy our SkillList tags to the gizmo so they can be used for the needtag
      if (isgizmo <> 0) then
        perform gizmo.pushtags[Skill.?]

        ~tags added to the gizmo are then automatically added to the parent of
        ~that gizmo - but that's where those tags were just pushed from, meaning
        ~that what happens is to duplicate them all.  So, delete the ones on
        ~ourself, then pull the tags from the gizmo.
        perform delete[Skill.?]
        perform gizmo.pulltags[Skill.?]
        endif
      ]]></eval>

    </component>

  <component
    id="Specialty"
    name="Specialization"
    autocompset="no"
    panellink="skills">
    
	  <identity group="Specialty"/>
    
	  <tag group="SpecialTab" tag="Specialty"/>
  
    <!-- Track the ability on the actor -->
    <eval index="1" phase="Setup" priority="5000"><![CDATA[
      perform forward[Specialty.?]
      ]]></eval>
      
    <!-- Each specialty that is allocated by the user costs 2 CP -->
    <eval index="2" phase="Traits" priority="10000">
      <before name="Calc resLeft"/>
      <after name="Bound trtUser"/><![CDATA[
      ~if this skill is not added directly to the hero (i.e. an advance), skip it entirely
      doneif (origin.ishero = 0)

      ~adjust the resource appropriately
      hero.child[resCP].field[resSpent].value += 2
    ]]></eval>
  </component>    

<!-- Specialty Helper component
        Each Specialty Gizmo derives from this component
  -->
  
  <component
    id="SpecHelp"
    name="Specialty Helper">

    <!-- Selection Tag Expressions -->
    <field
      id="SpecExpr"
      name="Specialization Tag Expression"
      type="derived"
      maxlength="500">
      </field>

    </component>

  <!-- Skill - all skills derive from this compset -->
  <compset
    id="Skill"
    forceunique="yes">
    <compref component="Skill"/>
    <compref component="Trait"/>
    <compref component="Domain"/>
    <compref component="CanAdvance"/>
    </compset>

  <!-- Specialty - all skill specialties derive from this compset -->
  <compset
    id="Specialty">
    <compref component="Specialty"/>
    <compref component="SpecialTab"/>
    <compref component="Domain"/>
    <compref component="CanAdvance"/>
  </compset>

  <entity
    id="entSpec"
    form="frmSpec">
    <bootstrap thing="SpecHelp"/>
  </entity>
form_Specialty.dat
Code:
<document signature="Hero Lab Data">

  <portal
    id="prtSpec"
    style="tblNormal">
    <table_dynamic
      component="Specialty"
      showtemplate="tmpSpec"
      choosetemplate="tmpSpec"
      scrollable="yes"
      alwaysupdate="yes"
      candidatepick="SpecHelp"
      candidatefield="SpecExpr"
      addpick="">
      
      <titlebar><![CDATA[
        @text = "Add a Specialty"
        ]]></titlebar>
      <headertitle><![CDATA[
        @text = "Specialty"
        ]]></headertitle>
      <additem><![CDATA[
        @text = "Add Specialty"
        ]]>
        </additem>
      </table_dynamic>      
    </portal>

  <template
    id="tmpSpec"
    name="Area of Expertise Pick"
    compset="Specialty"
    marginhorz="3"
    marginvert="1">

    <portal
      id="name"
      style="lblSmall">
      <label>
        <labeltext><![CDATA[
          @text = field[name].text & " (" & this.tagnames[Skill.?," "]  & ")"
          ]]></labeltext>
        </label>
      </portal>
    
    <portal
      id="delete"
      style="actDelete"
      tiptext="Click to delete this item">
      <action
        action="delete">
        </action>
      </portal>

    <position><![CDATA[
    
      ~set up our height based on our tallest portal
      height = portal[name].height

      ~if this is a "sizing" calculation, we're done
      doneif (issizing <> 0)

      ~position our tallest portal at the top
      portal[name].top = 0
      portal[name].left = 0
      portal[name].width = 250
      
      ~center the other portals vertically
      perform portal[delete].centervert

      ~position the delete portal on the far right
      perform portal[delete].alignedge[right,0]

      ]]></position>
    </template>

  <layout
    id="laySpec"
    marginvert="4">
    <portalref portal="prtSpec" taborder="20"/>
    <position><![CDATA[
      ~perform portal[prtSpec].batchadd
      ~perform batchplace
      
      ~position and size the table to span the full layout
      portal[prtSpec].left = 0
      portal[prtSpec].width = width
      portal[prtSpec].height = 400
      
      
      ]]></position>
    </layout>

  <form
	id="frmSpec"
	name="Specialty"
	marginhorz="10"
	marginvert="5">
	<layoutref layout="laySpec"/>
	<position><![CDATA[
	  layout[laySpec].width = 400
	  perform layout[laySpec].render
	  width = layout[laySpec].width
	  height = 400
	  ]]></position>
	</form>

  </document>
thing_skills.dat (one representative record)
Code:
<!-- Carbine Skill -->
  <thing
    id="skCarbine"
    name="Carbines"
    compset="Skill"
    isunique="yes"
    description="Use your Carbines skill when firing carbine class weapons. As the weapons most commonly issued to infantry, carbines offer versatility and lethality. They are designed for quick carry, ease of use, and close-quarters action">
    <fieldval field="trtAbbrev" value="Car"/>

    <tag group="Skills" tag="Combat"/>
    <child entity="entSpec" />
    </thing>
thing_specializations.dat (two representative items)
Code:
  <!-- Carbine Beam Skill Specialty -->
  <thing
    id="spCarbBeam"
    name="Beam"
    compset="Specialty"
    isunique="yes"
    description="">
    <tag group="Skill" tag="skCarbine"/>
  </thing>


<!-- Per World of Origin Skill Specialty -->
  <thing
    id="spXenoWrld"
    name="Per World of Origin"
    compset="Specialty"
    isunique="no"
    description="">
    <tag group="Skill" tag="skXeno"/>
    <tag group="User" tag="NeedDomain"/>
  </thing>

Last edited by Duggan; September 6th, 2017 at 04:54 PM. Reason: Interchanged quote blocks for code blocks
Duggan is offline   #1 Reply With Quote