Skeleton File Changes V3.1: Difference between revisions

From HLKitWiki
Jump to navigationJump to search
 
(21 intermediate revisions by the same user not shown)
Line 1: Line 1:
{{context|Kit Reference|Skeleton Data File Revision History}}
{{context|Kit Reference|Skeleton Data File Revision History}}
===File: "definition.def"===
Line 24: Eliminate the "manualroot" attribute so that the manual location uses the default.
Line 46: Replace the "required" attribute with "3.1" instead of "3.0".
===File: "tags.1st"===
Line 52: Insert the new tag shown below.
<pre>
<value id="NoAutoName"/>
</pre>
Line 65: Insert the new tag shown below.
<pre>
<value id="Dead"/>
</pre>
Line 79: Rename the "Column1" tag to "Traits".
Line 90: Insert the new tag shown below.
<pre>
<value id="StartEquip" name="Gear starts out equipped"/>
</pre>
Line 245: Insert the new tag group definition shown below.
<pre>
<group
  id="DomainTerm"
  dynamic="yes">
  <value id="Domain"/>
  </group>
</pre>
Line 254: Insert the new tag shown below.
<pre>
<value id="CenterName"/>
</pre>
Line 256: Insert the new tag group definitions shown below.
<pre>
<group
  id="ChooseSrc1"
  visible="no">
  <value id="Thing" name="All Things"/>
  <value id="Container" name="All Picks on Container"/>
  <value id="Hero" name="All Picks on Hero"/>
  </group>
<group
  id="ChooseSrc2"
  visible="no">
  <value id="Thing" name="All Things"/>
  <value id="Container" name="All Picks on Container"/>
  <value id="Hero" name="All Picks on Hero"/>
  </group>
</pre>
===File: "advancement.core"===
Line 19: Added the "Notation" tag shown below.
<pre>
<value id="Notation"/>
</pre>
Line 160: Insert new logic to handle notation advancements at the start of the Eval script, as shown below.
<pre>
~if this advancement has an annotation, there is no user-selection, so build
~the name from our pieces and we're done
if (tagis[Advance.Notation] <> 0) then
  perform gizmo.child[advDetails].setfocus
  field[livename].text = field[name].text & ": " & focus.field[advUser].text
  done
  endif
</pre>
===File: "components.core"===
Line 273: Change the reference to the "component.Ability" tag to "component.shortname".
Line 278: Change the reference to the "component.Ability" tag to "component.shortname".
Line 283: Insert the code below to use the standard name if no short name is defined.
<pre>
~if we don't have a short name, just use the regular name
if (empty(short) <> 0) then
  short = name
  endif
</pre>
Line 337: Insert the new "UserSelect" component definition that is provided below.
<pre>
<component
  id="UserSelect"
  name="User Selection">
  <!-- Text to display with the checkbox
        NOTE! If this field is empty, it means NO checkbox is shown for the pick.
  -->
  <field
    id="usrChkText"
    name="Checkbox Text"
    type="derived"
    maxlength="100">
    </field>
  <!-- Indicates whether the checkbox is selected is not -->
  <field
    id="usrIsCheck"
    name="Checked?"
    type="user"
    minvalue="0"
    maxvalue="1">
    </field>
  <!--  Label associated with the first thing-based menu -->
  <field
    id="usrLabel1"
    name="Thing Menu Label #1"
    type="static"
    maxlength="50">
    </field>
  <!-- Tracks the first selection made when a menu choice is required -->
  <field
    id="usrChosen1"
    name="Chosen Thing / Pick #1"
    type="user"
    style="menu">
    </field>
  <!-- Candidate tagexpr used to determine which picks/things are shown in menu #1
        NOTE! If this field is empty, it means NO first menu is shown for the pick.
  -->
  <field
    id="usrCandid1"
    name="Candidate TagExpr for Menu #1"
    type="derived"
    maxlength="1000"
    defvalue="">
    </field>
  <!-- Source to pull choices from within menu #1 -->
  <field
    id="usrSource1"
    name="Source for Menu #1 Choices"
    type="derived">
    <!-- Determine the source to choose from based on the tag, defaulting to "Hero" -->
    <calculate phase="Render" priority="10000"><![CDATA[
      if (tagis[ChooseSrc1.Thing] <> 0) then
        @value = 0
      elseif (tagis[ChooseSrc1.Container] <> 0) then
        @value = 1
      elseif (tagis[ChooseSrc1.Hero] <> 0) then
        @value = 2
      else
        @value = 2
        endif
      ]]></calculate>
    </field>
  <!--  Label associated with the second thing-based menu -->
  <field
    id="usrLabel2"
    name="Thing Menu Label #2"
    type="static"
    maxlength="50">
    </field>
  <!-- Tracks the second selection made when a menu choice is required -->
  <field
    id="usrChosen2"
    name="Chosen Thing / Pick #2"
    type="user"
    style="menu">
    </field>
  <!-- Candidate tagexpr used to determine which picks/things are shown in menu #2
        NOTE! If this field is empty, it means NO second menu is shown for the pick.
  -->
  <field
    id="usrCandid2"
    name="Candidate TagExpr for Menu #2"
    type="derived"
    maxlength="1000"
    defvalue="">
    </field>
  <!-- Source to pull choices from within menu #2 -->
  <field
    id="usrSource2"
    name="Source for Menu #2 Choices"
    type="derived">
    <!-- Determine the source to choose from based on the tag, defaulting to "Hero" -->
    <calculate phase="Render" priority="10000"><![CDATA[
      if (tagis[ChooseSrc2.Thing] <> 0) then
        @value = 0
      elseif (tagis[ChooseSrc2.Container] <> 0) then
        @value = 1
      elseif (tagis[ChooseSrc2.Hero] <> 0) then
        @value = 2
      else
        @value = 2
        endif
      ]]></calculate>
    </field>
  <!--  Label associated with the array-based menu -->
  <field
    id="usrLabelAr"
    name="Array Menu Label"
    type="static"
    maxlength="50">
    </field>
  <!-- Array of text items user can select from
        NOTE! If the 0th element is empty, it means NO menu is shown for the pick.
  -->
  <field
    id="usrArray"
    name="Array of Items to Choose"
    type="derived"
    style="array"
    arrayrows="10"
    maxlength="30">
    </field>
  <!-- Item selected from the array -->
  <field
    id="usrSelect"
    name="Selected Item in Array"
    type="user"
    maxlength="30">
    </field>
  <!-- Initialize the current array-based selection from the array if not defined -->
  <creation><![CDATA[
    if (empty(field[usrArray].arraytext[0]) = 0) then
      if (field[usrSelect].isempty <> 0) then
        field[usrSelect].text = field[usrArray].arraytext[0]
        endif
      endif
    ]]></creation>
  <!-- Integrate the various user selections into the name of the pick
        NOTE! Must be scheduled after the "shortname" field is synthesized at Render/100.
  -->
  <eval index="1" phase="Render" priority="500"><![CDATA[
    ~if we're not supposed to auto-amend the name for this pick, we're done
    if (tagis[User.NoAutoName] <> 0) then
      done
      endif
    ~if we have thing-based menus, determine the text to append to the name
    var choices as string
    if (field[usrCandid1].isempty = 0) then
      if (field[usrChosen1].ischosen <> 0) then
        choices = field[usrChosen1].chosen.field[name].text
      else
        choices = "-Choose-"
        endif
      if (field[usrChosen2].ischosen <> 0) then
        choices &= ", " & field[usrChosen2].chosen.field[name].text
        endif
    ~if we have an array-based menu, determine the text to append
    elseif (empty(field[usrArray].arraytext[0]) = 0) then
      choices = field[usrSelect].text
    ~if we have a selected checkbox, determine the text to append
    elseif (field[usrChkText].isempty = 0) then
      if (field[usrIsCheck].value <> 0) then
        choices = field[usrChkText].text
        endif
      endif
    ~if we have no text to append, we're done
    if (empty(choices) <> 0) then
      done
      endif
    ~add the selection to both the livename and shortname (if present) fields
    field[livename].text = field[name].text & ": " & choices
    if (tagis[component.shortname] <> 0) then
      field[shortname].text &= " (" & choices & ")"
      endif
    ]]></eval>
  <!-- Report a validation error if no selection has been made for a menu selection -->
  <evalrule phase="Validate" priority="10000" message="You must choose an option" summary="Choose!"><![CDATA[
    ~determine the number of menus that NEED selection
    ~Note: Remember that a non-empty tagexpr field indicates menu selection is used.
    var needed as number
    needed = !field[usrCandid1].isempty + !field[usrCandid2].isempty
    needed += !empty(field[usrArray].arraytext[0])
    ~determine the number of menus that HAVE selections
    var actual as number
    if (field[usrCandid1].isempty = 0) then
      actual += field[usrChosen1].ischosen
      endif
    if (field[usrCandid2].isempty = 0) then
      actual += field[usrChosen2].ischosen
      endif
    if (field[usrSelect].isempty = 0) then
      actual += 1
      endif
    ~if the user has chosen something whenever required, we're valid
    if (actual >= needed) then
      @valid = 1
      done
      endif
    ~mark any associated tab as invalid
    if (ispanel <> 0) then
      linkvalid = 0
      endif
    ]]></evalrule>
  </component>
</pre>
Line 400: Add the new Eval script below to the "Domain" component.
<pre>
<eval index="1" phase="Render" priority="500"><![CDATA[
  ~if we don't need a domain, there's nothing to do
  if (tagis[User.NeedDomain] = 0) then
    done
    endif
  ~if we're not supposed to auto-amend the name for this pick, we're done
  if (tagis[User.NoAutoName] <> 0) then
    done
    endif
  ~if we don't have a domain, use a placeholder for it
  var domain as string
  if (field[domDomain].isempty = 0) then
    domain = field[domDomain].text
  else
    domain = "????"
    endif
  ~add the domain to both the livename and shortname (if present) fields
  field[livename].text = field[name].text & ": " & domain
  if (tagis[component.shortname] <> 0) then
    field[shortname].text &= " (" & domain & ")"
    endif
  ]]></eval>
</pre>
Line 401: Replace the original Eval script with the new one shown below.
<pre>
<evalrule index="1" phase="Validate" priority="9000" message="????"><![CDATA[
  ~if no domain is needed or the domain is specified, we're valid
  if (tagis[User.NeedDomain] = 0) then
    @valid = 1
  elseif (field[domDomain].isempty = 0) then
    @valid = 1
    endif
  ~if we're valid, get out of here
  if (@valid <> 0) then
    done
    endif
  ~if we have a linked panel, flag it as invalid
  if (ispanel <> 0) then
    linkvalid = 0
    endif
  ~synthesize an appropriate message using the correct domain term
  var term as string
  term = tagnames[DomainTerm.?]
  if (empty(term) <> 0) then
    term = "Domain"
    endif
  @message = term & " must be specified"
  ]]></evalrule>
</pre>


===File: "actor.str"===
===File: "actor.str"===
Line 20: Line 413:
</pre>
</pre>


===File: "advancement.core"===
===File: "equipment.str"===
 
Line 27: Increase the "maxfinal" value from "50" to "100".
 
Line 219: Insert the Creation script shown below.
 
<pre>
<creation><![CDATA[
  ~if this is natural equipment, initialize the equipped state
  if (tagis[Equipment.Natural] <> 0) then
    field[grIsEquip].value = 1
    endif
 
  ~if this equipment is supposed to start out as equipped, initialize the state
  if (tagis[Equipment.StartEquip] <> 0) then
    field[grIsEquip].value = 1
    endif
  ]]></creation>
</pre>
 
Line 229: Change the Eval script priority from "1000" to "4000".
 
Line 584: Change the field type from "static" to "derived".
 
===File: "miscellaneous.str"===
 
Line 103: Insert the new lines of code below into the Finalize script.
 
<pre>
  @text = "{text ff0000}"
elseif (unspent > 0) then
</pre>
 
===File: "traits.str"===
 
Line 50: Change the timing of the Bound script, assign it a name, and establish a "before" dependency, as shown below.
 
<pre>
<bound phase="Traits" priority="1000" name="Bound trtUser">
  <before name="Calc trtFinal"/><![CDATA[
  @minimum = field[trtMinimum].value
  @maximum = field[trtMaximum].value
  ]]></bound>
</pre>
 
Line 97: Change the timing of the Eval script from "9999999" to "5000".
 
Line 130: Change the timing of the Eval script and setup "before" and "after" dependencies, as shown below.
 
<pre>
<eval index="2" phase="Traits" priority="10000">
  <before name="Calc resLeft"/>
  <after name="Bound trtUser"/><![CDATA[
  hero.child[resCP].field[resSpent].value += (field[trtUser].value - 1) * 7
  ]]></eval>
