FreeMarker Facet Output

From PCGen Wiki
Revision as of 00:12, 14 January 2015 by Tom Parker (talk | contribs)
Jump to: navigation, search


Purpose

This page describes the output available with FreeMarker variables. This replaces both the existing output tokens as well as providing the only access to variables that are visible to output due to the FACT Token and FACTSET Token.

Available Facets

Single Item Facets

  • DeityFacet: "pc.deity"
  • RaceFacet: "pc.race"
  • AlignmentFacet: "pc.alignment"
  • SizeFacet: "pc.sizeadjustment"

List/Sequence Facets

  • EquipmentFacet: "pc.equipment.all"
  • EquippedEquipmentFacet: "pc.equipment.equipped"
  • KitFacet: "pc.kits"
  • CheckFacet: "pc.checks"
  • ClassFacet: "pc.classes"
  • CompanionModFacet: "pc.companionmods"
  • DomainFacet: "pc.domains"
  • LanguageFacet: "pc.languages"
  • SkillFacet: "pc.skills"
  • StatFacet: "pc.stats"
  • TemplateFacet: "pc.templates"
  • WeaponProfModelFacet: "pc.weaponprofs"

Use in practice

Items

When a single item is called in FreeMarker, it is used as such (this assumes an XML output):

<deity>${pc.deity}</deity>

The "pc." provides context to the Player Character, since there are potentially other sources of information (e.g. about the game mode or the loaded data)

When dealing with individual items (like a Deity), the default is to produce the display name of the item. (not OUTPUTNAME, the Display Name, which is the name used as the first entry on the line in the LST file)

When other parameters of the item are desired, those are added to the end of the entry. For example, if symbol is a FACT on Deity, and it is VISIBLE to output, then you could use

<symbol>${pc.deity.symbol}<symbol>

Lists

When a list is called in FreeMarker is it important to treat it as a list. We distinguish those by using a plural keyword to fetch the items (such as "pc.checks"). In the case of a list, you generally want to increment over the list:

<#list pc.checks as check>
    <saving_throw>${check}</saving_throw>
</#list>

A few things to recognize:

  • pc.checks has no ${} around the item. This is because the "#list" already puts the system into a "state of mind" where FreeMarker understands it is dealing with FreeMarker variables and not plain text. Therefore, the ${} is redundant (will cause an error)
  • The #list function assigns a new variable, available within the list (in the example above, "check") that can then be treated just like other objects. Therefore, if there was an "MainStat" FACT on a PCCheck, you could do this:
<#list pc.checks as check>
  <saving_throw>  
    <ability>${check.mainstat}</ability>
  </saving_throw>
</#list>

If you need to increment across a list of objects while maintaining backwards compatibility to the old output tokens, you can use an assignment of a temporary variable (with a Hat Tip to Andrew W)

<#assign checknum = -1 />
<#list pc.checks as check>
  <#assign checknum = checknum + 1 />
  <saving_throw>  
    <ability>${check.mainstat}</ability>
    <total>${pcstring('CHECK.${checknum}.TOTAL')}</total>
  </saving_throw>
</#list>

Abilities

Abilities are unique in that they are not directly stored in PCGen. They have other characteristics (specifically, Nature, Pool, and the CHOOSE Selection)

In order to appropriately output these items, the pc.abilities list does not contain the Ability itself. Internally to the code, we are storing a combination of 4 things: Pool, Nature, Ability, Selection

  • Pool is the AbilityCategory used to select the item (may be Fighter Feat, so this is NOT the Category of the item in the LST file)
  • Nature is Virtual, Automatic, Normal
  • Ability is the Ability itself
  • Selection is the result of a CHOOSE

This "bundle" of 4 items is called a CNAbilitySelection.

We could increment across those, but you increment across the "block of 4" all at once. So we get something like:

<#list pc.abilities as cnas>

 <#if cnas.nature == "Virtual">
   <name>${cnas.ability.name}</name>
   <description>${cnas.ability.desc}</name>
 </#if>

</#list>

The problem is that if you had, say, Dodge twice, you'd end up with the description twice. Probably not what was intended, so you will need to account for that in how things are written to the output file. This probably deserves some macros to develop this out appropriately.