Category Archives: Build Notes

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

Finally, bits return

Added @ceiling(value) and @floor(value) functions to the solver (@ceil may also be used for @ceiling). @Ceiling(value) returns the smallest integer value that is greater than or equal to the given value. @Floor(value) returns the largest integer that is less than or equal to the given value.

Added some additional house-keeping to the end of the process that adds new traits to characters.

Updated GCACharacter events to include sender in all cases.

MultiSortedModCollection now Implements IEnumerable.

Modified the Undo handling of the Modifiers window to correct a crash issue when working on modifiers to modifiers.

Addressed an issue in startup with arranging the splitters.

Modified startup sequence slightly.

Fixed crash bug related to experimental feature when closing last open character.

Due to another print engine update, and some changes to GCACharacter, sheet plug-ins were re-compiled.

teeny bits

Added a new Box option type to Sheet Options. Like Header or Caption, this has no persistent data. This option allows for the sheet options to be displayed in a style a bit more like the regular Options window and the Compact view. If you use the Box type, any other option types following the Box will be loaded into the Box in the Sheet Options window. ColorBlockSheet has been updated to show this option in use.

Added DisplayScore() function to match DisplayName() function. Returns score for attributes, count for equipment, and level for everything else. Also added corresponding BaseDisplayScore() function.

GCA now supports displayscoreformula() to customize display of score/level values, if needed. This is primarily intended for use supporting split tech levels, but folks may find other uses.

Character Sheets will need to be updated to support DisplayScore for TL, if they’re just referencing the attribute score right now. (If they’re using Character.TL then they’re probably okay.)

Added an Advanced button to the Campaign Settings window in the TL display. This allows for building a DisplayScore for the TL.

I updated the print engine, which broke compatibility with older character sheets, so they’ve been recompiled. C1 still hasn’t fixed the clipping bug for text in defined areas.

Rebuilt bits

** Many of the changes in this update will improve performance and robustness. If I did them correctly. If not, we could see data corruption and/or an increase in odd behavior and crashes. **

I have changed how trait handling, tag lists, and the rollback of changes, are handled in the Edit Items, Advanced Edit Items, and Modifiers windows. This should make things more robust and less prone to damage from bad data.

I have adjusted the code that determines relationships between traits (which is what determines which traits are recalculated when you change something). Relationship determination should be done a bit more quickly now.

I have rebuilt a number of the parser routines to be more robust, which should reduce (hopefully eliminate) the instances where an errant open or close paren within braces or quotes was still being counted as a valid part of another container pair.

Given the change above, the %closeparen, %openparen, %closebrace, and %openbrace special variables mentioned in b 5.0.0.36 for @EndsWith and @StartsWith should no longer be necessary, if the corresponding characters are enclosed within quotes in the function, such as @endswith(“)”). The %quotes variable is still required, as there is no way to enclose the double quote character safely, but it’s also the least likely to be needed for anything. I’m leaving all of the variables available, though.

Vars are now run through the Text Function Solver during the trait’s calculation phase. This should speed things up when they’re used.

GCA will now read tag help information, for use in edit windows, from the tagdefs.xml file.

I changed a few things in various support routines to use certain Enums rather than Integers, which broke binary compatibility.

Overhauled bits

* Because I can’t get the long-press on touch screens to work inside the listboxes, and my potential work-around isn’t working to my satisfaction, I have currently made it so that double-clicking the title area (above the sub-heads, because those do OrderBy) of the character list in Compact and Classic view will call up the context menu for that list–IF you have selected items in the list box.

* Addressed font scaling issue in Advanced Edit display grid.

* GCA should now create a default library on startup if none exists.

* Addressed misplaced options button issue in Portrait box.

* The Protection box will no longer display information when no character is loaded.

* Updated the handling of some things in the Colors & Layout dialog.

* Overhauled the look of the Options window.

* Added a ‘Getting Started’ box to the Compact view, which offers some suggestions as to what to do once GCA has started up. This only displays if no character is loaded.

* Added support for a displaynameformula() tag. When using the DisplayName property of a Trait (which most trait lists inside GCA use), if displaynameformula() exists, GCA will use that to generate the name beging returned, instead of the built-in functions. In conjunction, the BaseDisplayName() function, or “me::basedisplayname” will return the same info as DisplayName, but will not use the formula, so it can be used within formulas to alter the output that GCA would have generated.

* Added functions to Solver:

@Len(<text>) returns the length of the given text.
@EndsWith(<text>, <check value>) returns 1 if <text> ends with <check value>, 0 if not. Case is ignored.
@StartsWith(<text>, <check value>) returns 1 if <text> starts with <check value>, 0 if not. Case is ignored.

