Weird Science Gizmos (Savage)

From HLKitWiki
Revision as of 16:50, 23 January 2009 by Rob (Talk | contribs)

Jump to: navigation, search

Context: HL KitAuthoring Examples … Savage Worlds Walk-Through 

Overview

We're going to dedicate a full section to this topic. The actual changes are not complex, but there are a variety of issues that need to be considered. This results in a series of steps that we'll address one at a time.

How Gizmos Differ

Gizmos are a special variety of arcane power. In addition to the power itself, gizmos need to be controlled. In general, the use of a gizmo entails use of the "Weird Science" skill. However, a "ray gun" gizmo might use the "Shooting" skill instead. We need to track the associated skill for each gizmo and allow the user to specify that skill.

Gizmos are devices, so they each have their own pool of power points. This pool needs to be tracked independently for each gizmo. That means we need to integrate the proper handling for trackers into gizmos and display them on the "In-Play" tab so that user can manage them.

The final wrinkle with gizmos is that they can be shared. This means that a character with no arcane background can possess a gizmo. We therefore have to allow all characters to possess gizmos, and gizmos from other characters must allow the player to specify the number of power points available to each gizmo. We even have to handle the case where a weird scientist has both his own gizmos and gizmos created by others.

Differentiating a Gizmo

The first thing we need to resolve is how we're going to differentiate a gizmo from a normal power. One option would be to handle gizmos and powers much like we do weapons. We could define a new "base" component that has all the common behaviors of the two, then have separate "Power" and "Gizmo" components with the distinct behaviors. This would entail adding a new component set for gizmos as well. While this approach would definitely work, it's a non-trivial amount of work, so we should only go that route if it's truly necessary.

