Category Archives: Build Notes

Excerpts from the change log and other notes related to new builds.

More exported bits

Moved calculation of charparry() up in the order of calculations for secondary characteristics, because it, too, is used in the calculation of some values in the routine that does charskillused, charskillscore, and charparryscore.

Added another special case check for trickle-through issues related to failing to meet minimum ST for a weapon.

Fleshed out the SimpleTextExport output.

Updated GCA5.Interfaces again: updated the RequestRunSpecificOptions event of IExportSheet; added the DialogOptions_RequestedOptions class. Shouldn’t affect print sheets.

Updated GCA5 to handle RequestRunSpecificOptions event handling for export plugins.

Added a form to display and process the selection of RunSpecificOptions by users.

Updated SimpleTextExport to raise the RequestRunSpecificOptions event if the user requests it in Options. (My current implementation would probably be better served with a simple message box, but I hope that it shows that much more sophisticated options could be requested, such as providing a character list and having only the selected characters exported.) Plus, added some more options for output handling.

Plug in these bits

Adjusted quick pick dialog a tiny bit.

Changed the GCA5.Interfaces structure as I broaden the plugin support. This necessitated creating a basic, minimal interface for the shared plugin features, and having the other interfaces inherit it. You will need to recompile any plugins you have, but you shouldn’t need to change anything else.

Added IBasicPlugin and IExportSheet to GCA5.Interfaces.

Created the SimpleTextExport plugin, which, as the name suggests, exports characters to a text file. This is still a work in progress, but does export stuff.

Added an Export… option to the File menu.

Added the Select Export Sheet dialog, which is what comes up when you select Export… from the File menu. This dialog allows you to select the Export Sheet you want to use for exporting purposes, and allows you to proceed through the export process if a sheet is selected.

Adjusted how GCA tracks plugins and Print Sheets, given that there are now more types of plugins and the other types are not suitable for printing/previewing.

NOTE: Export Sheets are not automatically compatible with Print Sheets, as they were for GCA4. This is due to the fact that the system now used by the print engine does an absolutely abysmal job of converting to other types of data, most of which is absolutely useless (PDF is okay, and is currently supported from Print Preview). Therefore, there’s no good way to translate the printer output to other output types automatically any more.

All included plugins have been recompiled due to interface changes.

Some fancy bits

Implemented a work-around for redrawing the Character lists correctly in Classic View when wrapping is used and the form is resized to change the widths of the lists.

Fixed a drawing bug in displaying traits in most character lists when there isn’t actually room to display the trait name.

Added support for saving traits to a data file from the Edit and Advanced Edit dialogs. Templates and meta-traits are not supported, and parents will not save children.

Added a Save to File… button to the Edit dialog for traits.

Added a Save to File… button to the Advanced Edit dialog. You can save Modifiers as well.

To address some issues, I have rebuilt/rearranged some things on the Advanced Edit dialogs, and altered how some of the features worked. While doing that, I added some icons to the Add Tag and Remove Tag buttons, and relocated all the grid-oriented buttons to a new row just under the grid. (To be specific, those buttons are now a part of the per-item grid control, rather than part of the overall form itself.)

Compact View trait lists now support multi-line (text wrapped) trait lines. Updated Options text to reflect this change.

Removed some calls that printed things to the splash dialog, as they were redundant with the Working dialog that appears anyway.

Simplified a bit of the ConfigEngine and GCASystem inter-relationship, to simplify handling, to promote more modularity, and to allow for better handling of multiple possible GCASystem objects.

With the change to GCASystem, GCA now just creates a new GCASystem for the Build Campaign Book dialog, which ensures that even when using the same Library as might be loaded in GCA already, any changes will be made to a different copy. This means it can now use the standard FastLoad files, if available for the starting Library, without having to load everything from scratch.

Fixed a problem around since GCA4, where bonuses to Block or Parry (as in Enhanced Block or Enhanced Parry) did not correctly spark a recalc/update of traits that had blockat() or parryat() values.