</pre>
 
Line 175: Change the timing of the Eval script and setup "before" and "after" dependencies, as shown below.
 
<pre>
<eval index="2" phase="Traits" priority="10000">
  <before name="Calc resLeft"/>
  <after name="Bound trtUser"/><![CDATA[
</pre>
 
Line 253: Change the test from keying on the usage pool to the actual mode, as shown below.
 
<pre>
~if the mode is creation, we're valid
if (state.iscreate <> 0) then
  @valid = 1
  done
  endif
</pre>
 
===File: "styles_output.aug"===
 
Line 217: Insert the new style shown below.
 
<pre>
<style
  id="outDots">
  <style_output
    textcolor="202020"
    font="ofntnormal"
    alignment="left">
    </style_output>
  </style>
</pre>
 
===File: "styles_ui.aug"===
 
Line 236: Insert the new resource definition shown below.
 
<pre>
<resource
  id="fntmenusm">
  <font
    face="Arial"
    size="30"
    style="bold">
    </font>
  </resource>
</pre>
 
Line 268: Insert the new color resource definitions shown below.
 
<pre>
<!-- color used for normal text throughout the ui -->
<resource
  id="clrnormal">
  <color
    color="f0f0f0">
    </color>
  </resource>
 
<!-- color used for text on the static panel - not quite as bright -->
<resource
  id="clrstatic">
  <color
    color="d2d2d2">
    </color>
  </resource>
 
<!-- color used for text in title labels -->
<resource
  id="clrtitle">
  <color
    color="c0c0c0">
    </color>
  </resource>
 
<!-- color used for names of automatically added picks -->
<resource
  id="clrauto">
  <color
    color="99efed">
    </color>
  </resource>
 
<!-- color used for disabled text -->
<resource
  id="clrdisable">
  <color
    color="808080">
    </color>
  </resource>
 
<!-- color used for summary text that should be a little dimmer than normal -->
<resource
  id="clrsummary">
  <color
    color="a0a0a0">
    </color>
  </resource>
 
<!-- color used for bright text -->
<resource
  id="clrbright">
  <color
    color="ffff88">
    </color>
  </resource>
 
<!-- color used for warning text -->
<resource
  id="clrwarning">
  <color
    color="ff0000">
    </color>
  </resource>
 
<!-- color used for prompt text inviting the user to change something -->
<resource
  id="clrprompt">
  <color
    color="ffff00">
    </color>
  </resource>
 
<!-- color used for the 'buy for free' checkbox on buy / sell panels -->
<resource
  id="clrchkfree">
  <color
    color="a8a800">
    </color>
  </resource>
 
<!-- color used for text on summary panels - a little dimmer than normal -->
<resource
  id="clrsummtxt">
  <color
    color="d0d0d0">
    </color>
  </resource>
 
<!-- color used for labels when choosing advancements -->
<resource
  id="clradvance">
  <color
    color="ffffff">
    </color>
  </resource>
 
<!-- color used for text on action buttons -->
<resource
  id="clraction">
  <color
    color="000088">
    </color>
  </resource>
 
<!-- colors used in edit controls -->
<resource
  id="clredittxt">
  <color
    color="d2d2d2">
    </color>
  </resource>
<resource
  id="clreditbck">
  <color
    color="000000">
    </color>
  </resource>
 
<!-- colors used in menu and chooser controls -->
<resource
  id="clrmenutxt">
  <color
    color="84c8f7">
    </color>
  </resource>
<resource
  id="clrmenuslt">
  <color
    color="1414f7">
    </color>
  </resource>
<resource
  id="clrmenubck">
  <color
    color="2a2c47">
    </color>
  </resource>
</pre>
 
Numerous Places: Change the style to reference a named color instead of a literal color, switching from a "textcolor" attribute to a "textcolorid" attribute. The list of changes is given below.
 
*Line 282 - "clrtitle"
*Line 293 - "clrstatic"
*Line 303 - "clrnormal"
*Line 313 - "clrnormal"
*Line 323 - "clrnormal"
*Line 335 - "clrauto"
*Line 347 - "clrdisable"
*Line 359 - "clrbright"
*Line 371 - "clrwarning"
*Line 384 - "clrprompt"
*Line 394 - "clrnormal"
*Line 404 - "clrdisable"
*Line 414 - "clrprompt"
*Line 424 - "clrwarning"
*Line 434 - "clrnormal"
*Line 444 - "clrdisable"
*Line 454 - "clrwarning"
*Line 464 - "clrnormal"
*Line 474 - "clrdisable"
*Line 484 - "clrsummary"
*Line 494 - "clrnormal"
*Line 504 - "clrnormal"
*Line 514 - "clrsummtxt"
*Line 524 - "clrdisable"
*Line 534 - "clrsummary"
*Line 545 - "clrsummary"
*Line 556 - "clradvance"
*Line 568 - "clradvance"
*Line 582 - "clrnormal"
*Line 596 - "clredittxt"
*Line 597 - "clreditbck"
*Line 607 - "clredittxt"
*Line 608 - "clreditbck"
*Line 618 - "clredittxt"
*Line 619 - "clreditbck"
*Line 624 - "clrdisable"
*Line 635 - "clrnormal"
*Line 652 - "clrnormal"
*Line 669 - "clrnormal"
*Line 732 - "clrnormal"
*Line 805 - "clraction"
*Line 836 - "clraction"
*Line 867 - "clrnormal"
*Line 901 - "clraction"
*Line 937 - "clraction"
*Line 971 - "clraction"
*Line 981 - "clraction"
*Line 991 - "clraction"
*Line 1025 - "clraction"
*Line 1059 - "clraction"
*Line 1085 - "clrnormal"
*Line 1119 - "clrnormal"
*Line 1145 - "clrnormal"
*Line 1171 - "clrnormal"
*Line 1205 - "clrnormal"
*Line 1231 - "clrnormal"
*Line 1265 - "clrnormal"
*Line 1299 - "clrnormal"
*Line 1333 - "clrnormal"
*Line 1359 - "clrnormal"
*Line 1385 - "clrnormal"
*Line 1411 - "clrnormal"
*Line 1445 - "clrnormal"
*Line 1471 - "clraction"
*Line 1497 - "clraction"
*Line 1531 - "clraction"
*Line 1557 - "clraction"
*Line 1583 - "clraction"
*Line 1609 - "clraction"
*Line 1643 - "clraction"
*Line 1677 - "clraction"
*Line 1711 - "clraction"
*Line 1745 - "clraction"
*Line 1779 - "clraction"
*Line 1813 - "clraction"
*Line 1847 - "clraction"
*Line 1881 - "clraction"
*Line 1915 - "clraction"
*Line 1949 - "clraction"
*Line 1983 - "clraction"
*Line 2017 - "clrnormal"
*Line 2051 - "clrnormal"
*Line 2085 - "clrnormal"
*Line 2119 - "clrnormal"
*Line 2153 - "clrnormal"
*Line 2206 - "clrdisable"
*Line 2232 - "clrnormal"
*Line 2241 - "clrwarning"
*Line 2252 - "clrdisable"
*Line 2261 - "clrchkfree"
*Line 2270 - "clrnormal"
*Line 2311 - "clrnormal"
*Line 2358 - "clrmenutxt"
*Line 2359 - "clrmenubck"
*Line 2360 - "clrmenuslt"
*Line 2361 - "clrnormal"
*Line 2371 - "clrmenutxt"
*Line 2372 - "clrmenubck"
*Line 2373 - "clrmenuslt"
*Line 2374 - "clrnormal"
*Line 2375 - "clrwarning"
*Line 2386 - "clrmenutxt"
*Line 2387 - "clrmenubck"
*Line 2397 - "clrwarning"
*Line 2398 - "clrmenubck"
 
Line 470: Insert the new style definition shown below.
 
<pre>
<!-- slightly smaller label that is left-aligned -->
<style
  id="lblSmlLeft">
  <style_label
    textcolorid="clrnormal"
    font="fntsmall"
    alignment="left">
    </style_label>
  </style>
</pre>
 
Line 1467: Insert the new style definition shown below.
 
<pre>
<!-- Style used on the master button -->
<style
  id="actMaster">
  <style_action
    textcolorid="clrnormal"
    font="fntactsml"
    up="actmastup" down="actmastdn" off="actmastup">
    </style_action>
  <resource
    id="actmastup"
    isbuiltin="yes">
    <bitmap
      bitmap="master_up.bmp"
      istransparent="yes">
      </bitmap>
    </resource>
  <resource
    id="actmastdn"
    isbuiltin="yes">
    <bitmap
      bitmap="master_down.bmp"
      istransparent="yes">
      </bitmap>
    </resource>
  </style>
</pre>
 
Line 2380: Insert the the new style definitions shown below.
 
<pre>
<!-- small menu portal -->
<style
  id="menuSmall"
  border="sunken">
  <style_menu
    textcolorid="clrmenutxt"
    backcolorid="clrmenubck"
    selecttextid="clrmenuslt"
    selectbackid="clrnormal"
    font="fntmenusm"
    droplist="menuarrsm"
    droplistoff="menuoffsm">
    </style_menu>
  <resource
    id="menuarrsm"
    isbuiltin="yes">
    <bitmap
      bitmap="menu_small_arrow.bmp">
      </bitmap>
    </resource>
  <resource
    id="menuoffsm"
    isbuiltin="yes">
    <bitmap
      bitmap="menu_small_arrow_off.bmp">
      </bitmap>
    </resource>
  </style>
 
<!-- small menu portal with coloring to indicate contents are in error -->
<style
  id="menuErrSm"
  border="sunken">
  <style_menu
    textcolorid="clrmenutxt"
    backcolorid="clrmenubck"
    selecttextid="clrmenuslt"
    selectbackid="clrnormal"
    activetextid="clrwarning"
    font="fntmenusm"
    droplist="menuarrsm"
    droplistoff="menuoffsm">
    </style_menu>
  </style>
</pre>
 
===File: "form_advance.dat"===
 
Line 28: Change the field reference from "name" to "thingname".
 
Line 123: Change the field reference from "name" to "thingname".
 
Line 222: Replace the code for shrinking the size to the new code shown below.
 
<pre>
perform portal[name].sizetofit[36]
perform portal[name].centervert
</pre>
 
Line 238: Replace the "label" element with the new behavior shown below.
 
<pre>
<label>
  <labeltext><![CDATA[
    ~use any domain term specified, else default to "domain"
    @text = parent.tagnames[DomainTerm.?]
    if (empty(@text) <> 0) then
      @text = "Domain"
      endif
    @text &= ":"
    ]]></labeltext>
  </label>
</pre>
 
Line 271: Insert the new template definition shown below.
 
<pre>
<template
  id="advNotate"
  name="Notation Specification"
  compset="AdvDetails">
 
  <portal
    id="lblnotate"
    style="lblStatic">
    <label
      text="Notation:">
      </label>
    </portal>
 
  <portal
    id="notation"
    style="editNormal">
    <edit
      field="advUser"
      maxlength="50">
      </edit>
    </portal>
 
  <position><![CDATA[
    ~set up our width and height
    height = portal[notation].height
    if (issizing <> 0) then
      done
      endif
 
    ~center everything vertically
    perform portal[lblnotate].centervert
    perform portal[notation].centervert
 
    ~position the label on the left with the edit portal next to it
    portal[lblnotate].left = 0
    perform portal[notation].alignrel[ltor,lblnotate,7]
    portal[notation].width = width - portal[notation].left
    ]]></position>
  </template>
</pre>
 
Line 309: Replace the script code for setting the line height to the code shown below.
 
<pre>
portal[notes].lineheight = 4
</pre>
 
Line 320: Insert the template reference shown below.
 
<pre>
<templateref template="advNotate" thing="advDetails" taborder="20"/>
</pre>
 
Line 345: Insert the code below to position the notation template
 
<pre>
~position the notation template in the same place
template[advNotate].left = portal[advNew].left
template[advNotate].top = portal[advNew].top
template[advNotate].width = portal[advNew].width
</pre>
 
Line 347: Insert the code below to set the notation template to non-visible.
 
<pre>
template[advNotate].visible = 0
</pre>
 
Line 356: Insert the code below to show the notation template when appropriate.
 
<pre>
elseif (container.parent.tagis[Advance.Notation] <> 0) then
  template[advNotate].visible = 1
</pre>
 
===File: "form_dashboard.dat"===
 
Line 121: Replace the Label script code with the new code shown below.
 
<pre>
@text = "{size 30}PP: {size 36}" & hero.child[trkPower].field[trkUser].text
</pre>
 
Line 189: Added the "isbuiltin" attribute to the element with a value of "yes".
 
===File: "form_static.dat"===
 
Line 59: Insert the new portal definition below.
 
<pre>
<portal
  id="master"
  style="actMaster"
  tiptext="Click this button to activate this ally's Master.">
  <action
    action="master">
    </action>
  </portal>
</pre>
 
Line 76 and 87: Put the contents of the Position script into a "<![CDATA[...]]>" block.
 
Line 77: Insert the code below at the start of the Position script.
 
<pre>
~only show the master button if the actor is a minion
portal[master].visible = hero.isminion
if (portal[master].visible <> 0) then
  perform portal[label].alignrel[ltor,master,8]
  endif
</pre>
 
===File: "form_taccon.dat"===
 
Line 179: Insert the "isbuiltin" attribute with a value of "yes".
 
Line 189: Insert the "isbuiltin" attribute with a value of "yes".
 
Line 199: Insert the "isbuiltin" attribute with a value of "yes".
 
Line 203: Insert the new portal definition shown below.
 
<pre>
<portal
  id="dead"
  style="imgNormal"
  tiptext="This character is dead or otherwise out of combat.">
  <image_literal
    image="tactical_dead.bmp"
    isbuiltin="yes"
    istransparent="yes">
    </image_literal>
  </portal>
</pre>
 
Line 216: Change the style assigned to the portal to "lblSmlLeft".
 
Line 225: Eliminate the left-alignment logic from the Label script as shown below.
 
<pre>
~squeeze inter-line spacing a bit
@text = "{leading -2}" & @text
</pre>
 
Line 254: Replace the "damage" and "status" portals with the new portal definitions shown below.
 
<pre>
<portal
  id="status1"
  style="lblSmlLeft">
  <label
    ismultiline="yes">
    <labeltext><![CDATA[
      ~start with the power points status
      @text = "{size 30}PP: {size 36}" & #traituser[trPowerPts] & " / " & #trait[trPowerPts]
 
      ~add the defense rating
      @text &= "{horz 12}{size 30}Def: {size 36}" & #trait[trDefense]
      ]]></labeltext>
    </label>
  </portal>
 
<portal
  id="status2"
  style="lblSmlLeft">
  <label
    ismultiline="yes">
    <labeltext><![CDATA[
      @text = "{size 30}HP: {size 36}" & field[acHPSumm].text
      ]]></labeltext>
    </label>
  </portal>
</pre>
 
Line 451: Renamed the portal from "column1" to "traits".
 
Line 461: Change the "foreach" statement to reference the "DashTacCon.Traits" tag expression.
 
Line 517: Append "sortas _NameSeq_" to the end of the "foreach" statement.
 
Line 544: Replace the "foreach" statement with the new statement shown below.
 
<pre>
foreach pick in hero where "(Adjustment.? | Helper.Activated) & !InPlay.Permanent" sortas _NameSeq_
  if (ismore <> 0) then
    @text &= "; "
    endif
  if (eachpick.tagis[component.Adjustment] <> 0) then
    @text &= eachpick.field[adjShort].text
  elseif (eachpick.tagis[component.shortname] <> 0) then
    @text &= eachpick.field[shortname].text
  else
    @text &= eachpick.field[name].text
    endif
  ismore = 1
  nexteach
</pre>
 
Line 669-681: Replace the script code that controls visibility and positioning with the new logic shown below.
 
<pre>
~position the "dead" indicator in the same location
portal[dead].left = leftedge
perform portal[dead].centervert
 
~hide all of the indicators and we'll pick one to show below (or none)
portal[dead].visible = 0
portal[acted].visible = 0
portal[noncombat].visible = 0
portal[never].visible = 0
 
~if we're in combat, handle things appropriately
if (state.iscombat <> 0) then
 
  ~determine which of the above four indicators is actually visible
  if (hero.tagis[Hero.Dead] <> 0) then
    portal[dead].visible = 1
  else
    portal[never].visible = hero.tagis[combat.never]
    portal[acted].visible = hero.tagis[combat.acted]
    portal[noncombat].visible = hero.tagis[combat.noncombat]
    endif
 
  ~adjust our left edge rightward past the indicators
  leftedge += portal[never].width + 4
  endif
</pre>
 
Line 759-778: Replace the script code that references the renamed "damage" and "status" portals with the new code shown below.
 
<pre>
~position the second status portal at the bottom of the region
perform portal[status2].alignedge[bottom,-margin - 2]
portal[status2].left = portal[name].left + 3
 
~position the first status portal in the region above the second status portal
perform portal[status1].alignrel[btot,status2,-1]
portal[status1].left = portal[status2].left
 
~if the status now overlaps the name, shift the status portals downward a
~little bit to make additional space
if (portal[status2].top < portal[name].bottom) then
  var adjust as number
  adjust = portal[name].bottom - portal[status2].top
  portal[status2].top += adjust
  adjust -= 1
  if (adjust > 1) then
    adjust -= 1
    endif
  portal[status1].top += adjust
  endif
</pre>
 
Line 851: Replace the code manipulating the "column1" portal with the following.
 
<pre>
~position the column of reminder traits
portal[traits].top = margin + 1
portal[traits].left = leftedge
portal[traits].lineheight = 3
</pre>
 
Line 860: Replace the reference to the "column1" portal with the "traits" portal.
 
Line 868: Insert the new code below to size the summary appropriately.
 
<pre>
perform portal[summary].sizetofit[28]
</pre>
 
Line 870-871: Replace the references to the "column1" portal with the "traits" portal.
 
===File: "procedures.dat"===
 
Line 780: Replace the "foreach" statement with the new logic shown below.
 
<pre>
foreach pick in hero where "(Adjustment.? | Helper.Activated) & !InPlay.Permanent"
  final &= "{br}"
  if (eachpick.tagis[Adjustment.?] <> 0) then
    final &= eachpick.field[adjName].text
  else
    final &= eachpick.field[name].text
    endif
  nexteach
</pre>
 
===File: "sheet_standard1.dat"===
 
Line 485: Replace the "dots" portal with the new definition below.
 
<pre>
<portal
  id="dots"
  style="outDots">
  <output_dots>
    </output_dots>
  </portal>
</pre>
 
Line 627: Insert the new logic below into the Position script.
 
<pre>
~limit our portal height to a single line of output
portal[details].lineheight = 1
</pre>
 
Line 661: Replace the "dots" portal with the new definition below.
 
<pre>
<portal
  id="dots"
  style="outDots">
  <output_dots>
    </output_dots>
  </portal>
</pre>
 
Line 670: Replace the entire Position script with the new logic shown below.
 
<pre>
~our height is the height of the tallest portal
height = portal[name].height
if (issizing <> 0) then
  done
  endif
 
~position the value at the right edge
perform portal[value].alignedge[right,0]
 
~size the name to fit the available space
portal[name].width = portal[value].left - 10
perform portal[name].sizetofit[40]
perform portal[name].autoheight
 
~the dots should span the region between the name and the value
perform portal[dots].alignrel[ltor,name,5]
portal[dots].width = portal[value].left - 5 - portal[dots].left
 
~center all portals vertically
perform portal[name].centervert
perform portal[value].centervert
perform portal[dots].centervert
</pre>
 
Line 711: Replace the entire Label script with the new logic shown below.
 
<pre>
if (stackable = 0) then
  @text = ""
elseif (field[stackQty].value = 1) then
  @text = ""
else
  @text = field[stackQty].text & "x"
  endif
</pre>
 
Line 731: Replace the entire Position script with the new logic shown below.
 
<pre>
~our height is the height of the tallest portal
height = portal[name].height
if (issizing <> 0) then
  done
  endif
 
~assign a fixed width to the value and position the name to the right
portal[value].width = 100
perform portal[name].alignrel[ltor,value,20]
 
~size the name to fit the available space
portal[name].width = width - portal[name].left
perform portal[name].sizetofit[36]
perform portal[name].autoheight
 
~center all portals vertically
perform portal[value].centervert
perform portal[name].centervert
</pre>
 
Lines 811-826: Replace the block of script code with the new logic shown below.
 
<pre>
~align everything horizontally
perform portal[badstr].alignrel[ltor,equipped,5]
perform portal[name].alignrel[ltor,badstr,5]
 
~size the name to fit the available space
portal[name].width = width - portal[name].left
perform portal[name].sizetofit[36]
perform portal[name].autoheight
 
~center all portals vertically
perform portal[badstr].centervert
perform portal[equipped].centervert
perform portal[name].centervert
 
~shift the "equipped" bitmap downward a little bit; this is because it is a
~lone bitmap drawn via encoded text, and bitmaps are never drawn within the
~descender portion of the text, which causes it to appear higher than we want it
portal[equipped].top += 4
</pre>
 
Line 867: Replace the "name" portal with the new element shown below.
 
<pre>
<portal
  id="name"
  style="outNameMed">
  <output_label
    field="shortname">
    </output_label>
  </portal>
</pre>
 
Line 912: Insert the new portal shown below.
 
<pre>
<portal
  id="dots"
  style="outDots">
  <output_dots>
    </output_dots>
  </portal>
</pre>
 
Lines 946-989: Replace the entire Position script with the new logic shown below.
 
<pre>
~our height is based on the tallest portal within
height = portal[name].height
if (issizing <> 0) then
  done
  endif
 
~if the weapon satisfies the minimum strength requirement, hide the bitmap
if (tagis[Helper.BadStrReq] = 0) then
  portal[badstr].visible = 0
  endif
 
~center all portals vertically
perform portal[badstr].centervert
perform portal[name].centervert
perform portal[attack].centervert
perform portal[damage].centervert
perform portal[dots].centervert
 
~position the range with the same baseline as the rest of the text; since it
~uses a smaller font, it will have a smaller height, so centering it will have
~it appear to float up relative to the other text
perform portal[range].alignrel[btob,name,0]
 
~establish suitable fixed widths for the various columns of data
portal[damage].width = 120
portal[attack].width = 70
portal[range].width = 260
 
~position everything horizontally, leaving a margin on both sides appropriately
portal[badstr].left = 5
perform portal[damage].alignedge[right,-5]
perform portal[name].alignrel[ltor,badstr,5]
perform portal[attack].alignrel[rtol,damage,-10]
perform portal[range].alignrel[rtol,attack,-10]
 
~if this is a ranged weapon, limit the name to the space up to the range details;
~otherwise, let the name extend over to the attack value
var limit as number
if (tagis[component.WeapRange] <> 0) then
  limit = portal[range].left
else
  limit = portal[attack].left
  endif
 
~limit the name to the extent determined above
if (portal[name].right > limit - 5) then
  portal[name].width = limit - portal[name].left - 5
  endif
 
~size the name to fit the available space
perform portal[name].sizetofit[36]
perform portal[name].autoheight
perform portal[name].centervert
 
~extend the dots from the right of the name across to the value on the right
if (portal[name].right > limit - 10) then
  portal[dots].visible = 0
else
  perform portal[dots].alignrel[ltor,name,5]
  portal[dots].width = limit - 5 - portal[dots].left
  endif
</pre>
 
Line 1039: Replace the entire Position script with the new logic shown below.
 
<pre>
~our height is the vertical extent of our portals
height = portal[name].height
if (issizing <> 0) then
  done
  endif
 
~size the name to fit the available space
portal[name].width = width
perform portal[name].sizetofit[36]
perform portal[name].autoheight
perform portal[name].centervert
</pre>
 
Line 1173: Replace the code for calculating the validation report height with the new logic below.
 
<pre>
perform portal[validate].autoheight
if (portal[validate].height > portal[validate].fontheight * maxlines) then
  portal[validate].lineheight = maxlines
  endif
</pre>
 
Numerous Places: Changes references to the "global" target reference over to "scenevalue". The list of locations is given below.
 
*Line 1208
*Line 1229
*Line 1315
*Line 1349
*Line 1442
*Line 1446
*Line 1464
*Line 1479
*Line 1480
*Line 1490
 
===File: "sheet_standard2.dat"===
 
Line 70: Changes reference to the "global" target reference over to "scenevalue".
 
===File: "summ_armory.dat"===
 
Line 76: Replace the "name" portal with the new element shown below.
 
<pre>
<portal
  id="name"
  style="lblSummary">
  <label>
    <labeltext><![CDATA[
      if (field[grIsEquip].value <> 0) then
        @text = "{b}{i}"
        endif
      @text &= field[name].text
      ]]></labeltext>
    </label>
  <mouseinfo/>
  </portal>
</pre>


Line 19: Added the "Notation" tag shown below.
Line 118: Replace the "name" portal with the new element shown below.


<pre>
<pre>
<value id="Notation"/>
<portal
  id="name"
  style="lblSummary">
  <label>
    <labeltext><![CDATA[
      if (field[grIsEquip].value <> 0) then
        @text = "{b}{i}"
        endif
      @text &= field[name].text
      ]]></labeltext>
    </label>
  <mouseinfo/>
  </portal>
</pre>
</pre>


Line 160: Insert new logic to handle notation advancements at the start of the Eval script, as shown below.
===File: "tab_armory.dat"===
 
Line 86: Change the component referenced from "WeapRange" to "Gear".
 
Line 265: Insert the "isbuiltin" attribute with a value of "yes".
 
Line 277: Insert the "isbuiltin" attribute with a value of "yes".
 
Line 319: Insert the "isbuiltin" attribute with a value of "yes".
 
Line 519: Insert the "isbuiltin" attribute with a value of "yes".
 
Line 531: Insert the "isbuiltin" attribute with a value of "yes".
 
===File: "tab_gear.dat"===
 
Line 122: Change the style from "lblNormal" to "lblLeft".
 
Line 143: Insert the "isbuiltin" attribute with a value of "yes".
 
Line 155: Insert the "isbuiltin" attribute with a value of "yes".
 
Line 198: Replace the entire Position script with the new logic shown below.


<pre>
<pre>
~if this advancement has an annotation, there is no user-selection, so build
~set up our height based on our tallest portal
~the name from our pieces and we're done
height = portal[info].height
if (tagis[Advance.Notation] <> 0) then
 
  perform gizmo.child[advDetails].setfocus
~if this is a "sizing" calculation, we're done
  field[livename].text = field[name].text & ": " & focus.field[advUser].text
if (issizing <> 0) then
   done
   done
  endif
~determine whether the container and heldby indicators should be visible
portal[container].visible = tagis[thing.holder?]
portal[heldby].visible = isgearheld
~center the portals vertically
perform portal[info].centervert
perform portal[name].centervert
perform portal[username].centervert
perform portal[gearmanage].centervert
perform portal[delete].centervert
perform portal[container].centervert
perform portal[heldby].centervert
~position the delete portal on the far right
perform portal[delete].alignedge[right,0]
~position the info portal to the left of the delete button
perform portal[info].alignrel[rtol,delete,-8]
~position the gear portal to the left of the info button
perform portal[gearmanage].alignrel[rtol,info,-8]
~calculate the space to reserve for the various indicators
var reserve as number
if (portal[heldby].visible <> 0) then
  reserve += portal[heldby].width + 2
  endif
if (portal[container].visible <> 0) then
  reserve += portal[container].width + 2
  endif
if (portal[heldby].visible + portal[container].visible <> 0) then
  reserve += 3
  endif
~position the name on the left and let it use all available space
var limit as number
limit = portal[gearmanage].left - 8 - reserve
portal[name].left = 0
portal[name].width = minimum(portal[name].width,limit)
~if this is a "custom" gear pick, show an edit portal instead of the name
var nextleft as number
if (tagis[Equipment.CustomGear] <> 0) then
  portal[name].visible = 0
  portal[username].left = portal[name].left
  portal[username].width = minimum(200,limit)
  nextleft = portal[username].right
else
  portal[username].visible = 0
  nextleft = portal[name].right
  endif
nextleft += 5
~show the 'container' icon to the right of the name (if visible)
if (portal[container].visible <> 0) then
  portal[container].left = nextleft
  nextleft = portal[container].right + 2
  endif
~show the 'held by' icon to the right of the container icon (if visible)
if (portal[heldby].visible <> 0) then
  portal[heldby].left = nextleft
  endif
~if the gear can't be deleted (i.e. it's been auto-added instead of user-added,
~set the style to indicate that behavior to the user
if (candelete = 0) then
  perform portal[name].setstyle[lblAuto]
  endif
</pre>
===File: "tab_journal.dat"===
Line 98: Replace the line of code that references the usage pool to the new line shown below.
<pre>
@text &= "{horz 40} Total XP: " & #resmax[resXP]
</pre>
===File: "thing_abilities.dat"===
Line 23: Insert the following material within the "abSample" ability.
<pre>
<!-- If checkbox selection is needed, make sure the compset includes "UserSelect"
      component and define this field appropriately.
<fieldval field="usrChkText" value="Menu1"/>
-->
<!-- If thing-based menu selection is needed, make sure the compset includes
      "UserSelect" component and define these fields and tags as appropriate.
<fieldval field="usrLabel1" value="Menu1"/>
<fieldval field="usrCandid1" value="component.Attribute"/>
<fieldval field="usrLabel2" value="Menu2"/>
<fieldval field="usrCandid2" value="component.Skill"/>
<tag group="ChooseSrc1" tag="Hero"/>
<tag group="ChooseSrc2" tag="Thing"/>
-->
<!-- If array-based menu selection is needed, make sure the compset includes
      "UserSelect" component and define these fields as appropriate.
<fieldval field="usrLabelAr" value="Menu1"/>
<arrayval field="usrArray" index="0" value="Choice #1"/>
<arrayval field="usrArray" index="1" value="Choice #2"/>
<arrayval field="usrArray" index="2" value="Choice #3"/>
-->
</pre>
===File: "thing_armory.dat"===
Line 18: Insert the following thing definition.
<pre>
<!-- Natural armor is automatically equipped -->
<thing
  id="armNatural"
  name="Natural Armor"
  compset="Armor"
  description="Description goes here"
  isunique="yes"
  holdable="no">
  <fieldval field="defDefense" value="1"/>
  <tag group="Equipment" tag="Natural"/>
  <tag group="Equipment" tag="AutoEquip"/>
  </thing>
</pre>
===File: "thing_attributes.dat"===
Line 18: Insert the following field value assignment.
<pre>
<fieldval field="trtAbbrev" value="Sam"/>
</pre>
Line 31: Insert the following field value assignment.
<pre>
<fieldval field="trtAbbrev" value="Str"/>
</pre>
===File: "thing_skills.dat"===
Line 18: Insert the following field value assignment.
<pre>
<fieldval field="trtAbbrev" value="Sam"/>
</pre>
Line 37: Insert the following field value assignment.
<pre>
<fieldval field="trtAbbrev" value="Mel"/>
</pre>
Line 50: Insert the following field value assignment.
<pre>
<fieldval field="trtAbbrev" value="Sht"/>
</pre>
===File: "thing_traits.dat"===
Line 38: Insert the following field value assignment.
<pre>
<fieldval field="trtAbbrev" value="Hlth"/>
</pre>
Line 60: Change the "Column1" tag reference to "Traits".
Line 77: Insert the following field value assignment.
<pre>
<fieldval field="trtAbbrev" value="Def"/>
</pre>
Line 96: Insert the following field value assignment.
<pre>
<fieldval field="trtAbbrev" value="Powr"/>
</pre>
Line 117: Change the "Column1" tag reference to "Traits".
Line 147: Change the "Column1" tag reference to "Traits".
===File: "visual.dat"===
Line 130: Insert the following code at the end of the Position script.
<pre>
~center the name if requested
if (tagis[SimpleItem.CenterName] <> 0) then
  perform portal[name].centerhorz
  endif
~if this is an auto-added pick, change its font to indicate that fact
if (ispick + !candelete >= 2) then
  perform portal[name].setstyle[lblAuto]
   endif
   endif
</pre>
</pre>


===Next===
Line 213: Insert the new template definition below.
 
<pre>
<!-- UserSelect template
      Similar to SimpleItem, except that this template is only suitable for
      showing picks and the items can employ various mechanisms for customizing
      the contents of the pick in some way. This template can be used or readily
      adapted when you integrate the "UserSelect" component into a component set
      and want to let the user customize the pick contents. For more details,
      please refer to the "UserSelect" component.
-->
<template
  id="UserSelect"
  name="User Selection"
  compset="UserSelect"
  marginhorz="3"
  marginvert="2">
 
  <portal
    id="name"
    style="lblNormal"
    showinvalid="yes">
    <label
      field="thingname">
      </label>
    </portal>
 
  <portal
    id="lblmenu1"
    style="lblSecond">
    <label
      field="usrLabel1">
      </label>
    </portal>
 
  <portal
    id="lblmenu2"
    style="lblSecond">
    <label
      field="usrLabel2">
      </label>
    </portal>
 
  <portal
    id="menu1"
    style="menuNormal">
    <menu_things
      field="usrChosen1"
      component="none"
      maxvisible="10"
      usepicksfield="usrSource1"
      candidatefield="usrCandid1">
      </menu_things>
    </portal>
 
  <portal
    id="menu2"
    style="menuNormal">
    <menu_things
      field="usrChosen2"
      component="none"
      maxvisible="10"
      usepicksfield="usrSource2"
      candidatefield="usrCandid2">
      </menu_things>
    </portal>
 
  <portal
    id="lblmenuar"
    style="lblSecond">
    <label
      field="usrLabelAr">
      </label>
    </portal>
 
  <portal
    id="menuarray"
    style="menuNormal">
    <menu_array
      field="usrSelect"
      array="usrArray"
      maxvisible="10">
      </menu_array>
    </portal>
 
  <portal
    id="checkbox"
    style="chkNormal">
    <checkbox
      field="usrIsCheck"
      dynamicfield="usrChkText">
      </checkbox>
    </portal>
 
  <portal
    id="info"
    style="actInfo">
    <action
      action="info">
      </action>
    <mouseinfo/>
    </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[info].height
 
    ~if this is a "sizing" calculation, we're done
    if (issizing <> 0) then
      done
      endif
 
    ~position our tallest portal at the top
    portal[info].top = 0
 
    ~center the other portals vertically
    perform portal[name].centervert
    perform portal[delete].centervert
    perform portal[lblmenu1].centervert
    perform portal[menu1].centervert
    perform portal[lblmenu2].centervert
    perform portal[menu2].centervert
    perform portal[lblmenuar].centervert
    perform portal[menuarray].centervert
    perform portal[checkbox].centervert
 
    ~determine whether our portals are visible; we only show them if requested
    ~Note: Remember that a non-empty tagexpr field indicates menu selection is used.
    if (field[usrCandid1].isempty <> 0) then
      portal[lblmenu1].visible = 0
      portal[menu1].visible = 0
    elseif (field[usrLabel1].isempty <> 0) then
      portal[lblmenu1].visible = 0
      endif
    if (field[usrCandid2].isempty <> 0) then
      portal[lblmenu2].visible = 0
      portal[menu2].visible = 0
    elseif (field[usrLabel2].isempty <> 0) then
      portal[lblmenu2].visible = 0
      endif
    if (empty(field[usrArray].arraytext[0]) <> 0) then
      portal[lblmenuar].visible = 0
      portal[menuarray].visible = 0
    elseif (field[usrLabelAr].isempty <> 0) then
      portal[lblmenuar].visible = 0
      endif
    if (field[usrChkText].isempty <> 0) then
      portal[checkbox].visible = 0
      endif
 
    ~position the delete portal on the far right and the info portal next to it
    perform portal[delete].alignedge[right,0]
    perform portal[info].alignrel[rtol,delete,-8]
 
    ~determine our effective right edge, allowing for the buttons above
    var edge as number
    edge = portal[info].left - 10
 
    ~setup the default portal width and gap to be used between and around portals
    var defwidth as number
    var gap as number
    defwidth = 100
    gap = 10
 
    ~determine the minimum amount of space we need to reserve for our portals
    var reserve as number
    if (portal[checkbox].visible <> 0) then
      reserve = defwidth
    elseif (portal[menuarray].visible <> 0) then
      reserve = portal[lblmenuar].width * portal[lblmenuar].visible
      reserve += defwidth + gap
    elseif (portal[menu1].visible <> 0) then
      reserve = portal[lblmenu1].width * portal[lblmenu1].visible
      reserve += defwidth + gap
      reserve += portal[lblmenu2].width * portal[menu2].visible
      reserve += (defwidth + gap) * portal[menu2].visible
      endif
 
    ~position the name on the left, reserving our minimum space for any portals
    var x as number
    portal[name].left = 0
    portal[name].width = minimum(portal[name].width,edge - portal[name].left - reserve)
    x = portal[name].right + gap
 
    ~setup the maximum width for our some portals, regardless of space available
    var maxwidth as number
    maxwidth = 150
 
    ~if we have a checkbox, size and position it appropriately
    if (portal[checkbox].visible <> 0) then
      portal[checkbox].left = x
 
    ~if we have an array-based menu, size and position it appropriately
    elseif (portal[menuarray].visible <> 0) then
      if (portal[lblmenuar].visible <> 0) then
        portal[lblmenuar].left = x
        x = portal[lblmenuar].right + 4
        endif
      portal[menuarray].left = x
      portal[menuarray].width = maxwidth
 
    ~if we have one thing-based menu, size and position it appropriately
    elseif (portal[menu1].visible + portal[menu2].visible = 1) then
      if (portal[lblmenu1].visible <> 0) then
        portal[lblmenu1].left = x
        x = portal[lblmenu1].right + 4
        endif
      portal[menu1].left = x
      portal[menu1].width = minimum(edge - portal[menu1].left,maxwidth)
 
    ~if we have two thing-based menus, size and position them appropriately
    elseif (portal[menu1].visible <> 0) then
      if (portal[lblmenu1].visible <> 0) then
        portal[lblmenu1].left = x
        x = portal[lblmenu1].right + 4
        endif
      portal[menu1].left = x
      var extra as number
      extra = (portal[lblmenu2].width + 4) * portal[lblmenu2].visible
      var actual as number
      actual = (edge - portal[menu1].left - extra - gap) / 2
      portal[menu1].width = minimum(actual,maxwidth)
      portal[menu2].width = portal[menu1].width
      x = portal[menu1].right + gap
      if (portal[lblmenu2].visible <> 0) then
        portal[lblmenu2].left = x
        x = portal[lblmenu2].right + 4
        endif
      portal[menu2].left = x
      endif
 
    ~if a menu is visible, make sure it has a selection
    if (portal[menu1].visible <> 0) then
      if (field[usrChosen1].ischosen = 0) then
        perform portal[menu1].setstyle[menuError]
        endif
      endif
    if (portal[menu2].visible <> 0) then
      if (field[usrChosen2].ischosen = 0) then
        perform portal[menu2].setstyle[menuError]
        endif
      endif
    if (portal[menuarray].visible <> 0) then
      if (field[usrSelect].isempty <> 0) then
        perform portal[menuarray].setstyle[menuError]
        endif
      endif
    ]]></position>
 
  </template>
