Gear and Load Limit (Savage)

From HLKitWiki
Revision as of 12:12, 18 December 2008 by Rob (talk | contribs)
(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)
Jump to navigationJump to search

Context: HL Kit … Authoring Examples … Savage Worlds Walk-Through 

Overview

All of the gear that characters carry is now in place, so it's an excellent time to re-visit something we didn't complete earlier. The character's load limit is directly influenced by the gear being carried, so we need to hook up that logic and then display it to the user appropriately.

Apply Gear Weights to Encumbrance

Every piece of gear that is carried by a character needs to appropriately apply its weight towards the encumbrance and load limit for that character. Both the encumbrance and load limit are managed via resources that we created earlier, so all we need to do is have every piece of gear subtract its weight from the encumbrance resource. Once that's done, it will automatically be accessed by the load limit resource. The Skeleton files provide an Eval script on the "Gear" component that will handle all of the details for us. All we need to do is modify that script so that it applies the weight to the proper target - the encumbrance resource.

Open the file "equipment.str" and locate the "Gear" component, then find the Eval script that accrues weights into the character. At the bottom of the script, there is a line that is commented out that accrues weight into a dummy resource. Remove the comment and then change the line of code to tally the gear weight into the "resEncumb" resource. All gear on the character should now be properly tracked against both the encumbrance and load limit.

Show Load Limit

We now need to show the encumbrance and load limit somewhere appropriate within HL. Probably the best place to show them would be on the "Basics" tab, beneath the table of attributes. Since we have two pieces of information already and there will likely be additional information that we'll want to display to the user, we'll create a new table portal. We'll also create a new separator beneath the attributes, placing our table beneath the separator and providing a very similar look to how things are handled in the righthand column of the "Basics" tab. All of this will take place within the file "tab_basics.dat".

Before we create a new table portal, we're going to need to identify the specific picks that should be shown within the table. This is most easily accomplished by defining a new tag that is specifically for this purpose. We'll add the tag to the "Helper" tag group and call it "Status", since all the information we'll show in this table is to convey status details about the character to the user. This new tag must be defined in the file "tags.1st".

Our new table portal should look almost the same as the existing "baCreation" table, so we start by copying that table. Then we can tweak the id to something unique, such as "baStatus". We can re-use the exact same template for showing the items in the new table as are used in the existing "baCreation" table, since all it really does is show the name and the "resShort" field of each resource in the table. Lastly, we change the tag expression in the "list" element to limit the items shown to those with the "Helper.Status" tag. This yields a new portal that should look similar to the one below.

<portal
  id="baStatus"
  style="tblInvis">
  <table_fixed
    component="Resource"
    template="baResource"
    sortset="explicit"
    scroller="no">
    <list>Helper.Status</list>
    </table_fixed>
  </portal> 

At this point, the new portal has been defined, but it has not yet been integrated into the layout. So we need to add both the portal and a new separator the layout. Once added, the new portal and template need to be properly sized, rendered, and positioned within the layout. The revisions to the "layout" element should end up looking very similar to those shown below.

