Author Archives: Armin

Bits of verbosity

b82

* Miscellaneous

Added a bit of code to the MiserOptionsBlock control.

Rebuilt the category warnings on classic view (shows when categories between character and library don’t match) to avoid using a third-party control I no longer want to use.

Adjusted Updater to examine library data beyond simply *.gdf files.

Updated a bunch of the error messages in the GCALibrary object to be more standardized, and to provide line numbers for the lines causing problems during the loading and processing of data files. (Still more to do here.)

* Unified View

Rebuilt the newbie box in the Unified view (the green one that appears only when no characters are loaded) to avoid using a third-party control I no longer want to use.

Adjusted how the Unified view handles locking/disabling the display, so that the newbie box is readable even when the rest of the stuff is disabled.

* Data Files: #Verbose

I have added the command #Verbose to data files. This has only two options, On or Off, like so:

#Verbose On
#Verbose Off

This allows you to turn on VerboseBookProcessing for a specific file, or portion of a file, for testing purposes, without having to have full-on verbosity for every file you’re loading. (Technically, this sets a different property, and does not affect the user’s VerboseBookProcessing setting at all; if they have that turned on, this will have no impact on it at all, and they’ll get the verbosity they desire.)

It should be considered polite to remove these directives from files before they’re made publicly available, as many users will find verbose book processing quite annoying.

* Data Files: #IF

I have added limited support for #IF blocks in data files. The structure is like this:

#IF want = value [THEN]
[...]
[#ELSEIF want = value [THEN]]
[...]
[#ELSE]
[...]
#END[IF]

Notice that the [THEN] parts are optional; GCA will remove them, but they’re not necessary. Same with the IF in #ENDIF; GCA considers any #END to be the end of the current #IF structure.

You may nest #IF..#END blocks.

Note that there is *no* expression evaluator involved here. Support exists for a tiny set of very specific comparisons, which I’ll cover here. If you try anything else, GCA will consider the block FALSE and continue on, happily ignoring that section (and provide an error in the log if you have verbose book processing turned on).

The two types of ‘want = value’ comparisons currently supported are these:

1) fileloaded = “name of file”

This allows you to see if a file has been loaded before this one. The file currently being processed does *not* count. You must use the exact file name that GCA has loaded (ignoring path information, and ignoring case).

GCA supports the following aliases for ‘fileloaded’, so you may use whichever you remember: fileloaded, loadedfile, fileisloaded, loaded, bookloaded, bookisloaded.

“name of file” may be in quotes or braces.

and

2) traitloaded = “name of trait”

This allows you to see if a particular trait exists in the current library data. Anything loaded before this comparison is a possibly valid subject.

GCA supports the following aliases for ‘traitloaded’, so you may use whichever you remember: traitloaded, traitexists, traitpresent, loadedtrait.

“name of trait” may be in quotes or braces, and must be in the standard fully qualified format, with prefix and full name and extension, as applicable.

Bits of engines

b81

* Various

Added a routine to ConfigEngine.

Addressed an issue where opening the Build Campaign Book window would reset user folder assignments to default values.

GCA now supports displayname() for system traits in data files, similar in intent to the existing displaycost() and displayweight() tags. When displayname() exists, the value of the tag will be used instead of the standard return from the DisplayName property (usually Full Name/TL). This tag is removed from the data for the character’s version of the trait, where displaynameformula() can still be used if desired.

* SelectX dialog

I have added an option to randomize the current SelectX dialog, and all remaining selection dialogs for the template. I didn’t have a split button, so I built a quick-n-dirty one to handle this, which is/replaces the previous Random button. Clicking the menu part of the button should offer a menu to pick either the normal behavior or the finish-it-randomly behavior. Clicking the button with the keyboard should also activate the menu selection options.

* Plugins

I have hooked up a Plugin Manager, accessible from the Plugins option on the Tools menu. This will allow for disabling plugins that you don’t want to make use of, so that they won’t load in the future, or for re-enabling them so that they will.

(I wanted to include an option that would re-load/re-compile the plugin on every use, for testing and writing of plugins, but the needed changes to the plugin structure, and managing the apparently required app domains and such, is currently beyond me.)