</pre>

Latest revision as of 10:43, 19 February 2009

Context: HL Kit &#133; Kit Reference &#133; Skeleton Data File Revision History 

File: "definition.def"

Line 24: Eliminate the "manualroot" attribute so that the manual location uses the default.

Line 46: Replace the "required" attribute with "3.1" instead of "3.0".

File: "tags.1st"

Line 52: Insert the new tag shown below.

<value id="NoAutoName"/>

Line 65: Insert the new tag shown below.

<value id="Dead"/>

Line 79: Rename the "Column1" tag to "Traits".

Line 90: Insert the new tag shown below.

<value id="StartEquip" name="Gear starts out equipped"/>

Line 245: Insert the new tag group definition shown below.

<group
  id="DomainTerm"
  dynamic="yes">
  <value id="Domain"/>
  </group>

Line 254: Insert the new tag shown below.

<value id="CenterName"/>

Line 256: Insert the new tag group definitions shown below.

<group
  id="ChooseSrc1"
  visible="no">
  <value id="Thing" name="All Things"/>
  <value id="Container" name="All Picks on Container"/>
  <value id="Hero" name="All Picks on Hero"/>
  </group>
<group
  id="ChooseSrc2"
  visible="no">
  <value id="Thing" name="All Things"/>
  <value id="Container" name="All Picks on Container"/>
  <value id="Hero" name="All Picks on Hero"/>
  </group>