@EndsWith and @StartsWith both use a few specialty variables instead of a few characters that GCA uses internally for parsing purposes. So, if you want to check for parens (), braces {}, or quotes “, you should instead use these variables as needed: %closeparen, %openparen, %closebrace, %openbrace, %quotes.

* Added to Text Function Solver:

$InsertInto( <target string>, <insert string>, <at position> ) which puts some text inside other text.

* The special case substitution $val() has been added to the Text Function Solver. This is identical in function to $textvalue(), just shorter.

* GCA will now support defining variables at the trait level. Variables are defined using the vars() tag, with the format vars(<name1>=<value1> [, <name2>=<value2>] [, <more name value pairs as needed>]). This allows for greatly reducing the complexity of certain types of formulas, such as the new displaynameformula() mentioned above. These are simple substitution variables; if you use vars(%name% = me::name), then the %name% variable stores the text “me::name”, not the actual name of the trait.

For example, to create a DisplayName that uses the same name that GCA would generate, but adds additional text of “Bonus Text” *within* the parenthetical information (if any), the straight formula might look like this:

displaynameformula($if(@endswith($val(me::basedisplayname), %closeparen) then $insertinto($val(me::basedisplayname), “; Bonus Text”, @len($val(me::basedisplayname))-1) else “(Bonus Text)” ))

Notice that we have to keep repeating the ‘$val(me::basedisplayname)’ bit over and over again (And $val() is necessary, because the Text Function Solver won’t replace any value references unless explicitly told to do so with the $val() or $textvalue() functions). And imagine the additional complexity if we wanted to include a trait value or tag reference instead of the simple constant “Bonus Text”.

So, we can simplify with a variable:

vars(%name% = $val(me::basedisplayname))

and the new displaynameformula() that makes use of it:

displaynameformula($if(@endswith(%name%, %closeparen) then $insertinto(%name%, “; Bonus Text”, @len(%name%)-1) else “%name% (Bonus Text)” ))

In this case, not drastically shorter as text goes, but much more readable.

Note that because GCA will replace the variable name indiscriminately within the target area, as the first step of evaluating an expression, you should ensure that your variable names are unlikely to conflict with other types of text. I recommend using a percent sign % at the beginning and end of each variable name, to ensure no accidents are likely to occur.

* It’s now possible to copy one or more tag/value pairs from inside the Advanced Edit window as an XML fragment, and to paste that fragment into another Advanced Edit window, in order to copy specific tags from one trait to another. To copy tags, select each of the tags you want to copy in the grid, then press CTRL+SHIFT+C to copy them (CTRL+C just copies the text value of those cells). You’ll now have an XML fragment which you can paste anywhere that accepts text. To paste such a fragment into GCA as tags, click on the edit grid in Advanced Edit to ensure that it’s active (but you don’t want to be editing a value, or the paste will go into that field as text), then press CTRL+V to insert the tags.

Dropped bits

I have updated children to be kept as references in a SortedTraitCollection. This is a significant change, and may cause things to explode. Importantly, this change allows for more easily feeding through OrderBy requests, and for customizing the display order of child items in the future. However, this does create some additional hoops to jump through when loading characters, because not everything being referenced will exist yet.

ChildKeyList() and ParentKey() will no longer be returned when a TagList is requested. They will no longer appear in the Advanced Edit Traits window.

I apparently broke binary compatibility for plugins again, by changing the ChildKeyList property to allow an optional parameter.

I also updated the versions on the included plugins, and on the Interfaces assembly, while attempting to fix an issue with the setup program not correctly updating things.

When changing the OrderBy by double-clicking the header of a trait list, GCA will now apply the new order to the children being displayed in the list. Of course, children will still be listed under their parents, so the ordering will only affect how they’re shown within their own block.

Drag and drop visual indicators should display correctly now, even when the listbox has been scrolled.

Drag and drop in the lists should now allow dropping items to become children of other items, although it does currently require dropping onto an existing child of the intended parent.

Dragging a child item onto a non-child item will remove that child from its current parent.

Dragging a trait over a parent item should now also display a ‘drop zone’ indicator labeled “Make child of” on the right-hand side of the list box. Dropping onto that ‘drop zone’ should make the trait a child of the parent.

I have added a button, called “Easier Dragging”, to the third toolbar. When active, this option makes it simpler to begin a drag and drop operation in the trait boxes, but makes it harder to select traits by dragging. I don’t know if I’ll leave it there, but for now that’s where it is.

Dragged bits

Loading a character should no longer spit the character’s load-log into the Info pane.