NOTE: The disabling process, when loading plugins during subsequent GCA start-ups, assumes one plugin per folder, and disallows loading anything from a folder that contains a previously disabled plugin. This is to prevent loading it entirely, because otherwise the current system would load it into memory first, before discarding it.

Bits of confusion

b80

* Various

Added an options menu (gear icon) to the library panel (used in the Unified and Sheet views) in the title bar of the library pane. Right now, the only option is Reload Library, which will do that.

Also added a Reload This Library option to the Library button on the toolbar.

Hooked up and enabled the Modifiers and Edit buttons for the currently selected traits in the Select Items dialog.

Added a CollectionKey property to the Category object. Changed all calls in the program using a key for a category to use it.

When GCA can’t find one of the files in a specified library, the dialog it puts up to let the user specify the replacement file should now actually be a useful file browser.

* #ChoiceList

Expanded the number of altXlist() up to alt9list().

Added the new tag autoaccept() to the list of tags for #ChoiceList. If autoaccept() has any content, then GCA will simply accept the default values for the #ChoiceList without bothering to show the dialog to the user.

* Files

Finally incorporated into GCA 5 Changes.GDF the changes Emily made to various Damage Resistance modifiers to make them compliant with targeted locations for the DR.

Some bits compiled, some bits not

b79

* Various

Alt Attacks panel elements in Simple Edit should not be randomly visible at inappropriate times any longer.

Fixed @HasMod, @ItemHasMod, and @OwnerHasMod functions, so that they’ll look for modifiers that have name extensions using either the old “name (name ext)” format, or the newer “name, name ext” format that modifiers display with now.

Added FullNameOldStyle property to GCAModifier, which returns the full name of the modifier in the old style of “name (name ext)”.

When building the list of applicable symbol images for a trait, the trait should no longer allow the same symbol to be added more than once. (Allowing that to happen was an oversight.) This is based on the given symbol name, not the image used.

When looking for body images created by data files, if full path info isn’t given, GCA will now look for them in the user image bin first, before the system image bin.

SystemTraits now implement ITaggedObject.

* Flag Symbols

AKA those little icons marking supernatural, exotic, etc.

Greatly expanded support for how these can specify criteria, which required creating a new system to handle it. That should now be working.

The basic specification for symbols in data files is the same as it was:

name of symbol , image file , criteria

The criteria support has greatly improved. Where before criteria would be structured like this:

traittype where tag comparison tagvalue

such as

Ads where cat listincludes Mental

allowing only for a single comparison statement after the ‘where’ keyword, you can now specify as many comparisons as you need to be specific, even using and/or symbols and grouping parens if necessary. The TraitType declaration is fixed, however.

So, now you can expand everything after the ‘where’ keyword, so you could have that portion of the criteria be something like this, for example:

tag compare tagvalue | tag compare tagvalue , tag compare tagvalue , ( tag compare tagvalue | tag compare tagvalue )

Basically, it’s handled like Needs, where it’s designed to break apart criteria on OR markers first, so if you want to do a simple OR selection among a list of AND items, enclose them in parens as you’d do in a Needs.

In the pseudo-example above, GCA would see the example as two major OR blocks, either of which couuld be True for the symbol to be applied. They are:

tag compare tagvalue OR
tag compare tagvalue , tag compare tagvalue , ( tag compare tagvalue | tag compare tagvalue )

Notice that the second is much longer, and includes a sub-clause OR in parens.

You can also use & or + as the AND symbols, instead of just commas, in case you might prefer that. Sometimes that might be more clear. Unfortunately, the | is the only symbol for OR, and you can NOT use the words AND or OR instead of the symbols. So, the above example could also be written like this:

tag compare tagvalue | tag compare tagvalue & tag compare tagvalue & ( tag compare tagvalue | tag compare tagvalue )

In addition to the expanded structure in general, the comparisons that are allowed have been expanded as well, so you can now use any of the comparisons shown here:

tag { = | > | < | <> | >= | <= | is | isnot | includes | excludes | listincludes | listexcludes } tagvalue