I have added support for “user targetable” bonuses, which will allow the user to choose the targets to which the bonus is meant to apply. Items that grant this new type of bonus will use %chosentarget% as the Target part of the bonus, such as gives(+1 to %chosentarget%). GCA will manage the new chosentargets() tag, which will keep the names of the target items, and provide a UI for it through the use of a new button on the Edit Traits dialog, which will pop up a pick list from which they can choose target items. When bonuses are generated by the trait, GCA will create one bonus for each target, in each case replacing the %chosentarget% with the name of the target item.

File authors can limit the available targets presented to the user by using the targetlistincludes() tag on the item, which includes one or more criteria for adding traits to the list, using a structure similar to that in the #BuildSelectList directive. It’s structured like this:

targetlistincludes( <Type> [ where <tag> [ is | isnot | includes | excludes | listincludes | listexcludes ] <tagvalue> ][, <etc.>] )

which allows for specifying just the list type in <Type> if that’s the only limit required. If more restriction is needed, see the docs for #BuildSelectList to see how the Where block works. Note: GCA will never include locked or hidden traits as valid targets. In addition, <Type> may be Any or All to specify selecting from all traits, not just one type.

As an example, instead of requiring users to add a Weapon Master Damage Bonus modifier to every weapon that gets the bonus, the bonus can be included with the Weapon Master advantage, and can use the new %chosentarget% target instead. The user can then select or modify the weapons that apply whenever they need to do so in the Edit window.

Here’s the modified version of Weapon Master:

Weapon Master (Targets), 20/25/30/35/40/45, levelnames(one specific weapon, two weapons normally used together, a small class of weapons, a medium class of weapons, a large class of weapons, all muscle powered weapons), page(B99), upto(6), cat(Mundane, Physical),
   x(_
      #InputToTagReplace("Please specify the weapon, weapons, or class of weapons you have Mastery of:", nameext, , "Weapon Master")_
   ),
   gives(_
         =+@if(_
               $modetag(charskillscore) = ST:DX+1 _
              THEN @textindexedvalue($modetag(dmg), ("thr", char::basethdice), ("sw", char::baseswdice), ELSE $solver(me::dmg)) _
               ELSE @if(_
                        $modetag(charskillscore) > ST:DX+1 _
                        THEN @textindexedvalue($modetag(dmg), ("thr", 2 * char::basethdice), ("sw", 2 * char::baseswdice), ELSE 2*$solver(me::dmg)) _
                        ELSE 0 _
                        )_
               ) to %chosentarget%::damage$ listas Weapon Master Damage Bonus _
      ),
   targetlistincludes(_
         Equipment where charreach isnot "", 
         Equipment where charrangemax isnot ""_
         )

Some nice bits

Added support for the SystemTrait only tag invisible(yes), which is a flag tag telling GCA that the item is ‘invisible’, and should never be shown to the user. Support for this is added with the understanding that it simplifies certain types of data constructs, allowing an ‘invisible’ trait to be added to the character by another trait, whereupon it will be visible, but presumably as a child trait, or perhaps otherwise linked to the adding item. For example, you could create Equipment versions of certain advantages by duplicating the advantages with “Gear” name extensions and zeroed costs, but make them invisible so they aren’t taken accidentally (or make invisible the current ones if they’re only available as gear in your game). Then you could make Equipment items that add those invisible traits to get the appropriate effects–the added traits are visible to the user as normal traits. (Note: GCA does not support this tag for attributes. Also note that categories for these traits are still considered valid, so a category filled with invisible items will appear like an empty category to the user, which may be confusing in some cases.)

Fixed bug in last build that allowed backup characters that were loaded after a crash to incorrectly be listed in the Recent Files list.

Fixed a bug introduced some time back in how certain GCA elements displayed child items that were of a different type than their parent items.

Fixed some outstanding issues with the Campaign Settings dialog, and with the display score builder feature for campaign TL.

Added missing support to undo changes to TL when canceling Campaign Settings dialog.

After the Campaign Settings dialog has closed, if the TL has been changed, GCA will now pop up a dialog to let you adjust the TL to match the new TL for any existing /TL traits the character has.

Added a ‘url’ tag to the bookcodes.xsd, to support linking to the SJGames page for the book. Updated bookcodes.xml with URLs for included books. Added ability to visit the URL given in bookcodes.xml from the PDFs dialog.