File: "advancement.core"

Line 19: Added the "Notation" tag shown below.

<value id="Notation"/>

Line 160: Insert new logic to handle notation advancements at the start of the Eval script, as shown below.

~if this advancement has an annotation, there is no user-selection, so build
~the name from our pieces and we're done
if (tagis[Advance.Notation] <> 0) then
  perform gizmo.child[advDetails].setfocus
  field[livename].text = field[name].text & ": " & focus.field[advUser].text
  done
  endif

File: "components.core"

Line 273: Change the reference to the "component.Ability" tag to "component.shortname".

Line 278: Change the reference to the "component.Ability" tag to "component.shortname".

Line 283: Insert the code below to use the standard name if no short name is defined.

~if we don't have a short name, just use the regular name
if (empty(short) <> 0) then
  short = name
  endif

Line 337: Insert the new "UserSelect" component definition that is provided below.

<component
  id="UserSelect"
  name="User Selection">

  <!-- Text to display with the checkbox
        NOTE! If this field is empty, it means NO checkbox is shown for the pick.
  -->
  <field
    id="usrChkText"
    name="Checkbox Text"
    type="derived"
    maxlength="100">
    </field>

  <!-- Indicates whether the checkbox is selected is not -->
  <field
    id="usrIsCheck"
    name="Checked?"
    type="user"
    minvalue="0"
    maxvalue="1">
    </field>

  <!--  Label associated with the first thing-based menu -->
  <field
    id="usrLabel1"
    name="Thing Menu Label #1"
    type="static"
    maxlength="50">
    </field>

  <!-- Tracks the first selection made when a menu choice is required -->
  <field
    id="usrChosen1"
    name="Chosen Thing / Pick #1"
    type="user"
    style="menu">
    </field>

  <!-- Candidate tagexpr used to determine which picks/things are shown in menu #1
        NOTE! If this field is empty, it means NO first menu is shown for the pick.
  -->
  <field
    id="usrCandid1"
    name="Candidate TagExpr for Menu #1"
    type="derived"
    maxlength="1000"
    defvalue="">
    </field>

  <!-- Source to pull choices from within menu #1 -->
  <field
    id="usrSource1"
    name="Source for Menu #1 Choices"
    type="derived">
    <!-- Determine the source to choose from based on the tag, defaulting to "Hero" -->
    <calculate phase="Render" priority="10000"><![CDATA[
      if (tagis[ChooseSrc1.Thing] <> 0) then
        @value = 0
      elseif (tagis[ChooseSrc1.Container] <> 0) then
        @value = 1
      elseif (tagis[ChooseSrc1.Hero] <> 0) then
        @value = 2
      else
        @value = 2
        endif
      ]]></calculate>
    </field>

  <!--  Label associated with the second thing-based menu -->
  <field
    id="usrLabel2"
    name="Thing Menu Label #2"
    type="static"
    maxlength="50">
    </field>

  <!-- Tracks the second selection made when a menu choice is required -->
  <field
    id="usrChosen2"
    name="Chosen Thing / Pick #2"
    type="user"
    style="menu">
    </field>

  <!-- Candidate tagexpr used to determine which picks/things are shown in menu #2
        NOTE! If this field is empty, it means NO second menu is shown for the pick.
  -->
  <field
    id="usrCandid2"
    name="Candidate TagExpr for Menu #2"
    type="derived"
    maxlength="1000"
    defvalue="">
    </field>

  <!-- Source to pull choices from within menu #2 -->
  <field
    id="usrSource2"
    name="Source for Menu #2 Choices"
    type="derived">
    <!-- Determine the source to choose from based on the tag, defaulting to "Hero" -->
    <calculate phase="Render" priority="10000"><![CDATA[
      if (tagis[ChooseSrc2.Thing] <> 0) then
        @value = 0
      elseif (tagis[ChooseSrc2.Container] <> 0) then
        @value = 1
      elseif (tagis[ChooseSrc2.Hero] <> 0) then
        @value = 2
      else
        @value = 2
        endif
      ]]></calculate>
    </field>

  <!--  Label associated with the array-based menu -->
  <field
    id="usrLabelAr"
    name="Array Menu Label"
    type="static"
    maxlength="50">
    </field>

  <!-- Array of text items user can select from
        NOTE! If the 0th element is empty, it means NO menu is shown for the pick.
  -->
  <field
    id="usrArray"
    name="Array of Items to Choose"
    type="derived"
    style="array"
    arrayrows="10"
    maxlength="30">
    </field>

  <!-- Item selected from the array -->
  <field
    id="usrSelect"
    name="Selected Item in Array"
    type="user"
    maxlength="30">
    </field>

  <!-- Initialize the current array-based selection from the array if not defined -->
  <creation><![CDATA[
    if (empty(field[usrArray].arraytext[0]) = 0) then
      if (field[usrSelect].isempty <> 0) then
        field[usrSelect].text = field[usrArray].arraytext[0]
        endif
      endif
    ]]></creation>

  <!-- Integrate the various user selections into the name of the pick
        NOTE! Must be scheduled after the "shortname" field is synthesized at Render/100.
  -->
  <eval index="1" phase="Render" priority="500"><![CDATA[
    ~if we're not supposed to auto-amend the name for this pick, we're done
    if (tagis[User.NoAutoName] <> 0) then
      done
      endif

    ~if we have thing-based menus, determine the text to append to the name
    var choices as string
    if (field[usrCandid1].isempty = 0) then
      if (field[usrChosen1].ischosen <> 0) then
        choices = field[usrChosen1].chosen.field[name].text
      else
        choices = "-Choose-"
        endif
      if (field[usrChosen2].ischosen <> 0) then
        choices &= ", " & field[usrChosen2].chosen.field[name].text
        endif

    ~if we have an array-based menu, determine the text to append
    elseif (empty(field[usrArray].arraytext[0]) = 0) then
      choices = field[usrSelect].text

    ~if we have a selected checkbox, determine the text to append
    elseif (field[usrChkText].isempty = 0) then
      if (field[usrIsCheck].value <> 0) then
        choices = field[usrChkText].text
        endif
      endif

    ~if we have no text to append, we're done
    if (empty(choices) <> 0) then
      done
      endif

    ~add the selection to both the livename and shortname (if present) fields
    field[livename].text = field[name].text & ": " & choices
    if (tagis[component.shortname] <> 0) then
      field[shortname].text &= " (" & choices & ")"
      endif
    ]]></eval>

  <!-- Report a validation error if no selection has been made for a menu selection -->
  <evalrule phase="Validate" priority="10000" message="You must choose an option" summary="Choose!"><![CDATA[
    ~determine the number of menus that NEED selection
    ~Note: Remember that a non-empty tagexpr field indicates menu selection is used.
    var needed as number
    needed = !field[usrCandid1].isempty + !field[usrCandid2].isempty
    needed += !empty(field[usrArray].arraytext[0])

    ~determine the number of menus that HAVE selections
    var actual as number
    if (field[usrCandid1].isempty = 0) then
      actual += field[usrChosen1].ischosen
      endif
    if (field[usrCandid2].isempty = 0) then
      actual += field[usrChosen2].ischosen
      endif
    if (field[usrSelect].isempty = 0) then
      actual += 1
      endif

    ~if the user has chosen something whenever required, we're valid
    if (actual >= needed) then
      @valid = 1
      done
      endif

    ~mark any associated tab as invalid
    if (ispanel <> 0) then
      linkvalid = 0
      endif
    ]]></evalrule>

  </component>