Remember the usual rules, and enclose tagvalue in quotes or braces if it includes commas or spaces.

* Equipment

Addressed a crash-bug related to equipment costs and modifiers that use those costs to grant bonuses to other things.

Equipment items have a couple of new tags available, which might not be necessary, but seemed potentially useful:

* preformulacost() and preformulaweight() include the cost and weight of an item as calculated up to the point just before any given costformula() or weightformula() is evaluated.

* prechildrencost() and prechildrenweight() contain the cost and weight values for an item before any children are calculated and included into the cost and weight.

* postformulacost() and postformulaweight() contain the cost and weight values for an item after any existing formulas for those values may have been evaluated. Right now, this amounts to exactly the same values as prechildrencost() and prechildrenweight().

* Loadouts

Added two new functions to LoadOutManager:

Public Function UnassignedItems(OwnerChar As GCACharacter) As Collection
Public Function UnassignedItemsAsLoadout(OwnerChar As GCACharacter) As LoadOut

These do similar things, just the first returns a simple Collection containing all unassigned items and the second returns a basic LoadOut that contains all unassigned items (named “All unassigned items”), Note that the LoadOut returned in this case is not considered ‘owned’ by LoadOutManager, and is therefore not managed by it; you can’t use LoadOutManager functions to work with it, although you can of course use the functions of the LoadOut itself.

* Plugins

The first draft of support for ‘compilable’ plugins is now working. This will take a source code file, and compile an assembly from it in memory, from which it will then create an instance of the related plugin. This will allow for shipping a plugin as a source file (and an XML file that gives more info to the compiler), which can then be compiled on the user machine when loading plugins at startup. (NOTE: After testing of the release build, an exception gets thrown related to being unable to write the DLL, which is supposed to be in memory, so that’s odd. However, switching things to write the DLL to disk does appear to work, so that’s now being done; the DLL is saved in the appdata\plugins folder. It will still re-compile such plugins every time GCA starts.)

Compilation itself seems to go pretty quickly, so I don’t forsee a speed issue. It also appears to work fine on my non-administrator test account.

If things seem to work out with this in larger scale testing, I’m really hoping this will allow for shipping sheet plugins that don’t have to be recompiled every damn time I update the ComponentOne report engine that I use for printing.

An example of this is included in the installed GCA plugins folder, in the \testOfficialCharacterSheet\ folder. This has two source code files and a compile.xml file. If things are working, GCA will load these, compile them, and you’ll see an additional character sheet called “TESTING GURPS 4th Edition Official Character Sheet” available for use. It’s exactly the same as the standard official sheet, except for name (and version is 1.0.1.x) and how it was created. (Note that the source code has some additional Imports statements added at the top, because they seemed to be required to make things work during the process.)

The \testOfficialCharacterSheet\ sheet will be replaced as soon as possible with a more useful new sheet.

* Files

Incorporated the entirety of Eric’s GCA5 Symbols library into the \images\ folder. [Eric added to art credits.]

Included Eric’s GCA5 Symbols.GDF and the updated GCA5 Changes.GDF files into \books\.

Store bits, get bits, edit bits

b78

* Various

Set the Duplicate Card dialog to fixed borders.

Session files should no longer be getting inserted into the most-recently-used list.

Updated FastLoad structure to support inclusion of #Store values.

* Store and Get

Finished something started way back in b57: support for #Store and #Get().

#Store is a data file directive that allows storing text as a named block for use elsewhere in the Library, such as ‘#store warning=Don’t Do That!’. These are basically global variables on the Library level, rather than at the trait level, and in concept are similar to Lists, but store only a single item of text, rather than a group of related text items.

#Get allows you to retrieve #Store values.

Like with #Choice or other such directives, these are for use in building other library features, such as SelectX dialogs, or #Choice dialogs. You can use these to insert what will be character features, such as storing a formula that’s inserted into a trait, but remember that #Get is only processed when a trait is added to the character.

The #Store template looks like this:

#store VarName=text

The VarName should be simple, but if necessary (when it includes an = sign) it can be enclosed in quotes or braces.