<layout
  id="basics">
  <portalref portal="baAttrib" taborder="10"/>
  <portalref portal="baStatus" taborder="20"/>
  <portalref portal="baTrait" taborder="30"/>
  <portalref portal="baRank" taborder="40"/>
  <portalref portal="baCreation" taborder="50"/>
  <portalref reference="separator1" portal="Horizontal"/>
  <portalref reference="separator2" portal="Horizontal"/>
  <portalref reference="separator3" portal="Horizontal"/>
  <position><![CDATA[
    ~size and position the attributes table in the top left; we set the height to
    ~the full layout height, but the table will only use the space it needs
    portal[baAttrib].width = width / 2 - 5
    portal[baAttrib].left = 0
    portal[baAttrib].height = height 

    ~size and position the traits table in the upper right
    portal[baTrait].width = portal[baAttrib].width
    portal[baTrait].left = width - portal[baTrait].width
    portal[baTrait].height = height 

    ~set the separator widths
    portal[separator1].width = portal[baTrait].width - 50
    portal[separator2].width = portal[baTrait].width - 50
    portal[separator3].width = portal[baAttrib].width - 50

    ~position the first separator beneath the derived traits
    portal[separator1].top = portal[baTrait].bottom + 15
    portal[separator1].left = portal[baTrait].left + (portal[baTrait].width - portal[separator1].width) / 2

    ~size and position the rank details table beneath the first separator
    portal[baRank].width = portal[baTrait].width
    portal[baRank].left = portal[baTrait].left
    portal[baRank].top = portal[separator1].bottom + 15

    ~position the second separator beneath the rank details
    portal[separator2].top = portal[baRank].bottom + 15
    portal[separator2].left = portal[baRank].left + (portal[baRank].width - portal[separator2].width) / 2

    ~size and position the creation details table beneath the second separator
    portal[baCreation].width = portal[baTrait].width
    portal[baCreation].left = portal[baTrait].left
    portal[baCreation].top = portal[separator2].bottom + 15
    portal[baCreation].height = height - portal[baCreation].top

    ~position the third separator beneath the attributes
    portal[separator3].top = portal[baAttrib].bottom + 20
    portal[separator3].left = portal[baAttrib].left + (portal[baAttrib].width - portal[separator3].width) / 2

    ~size and position the status details table beneath the third separator
    portal[baStatus].width = portal[baAttrib].width
    portal[baStatus].left = portal[baAttrib].left
    portal[baStatus].top = portal[separator3].bottom + 15
    portal[baStatus].height = height - portal[baStatus].top
    ]]></position> 
  </layout> 

The final step in getting the encumbrance and load limit to appear is to locate the resource things and assign them the necessary tags. Open the file "thing_miscellaneous.dat" and you can find the two resources - the unique ids are "resEncumb" and "resLoadLim". We need to assign both things the "Helper.Status" tag so that they will be included in the table. Since the table uses an explicit sort order, we also need to assign one resource an "explicit.1" tag and the other an "explicit.2" tag, thereby specifying the order in which the resources will appear within the table portal.

Non-Standard Display

Both the encumbrance and load limit are showing up to the user now, but the information being shown is not very useful. For the encumbrance, we need to show the current weight being carried and the next load limit threshold, and we need to do it in a way that is intuitively obvious to the user. For the load limit, we should show the current load limit multiplier being utilized and any corresponding penalty that is being applied for exceeding the basic load limit. Ideally, we should also color-highlight the load limit information, putting it in yellow when any penalty is being applied and in red if the character has exceeded the standard limit for what can be carried. Our problem is that the table is hard-wired to show the "resShort" field for each resource, and there's no way to actually change that behavior.

The trick is that the "resShort" field is synthesized via an Eval script within the "Gear" component. We can override the contents generated by the component if we schedule our own script on the thing that runs after the one on the component. By taking a peek at the file "equipment.str", we can determine the timing of the component Eval script. So we define new Eval scripts on the two resources that we schedule to occur a little bit later in the evaluation process. When the scripts run on the picks, it will clobber whatever contents were generated for the "resShort" field by the component. Our new Eval script for the "resEncumb" resource should look very close to the one below.

<eval index="2" phase="Render" priority="10000"><![CDATA[
  ~show the total weight carried and the maximum for the current load level
  field[resShort].text = field[resSpent].value & " / " & field[resMax].value
  ]]></eval>

For the "resLoadLim" resource, the new Eval script entails a bit more logic, but it should end up looking similar to the one below.

<eval index="3" phase="Render" priority="10000"><![CDATA[
  ~start with our load limit multiple
  var short as string
  short = field[resMax].value

  ~calculate how many multiples we've consumed
  var multiples as number
  multiples = 1
  if (field[resExtra].value >= field[resMax].value) then
    multiples += round(field[resExtra].value / field[resMax].value,0,-1)
    endif

  ~append the number of multiples carried
  short &= "x" & multiples

  ~append any adjustment incurred for overrage
  if (multiples > 1) then
    var overage as number
    overage = multiples - 1
    short &= " (-" & overage & ")"
    endif

  ~color highlight based on the severity of our overage
  if (multiples > 4) then
    short = "{text ff0000}" & short
  elseif (multiples > 1) then
    short = "{text ffff00}" & short
    endif

  ~put the result into the field
  field[resShort].text = short
  ]]></eval>