Line 400: Add the new Eval script below to the "Domain" component.

<eval index="1" phase="Render" priority="500"><![CDATA[
  ~if we don't need a domain, there's nothing to do
  if (tagis[User.NeedDomain] = 0) then
    done
    endif

  ~if we're not supposed to auto-amend the name for this pick, we're done
  if (tagis[User.NoAutoName] <> 0) then
    done
    endif

  ~if we don't have a domain, use a placeholder for it
  var domain as string
  if (field[domDomain].isempty = 0) then
    domain = field[domDomain].text
  else
    domain = "????"
    endif

  ~add the domain to both the livename and shortname (if present) fields
  field[livename].text = field[name].text & ": " & domain
  if (tagis[component.shortname] <> 0) then
    field[shortname].text &= " (" & domain & ")"
    endif
  ]]></eval>

Line 401: Replace the original Eval script with the new one shown below.

<evalrule index="1" phase="Validate" priority="9000" message="????"><![CDATA[
  ~if no domain is needed or the domain is specified, we're valid
  if (tagis[User.NeedDomain] = 0) then
    @valid = 1
  elseif (field[domDomain].isempty = 0) then
    @valid = 1
    endif

  ~if we're valid, get out of here
  if (@valid <> 0) then
    done
    endif

  ~if we have a linked panel, flag it as invalid
  if (ispanel <> 0) then
    linkvalid = 0
    endif

  ~synthesize an appropriate message using the correct domain term
  var term as string
  term = tagnames[DomainTerm.?]
  if (empty(term) <> 0) then
    term = "Domain"
    endif
  @message = term & " must be specified"
  ]]></evalrule>

File: "actor.str"

Line 163: Change the reference to the "trtLeft" field to "trtUser".

Line 221: Replace the Eval script with the revised script below.

<eval index="1" phase="Final" priority="1000"><![CDATA[
  ~if no damage has been incurred, assign a tag to indicate that state
  if (field[acHPNow].value >= field[acHPMax].value) then
    perform hero.assign[Hero.NoDamage]

  ~if the hero is dead or otherwise out of combat, indicate that state
  elseif (field[acHPNow].value = 0) then
    perform hero.assign[Hero.Dead]
    endif
  ]]></eval>

File: "equipment.str"

