Author Archives: Armin

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.

I got yer bits right here

Addressed an element name case-matching error related to ‘launchcodes.xsd’ tripping an XML error message.

When GCA saves backup copies of open characters, it now saves current program settings as well.

In the Launch PDFs window, adjusted the base system folder used when browsing for the home PDF bin.

Added support for the ItemNotes system:

* Public Function ItemNotesModeCount() As Integer

Returns the number of modes represented in the ItemNotes

* Public Function ItemNotes(Mode As Integer) As Collection

Returns a Collection containing all the ItemNotes for a given mode. Collection will be empty if no notes are found. If Mode is < 1, data for first Mode is returned. If Mode is > Mode count, data for last found Mode is returned.

* Public Function ItemNotesModeCollections() As Collection

Represents a Collection of Modes, each Mode item containing a Collection of ItemNotes. (You have a collection of Modes, with count = ItemNotesModeCount(); each collection item contains a collection of item notes as per ItemNotes(Mode as Integer) as Collection.)

* Public Function ItemNotesText(Mode As Integer, Optional ByVal Sep As String = ” • “) As String

Returns all the ItemNotes for a given mode as a single string, separated by Sep. (Default Sep is a bullet.)

Updated some of the things in the Protection system:

* Layers

If using User Managed Layers, the markers used to designate correspondence between armor items and layer values have been changed to use capital letters instead of the various footnote symbols. Within the location’s DR/DB value strings, the letters will be within brackets. This system appears much more readable and much easier to cross-reference.

* Deflect and Fortify stacking

The way Deflect and Fortify stacking issues are flagged has changed. If using User Managed Layers, then the layer that has had its Deflect or Fortify value ignored due to stacking will have a lower case ‘s’ appended to the Layer marker within the brackets. If not using User Managed Layers, then the ‘s’ marker just appears in brackets after the value string.

If there are Deflect or Fortify stacking issues at a location, a ‘-s’ marker is appended to the layers ‘L’ marker in the location box title.

* Other

Updated the values displayed in the Layers listbox of the Layers panel of the Protection window.

Updated the Protection box in Compact View to include a list of the applied armor. Clicking on an armor item will now highlight in gold all affected location boxes on the paper-doll. Conversely, clicking on a location box will highlight the armor items that affect it.

Updated the drawing of thee Protection box to reduce flashing during self-contained redraws.

Updated the default display order of the boxes in Compact View: Protection now comes directly after Equipment and before Melee Attacks; Messages is moved to the end.

In the Options dialog, the active character in GCA should now be the initial character active on the Current Character Options tab.

Updated ColorBlockSheet character sheet to include a listing of the applied armor and shields for the current loadout in the Protection block.

Updated code in a bunch of places to make use of newer systems and references, and to correct some hidden bugs resulting from bad references.

Updated some menu item handling.

Updated the Random Character system, and added support for it to the ChoiceList dialog and some of the message dialogs. The system will now allow for creating multiple random characters from the selected character template, or simply applying the randomized character template to the current character.

Updated Options for the hide/unhide of the explainer on the Random Character dialog.

I have changed the IDKey generation in GCA5 to be sourced from the System, rather than independently per character. The character still saves the last key it was issued, and this serves as a floor for future key requests in case a situation should arise where the System last key is lost. The new System key floor starts at 10,000 and increments from there–unless given a floor above the current last key, in which case the new key jumps to floor+1. This new system should ensure that all IDKeys are unique for all traits across all characters across an installation of GCA5 — assuming that no existing characters already had keys over 10,000.

IMPORTANT: I was going to do something a bit more complex for the new IDKey generation, and therefore had changed the IDKey to use Long values instead of Integer values. Changing to Long values required touching a lot of places in the code, and some may have been missed. If you encounter an overflow error, or a math exception, please let me know! This is very unlikely to be noticed until the auto-incrementing actually reaches the limits of Integer values.

Just a few little bits

Updated some of the menu icons.

Added a Traits menu to the main menu bar, which allows access to the same features as the right-click menu in trait lists.

Added options and UI to allow the user to select and use a page number link color of their choice, and to underline the links if desired. The default color is blue. (Changed the data file ‘touches’ tracking info text to the purple color.)

Added support for various default PDF readers to the launchcodes.xml file, which will be available for selection in the Options dialog by clicking the ‘…’ button next to the ‘PDF reader’ text box. Selecting one of the options will replace the text in the related text boxes with the info from the selected option. Only has codes for Acrobat and Sumatra right now.

Trying out a new trait icon in the right-side icon column: eye glasses, to show that the trait is to be included on the GM sheet.

Added a couple additional small bits of info to the View Info text for character traits: “Include on GM Sheet” if the trait is so flagged; and “Component Of: X” if the trait is a component item. Both of these also currently have icons in the right-side icon column of trait lists, but icon precedence may prevent the icons from showing, or make them difficult to see.

Launched bits

Fixed an issue related to needs items in braces when auto-adding prereqs.

Added a ‘Copy from Default’ button to Current Character Options.

