• Please note: In an effort to ensure that all of our users feel welcome on our forums, we’ve updated our forum rules. You can review the updated rules here: http://forums.wolflair.com/showthread.php?t=5528.

    If a fellow Community member is not following the forum rules, please report the post by clicking the Report button (the red yield sign on the left) located on every post. This will notify the moderators directly. If you have any questions about these new rules, please contact support@wolflair.com.

    - The Lone Wolf Development Team

Example of skills tab like Cortex?

TCArknight

Well-known member
Ok, I'm at a loss... I need to set up a Skills tab like the one used in the Cortex dataset, but I keep getting Nothing to Choose from messages.

Is there a good example of a skill tab similar to this around? I haven't been able to find it with my weak search-fu. :(
 
More detail please? I need to know about the component you've set on your table, the candidate expression, the list expression, and that you've been absolutely careful to match the tags on your things to the tags allowed by the candidate and list expressions.
 
Sorry Mathias! I was tired and not thinking clear when made that last post....

Here's the various components and portals: (this is a long one)
Code:
<!-- Skill component
        Each skill derives from this component
  -->
  <component
    id="Skill"
    name="Skill"
    autocompset="no">

    <!-- field that indicates of the skill is Professional for advancement purposes -->
    <field
      id="sklIsProf"
      name="Is Professional"
      type="derived"
      defvalue="0">
      </field>

    <!-- Net final roll that includes the value of the linked attribute -->
    <field
      id="sklRoll"
      name="Net Skill Roll"
      type="derived"
      defvalue="0">

      </field>

    <!-- Each skill is associated with a specific attribute that must be identified -->
    <linkage linkage="attribute" optional="no"/>

    <!-- Each skill needs its own identity tag so existing skills can be identified during advancement -->
    <identity group="Skill"/>
    <identity group="SkillGen"/>

    <!-- Every skill is shown on the "Rolls" mouse-over on the Dashboard/TacCon -->
    <tag group="DashTacCon" tag="Rolls"/>

    <!-- Track the skill on the actor -->
    <eval index="1" phase="Setup" priority="1000"><![CDATA[
      perform forward[Skill.?]

      perform assign[SkillGen.zLast]
      ]]></eval>

    <!-- Each skill point 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 += field[trtUser].value * 2
      ]]></eval>

    </component>

  <!-- Skill Speciality component
        Each skill Speciality derives from this component
  -->
  <component
    id="SkillSpec"
    name="Specialty"
    autocompset="no">

    <!-- Net final roll that includes the value of the linked attribute -->
    <field
      id="spcRoll"
      name="Net Skill Roll"
      type="derived"
      defvalue="0">

      </field>

    <!-- Each skill specialty is associated with a specific skill that must be identified -->
    <linkage linkage="skill" optional="no"/>

    <!-- Each skill needs its own identity tag so existing skills can be identified during advancement -->
    <identity group="SkillSpec"/>

    <!-- Every skill is shown on the "Rolls" mouse-over on the Dashboard/TacCon -->
    <tag group="DashTacCon" tag="Rolls"/>

    <!-- Track the skill on the actor -->
    <eval index="1" phase="Setup" priority="5000"><![CDATA[
      perform forward[SkillSpec.?]
      ]]></eval>

    <!-- Each skill point 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 += 1
      ]]></eval>

    </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>

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

  <!-- Sort skills, general first, then specialties -->
  <sortset
    id="Skills"
    name="Skills">
    <sortkey isfield="no" id="SkillGen"/>
    <sortkey isfield="no" id="SkillCat"/>
    <sortkey isfield="no" id="_Name_"/> 
 
    </sortset>

(... continued in next post)
 