Line 27: Increase the "maxfinal" value from "50" to "100".

Line 219: Insert the Creation script shown below.

<creation><![CDATA[
  ~if this is natural equipment, initialize the equipped state
  if (tagis[Equipment.Natural] <> 0) then
    field[grIsEquip].value = 1
    endif

  ~if this equipment is supposed to start out as equipped, initialize the state
  if (tagis[Equipment.StartEquip] <> 0) then
    field[grIsEquip].value = 1
    endif
  ]]></creation>

Line 229: Change the Eval script priority from "1000" to "4000".

Line 584: Change the field type from "static" to "derived".

File: "miscellaneous.str"

Line 103: Insert the new lines of code below into the Finalize script.

  @text = "{text ff0000}"
elseif (unspent > 0) then

File: "traits.str"

Line 50: Change the timing of the Bound script, assign it a name, and establish a "before" dependency, as shown below.

<bound phase="Traits" priority="1000" name="Bound trtUser">
  <before name="Calc trtFinal"/><![CDATA[
  @minimum = field[trtMinimum].value
  @maximum = field[trtMaximum].value
  ]]></bound>

Line 97: Change the timing of the Eval script from "9999999" to "5000".

Line 130: Change the timing of the Eval script and setup "before" and "after" dependencies, as shown below.

<eval index="2" phase="Traits" priority="10000">
  <before name="Calc resLeft"/>
  <after name="Bound trtUser"/><![CDATA[
  hero.child[resCP].field[resSpent].value += (field[trtUser].value - 1) * 7
  ]]></eval>

Line 175: Change the timing of the Eval script and setup "before" and "after" dependencies, as shown below.