Added trap to exit a Random selection of traits in a Select dialog if too many tries has still failed to create a valid set of random selections.

In Select dialogs, you can now add traits that already exist on the character to the character list from the Available list. Such items in the Available list are marked with a green check mark. Note that the points already spent in the trait won’t count against the points needed in the dialog. (Doing this previously required using the existing() tag on a #newitem to reference a known existing trait that you wanted to make use of. That option still remains.) This should simplify some constructions in templates.

Added an “override requirements” checkbox to the Select dialog. This allows you to activate the OK button and move on with the template, even though you may not have satisfied the specified requirements.

Adjusted the layout of the Select dialog a little, allowing for dynamic resizing of the user instruction area, and added an Explainer panel.

Added the UI in Options for the hiding of the Explainer panel in the Select dialog.

Moved the page info higher up in the View Info text display.

Added code to allow double-clicking on a page reference in View Info to launch the associated PDF. If GCA has information about a PDF for the given page reference, the page info will be a purple color, and double-clicking will perform the launch. If the page number isn’t purple, it’s not a link, and double-clicking will only irritate you. Right now, all page info is in the “bookcodes.xml” file in the GCA install folder. It only has a couple test references, since I don’t have any idea what the default names are for the official PDFs.

Added code & UI to Options to allow the user to specify their PDF reader and necessary launch arguments. Default is for Acrobat.

Added code & UI for a dialog, accessible from the PDF Launching box in Options, to allow the user to set a base PDF bin, and to set specific files and offsets for the PDFs that match the various book references that GCA uses. Changes made here are saved to a user version of the “bookcodes.xml” file in the user’s Books bin.

Bits modifiers

Added code to allow the Sheets drop-down on the Sheet View and Print Preview dialog toolbars to stretch out more if there is room for it.

Added some functions to SortedTraitCollection.

Restored drag-n-drop to Sheet view.

Sheet View should now retain its view position as much as possible when adding or removing items from the character sheet.

Added initial support for a Substitutions system, which allows one trait to substitute for another when GCA is tracking down references. This means you could create a ‘Guns (Small)’ skill that substitutes for ‘Guns (Pistol)’, and then when a reference to ‘Guns (Pistol)’ is being sought by GCA, ‘Guns (Small)’ would be considered a valid return. You create a substitution table by using the subsfor() tag in the item that is intended to substitute for the others. For example, our ‘Guns (Small)’ item would include ‘subsfor(“SK:Guns (Pistol)”)’ in order to create the substitution table. Multiple entries can be submitted at once in subsfor() by separating them with commas. The trait type prefix code is required in the subsfor() definition. Implementation is currently limited, but should be working in most places, such as defaults and weapons tables. Note that the item that is the substitute also qualifies as an existing instance of anything for which it substitutes, so adding one of those items after the substitution table is created would be considered a duplicate by GCA, and will be refused by default.

If the CTRL button is held down when drag-n-dropping a system item into a Character list in Compact View or Classic View, or onto the sheet in Sheet View, GCA will now add that trait even if it is a duplicate of an existing trait.

Added initial support for tracking what files ‘touch’ system items as they’re created and modified by data files. This will allow data file authors or debuggers to click on a system item and see in the View Info pane how the item was affected by various data files. Currently supports trait creation, replacing of previous traits, automatic replacement or merging of duplicate tag data, cloning, mergetags, and replacetags. (The related option in Options must be On when the fastload files are built in order for the data to be available; GCA won’t bother to track it if the option is Off.)

Added UI for the data file ‘touch’ tracking system option to Options, and altered the title/text of the enclosing options block from Logging to Book Processing.

Added #CloneMod data file command. Works like #Clone, but clones a modifier. Unlike traits, modifiers don’t have an item type, so they’re unique within their groups, so #CloneMod requires specifying the group and the full name of the modifier, like so: #CloneMod “group:modifier name” as “group 2:modifier name 2”.

Added #MergeModTags and #ReplaceModTags data file commands. You must target them using a group and name as specified for #CloneMod, but otherwise work as you’d expect from #MergeTags and #ReplaceTags. (For example: #replacemodtags in “Burning Attack Enhancements:Partial Dice” with “cost(+1/+2),formula(%level * 5)” ) The ALL keyword is not supported.

Added #DeleteModsFromGroup data file command. This allows for deleting specific modifiers from existing data. Similar to #DeleteFromGroup in structure, you specify the Mod Group from which you’re deleting items, then a space, then all the modifiers from that group that you want to delete, in a comma separated list. Enclose the mod group name in quotes, and enclose any modifier names that contain commas inside quotes as well. (For example: #DeleteModsFromGroup “Burning Attack Enhancements” Partial Dice, “Partial Dice, Per Die” )

Added #DeleteModGroup data file command. This allows deleting an entire group and all its modifiers at once. Specify the mod group name to remove, and its all removed. (For example: #DeleteModGroup “Burning Attack Limitations”)

Updated OfficialCharacterSheet to correctly reduce the component name column widths by the component indent level when printing traits.

Rebuilt plugins.