The text bit can be whatever text you want, so long as it conforms to GCA’s data file rules (one line, or put together from multiple lines using line continuation). Don’t enclose text in quotes or braces unless you want them whereever the text is going to be inserted. Includes support for ~P (that’s a tilde followed by a capital P) for inserting a carriage return/line feed into the text, which is converted during #get() retrieval.

Be conscious of where the text is going to go; don’t include things like unbalanced parens or other characters that might result in the destination no longer being correctly parseable after the value is inserted.

Whitespace at the front or end of either part is trimmed.

The #Get() template looks like this:

#get(VarName)

And simply replaces the entirety of the #get() command with the retrieved value.

A couple examples:

[ADS]
<_TESTING>
#Store TestData=This is a Test
Example 1 (#GET(TESTDATA)), 5/10

#Store DialogTitle=Test Dialog
#Store DialogText = Hello!~PThis is a dialog to demonstrate the #Store and #Get commands.~PTry it!
#Store DialogList = Item 1 Chosen, Item 2 Chosen, Item 3 Chosen
Example 2 (%choice%), 5/10, x(#ChoiceList(list(#get(dialoglist)),Title(#get(dialogtitle)),Text(#get(dialogtext)) ))

In Example 1, the name extension becomes ‘This is a Test’ when added to the character.

In Example 2, a Choice dialog pops up when added to a character, and the dialog is populated with the #Store values.

* Simple Edit

Rebuilt Simple Edit’s display features, to correct a bug, and to allow for more easily expanding it with additional features in the future.

Added support for additional full-cost ‘active slots’ in Alternative Abilities, so that you pay full cost for X slots, and pay 1/5 cost for the rest of the Alternative Abilities in the group. This now has UI in Simple Edit and is supported with the altabilityslots() tag.

All the multi-line text boxes in Simple Edit should now support CTRL+A to select all the text.

Extending the Party a bit

b77

Reverted the previous ‘fix’ for the trickle-thru setup, because it allowed for endless loops to occur in certain circumstances. Addressed the particular concern elsewise.

Altered some log messages a tad.

* Party Stuff

Updated .gca5party files to support additional Party View data tacked to the end.

When saving a Party to a .gca5party file, GCA now includes the Party View information.

GCA now saves the currently loaded characters in a ‘session’ as a Party file, rather than as a list of character files. This allows for correctly restoring sessions with their Party information.

Character cards in Party View can now be sent to the front or back of the stack using the Gear menu, or to the back of the stack by clicking the Done button.

When duplicating a character card, the Duplicate Card dialog now appears, allowing you to set various options for the duplication process.

Bits of conditional fencing

b76

* Various

Trying out copies of the TL/Speed/Dodge/damage blocks from Classic Attributes on the General Information box in Unified.

Changed output of Windows version in the startup log.

If GCA finds gca5.prefs in its home folder, it will run in “portable” mode.

Added UI for changing User Folders (aka the various Bins) to Options.

Added an option to Options to allow/disallow auto-setting of Tablet mode when GCA starts up.

Added an option to the main window’s View menu to force Tablet Mode on or off. If on, auto-setting on startup is ignored.

Fixed a bug in the code that sets up trickle-thru calculations.

Updated the error messages related to plugins.

* Fencing Weapon

Added support for a fencingweapon() tag. (Maybe it should be lightweapon() instead?) The value for this tag, for current testing purposes, should be ‘char::enclevel’ such as fencingweapon(char::enclevel) because that will force GCA to create an association between the character and the trait, to ensure it’s recalculated when GCA’s encumbrance level changes. The given value of the tag is not used.

When this tag exists, and the character’s encumbrance level is above 0, GCA will create a charfencingpenalty(-X) tag, and add an item to the bonus list for encumbrance level affecting fencing weapon attacks and parries.

GCA will then use the charfencingpenalty() value to reduce the charskillscore() for the weapon. It then adds that value *back* before calculating the charparryscore() based on charskillscore(), and then reduces charparryscore() by that amount.

Net result: charskillscore() is reduced by EncLevel for the attack tables, and charparryscore() is reduced by EncLevel for the attack tables, and charparryscore() is not affected by ‘double dipping’ the encumbrance penalty.

* Conditional Select()

Added support for the new conditional() tag in the Select() structure. The conditional(), if it exists, must evaluate to True (a non-zero result) in order for the Select() to be processed.

	triggers(_
		select(_
			text("Select with Conditional. You'll never see this one."),
			conditional(@sametext("alpha", "bravo")),
			itemswanted(atleast 1),
			list(_
				DI:Alcoholism, 
				DI:Stubbornness, 
				DI:Workaholic_
				)_
			)_
		)

In this example, @sametext(“alpha”, “bravo”) evaluates to 0, so it would not be shown. Conditional() is, obviously, math enabled, so it supports the full Solver functionality to determine if the conditional() applies.

A bit of a grab bag

b75

* Bug Fixes

In some peculiar circumstances, certain updates of the lists in the Classic View were throwing exceptions. I have rearranged the order of operations in the code a little bit to address this issue.

When Print Previewing a sheet, the flag telling the sheet whether or not it was in Sheet View should now be set correctly.

* Other

Added a Traits dialog. This is currently available from any trait list box in Unified view via the gear icon drop-down menu.

Changed the way some things worked in the Classic trait lists, so that they could be re-used in the Traits dialog.

Added support for a new PermanentButton ActionType in Sheet View, which allows for creating buttons on the character sheet that remain active and usable at all times.

* Data Files

Updated to include Eric’s current update batch.

* ColorBlockSheet

Updated to make use of the new PermanentButton ActionType. This now puts buttons into the Header to call up the Traits dialog for the specified type of trait.

* Plug-ins

I have updated the third-party controls. This breaks sheet plug-ins, which will have to be re-compiled against the new versions. All included plug-ins have been updated.

From past experience, updating the third-party controls can also lead to strange behavior in GCA if some things are a little incompatible. This might affect the tab controls, the grids in Advanced Edit and maybe a couple other things.

It appears the updated controls also have more dependencies on other libraries from the vendor, which has increased the installation size some.

Grab bag of bits and bugs

b74

* Bug fixes

Addressed an issue related to extremely large numbers being returned using exponential notation, and GCA not handling that correctly internally when dealing with those values within an expression.

Hitting Enter in the editable column of the classic trait Attribute lists will now commit the entered value.

Addressed a bug that didn’t restore modifier bonuses correctly when canceling out of the Edit Traits window.

The trait tag ‘chareffectivest’ was missing from the tags meant to be handled by the Modes system, and has been added.

* Other

Added an IsMetric function to Character, which returns True if the character has the ‘Metric’ attribute and its value is 1.

GCA’s displays should now show ‘kg’ or ‘m’ instead of ‘lbs’ or ‘yds’ when using the metric settings.

Updated the center column of the Classic View’s Attributes tab:

  • Redesigned to be more in line with the style used elsewhere in the program. This also allows for more responsive resizing.
  • Replaced the Encumbrance and Move sections with the Move box used elsewhere, since it’s already of the right style, and has been reworked to auto-size better.

Rebuilt the Move box used in Unified, Party, and now Classic views:

  • It will now dynamically resize the displayed columns to better fit the data.
  • If necessary, it will now drop columns if the data items are too large to allow everything to fit in the space available. This will not be noticeable to most people in most cases, but if a character has really large values for the Carry row, you’ll see it.
  • There should now be reduced ‘flashing’ during redraws.
  • The Carry row now displays formatted values, should they be large enough where that will matter.

Still improving Party bits

b73

* Party View

Made the entries in the History block two-rows each.

Added the ability to make rolls for traits in trait lists by clicking the new roll button next to each list entry.

Added a Roll History block to character cards to track the rolls that have been made (it will track the last 200 rolls made, if you never Reset them).

Added an Encumbrance & Move block to character cards.

Updated traits list block to allow for attributes in the lists, too.

Added ability for all rolls for the currently selected trait to be highlighted in the roll history.

Columns in the card designer can now be reordered by shifting them left or right using the new buttons for that purpose on the column headers.

Miscellaneous fixes and polishes.

* Other

Updated the text of the log messages slightly when checking for program and library updates.