Altered the library loading of system traits to make duplicate x() tags merge their list values when duplicates are found, rather than the standard behavior of replacing values. There is a lot of ‘dirty’ data in the data files where these tags are duplicated to add additional info, and in the case of the x() tag, this was passively allowed in GCA4 (due to it finding the #directives anywhere in the tag data, regardless of duplicate tags). Due to GCA5 actively refusing duplicate tags during the loading process, the duplicate data for the x() tag is lost, so the old, forgiving way does not work now. This new merging behavior should allow the multiple x() tags to work in GCA5 by merging all the duplicate data into a single x() tag. This means that a number of ‘wizard’ type traits, such as the various skills starting with _, and of type %typelist, will now work as intended again.

Also altered library loading of page() to merge values.

The changes to Library loading of system trait x() and page() tags necessitates rebuilding FastLoad files, so the FastLoad version has been changed. Your FastLoad files will be rebuilt as a result.

Updated the code in the Classic View character trait lists so that double clicking the column headers will allow you to turn back off the OrderedBy status. That is, double-clicking will cycle through Ascending, Descending, and Off. Off will restore the list display to the standard order.

Updated the Classic View character trait lists so that adjusting the points/level/cost of traits will preserve their OrderedBy status within the list–rebuilding the list to show the updated order as traits are incremented or decremented. (Note that this may not be entirely desireable when you have a giant list of items, but it works reasonably well for moderate or small lists.)

Updated the Compact View trait boxes to allow double-clicking on the column headers to order the box contents, as in Classic View. Note that the Compact boxes will not re-order the display while adjusting values, unlike Classic View, because the boxes allow for adjusting directly on the trait line itself, and it’s rather annoying to have the interaction area jump to another part of the box while you’re trying to use it.

Changed the sort order markers in trait lists to always be small triangles, although it’s possible to choose between gray (the default), red, and yellow markers. This selection is still by right-clicking on the headers in Classic View, and is now on the box’s option menu (the gear icon) in Compact View. Each marker selection is individual to the type of items. You can also set them in the Colors & Layout dialog.

You may now drag and drop traits from the Library panel onto trait boxes in Compact View, to add them to the character. Any type of trait may be dropped onto any trait box, but they’re added only to the appropriate box. You may now also drop traits onto the sheet area of the Sheet View to add them to the character.

You may now drag and drop traits from the Library list to the Character list in the Classic View.

You may now drag and drop to rearrange the order of User Ordered Layers in the Armor Layers Manager.

The Colors & Layout dialog has been upgraded. It now uses the correct boxes for each box type, and will use sample data from the current character (or from a system sample character, if no other character is loaded). You can also drag and drop the box names within the list box to reorder them, instead of having to use the up and down buttons.

You can now elect to manage the ordering of your character’s traits yourself, if you turn on User Trait Ordering in Options > Current Character Options. When in this mode, traits are shown in the order they are added to the character, but you can drag and drop the traits into new positions in the various trait lists. [Plug-ins note: If you want to implement display support for this feature, check the AllowUserTraitOrdering property, and if True, access traits with either DirectItem(Index as Integer) instead of Item(Index as Integer), or use the new Item overload Item(Index As Integer, DirectAccess As Boolean).]

The OrderBy system in the SortedTraitCollection has been adjusted. [Plug-ins note: If you change OrderBy, it will automatically rebuild the ordered list. However, calling OrderBy if the OrderBy string has not changed will not trigger an OrderItems rebuild. You should still call OrderItems to rebuild the list as necessary if you’re ordering by something that changes, such as points or level, but there’s no need to call OrderItems when new items are added to the collection otherwise, as they’ll be inserted into the ordered list as items are added to SortedTraitCollection.]

Function bits

* The Find Traits window is now available.

* Added support for upformula() and downformula() for Attributes. Using these tags allows you to specify a formula to use for calculating the cost of the attribute when raising or lowing the attribute from the base value.

* Added support for an ‘onlyif’ clause in bonuses. This is basically the same as the ‘unless’ clause, but may be easier for some folks to visualize, because it’s positive instead of negative. OnlyIf is used in the gives() bonus structure after ‘upto’ but before ‘unless’, like so:

‘+2 to SK:Skill [ upto 10][ onlyif TARGET::tag > 0][ unless TARGET::tag = 0][ when “running from danger”][ listas “Some bonus text”]

OnlyIf and Unless both restrict when a bonus is applied. You may use either or both, but if you use both in the same bonus, you must keep in mind that OnlyIf is checked first, and if the target DOES NOT satisfy the requirement, then the bonus WILL NOT be applied, regardless of the Unless statement. The Unless clause further restricts bonus application to traits that satisfy the OnlyIf requirement; it never restricts or excepts the results of the OnlyIf clause. If you only use one or the other clause, then when the exception or requirement applies should be fairly clear.

* Added the @TextIsInText(<IsThis>, <WithinThis>) function to the Solver, which returns 1 if the <IsThis> text is contained within the <WithinThis> text, and 0 if not. As with most such things in GCA, case is ignored.

* Added two new functions to the Solver, which allow for searching for a text item within a list of text items:

@TextIsInList(<IsThis>, {<Within This Comma Separated List of Items>})
@TextIsInListAlt(<IsThis>, <UsingThisSeparatorCharacter>, {<Within This List of Items>})

These are similar, except that @TextIsInList assumes a comma separated list of items, as is used in the cat() or page() tags, while @TextIsInListAlt allows you to specify the character used for separating the items in the list, such as the pipe (|) character used in skillused(). You should always enclose the list parameter inside braces to ensure safely defining the list of items as a single unit. You can, of course, either specify the list items manually, or obtain them using something like $textvalue(me::cat). Comparison of items ignores case, as always. The value returned is 0 if the item was not found, or the index number (1-based) of the list item that was matched.

* Addressed some drawing/refresh related things on the Protection Window.

* Addressed issue related to body image file support in the Protection Window.

* Fixed a bug locating the system images bin.

* Fixed an initialization issue with system traits.

* Made some minor adjustments to the list-based trait boxes in Compact View.

NOTE:

* Removed the old versions of the various trait boxes in Compact View. Please let me know if you see any issues with screen updates or other weird behavior in Compact View.

* Changed the folder references used internally. Also changed how they’re stored in the Folders section of the gca5.prefs file. If you’ve never changed these, nothing should be different, because the defaults are the same. However, if you have changed them, you’ll need to update the new versions.

Scaled bits

You can now right-click on the paperdoll image in the Protection window to access a context menu of some related functions.

You can now resize the body part boxes on the Protection window using the mouse.

Fixed a teeny little wiggle of an issue with the dragging of body part boxes in the Protection window.

Adjusted the look of a couple things in the Protection window.

Addressed some major issues related to scaling the Protection window for Zoom modes other than Normal.

The Library panel (used in Compact and Sheet views) has been updated so that type-to-search works like it does in other places. It has also been updated to respond to the same keys as other areas for adding traits to the character.

Ordered bits

Updated Protection and Loadout windows to add and remove items from loadouts, related protection lists, and ordered layer lists, more robustly.

Removed the Loadout Manager button from the Protection window. It doesn’t actually work correctly given the need to allow the user to Cancel out of the window.

When doing the User Ordered Layers, I forgot to include support for the overall DR bonus, which comes from an attribute that has no location() or dr() tags. I worked up some code to include support for it.

Added some spiffy new interactive stuff to the Protection window.

You can also now drag the body part boxes around with the mouse in the Protection window. This should greatly simplify creating custom layouts.

Because it’s now so easy to adjust the location of the displayed body part boxes on the paperdoll, I’ve allowed the print/Compact view versions of the paperdoll image to grow the box downward as necessary to display excess content.

When using User Ordered Layers, GCA will now tag each layer’s value in the DR box with a footnote symbol, and the footnote symbol will be associated with the item granting that layer of protection. (The footnote symbols are the standard SJGames ones, without the * of course, so they’ll double and triple up once each of the available four symbols is used.) For now, you can see the symbol associations in the Layers pane (see below) of the Protection window. I’ll see about doing something for the Compact view Protection boxes later.

Testing some stuff: If you have User Ordered Layers, a Layers pane (much like the Layers window) will appear on the Protection window. You can resize this pane. You can click one of the two buttons in it to switch orientation between Horizontal and Vertical. You can click the other button to toggle between three different separators for the DR values: plus sign (the default), bullet, and space.

Body of bits

* Done long ago, but probably not mentioned: the prefix tags for Cultural Familiarities and Languages are CU: and LA:, respectively

* Made some adjustments to bonus handling:

(1) Added support for granting bonuses “to Cultures” or “to Languages”
(2) Added support for granting bonuses to a Cultural Familiarity or Language based on their category using “to CUCAT:<X>” or “to LACAT:<X>”.

* Moved a prefix-tag related routine to a different module.

* You can now save your customized Body Type (locations and image) to a data file from the Locations tab in the Protection window.

* You can now select between the available paperdoll body images on the Locations tab of the Protection window, if the associations have been set in the data files.

* The first draft of the user-ordered armor layering system is now working. This is available from the Layers button on the Protection window. This will allow you to arrange the order in which DR is applied, and will result in the DR values on the paperdoll image being listed out individually, rather than having GCA do its best to combine them into a single value. There’s currently no system in place to show what armor item each layer value comes from on the paperdoll; that’s still something I have to figure out.

* The display of the paperdoll image in the Compact view and when printed now more closely reflects the sizes of the boxes shown in the Protection window. However, the display of the data has also been improved to make better use of the space, which should help when there are a lot of layer values to display:

(1) The “DR:” label is now only shown when DB is also being printed
(2) Content will now wrap within the content area of the box.
(3) The box will allow one additional line of height if needed to display all the content.