Gear and Load Limit (Savage)
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 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 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.pri", 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 runs on the things, 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 value="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 value="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>