Added a flag and changed the loading of book codes slightly so that the new URL tag will flow through to the user’s data even if they have modified existing book code info (such as setting files for their PDFs). This will only apply for data saved to the user’s bookcodes.xml without a url tag; once saved with one, any future changes to the system url can’t flow through.

Also updated many book names in bookcodes.xml to match SJGames style, rather than the filename style I started with, but if you’ve made any changes to book data (such as setting files for your PDFs), you won’t see them changed in your PDFs dialog.

Updated a bunch of tag definitions in tagdefs.xml.

I have created a new child profile option that you can activate with a checkbox in Edit. This cannot be combined with the Alternative Abilities option, so turning on one automatically disables the other. The new option is: the parent item applies its Modifiers to child items. (It’s probably more appropriate to state it as all child items also use parent modifiers, but whatever.) When this is checked, each child item will apply the parent item’s cost Modifiers as if they were their own; they are applied in conjunction with any modifiers the child item has of its own. I think this will be called a Shared Modifiers Parent unless a better name comes up.

Trying out a second column of icons on the right side of character trait lists. This column has icons for parent items, and for certain types of child items, such as items that are children of an Alternative Abilities Parent or are children of a Shared Modifiers Parent.

A bit different

Added an Unspent entry to the points bar.

Added first draft of dialog for Party Log Entry, from the Party menu.

Added support for saving a Party list file from the Party menu. A Party file saves references to all the currently loaded characters in a GCA5party file, which allows you to load them all at once in the future by loading just that one GCA5party file.

Updated CampaignLog to allow fractional point values in log entries.

Reworked how a couple of my controls work to better handle scaling for the zoom modes.

Changed a couple icons in Options.

Added some icons to the Tools menu.

Added first draft of the Build Campaign Book window. This allows you to load a library, delete traits you don’t like, and then save the entire thing as a single book file (.GDF file), and to optionally save a campaign library (.GDS file) for it as well. This should help simplify building campaign specific files for sharing with players.

Updated library manager to delete FastLoad files when deleting the owning library.

When creating a new character using New, Choosing Library…, the Manage Your Library dialog is now properly set to allow you to double-click on a library to select it and close the window.

For quite a while, I’ve been intending to redo the system for loading character files, so that more of the logic would be handled entirely within the GCAEngine, where it really belongs. I have now done a big chunk of that, and have switched to the new system as of now for the standard handling. Along with this support, it’s now possible to load these additional file types: GCA4base, GCA5base, GCA4party, and GCA5party.

With the new file loading system, you can now load files as “Read Only”, which effectively means GCA won’t assign them a filename right away (usually it starts with the one it was loaded from). You will be required to use Save As… to save the file; but of course you can save over the old file if you wish, because that will not be prevented beyond the confirmation dialog that pops up.

When loading a GCA4 file, GCA5 will now automatically treat it as “Read Only”, as described above. This is a safety precaution to avoid accidentally overwriting older files with newer data that may not be completely compatible with GCA4.

A bit technical

 Added some more robust versions of a few simple workhorse routines, for more troublesome chores.

For some of the examples in this entry, we’ll be using the Self-Control Roll modifier defined in entry b 5.0.0.53, and for others we’ll be using these :