Code:
  <!-- baSkill portal
        Presents a table consisting of all skills for the character, which
        are shown in alphabetical order (the default).

        We use a "headertitle" script to place a suitable title above the table.
  -->
  <portal
    id="baSkill"
    style="tblInvis">
    <table_dynamic
      component="Skill"
      showtemplate="baSklPick"
      choosetemplate="skThing"
      scrollable="yes">
      <candidate inheritlist="yes">!Hide.Skill</candidate>
      <titlebar><![CDATA[
        @text = "Add a Skill"
        ]]></titlebar>
      <!-- <list>!Hide.Skill</list> -->
      <headertitle><![CDATA[
        @text = "Skills"
        ]]></headertitle>
      <additem><![CDATA[
        ~if we're in advancement mode, we've been frozen, so display accordingly
        if (state.iscreate = 0) then
          @text = "{text clrgrey}Add/Increase Skills Via Advances Tab"
          done
          endif

        ~get the color-highlighted "add" text
        @text = "Add a Skill"
        ]]></additem>
      </table_dynamic>
    </portal>

  <!-- skThing template
        Displays the name of the skill, with its linked attribute at the right edge.
  -->
  <template
    id="skThing"
    name="Skill Thing"
    compset="Skill"
    marginhorz="3"
    marginvert="2">

    <portal
      id="name"
      style="lblNormal"
      showinvalid="yes">
      <label
        field="name">
        </label>
      </portal>

    <portal
      id="attribute"
      style="lblSecond">
      <label>
        <labeltext><![CDATA[
          @text = linkage[attribute].field[name].text
          ]]></labeltext>
        </label>
      </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)

      ~center the portals vertically
      perform portal[name].centervert
      perform portal[attribute].centervert

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

      ~position the name on the left and let it use all available space
      portal[name].left = 0
      portal[name].width = minimum(portal[name].width,portal[attribute].left - 8)
      ]]></position>

    </template>

  <!-- baSklPick template
        Displays one skill within the table of skills. This template is very
        similar to the one used for attributes. The key differences are that this
        template is tied to skills and has slightly different margins for closer
        grouping of the items in the table.
  -->
  <template
    id="baSklPick"
    name="Skill Pick"
    compset="Skill"
    marginhorz="23"
    marginvert="3">

    <portal
      id="name"
      style="lblNormal"
      showinvalid="yes">
      <label
        field="name">
        </label>
      </portal>

    <portal
      id="value"
      style="incrSimple">
      <incrementer
        field="trtUser">
        </incrementer>
      <mouseinfo><![CDATA[
        if (hero.tagis[mode.creation] = 0) then
          @text = "Skills must be modified via the Advances tab once the character is locked for play."
        elseif (autonomous = 0) then
          @text = "This trait has been improved via the Advances tab and cannot be modified further from here."
        else
          @text = "Allocate points to this skill by clicking on the arrows to increase/decrease the number of points assigned."
          endif
        ]]></mouseinfo>
      </portal>

    <portal
      id="info"
      style="actInfo">
      <action
        action="info">
        </action>
      </portal>

    <portal
      id="skSpec"
      style="actLarge">
      <action
        action="trigger"
        buttontext="Specialization">      
        <trigger><![CDATA[
          notify "Adding Specialization to " & field[name].text & " skill." 
          ]]></trigger>
        </action>
      </portal>

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

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

      ~freeze our value in advancement mode or if an advancement has modified us
      ~Note: All freezing must be done *before* any positioning is performed.
      if (state.iscreate = 0) then
        portal[value].freeze = 1
      elseif (autonomous = 0) then
        portal[value].freeze = 1
        endif

      ~position our tallest portal at the top
      portal[info].top = 0

      ~center the other portals vertically
      perform portal[name].centervert
      perform portal[value].centervert

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

      ~position the incrementer to the left of the info portal (plus a gap)
      perform portal[value].alignrel[rtol,info,-10]

      ~only show the master button if the actor is a minion
      portal[skSpec].visible = tagis[User.HasSpec]
      
      if (portal[skSpec].visible <> 0) then
        ~position the skSpec to the left of the incrementer portal (plus a gap)
        portal[skSpec].width = 100
        perform portal[skSpec].alignrel[rtol,value,-10]
        
        ~position the name on the left and make sure its width does not exceed the available space
        portal[name].left = 0
        portal[name].width = minimum(portal[name].width,portal[skSpec].left - portal[name].left - 10)
      else        
        ~position the name on the left and make sure its width does not exceed the available space
        portal[name].left = 0
        portal[name].width = minimum(portal[name].width,portal[value].left - portal[name].left - 10)
        endif
      
      
      ]]></position>

    </template>