Gizmos are a proper superset of powers (i.e. they add behaviors but don't change any behaviors). In addition, there are only two pieces of new information that need to be tracked for powers. This means that the various new components we're considering would each be relatively small. An easier solution might be to just add the gizmo behaviors to the "Power" component and then use a tag to indicate whether a power is actually a gizmo. Since the changes we need to make aren't very complicated, using a tag ought to be more than adequate, so we'll give this approach a try.

We're actually going to have two different types of gizmos when we're finished. We need to identify gizmos in general, which can be handled via one tag. We also need to differentiate between gizmos created by the character and gizmos borrowed from another character. We'll refer to borrowed gizmos as "foreign" gizmos, and we can handle this distinction via a second tag. For simplicity, we'll just define these tags within the "Helper" tag group, and the new tags should look like below.

<value id="Foreign"/>
<value id="Gizmo"/>

We'll worry about how and when to assign these tags in the next section.

Managing Shared Gizmos

Gizmos that are shared need to be managed appropriately by the user. We currently only show the "Arcane" tab when a character has an arcane background, but we could always change that behavior. If we always showed the "Arcane" tab, then shared gizmos could be handled on it. The problem with this approach is that shared gizmos are more generally perceived as "gear" - instead of arcane powers by - by characters that are using them. As such, it would probably be better if we added shared gizmos to the "Gear" tab.

Our first task is to decide how we're going to handle shared gizmos on the separate tab. We can easily share the same template for displaying shared gizmos and powers. The question is whether we can also share the same table portal. Unfortunately, we can't. The two tables need to show different collections of powers/gizmos, so we need to use a different List tag expression on each. The existing table portal on the "Arcane" tab needs to show powers that do not possess the "Helper.Foreign" tag, which the table on the "Gear" tab only shows powers that do possess the tag. We also want to change the various text displayed for the header, adding an item, etc.

We can modify the "apPowers" table portal on the "Arcane" tab to have a suitable List tag expression, yielding the portal shown below.

<portal
  id="apPowers"
  style="tblNormal">
  <table_dynamic
    component="Power"
    showtemplate="apPower"
    choosetemplate="SimpleItem"
    addpick="resPowers"
    descwidth="350">
    <list>!Helper.Foreign</list>
    <titlebar><![CDATA[
      @text = "Add an Arcane Power - " & hero.child[resPowers].field[resSummary].text
      ]]></titlebar>
    <description/>
    <headertitle><![CDATA[
      @text = "Arcane Powers -  " & hero.child[resPowers].field[resSummary].text
      ]]></headertitle>
    <additem><![CDATA[
      ~get the color-highlighted "add" text
      @text = field[resAddItem].text
      ]]></additem>
    </table_dynamic>
  </portal>

For our new table portal on the "Gear" tab, we can start by copying the "apPowers" portal. We can then give it a new id, change the List tag expression to only include powers that possess the tag, and revise the various text shown via the scripts. However, there is one important question we haven't resolved yet. How do we get the "Helper.Foreign" tag to be assigned to items added via our new table?

The answer to this is the "autotag" element. Table portals can assign tags to each pick that they add to the hero. The assigned tags behave as if they are part of the defined nature of the pick. Consequently, by specifying an "autotag" element that assigns the "Helper.Foreign" tag, all picks added by the new table possess the tag, while all picks added by the original table on the "Arcane" tab do not.

Putting all this together results in the following new table portal being defined.


<portal

 id="grGizmos"
 style="tblNormal">
 <table_dynamic
   component="Power"
   showtemplate="apPower"
   choosetemplate="SimpleItem"
   descwidth="350">
   <list>Helper.Foreign</list>
   <candidate/>
   <autotag group="Helper" tag="Foreign"/>
   <titlebar><![CDATA[
     @text = "Add a Borrowed Weird Science Gizmo"
     ]]></titlebar>
   <description/>
   <headertitle><![CDATA[
     @text = "Borrowed Weird Science Gizmos"
     ]]></headertitle>
   <additem><![CDATA[
     @text = "Add a Borrowed Weird Science Gizmo"
     ]]></additem>
   </table_dynamic>
 </portal>

The final thing we need to do is integrate our new table portal into the layout. The layout for gear currently contains all the gear and any vehicles. We'll insert the shared gizmos between the two tables. We can use the same approach as is already used for the vehicles, reserving space for a single item in the table. This way, we can easily integrate the new portal and dedicate the majority of space on the table to normal gear. If there is space left over, we'll allocate it first to additional shared gizmos and lastly to additional vehicles. The revised layout should look like the one below.

<layout
  id="gear">
  <portalref portal="grGear" taborder="10"/>
  <portalref portal="grGizmos" taborder="20"/>
  <portalref portal="grVehicle" taborder="30"/>

  <!-- This script sizes and positions the layout and its child visual elements. -->
  <position><![CDATA[
    ~set all tables to span the full width of the layout
    portal[grGear].width = width
    portal[grGizmos].width = width
    portal[grVehicle].width = width

    ~position the vehicles table at the bottom with a minimum height of 2 items
    portal[grVehicle].maxrows = 2
    portal[grVehicle].top = height - portal[grVehicle].height

    ~position the gizmos table above the vehicles table with a minimum of 1 item
    portal[grGizmos].maxrows = 1
    portal[grGizmos].top = portal[grVehicle].top - portal[grGizmos].height

    ~position and size the gear table to fill all remaining space
    portal[grGear].top = 0
    portal[grGear].height = portal[grGizmos].top - 10

    ~position and size the gizmos and vehicle tables to use the remaining space
    ~at the bottom
    portal[grGizmos].top = portal[grGear].bottom + 10
    portal[grGizmos].height = portal[grVehicle].top - portal[grGizmos].top
    portal[grVehicle].top = portal[grGizmos].bottom + 10
    portal[grVehicle].height = height - portal[grVehicle].top
    ]]></position>

  </layout>

If we reload the data files and give

Adding the Fields

Revising the Template

Tracking Power Points

Validation

-define and assign "Gizmo" tag via script -create new tab panel that shares the template -differentiate shared gizmo via "Foreign" tag -new table portal only shows foreign gizmos and old one only shows native gizmos -add new portal to layout -add fields for linked skill and power points -add Tracker component to Power compset -add portals to template for specifying skill and power points -determine whether menu and edit portals are visible - impacts height of template -position menu and edit portals -add tag to reset trackers to maximum -add script to setup power points -hide non-gizmos from list of trackers on in-play tab -verify gizmos have linked skill assigned -verify foreign gizmos have non-zero power points assigned -highlight menu in red if no selection is chosen