<eval index="2" phase="Traits" priority="10000">
  <before name="Calc resLeft"/>
  <after name="Bound trtUser"/><![CDATA[

Line 253: Change the test from keying on the usage pool to the actual mode, as shown below.

~if the mode is creation, we're valid
if (state.iscreate <> 0) then
  @valid = 1
  done
  endif

File: "styles_output.aug"

Line 217: Insert the new style shown below.

<style
  id="outDots">
  <style_output
    textcolor="202020"
    font="ofntnormal"
    alignment="left">
    </style_output>
  </style>

File: "styles_ui.aug"

Line 236: Insert the new resource definition shown below.

<resource
  id="fntmenusm">
  <font
    face="Arial"
    size="30"
    style="bold">
    </font>
  </resource>

Line 268: Insert the new color resource definitions shown below.

<!-- color used for normal text throughout the ui -->
<resource
  id="clrnormal">
  <color
    color="f0f0f0">
    </color>
  </resource>

<!-- color used for text on the static panel - not quite as bright -->
<resource
  id="clrstatic">
  <color
    color="d2d2d2">
    </color>
  </resource>

<!-- color used for text in title labels -->
<resource
  id="clrtitle">
  <color
    color="c0c0c0">
    </color>
  </resource>

<!-- color used for names of automatically added picks -->
<resource
  id="clrauto">
  <color
    color="99efed">
    </color>
  </resource>

<!-- color used for disabled text -->
<resource
  id="clrdisable">
  <color
    color="808080">
    </color>
  </resource>

<!-- color used for summary text that should be a little dimmer than normal -->
<resource
  id="clrsummary">
  <color
    color="a0a0a0">
    </color>
  </resource>

<!-- color used for bright text -->
<resource
  id="clrbright">
  <color
    color="ffff88">
    </color>
  </resource>

<!-- color used for warning text -->
<resource
  id="clrwarning">
  <color
    color="ff0000">
    </color>
  </resource>

<!-- color used for prompt text inviting the user to change something -->
<resource
  id="clrprompt">
  <color
    color="ffff00">
    </color>
  </resource>

<!-- color used for the 'buy for free' checkbox on buy / sell panels -->
<resource
  id="clrchkfree">
  <color
    color="a8a800">
    </color>
  </resource>

<!-- color used for text on summary panels - a little dimmer than normal -->
<resource
  id="clrsummtxt">
  <color
    color="d0d0d0">
    </color>
  </resource>

<!-- color used for labels when choosing advancements -->
<resource
  id="clradvance">
  <color
    color="ffffff">
    </color>
  </resource>

<!-- color used for text on action buttons -->
<resource
  id="clraction">
  <color
    color="000088">
    </color>
  </resource>

<!-- colors used in edit controls -->
<resource
  id="clredittxt">
  <color
    color="d2d2d2">
    </color>
  </resource>
<resource
  id="clreditbck">
  <color
    color="000000">
    </color>
  </resource>

<!-- colors used in menu and chooser controls -->
<resource
  id="clrmenutxt">
  <color
    color="84c8f7">
    </color>
  </resource>
<resource
  id="clrmenuslt">
  <color
    color="1414f7">
    </color>
  </resource>
<resource
  id="clrmenubck">
  <color
    color="2a2c47">
    </color>
  </resource>

Numerous Places: Change the style to reference a named color instead of a literal color, switching from a "textcolor" attribute to a "textcolorid" attribute. The list of changes is given below.

  • Line 282 - "clrtitle"
  • Line 293 - "clrstatic"
  • Line 303 - "clrnormal"
  • Line 313 - "clrnormal"
  • Line 323 - "clrnormal"
  • Line 335 - "clrauto"
  • Line 347 - "clrdisable"
  • Line 359 - "clrbright"
  • Line 371 - "clrwarning"
  • Line 384 - "clrprompt"
  • Line 394 - "clrnormal"
  • Line 404 - "clrdisable"
  • Line 414 - "clrprompt"
  • Line 424 - "clrwarning"
  • Line 434 - "clrnormal"
  • Line 444 - "clrdisable"
  • Line 454 - "clrwarning"
  • Line 464 - "clrnormal"
  • Line 474 - "clrdisable"
  • Line 484 - "clrsummary"
  • Line 494 - "clrnormal"
  • Line 504 - "clrnormal"
  • Line 514 - "clrsummtxt"
  • Line 524 - "clrdisable"
  • Line 534 - "clrsummary"
  • Line 545 - "clrsummary"
  • Line 556 - "clradvance"
  • Line 568 - "clradvance"
  • Line 582 - "clrnormal"
  • Line 596 - "clredittxt"
  • Line 597 - "clreditbck"
  • Line 607 - "clredittxt"
  • Line 608 - "clreditbck"
  • Line 618 - "clredittxt"
  • Line 619 - "clreditbck"
  • Line 624 - "clrdisable"
  • Line 635 - "clrnormal"
  • Line 652 - "clrnormal"
  • Line 669 - "clrnormal"
  • Line 732 - "clrnormal"
  • Line 805 - "clraction"
  • Line 836 - "clraction"
  • Line 867 - "clrnormal"
  • Line 901 - "clraction"
  • Line 937 - "clraction"
  • Line 971 - "clraction"
  • Line 981 - "clraction"
  • Line 991 - "clraction"
  • Line 1025 - "clraction"
  • Line 1059 - "clraction"
  • Line 1085 - "clrnormal"
  • Line 1119 - "clrnormal"
  • Line 1145 - "clrnormal"
  • Line 1171 - "clrnormal"
  • Line 1205 - "clrnormal"
  • Line 1231 - "clrnormal"
  • Line 1265 - "clrnormal"
  • Line 1299 - "clrnormal"
  • Line 1333 - "clrnormal"
  • Line 1359 - "clrnormal"
  • Line 1385 - "clrnormal"
  • Line 1411 - "clrnormal"
  • Line 1445 - "clrnormal"
  • Line 1471 - "clraction"
  • Line 1497 - "clraction"
  • Line 1531 - "clraction"
  • Line 1557 - "clraction"
  • Line 1583 - "clraction"
  • Line 1609 - "clraction"
  • Line 1643 - "clraction"
  • Line 1677 - "clraction"
  • Line 1711 - "clraction"
  • Line 1745 - "clraction"
  • Line 1779 - "clraction"
  • Line 1813 - "clraction"
  • Line 1847 - "clraction"
  • Line 1881 - "clraction"
  • Line 1915 - "clraction"
  • Line 1949 - "clraction"
  • Line 1983 - "clraction"
  • Line 2017 - "clrnormal"
  • Line 2051 - "clrnormal"
  • Line 2085 - "clrnormal"
  • Line 2119 - "clrnormal"
  • Line 2153 - "clrnormal"
  • Line 2206 - "clrdisable"
  • Line 2232 - "clrnormal"
  • Line 2241 - "clrwarning"
  • Line 2252 - "clrdisable"
  • Line 2261 - "clrchkfree"
  • Line 2270 - "clrnormal"
  • Line 2311 - "clrnormal"
  • Line 2358 - "clrmenutxt"
  • Line 2359 - "clrmenubck"
  • Line 2360 - "clrmenuslt"
  • Line 2361 - "clrnormal"
  • Line 2371 - "clrmenutxt"
  • Line 2372 - "clrmenubck"
  • Line 2373 - "clrmenuslt"
  • Line 2374 - "clrnormal"
  • Line 2375 - "clrwarning"
  • Line 2386 - "clrmenutxt"
  • Line 2387 - "clrmenubck"
  • Line 2397 - "clrwarning"
  • Line 2398 - "clrmenubck"

Line 470: Insert the new style definition shown below.

<!-- slightly smaller label that is left-aligned -->
<style
  id="lblSmlLeft">
  <style_label
    textcolorid="clrnormal"
    font="fntsmall"
    alignment="left">
    </style_label>
  </style>

Line 1467: Insert the new style definition shown below.

<!-- Style used on the master button -->
<style
  id="actMaster">
  <style_action
    textcolorid="clrnormal"
    font="fntactsml"
    up="actmastup" down="actmastdn" off="actmastup">
    </style_action>
  <resource
    id="actmastup"
    isbuiltin="yes">
    <bitmap
      bitmap="master_up.bmp"
      istransparent="yes">
      </bitmap>
    </resource>
  <resource
    id="actmastdn"
    isbuiltin="yes">
    <bitmap
      bitmap="master_down.bmp"
      istransparent="yes">
      </bitmap>
    </resource>
  </style>

Line 2380: Insert the the new style definitions shown below.

<!-- small menu portal -->
<style
  id="menuSmall"
  border="sunken">
  <style_menu
    textcolorid="clrmenutxt"
    backcolorid="clrmenubck"
    selecttextid="clrmenuslt"
    selectbackid="clrnormal"
    font="fntmenusm"
    droplist="menuarrsm"
    droplistoff="menuoffsm">
    </style_menu>
  <resource
    id="menuarrsm"
    isbuiltin="yes">
    <bitmap
      bitmap="menu_small_arrow.bmp">
      </bitmap>
    </resource>
  <resource
    id="menuoffsm"
    isbuiltin="yes">
    <bitmap
      bitmap="menu_small_arrow_off.bmp">
      </bitmap>
    </resource>
  </style>

<!-- small menu portal with coloring to indicate contents are in error -->
<style
  id="menuErrSm"
  border="sunken">
  <style_menu
    textcolorid="clrmenutxt"
    backcolorid="clrmenubck"
    selecttextid="clrmenuslt"
    selectbackid="clrnormal"
    activetextid="clrwarning"
    font="fntmenusm"
    droplist="menuarrsm"
    droplistoff="menuoffsm">
    </style_menu>
  </style>

File: "form_advance.dat"

Line 28: Change the field reference from "name" to "thingname".

Line 123: Change the field reference from "name" to "thingname".

Line 222: Replace the code for shrinking the size to the new code shown below.

perform portal[name].sizetofit[36]
perform portal[name].centervert

Line 238: Replace the "label" element with the new behavior shown below.

<label>
  <labeltext><![CDATA[
    ~use any domain term specified, else default to "domain"
    @text = parent.tagnames[DomainTerm.?]
    if (empty(@text) <> 0) then
      @text = "Domain"
      endif
    @text &= ":"
    ]]></labeltext>
  </label>

Line 271: Insert the new template definition shown below.

<template
  id="advNotate"
  name="Notation Specification"
  compset="AdvDetails">

  <portal
    id="lblnotate"
    style="lblStatic">
    <label
      text="Notation:">
      </label>
    </portal>

  <portal
    id="notation"
    style="editNormal">
    <edit
      field="advUser"
      maxlength="50">
      </edit>
    </portal>

  <position><![CDATA[
    ~set up our width and height
    height = portal[notation].height
    if (issizing <> 0) then
      done
      endif

    ~center everything vertically
    perform portal[lblnotate].centervert
    perform portal[notation].centervert

    ~position the label on the left with the edit portal next to it
    portal[lblnotate].left = 0
    perform portal[notation].alignrel[ltor,lblnotate,7]
    portal[notation].width = width - portal[notation].left
    ]]></position>
  </template>

Line 309: Replace the script code for setting the line height to the code shown below.

portal[notes].lineheight = 4

Line 320: Insert the template reference shown below.

<templateref template="advNotate" thing="advDetails" taborder="20"/>

Line 345: Insert the code below to position the notation template

~position the notation template in the same place
template[advNotate].left = portal[advNew].left
template[advNotate].top = portal[advNew].top
template[advNotate].width = portal[advNew].width

Line 347: Insert the code below to set the notation template to non-visible.

template[advNotate].visible = 0

Line 356: Insert the code below to show the notation template when appropriate.

elseif (container.parent.tagis[Advance.Notation] <> 0) then
  template[advNotate].visible = 1

File: "form_dashboard.dat"

Line 121: Replace the Label script code with the new code shown below.

@text = "{size 30}PP: {size 36}" & hero.child[trkPower].field[trkUser].text

Line 189: Added the "isbuiltin" attribute to the element with a value of "yes".

File: "form_static.dat"

Line 59: Insert the new portal definition below.

<portal
  id="master"
  style="actMaster"
  tiptext="Click this button to activate this ally's Master.">
  <action
    action="master">
    </action>
  </portal>

Line 76 and 87: Put the contents of the Position script into a "<![CDATA[...]]>" block.

Line 77: Insert the code below at the start of the Position script.

~only show the master button if the actor is a minion
portal[master].visible = hero.isminion
if (portal[master].visible <> 0) then
  perform portal[label].alignrel[ltor,master,8]
  endif

File: "form_taccon.dat"

Line 179: Insert the "isbuiltin" attribute with a value of "yes".

Line 189: Insert the "isbuiltin" attribute with a value of "yes".

Line 199: Insert the "isbuiltin" attribute with a value of "yes".

Line 203: Insert the new portal definition shown below.

<portal
  id="dead"
  style="imgNormal"
  tiptext="This character is dead or otherwise out of combat.">
  <image_literal
    image="tactical_dead.bmp"
    isbuiltin="yes"
    istransparent="yes">
    </image_literal>
  </portal>

Line 216: Change the style assigned to the portal to "lblSmlLeft".

Line 225: Eliminate the left-alignment logic from the Label script as shown below.

~squeeze inter-line spacing a bit
@text = "{leading -2}" & @text

Line 254: Replace the "damage" and "status" portals with the new portal definitions shown below.

<portal
  id="status1"
  style="lblSmlLeft">
  <label
    ismultiline="yes">
    <labeltext><![CDATA[
      ~start with the power points status
      @text = "{size 30}PP: {size 36}" & #traituser[trPowerPts] & " / " & #trait[trPowerPts]

      ~add the defense rating
      @text &= "{horz 12}{size 30}Def: {size 36}" & #trait[trDefense]
      ]]></labeltext>
    </label>
  </portal>

<portal
  id="status2"
  style="lblSmlLeft">
  <label
    ismultiline="yes">
    <labeltext><![CDATA[
      @text = "{size 30}HP: {size 36}" & field[acHPSumm].text
      ]]></labeltext>
    </label>
  </portal>

Line 451: Renamed the portal from "column1" to "traits".

Line 461: Change the "foreach" statement to reference the "DashTacCon.Traits" tag expression.

Line 517: Append "sortas _NameSeq_" to the end of the "foreach" statement.

Line 544: Replace the "foreach" statement with the new statement shown below.

foreach pick in hero where "(Adjustment.? | Helper.Activated) & !InPlay.Permanent" sortas _NameSeq_
  if (ismore <> 0) then
    @text &= "; "
    endif
  if (eachpick.tagis[component.Adjustment] <> 0) then
    @text &= eachpick.field[adjShort].text
  elseif (eachpick.tagis[component.shortname] <> 0) then
    @text &= eachpick.field[shortname].text
  else
    @text &= eachpick.field[name].text
    endif
  ismore = 1
  nexteach

Line 669-681: Replace the script code that controls visibility and positioning with the new logic shown below.

~position the "dead" indicator in the same location
portal[dead].left = leftedge
perform portal[dead].centervert

~hide all of the indicators and we'll pick one to show below (or none)
portal[dead].visible = 0
portal[acted].visible = 0
portal[noncombat].visible = 0
portal[never].visible = 0

~if we're in combat, handle things appropriately
if (state.iscombat <> 0) then

  ~determine which of the above four indicators is actually visible
  if (hero.tagis[Hero.Dead] <> 0) then
    portal[dead].visible = 1
  else
    portal[never].visible = hero.tagis[combat.never]
    portal[acted].visible = hero.tagis[combat.acted]
    portal[noncombat].visible = hero.tagis[combat.noncombat]
    endif

  ~adjust our left edge rightward past the indicators
  leftedge += portal[never].width + 4
  endif

Line 759-778: Replace the script code that references the renamed "damage" and "status" portals with the new code shown below.

~position the second status portal at the bottom of the region
perform portal[status2].alignedge[bottom,-margin - 2]
portal[status2].left = portal[name].left + 3

~position the first status portal in the region above the second status portal
perform portal[status1].alignrel[btot,status2,-1]
portal[status1].left = portal[status2].left

~if the status now overlaps the name, shift the status portals downward a
~little bit to make additional space
if (portal[status2].top < portal[name].bottom) then
  var adjust as number
  adjust = portal[name].bottom - portal[status2].top
  portal[status2].top += adjust
  adjust -= 1
  if (adjust > 1) then
    adjust -= 1
    endif
  portal[status1].top += adjust
  endif

Line 851: Replace the code manipulating the "column1" portal with the following.

~position the column of reminder traits
portal[traits].top = margin + 1
portal[traits].left = leftedge
portal[traits].lineheight = 3

Line 860: Replace the reference to the "column1" portal with the "traits" portal.

Line 868: Insert the new code below to size the summary appropriately.

perform portal[summary].sizetofit[28]

Line 870-871: Replace the references to the "column1" portal with the "traits" portal.

File: "procedures.dat"

Line 780: Replace the "foreach" statement with the new logic shown below.

foreach pick in hero where "(Adjustment.? | Helper.Activated) & !InPlay.Permanent"
  final &= "{br}"
  if (eachpick.tagis[Adjustment.?] <> 0) then
    final &= eachpick.field[adjName].text
  else
    final &= eachpick.field[name].text
    endif
  nexteach

File: "sheet_standard1.dat"

Line 485: Replace the "dots" portal with the new definition below.

<portal
  id="dots"
  style="outDots">
  <output_dots>
    </output_dots>
  </portal>

Line 627: Insert the new logic below into the Position script.

~limit our portal height to a single line of output
portal[details].lineheight = 1

Line 661: Replace the "dots" portal with the new definition below.

<portal
  id="dots"
  style="outDots">
  <output_dots>
    </output_dots>
  </portal>

Line 670: Replace the entire Position script with the new logic shown below.

~our height is the height of the tallest portal
height = portal[name].height
if (issizing <> 0) then
  done
  endif

~position the value at the right edge
perform portal[value].alignedge[right,0]

~size the name to fit the available space
portal[name].width = portal[value].left - 10
perform portal[name].sizetofit[40]
perform portal[name].autoheight

~the dots should span the region between the name and the value
perform portal[dots].alignrel[ltor,name,5]
portal[dots].width = portal[value].left - 5 - portal[dots].left

~center all portals vertically
perform portal[name].centervert
perform portal[value].centervert
perform portal[dots].centervert

Line 711: Replace the entire Label script with the new logic shown below.

if (stackable = 0) then
  @text = ""
elseif (field[stackQty].value = 1) then
  @text = ""
else
  @text = field[stackQty].text & "x"
  endif

Line 731: Replace the entire Position script with the new logic shown below.

~our height is the height of the tallest portal
height = portal[name].height
if (issizing <> 0) then
  done
  endif

~assign a fixed width to the value and position the name to the right
portal[value].width = 100
perform portal[name].alignrel[ltor,value,20]

~size the name to fit the available space
portal[name].width = width - portal[name].left
perform portal[name].sizetofit[36]
perform portal[name].autoheight

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

Lines 811-826: Replace the block of script code with the new logic shown below.

~align everything horizontally
perform portal[badstr].alignrel[ltor,equipped,5]
perform portal[name].alignrel[ltor,badstr,5]

~size the name to fit the available space
portal[name].width = width - portal[name].left
perform portal[name].sizetofit[36]
perform portal[name].autoheight

~center all portals vertically
perform portal[badstr].centervert
perform portal[equipped].centervert
perform portal[name].centervert

~shift the "equipped" bitmap downward a little bit; this is because it is a
~lone bitmap drawn via encoded text, and bitmaps are never drawn within the
~descender portion of the text, which causes it to appear higher than we want it
portal[equipped].top += 4

Line 867: Replace the "name" portal with the new element shown below.

<portal
  id="name"
  style="outNameMed">
  <output_label
    field="shortname">
    </output_label>
  </portal>

Line 912: Insert the new portal shown below.

<portal
  id="dots"
  style="outDots">
  <output_dots>
    </output_dots>
  </portal>

Lines 946-989: Replace the entire Position script with the new logic shown below.

~our height is based on the tallest portal within
height = portal[name].height
if (issizing <> 0) then
  done
  endif

~if the weapon satisfies the minimum strength requirement, hide the bitmap
if (tagis[Helper.BadStrReq] = 0) then
  portal[badstr].visible = 0
  endif

~center all portals vertically
perform portal[badstr].centervert
perform portal[name].centervert
perform portal[attack].centervert
perform portal[damage].centervert
perform portal[dots].centervert

~position the range with the same baseline as the rest of the text; since it
~uses a smaller font, it will have a smaller height, so centering it will have
~it appear to float up relative to the other text
perform portal[range].alignrel[btob,name,0]

~establish suitable fixed widths for the various columns of data
portal[damage].width = 120
portal[attack].width = 70
portal[range].width = 260

~position everything horizontally, leaving a margin on both sides appropriately
portal[badstr].left = 5
perform portal[damage].alignedge[right,-5]
perform portal[name].alignrel[ltor,badstr,5]
perform portal[attack].alignrel[rtol,damage,-10]
perform portal[range].alignrel[rtol,attack,-10]

~if this is a ranged weapon, limit the name to the space up to the range details;
~otherwise, let the name extend over to the attack value
var limit as number
if (tagis[component.WeapRange] <> 0) then
  limit = portal[range].left
else
  limit = portal[attack].left
  endif

~limit the name to the extent determined above
if (portal[name].right > limit - 5) then
  portal[name].width = limit - portal[name].left - 5
  endif

~size the name to fit the available space
perform portal[name].sizetofit[36]
perform portal[name].autoheight
perform portal[name].centervert

~extend the dots from the right of the name across to the value on the right
if (portal[name].right > limit - 10) then
  portal[dots].visible = 0
else
  perform portal[dots].alignrel[ltor,name,5]
  portal[dots].width = limit - 5 - portal[dots].left
  endif

Line 1039: Replace the entire Position script with the new logic shown below.

~our height is the vertical extent of our portals
height = portal[name].height
if (issizing <> 0) then
  done
  endif

~size the name to fit the available space
portal[name].width = width
perform portal[name].sizetofit[36]
perform portal[name].autoheight
perform portal[name].centervert

Line 1173: Replace the code for calculating the validation report height with the new logic below.

perform portal[validate].autoheight
if (portal[validate].height > portal[validate].fontheight * maxlines) then
  portal[validate].lineheight = maxlines
  endif

Numerous Places: Changes references to the "global" target reference over to "scenevalue". The list of locations is given below.

  • Line 1208
  • Line 1229
  • Line 1315
  • Line 1349
  • Line 1442
  • Line 1446
  • Line 1464
  • Line 1479
  • Line 1480
  • Line 1490

File: "sheet_standard2.dat"

Line 70: Changes reference to the "global" target reference over to "scenevalue".

File: "summ_armory.dat"

Line 76: Replace the "name" portal with the new element shown below.

<portal
  id="name"
  style="lblSummary">
  <label>
    <labeltext><![CDATA[
      if (field[grIsEquip].value <> 0) then
        @text = "{b}{i}"
        endif
      @text &= field[name].text
      ]]></labeltext>
    </label>
  <mouseinfo/>
  </portal>

Line 118: Replace the "name" portal with the new element shown below.

<portal
  id="name"
  style="lblSummary">
  <label>
    <labeltext><![CDATA[
      if (field[grIsEquip].value <> 0) then
        @text = "{b}{i}"
        endif
      @text &= field[name].text
      ]]></labeltext>
    </label>
  <mouseinfo/>
  </portal>

File: "tab_armory.dat"

Line 86: Change the component referenced from "WeapRange" to "Gear".

Line 265: Insert the "isbuiltin" attribute with a value of "yes".

Line 277: Insert the "isbuiltin" attribute with a value of "yes".

Line 319: Insert the "isbuiltin" attribute with a value of "yes".

Line 519: Insert the "isbuiltin" attribute with a value of "yes".

Line 531: Insert the "isbuiltin" attribute with a value of "yes".

File: "tab_gear.dat"

Line 122: Change the style from "lblNormal" to "lblLeft".

Line 143: Insert the "isbuiltin" attribute with a value of "yes".

Line 155: Insert the "isbuiltin" attribute with a value of "yes".

Line 198: Replace the entire Position script with the new logic shown below.

~set up our height based on our tallest portal
height = portal[info].height

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

~determine whether the container and heldby indicators should be visible
portal[container].visible = tagis[thing.holder?]
portal[heldby].visible = isgearheld

~center the portals vertically
perform portal[info].centervert
perform portal[name].centervert
perform portal[username].centervert
perform portal[gearmanage].centervert
perform portal[delete].centervert
perform portal[container].centervert
perform portal[heldby].centervert

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

~position the info portal to the left of the delete button
perform portal[info].alignrel[rtol,delete,-8]

~position the gear portal to the left of the info button
perform portal[gearmanage].alignrel[rtol,info,-8]

~calculate the space to reserve for the various indicators
var reserve as number
if (portal[heldby].visible <> 0) then
  reserve += portal[heldby].width + 2
  endif
if (portal[container].visible <> 0) then
  reserve += portal[container].width + 2
  endif
if (portal[heldby].visible + portal[container].visible <> 0) then
  reserve += 3
  endif

~position the name on the left and let it use all available space
var limit as number
limit = portal[gearmanage].left - 8 - reserve
portal[name].left = 0
portal[name].width = minimum(portal[name].width,limit)

~if this is a "custom" gear pick, show an edit portal instead of the name
var nextleft as number
if (tagis[Equipment.CustomGear] <> 0) then
  portal[name].visible = 0
  portal[username].left = portal[name].left
  portal[username].width = minimum(200,limit)
  nextleft = portal[username].right
else
  portal[username].visible = 0
  nextleft = portal[name].right
  endif
nextleft += 5

~show the 'container' icon to the right of the name (if visible)
if (portal[container].visible <> 0) then
  portal[container].left = nextleft
  nextleft = portal[container].right + 2
  endif

~show the 'held by' icon to the right of the container icon (if visible)
if (portal[heldby].visible <> 0) then
  portal[heldby].left = nextleft
  endif

~if the gear can't be deleted (i.e. it's been auto-added instead of user-added,
~set the style to indicate that behavior to the user
if (candelete = 0) then
  perform portal[name].setstyle[lblAuto]
  endif

File: "tab_journal.dat"

Line 98: Replace the line of code that references the usage pool to the new line shown below.

@text &= "{horz 40} Total XP: " & #resmax[resXP]

File: "thing_abilities.dat"

Line 23: Insert the following material within the "abSample" ability.

<!-- If checkbox selection is needed, make sure the compset includes "UserSelect"
      component and define this field appropriately.
<fieldval field="usrChkText" value="Menu1"/>
-->

<!-- If thing-based menu selection is needed, make sure the compset includes
      "UserSelect" component and define these fields and tags as appropriate.
<fieldval field="usrLabel1" value="Menu1"/>
<fieldval field="usrCandid1" value="component.Attribute"/>
<fieldval field="usrLabel2" value="Menu2"/>
<fieldval field="usrCandid2" value="component.Skill"/>
<tag group="ChooseSrc1" tag="Hero"/>
<tag group="ChooseSrc2" tag="Thing"/>
-->

<!-- If array-based menu selection is needed, make sure the compset includes
      "UserSelect" component and define these fields as appropriate.
<fieldval field="usrLabelAr" value="Menu1"/>
<arrayval field="usrArray" index="0" value="Choice #1"/>
<arrayval field="usrArray" index="1" value="Choice #2"/>
<arrayval field="usrArray" index="2" value="Choice #3"/>
-->

File: "thing_armory.dat"

Line 18: Insert the following thing definition.

<!-- Natural armor is automatically equipped -->
<thing
  id="armNatural"
  name="Natural Armor"
  compset="Armor"
  description="Description goes here"
  isunique="yes"
  holdable="no">
  <fieldval field="defDefense" value="1"/>
  <tag group="Equipment" tag="Natural"/>
  <tag group="Equipment" tag="AutoEquip"/>
  </thing>

File: "thing_attributes.dat"

Line 18: Insert the following field value assignment.

<fieldval field="trtAbbrev" value="Sam"/>

Line 31: Insert the following field value assignment.

<fieldval field="trtAbbrev" value="Str"/>

File: "thing_skills.dat"

Line 18: Insert the following field value assignment.

<fieldval field="trtAbbrev" value="Sam"/>

Line 37: Insert the following field value assignment.

<fieldval field="trtAbbrev" value="Mel"/>

Line 50: Insert the following field value assignment.

<fieldval field="trtAbbrev" value="Sht"/>

File: "thing_traits.dat"

Line 38: Insert the following field value assignment.

<fieldval field="trtAbbrev" value="Hlth"/>

Line 60: Change the "Column1" tag reference to "Traits".

Line 77: Insert the following field value assignment.

<fieldval field="trtAbbrev" value="Def"/>

Line 96: Insert the following field value assignment.

<fieldval field="trtAbbrev" value="Powr"/>

Line 117: Change the "Column1" tag reference to "Traits".

Line 147: Change the "Column1" tag reference to "Traits".

File: "visual.dat"

Line 130: Insert the following code at the end of the Position script.

~center the name if requested
if (tagis[SimpleItem.CenterName] <> 0) then
  perform portal[name].centerhorz
  endif

~if this is an auto-added pick, change its font to indicate that fact
if (ispick + !candelete >= 2) then
  perform portal[name].setstyle[lblAuto]
  endif

Line 213: Insert the new template definition below.

<!-- UserSelect template
      Similar to SimpleItem, except that this template is only suitable for
      showing picks and the items can employ various mechanisms for customizing
      the contents of the pick in some way. This template can be used or readily
      adapted when you integrate the "UserSelect" component into a component set
      and want to let the user customize the pick contents. For more details,
      please refer to the "UserSelect" component.
-->
<template
  id="UserSelect"
  name="User Selection"
  compset="UserSelect"
  marginhorz="3"
  marginvert="2">

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

  <portal
    id="lblmenu1"
    style="lblSecond">
    <label
      field="usrLabel1">
      </label>
    </portal>

  <portal
    id="lblmenu2"
    style="lblSecond">
    <label
      field="usrLabel2">
      </label>
    </portal>

  <portal
    id="menu1"
    style="menuNormal">
    <menu_things
      field="usrChosen1"
      component="none"
      maxvisible="10"
      usepicksfield="usrSource1"
      candidatefield="usrCandid1">
      </menu_things>
    </portal>

  <portal
    id="menu2"
    style="menuNormal">
    <menu_things
      field="usrChosen2"
      component="none"
      maxvisible="10"
      usepicksfield="usrSource2"
      candidatefield="usrCandid2">
      </menu_things>
    </portal>

  <portal
    id="lblmenuar"
    style="lblSecond">
    <label
      field="usrLabelAr">
      </label>
    </portal>

  <portal
    id="menuarray"
    style="menuNormal">
    <menu_array
      field="usrSelect"
      array="usrArray"
      maxvisible="10">
      </menu_array>
    </portal>

  <portal
    id="checkbox"
    style="chkNormal">
    <checkbox
      field="usrIsCheck"
      dynamicfield="usrChkText">
      </checkbox>
    </portal>

  <portal
    id="info"
    style="actInfo">
    <action
      action="info">
      </action>
    <mouseinfo/>
    </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[info].height

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

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

    ~center the other portals vertically
    perform portal[name].centervert
    perform portal[delete].centervert
    perform portal[lblmenu1].centervert
    perform portal[menu1].centervert
    perform portal[lblmenu2].centervert
    perform portal[menu2].centervert
    perform portal[lblmenuar].centervert
    perform portal[menuarray].centervert
    perform portal[checkbox].centervert

    ~determine whether our portals are visible; we only show them if requested
    ~Note: Remember that a non-empty tagexpr field indicates menu selection is used.
    if (field[usrCandid1].isempty <> 0) then
      portal[lblmenu1].visible = 0
      portal[menu1].visible = 0
    elseif (field[usrLabel1].isempty <> 0) then
      portal[lblmenu1].visible = 0
      endif
    if (field[usrCandid2].isempty <> 0) then
      portal[lblmenu2].visible = 0
      portal[menu2].visible = 0
    elseif (field[usrLabel2].isempty <> 0) then
      portal[lblmenu2].visible = 0
      endif
    if (empty(field[usrArray].arraytext[0]) <> 0) then
      portal[lblmenuar].visible = 0
      portal[menuarray].visible = 0
    elseif (field[usrLabelAr].isempty <> 0) then
      portal[lblmenuar].visible = 0
      endif
    if (field[usrChkText].isempty <> 0) then
      portal[checkbox].visible = 0
      endif

    ~position the delete portal on the far right and the info portal next to it
    perform portal[delete].alignedge[right,0]
    perform portal[info].alignrel[rtol,delete,-8]

    ~determine our effective right edge, allowing for the buttons above
    var edge as number
    edge = portal[info].left - 10

    ~setup the default portal width and gap to be used between and around portals
    var defwidth as number
    var gap as number
    defwidth = 100
    gap = 10

    ~determine the minimum amount of space we need to reserve for our portals
    var reserve as number
    if (portal[checkbox].visible <> 0) then
      reserve = defwidth
    elseif (portal[menuarray].visible <> 0) then
      reserve = portal[lblmenuar].width * portal[lblmenuar].visible
      reserve += defwidth + gap
    elseif (portal[menu1].visible <> 0) then
      reserve = portal[lblmenu1].width * portal[lblmenu1].visible
      reserve += defwidth + gap
      reserve += portal[lblmenu2].width * portal[menu2].visible
      reserve += (defwidth + gap) * portal[menu2].visible
      endif

    ~position the name on the left, reserving our minimum space for any portals
    var x as number
    portal[name].left = 0
    portal[name].width = minimum(portal[name].width,edge - portal[name].left - reserve)
    x = portal[name].right + gap

    ~setup the maximum width for our some portals, regardless of space available
    var maxwidth as number
    maxwidth = 150

    ~if we have a checkbox, size and position it appropriately
    if (portal[checkbox].visible <> 0) then
      portal[checkbox].left = x

    ~if we have an array-based menu, size and position it appropriately
    elseif (portal[menuarray].visible <> 0) then
      if (portal[lblmenuar].visible <> 0) then
        portal[lblmenuar].left = x
        x = portal[lblmenuar].right + 4
        endif
      portal[menuarray].left = x
      portal[menuarray].width = maxwidth

    ~if we have one thing-based menu, size and position it appropriately
    elseif (portal[menu1].visible + portal[menu2].visible = 1) then
      if (portal[lblmenu1].visible <> 0) then
        portal[lblmenu1].left = x
        x = portal[lblmenu1].right + 4
        endif
      portal[menu1].left = x
      portal[menu1].width = minimum(edge - portal[menu1].left,maxwidth)

    ~if we have two thing-based menus, size and position them appropriately
    elseif (portal[menu1].visible <> 0) then
      if (portal[lblmenu1].visible <> 0) then
        portal[lblmenu1].left = x
        x = portal[lblmenu1].right + 4
        endif
      portal[menu1].left = x
      var extra as number
      extra = (portal[lblmenu2].width + 4) * portal[lblmenu2].visible
      var actual as number
      actual = (edge - portal[menu1].left - extra - gap) / 2
      portal[menu1].width = minimum(actual,maxwidth)
      portal[menu2].width = portal[menu1].width
      x = portal[menu1].right + gap
      if (portal[lblmenu2].visible <> 0) then
        portal[lblmenu2].left = x
        x = portal[lblmenu2].right + 4
        endif
      portal[menu2].left = x
      endif

    ~if a menu is visible, make sure it has a selection
    if (portal[menu1].visible <> 0) then
      if (field[usrChosen1].ischosen = 0) then
        perform portal[menu1].setstyle[menuError]
        endif
      endif
    if (portal[menu2].visible <> 0) then
      if (field[usrChosen2].ischosen = 0) then
        perform portal[menu2].setstyle[menuError]
        endif
      endif
    if (portal[menuarray].visible <> 0) then
      if (field[usrSelect].isempty <> 0) then
        perform portal[menuarray].setstyle[menuError]
        endif
      endif
    ]]></position>

  </template>