I made a correction to the portal, (I did have compset="Skills" instead of just "Skill" and I think it should work, but I'm now unsure how to force the incrementer to 1 after I add the skill. And also, what I need to change to incluse the SkillSpec defined for the specific skills after a General is added to the character. (I also need to include "- <Skill> Specialties -" As the first Specialty for a placeholder, right?)

Also, how do I not remove a skill from the list if it's one with a Domain that can be chosen multiple times?

Thanks!
Thomas


Would adding an Identity of HasSkill added to the Skill compset be involved in some way?
 
Sorry, did you fix the original issue by fixing the name of the component, or is that still around?

What incrementer? What's it supposed to be doing? What are the minimum and maximum values allowed for the field that the incrementer is linked to?
 
Sorry Mathias, I'm having some major headaches at work and haven't explained well due to brain overload :)

Once I changed the component="Skills" to just "Skill" it seems to work. I click on the Add a skill entry on the table, and a chooser is popped up containing all skillnames and the attribute they are linked to. Right now, it's correctly not showing the Specialties because they are "Spec" components instead of "Skill".

I think a lot of my confusion is where do i need the needtag entry and what on the panel will use that?

The incrementer is on the baSklPick template. It changes how many ranks of the skill are present. The minimum right now is 0, and the max is 6. I guess I could just reset the minimum to 1 and it'll do what I'm asking.
 
Last edited:
Putting each of the questions you want to ask me in a separate post (or even a separate thread) is a good rule of thumb for reducing the chance that things are missed among many paragraphs of text.

You can create a component that doesn't have anything else in it, and then add that component to the compsets for both your skills and your specialties - then, change the component on the table to that shared component - that way, you can add either skills or specialties to the same table.

(Also think about what mechanisms do need to be shared between skills and specialties - you may end up moving a lot of things into that shared component).

This is the needtag on the skills table in Cortex:
Code:
<needtag container="HasSkill" thing="SkillGen"/>

A script on the general skill component has this line:

perform forward[HasSkill.?]

(HasSkill and SkillGen are both identity tags on the general skill component).

Then, the general skills component has this entry:
Code:
<!-- They need a dummy SkillGen tag that matches the dummy assigned to the hero, so that the list expression will display them before any other general skills have been selected -->
<tag group="SkillGen" tag="zLast"/>

A script in actor.str assigns HasSkill.zLast to the hero.

This goes in tags.1st:

Code:
<!-- General Skill group - the unique ID of each general skill, so that specialties can identify their skill. -->
<group
id="SkillGen"
dynamic="yes">
<value id="zLast" name="_General Skill"/> <!-- Added to all general skills and to the hero, so that general skills always fulfill the needtag expression -->
</group>
 
<!-- General Skill group - the unique ID of each general skill, so that specialties can identify their skill. -->
<group
id="HasSkill"
dynamic="yes">
<value id="zLast" name="_General Skill"/> <!-- Added to all general skills and to the hero, so that general skills always fulfill the needtag expression -->
</group>

Then, each specialty has the SkillGen tag for its specialty added to the thing definition.

The result is that general skills always match the needtag, since they all have SkillGen.zLast, matching the hero's HasSkill,.zLast, and that specialties match the needtag once their general skill is added, and it adds its HasSkill tag to the hero.
 
Is there a way to Automatically assign the SkillGen tag of the linked skill to a Specialization?

I have this:
Code:
<!-- Each skill specialty is associated with a specific skill that must be identified  -->
    <linkage linkage="skill" optional="no"/>

    <!-- Track the skill on the actor -->
    <eval index="3" phase="Setup" priority="5000"><![CDATA[
      var linkTags as string
      linkTags = linkage.pulltags
      ~notify linkTags

      perforn assignstr[linkTags]
      ]]></eval>