[MODIFIERS]
<Chronic Pain>
Interval, *0.5/*1/*1.5/*2, upto(4), downto(1), 
   shortname( #format $val(me::levelname) ),
   levelnames(1 hour, 2 hours, 4 hours, 8 hours), group(Chronic Pain), page(B126),
   displaynameformula( $val(me::name): $val(me::levelname) )

Frequency, *0.5/*1/*2/*3, upto(4), downto(1), group(Chronic Pain), page(B126), 
   shortname( #format $val(me::levelname) ),
   levelnames(6 or less, 9 or less, 12 or less, 15 or less),
   displaynameformula( $val(me::name): Attack occurs on a roll of $val(me::levelname) )

 GCA now supports specifying modifiers by reference in initmods(), so an entire modifier definition no longer needs to be included. The existing behavior is preserved, but now you can also specify a reference to a modifier instead, using the #ref directive and this format:

initmods(#ref <Modifier Name>[ = X] [FROM <Group Name>] )

The braces are optional if not needed to protect parsing on the = or FROM keywords, or the pipes separating various initmods() items. (If the modifier has a name extension, you do need to include it inside parens as part of Modifier Name, as per usual.)

The assignment is optional, but if used sets the initial level of the modifier.

The FROM <Group Name> section is optional if the modifier is also found in one of the defined mods() modifier groups, but required if not.

Do NOT include the #ref, FROM, or assignment within any braces around names. (You may include the entire statement inside quotes or braces to separate it from other modifier blocks within the initmods().)

Using the Self-Control Roll modifier example from entry 5.0.0.53 below, you can refer to it in an initmods() like this:

initmods(#ref Self-Control Roll = 2 FROM Self-Control)

which will look for it in the Modifiers group called Self-Control, and assign it at level 2 (12 or less).

In a trait, it might look like this:

[DISADVANTAGES]
<Mundane Mental>
Chronic Depression, -15, mods(Self-Control), page(B126), cat(Mundane, Mental),
   initmods( #ref Self-Control Roll = 2 )

Note that because the mods(Self-Control) tag exists in this item, GCA will find the modifier even though we don’t explicitly provide a group to look in.

You can mix with the full-definition method, too:

[DISADVANTAGES]
<Mundane Mental>
Chronic Depression, -15, mods(Self-Control), page(B126), cat(Mundane, Mental),
   initmods( #ref Self-Control Roll = 2 | _
             Mitigator: Meds, -60%, group(_General), page(B112), 
                mitigator(yes), shortname(w/Meds)_
   )

 GCA now supports specifying modifiers by reference using the new #ref directive in the With/And blocks of the adds() and creates() tags, instead of having to include full definitions. The existing behavior is preserved, but now you can also use this new format to reference existing modifiers:

adds(<Trait> _
   with "#ref <Modifier Name>[ = X] [FROM <Group Name>]" _
   and  "#ref <Modifier Name>[ = X] [FROM <Group Name>]" _
)

For example:

Chronic Depression 4, -15, mods(Self-Control), page(B126), cat(Mundane, Mental),
   adds(_
        DI:Chronic Pain=3 _
        with " #ref Interval=3 " _
        and  #ref Frequency _
   )

If the FROM block is left off, the mods() tag of the newly added trait will be used when searching for the specified modifiers. In the example above, Interval and Frequency will be found because Chronic Pain has those in its mods() tag.

 GCA now supports specifying modifiers using the new #ref directive in addmods(). The existing behavior is preserved, but now you can also use this new format:

addmods(#ref <Modifier Name>[ = X] [FROM <Group Name>] to <TargetTrait> )

This can also be mixed with the other valid addmods() references (“<ModGroup>:<ModName>” or “#newmod()”). For example:

addmods( ( "Chronic Pain:Interval", "#ref Frequency=2 from Chronic Pain" ) to "DI:Chronic Pain" )

The first reference is the existing format of <Group Name>:<Modifier Name>, and the second is the new format. Note also that the new reference format allows for specifying a level for leveled modifiers, while the old reference format does not.

Keep in mind that if you leave off the FROM portion in this usage, the mods() tag of the <TargetTrait> will be used to find the modifier. In our example above, we could have used “#ref Frequency=2” because Chronic Pain has the Chronic Pain mod group in its mods() tag.

Some crunchy bits

* Added a sort-of explainer tile to the top of the Default Character Options tab in Options.

* Added an option to allow multi-line/word-wrapped trait names in Classic View trait lists. (It is Off by default.)

* Updated the image for the Export PDF button in Print Preview.

* Fixed bug that prevented loading a character with a chosen library, if that library was already loaded by a character and any changes were made to the library books, requiring the library to be reloaded.

* Fixed a couple issues in the Find Traits dialog.

* Fixed crash if changing a sheet in Sheet View when no character is loaded.

* I’ve added support for a base() tag for advantage-type traits. If base() exists, GCA will calculate it, and add it on to the final level of the advantage as a ‘base value’ instead of the normal base value of 0.

* Adjusted the order for calculating secondary characteristics for traits (damage, reach, skill used, etc.) because calculating the skill used was being done after damage, when it should have been done before damage; certain bonuses (such as weapon master) are based on character skill. This fixed a problem with damage values for such instances being a step behind unless you did a recalc everything, and now they stay current.

* Messed about with the Explainers again. They’re now even easier for me to create and adjust, and I think they look more consistant with other elements across the program.

* Added a dialog for the character’s messages. This content already appears as a box in Compact View, but it’s now accessible as a dialog from the Character menu.

* Character messages are now saved with a character, so they’ll stick around unless dismissed.

* The color selections for the Compact View boxes as set in the Colors & Layout dialog should now be remembered.

* Modifiers now support downto() and displaynameformula().

* Modifiers now have access to a some additional values through TagItem(): levelname, shortlevelname, caption, levelcaption,  displayname, and basedisplayname. (Like Caption returns values using shortname(), LevelCaption returns values using shortlevelnames(); shortlevelname and levelcaption are aliases, and return the same value.)

* Modifiers now support a new directive, #format, within the shortname() tag, which tells it to format the output in a particular way–pretty much just like displaynameformula(), but obviously set up a tad differently. It is used like so: shortname( #format $val(me::levelname) ). #Format must be the first part of the tag value, and everything that follows is the format/formula to use. If you need spaces on one end or another, enclose the text after the #format directive in quotes or braces.

* These changes to modifiers mean that you can now define a modifier something like this:

<Self-Control>
Self-Control Roll, *0.5/*1/*1.5/*2, upto(4), downto(1), group(Self-Control), page(B121),
   shortname(#format $val(me::shortlevelname) ),
   levelnames("15 or less, almost all the time",
              "12 or less, quite often",
              "9 or less, fairly often",
              "6 or less, quite rarely"),
   shortlevelnames(15 or less,
                   12 or less,
                   9 or less,
                   6 or less),
displaynameformula( You resist on a roll of $val(me::levelname) )

(I set up this example in order of increasing costs, which is in decreasing order of Roll value. It could, of course, also be set up for the reverse order, instead.)

Inside GCA, the user sees “Self-Control Roll” in the Available Modifiers list; when added to the character they see “You resist on a roll of 15 or less, almost all the time” in the Applied Modifiers list; and for the caption within the item using this modifier, they see “15 or less, *0.5”. If the user then increments the modifier, the values change appopriately to the next levels.

Further, if you need some item to check for the existance of this modifier with @hasmod(), you can simply use @hasmod(Self-Control Roll), rather than needing to check for the name of each individual level, as is the case now with each level being a separate modifier.

* Made a small code adjustment to how the Edit dialog displays an item’s included modifiers.

* Added a warning to the log when a PDF can’t be launched because it wasn’t found.

* Added a safety check to ColorBlockSheet so it won’t try to print non-existant current loadout information.

* Updated OfficialCharacterSheet to add an option for the color of the ‘Included’ and ‘Conditional’ lines for bonuses.

Taste just a bit

GCA will now remember the trait type selections in the library lists of the Compact and Sheet Views between sessions.

Fixed bug in #DeleteByTag data file command.

Fixed bug in Edit dialog that didn’t save changes to Page.

Fixed bug in Edit dialog that displayed Show Modes checkbox when it shouldn’t.

Added an option in the Compact View display options to specify if you want the blocks to wrap or not (it is on by default). Turning wrapping off will result in all the blocks displaying linearly, which may be easier to view/reference for some folks when the primary scrolling is along just one axis.

Added an additional ‘bold link’ option to the PDF Launcher options.

Added an ‘Export PDF…’ button to Print Preview.

Apparently I changed the default footnote style when I updated the FootnoteManager. You should be sure to set the FootnoteStyle to the desired type after initializing the FootnoteManager.

Fixed ColorBlockSheet to address the issue with footnotes.

Updated ColorBlockSheet with some additional features and options.

Updated OfficialCharacterSheet to display the ‘Included’ and ‘Conditional’ lines for bonuses to traits in the various trait listings. Also added a sheet option to allow for setting a different font for these lines.

Take yer bits

Fixed some bugs in the new stuff for the Protection box in Compact View.

Protection box’s Copy to Clipboard option now copies the entire graphic area (except the buttons in the header).

The Protection box will now add a message between the paper doll and the armor list if the user has enabled Allow Deflect Stacking or Allow Fortify Stacking on the character.

Made attack modes a separately managed collection of objects within a trait. This has upsides and downsides, but obviously I feel the upsides outweigh the downsides. This means various places had to be updated or modified. For sheet authors, I tried to retain all previous methods of access as well as allowing for the new system. In addition to the old access methods, accessing mode data can now be handled through the ModeManager class that all traits now have (Modes as ModeManager), and individual mode data can be accessed through that or by getting a single mode as a Mode object.

Note: Because of the new Modes system, notes() and itemnotes() are explicitly mode enabled tags. This means a Mode will be created if a notes() or itemnotes() tag exists, even if no other mode data applies.

The ItemNotes system implemented last build no longer applies given the new Modes handling, so it has been removed. Equivalent functionality has been included in the Mode object.

Adjusted the Edit Trait dialog weapon mode displays; they now allow for setting DamageBasedOn individually within them, and will display ItemNotes() if present.

For the record, these are all the currently supported, GCA-handled Mode tags (also available from the ModeTags collection in GCACharacter):

  • “mode”, “notes”, “itemnotes”, “damageistext”, “minstbasedon”, “damagebasedon”, “lc”
  • “acc”, “armordivisor”, “break”, “damage”, “dmg”, “damtype”, “minst”, “parry”, “radius”, “rangehalfdam”, “rangemax”, “reach”, “rcl”, “rof”, “shots”, “skillused”
  • “characc”, “chararmordivisor”, “charbreak”, “chardamage”, “chardamtype”, “charminst”, “charparry”, “charradius”, “charrangehalfdam”, “charrangemax”, “charreach”, “charrcl”, “charrof”, “charshots”, “charskillused”, “charskillscore”, “charparryscore”

Adjusted calculation of charlocation() so that there will now always be a charlocation() tag if there was also a location() tag.

Added code to handle partial coverage for armor items, finally making use of the coverage() tag. This system will use charlocation() and coverage() to generate new charcoverage() and locationcoverage() tags, and to rebuild the charlocation() tag if it had mulitiple entries for the same body part. The system takes tags that might look like this: “location(Skull, Face, Face, Face),coverage(1, 1/6, 2/6, 1/6*)” and should end up with something that looks like this: “charlocation(Skull, Face),charcoverage(1, 4/6*),locationcoverage(Skull, Face (4/6*))”. For technical reasons, coverage() may have values that are empty or are some other whole value to represent full coverage; any partial coverage should be in the form of X/6.

I also created a correction routine to fix location() values that may have partial coverage values within them. For example, location(Skull, Face (1/6)), which aren’t valid within GCA itself, but are generated by some of the existing armor builder items. GCA will see and fix these so that they are correctly formatted location() items without the partial coverage values. If a coverage() tag already exists, the coverage values in location() are discarded; if no coverage() exists, GCA creates it from the values in the location() tag.

Updated the Protection dialog, Layers dialog, and the Protection box to show the new locationcoverage() value where applicable.

Touched a lot more places to update code and strengthen type references.

Updated the FootnoteManager to allow for Alpha footnote markers. Also allows for optionally enclosing the marker in parens, braces, or brackets when returning the FootnoteWithMarker() or FootnoteBlock(). This did change the interfaces a bit, so plugins will need to be recompiled.

  • Public Function FootnoteBlock(Optional ByVal Separator As String = vbCrLf, Optional ByVal MarkerEnclosure As FootnoteEnclosureStyle = FootnoteEnclosureStyle.None) As String
  • Public Function FootnoteWithMarker(ByVal Index As Integer, Optional ByVal MarkerEnclosure As FootnoteEnclosureStyle = FootnoteEnclosureStyle.None) As String

Updated ColorBlockSheet to use LocationCoverage() in the Protection section.