I get a message about linkage being an invalid variable.
 
You've got some other problems in that script:

pulltags needs to identify the tags it pulls:

pulltags[SkillGen.?]

pulltags[] is an order to perform an operation - it does not return the text ids of the tags it copies & pastes.
 
Thanks Mathias. :)

On another note, the needtag doesn't seem to be working for me. :(
Code:
<table_dynamic
      component="BaseSkill"
      showtemplate="baSklPick"
      choosetemplate="skThing"
      showsortset="SkillSort"
      choosesortset="SkillSort"
      scrollable="yes">
      <candidate inheritlist="yes">!Hide.Skill</candidate>
      <needtag container="HasSkill" thing="SkillGen"/>

  <!-- AllSkills - all skills and specialties -->
  <compset
    id="AllSkills">
    <compref component="Skill"/>
    <compref component="SkillSpec"/>
    </compset>

<!-- Sort skills, general first, then specialties -->
  <sortset
    id="SkillSort"
    name="SkillSort">
    <sortkey isfield="no" id="SkillGen"/>
    <sortkey isfield="no" id="SkillSpec"/>
    <sortkey isfield="no" id="_Name_"/> 
    </sortset>

  <!-- Skill component
        Each skill derives from this component
  -->
  <component
    id="Skill"
    name="Skill"
    autocompset="no">

    <!-- Each skill is associated with a specific attribute that must be identified -->
    <linkage linkage="attribute" optional="no"/>

    <!-- Each skill needs its own identity tag so existing skills can be identified during advancement -->
    <identity group="BaseSkill"/>
    <identity group="HasSkill"/>
    <identity group="SkillGen"/>

    <!-- Track the skill on the actor -->
    <eval index="1" phase="Setup" priority="100"><![CDATA[
      perform forward[BaseSkill.?]
      perform forward[HasSkill.?]
      perform forward[SkillGen.?]

      perform assign[SkillGen.zLast]

      ]]></eval>

  <!-- Skill Speciality component
        Each skill Speciality derives from this component
  -->
  <component
    id="SkillSpec"
    name="Specialty"
    autocompset="no">

    <!-- Each skill specialty is associated with a specific skill that must be identified  -->
    <linkage linkage="skill" optional="no"/>

    <!-- Each skill needs its own identity tag so existing skills can be identified during advancement -->
    <identity group="SkillSpec"/>
    <identity group="SkillGen"/>

    <!-- Track the skill on the actor -->
    <eval index="1" phase="Setup" priority="100"><![CDATA[
      perform forward[SkillSpec.?]
      ]]></eval>

With the above needtag in place, there's Nothing to Choose From when go to select skills, and without it, all skills and specialties show up.

With the screenshot below, the hero has the SkillGen.zLast and HasSkill.zLast
Thoughts?
 

Attachments

  • hero tags.jpg
    hero tags.jpg
    46.5 KB · Views: 7
I think you missed this one:

Then, the general skills component has this entry:
Code:
<!-- They need a dummy SkillGen tag that matches the dummy assigned to the hero, so that the list expression will display them before any other general skills have been selected -->
<tag group="SkillGen" tag="zLast"/>
 
Ah - you did that in a script, not a tag element.

Scripts on an item are not run until AFTER an item has been added to the character, so the script that you have assigning HasSkill.zLast will not run until after it's been added to the character. Needtag needs to look for that tag BEFORE it's been added to the character.
 
Last edited:
With the way things are set up, when a skill or specialization are chosen, it disappears from the list. Is there a way to keep a specific skill on the list if it can be chosen multiple times, say due to choosing a different domain each time?
 
Those skills that can be chosen multiple times aren't set to useronce or unique, right? Only the skills that are supposed to be unique have that set?
 
Yep, I has it defined as forceunique="yes". Removed that, and I could set the needed skills to unique="no".

Thanks!
 
Back
Top