GDF3 File and Data Specifications for GCA4
Root FileSpec Page |
GCA Site Home | Docs & Help Page |
This document is built off of notes in the Change Log. Not a lot of editing has been done, beyond organizing things. Hope it helps anyway.
As of b287, GCA is now capable of calculating a variety of secondary trait features, most related to weapons. These features can all be modified with bonuses from gives() tags.
Applying a bonus to a secondary feature is done in the usual fashion, by appending "::
To go along with the above change, the 'Owner' object should now be a valid target for bonuses from Modifiers, but currently only for modifiers applied to traits & equipment (not modifiers applied to other modifiers). So, for example, you could have a modifer that applied a +1d damage bonus to the item it was applied to, by using this gives() with the modifier: gives(+1d to owner::damage$).
The Me object should now be a valid base target for bonuses to tags (such as "-1 to me::weight"). This allows for items to apply bonuses to their own tags without the need for modifiers, which may be helpful when creating custom magic items or whatever.
When assigning a specific string value to a tag from a bonus, such as "1-2 to owner::reach$", you should generally do so using a static assignment, using the = sign. Doing so will prevent GCA from including the + sign as part of the text. If assigning a string in this fashion, you may include the text in quotes, and GCA will strip the quotes during the creation of the text bonus. So, to set reach to "2,3", for example, you might use a gives() like so: gives(=nobase to owner::reach$, ="2,3" to owner::reach$)
Any additional notes are made below, for the type of item being calculated.
This is the level for parrying, as calced by GCA using the parryat() tag. Usually only applies to skills.
Applying bonuses would be done by targeting ::parryat.
This is the level for blocking, as calced by GCA using the blockat() tag. Usually only applies to skills.
Applying bonuses would be done by targeting ::blockat.
Acc values should now be calculated for any trait with an acc() tag. Results in the characc() tag. In the case of an acc() with format X+Y, acc bonus is applied only to X.
GCA now supports the armordivisor() tag, and will calculate a chararmordivisor() tag if necessary. This tag is assumed to be numeric in nature, and GCA will fully calculate it with bonuses and such. Because this is now a tag on its own merits, don't include the data inside it within additional parens--the parens will be added as necessary when GCA builds the output. Remember modes blah blah blah.
DR values should now be calculated for any trait with a dr() tag. As with other tags calculated from a starting tag value, the results are put into the charX() version of the tag--chardr() in this case.
DB values should now be calculated for any trait with a db() or pd() tag. Note that GCA will allow for the pd() tag to be used as a synonym for db() in this case, and when granting bonuses to the DB of an item ('owner::pd' is the same to GCA as 'owner::db', for example), but it will only create the chardb() tag to contain the result.
This is the damage specific to the weapon as found on the character. This is calculated by GCA based on the damage() tag. Applies to anything that might have damage.
Applying standard bonuses would be done by targeting ::damage. Many non-standard bonuses, such as adding dice or including special formulas, would be done by targeting ::damage$.
More info:
* To apply dice of damage, you need to append a $ sign to the end of the tag, as that tells GCA that you're dealing with strings (text blocks) in the bonus, and it shouldn't calculate the bonus to get a value (that would lose the 'd' part of a die bonus during calculation). So, to add a +1d bonus to a Broadsword, you'd use "+1d to EQ:Broadsword::damage$", and GCA would append the "+1d" part to the damage string before sending it to the routine that calculates the final character damage. This will result in the correct damage being determined. It's important to remember that little $ sign when you want to add dice.
* Added a special case bonus item for giving a bonus to damage$: =nobase. If you have a gives like this: gives(=nobase to owner::damage$), then GCA will handle the '=nobase' as a special case, and eliminate the base damage for the item. This means all damage, if any, will have to come from bonuses. Without any bonuses, chardamage would be 0.
* Added a special case bonus item for giving a bonus to damage$: =nocalc. This is only enabled for damage$. If you have a gives like this: gives(=nocalc to owner::damage$), then GCA will handle the '=nocalc' as a special case, and will not attempt to calculate the damage from the damage string--instead, GCA will simply use the damage string as the chardamage(). GCA will still perform all special case substitutions and other processing, however. If using both =nobase and =nocalc, you can combine the two like so: =nobasenocalc or =nocalcnobase.
* Created a special case substitution value/function for use inside of damage calcs. This function is $modetag(), which will return the text value of a tag name included inside the parens, as it applies to the current weapon mode being calculated. For example, a weapon with two modes, one doing 1d cut and one doing 1d-1 imp, would return cut for $modetag(damtype) in mode 1, and imp for $modetag(damtype) in mode 2.
An example of how this works is something like this:
gives(=+@textindexedvalue( $modetag(damtype), ("cut", 1), ("imp", 1) ) to owner::damage$)
which gives a bonus to damage *only* when the damage type is cut or imp. (It does result in the whole ugly formula going into the bonuslist(), which I don't like at all, but see no way around at the moment.)
Char version of damtype() will now be created and placed in chardamtype(). Because of the nature of damtype(), only targeted bonuses to damtype$ will be processed for creation of chardamtype(). Remember that damtype() is mode specific in many cases, and changes or bonuses would be applied to all mode values. As with reach(), you can use $modetag() and $functions to adjust processing for different modes.
Char version of parry() will now be created and placed in charparry(). NOTE that this is the parry adjustment for individual weapons, as found in equipment lists. Remember that parry() is mode specific in many cases, and changes or bonuses would be applied to all mode values. As with reach(), you can use $modetag() and $functions to adjust processing for different modes.
GCA will now find the charparryscore() based on the skill found in the charskillused() tag.
GCA now calculates the charparryscore() using a new method. This new method uses the parryat() and the charskillscore() of the charskillused(), using the parryat() as the template, and the charskillscore() in place of the level or score reference in the parryat(). This allows for calculating the correct charparryscore() even when adjustments need to be made to the charskillscore() for some reason, including operating from default or at an additional penalty. It includes any bonuses existing in parryatbonus() and parryatmult(), and adjusts for charparry(). As before, it needs to add back adjustments from parryat() included after the +3, to avoid double penalties.
Added the global parry bonus represented by the Parry attribute into the calculation of charparryscore(), because I forgot to include it.
This is the range specific to the weapon as found on the character. This is calculated by GCA based on the rangehalfdam() tag. Applies to anything that might have this range tag.
Added support for applying bonuses to 'rangehalfdam' and 'rangemax' tags of items. Note that GCA does not always calculate ranges for items, so these bonuses may not always be applied. I have made an adjustment to the range calculation routine, however, so that if there is some bonus, and GCA can determine a non-zero numerical value for the range being looked at, GCA will go ahead and try to calculate the new range with bonus.
Range values should now be calculated for any trait with appropriate range tags, not just equipment.
Updated handling of range calcs (the rangehalfdam and rangemax tags) to support use of 'nobase'
Updated handling of range calcs (the rangehalfdam and rangemax tags) so that if 'nobase' is used, and no other bonuses apply, the character range tags will be returned empty (as if the item had no range assigned, basically, which is different than a range of 0).
This is the range specific to the weapon as found on the character. This is calculated by GCA based on the rangemax() tag. Applies to anything that might have this range tag.
Added support for applying bonuses to 'rangehalfdam' and 'rangemax' tags of items. Note that GCA does not always calculate ranges for items, so these bonuses may not always be applied. I have made an adjustment to the range calculation routine, however, so that if there is some bonus, and GCA can determine a non-zero numerical value for the range being looked at, GCA will go ahead and try to calculate the new range with bonus.
Range values should now be calculated for any trait with appropriate range tags, not just equipment.
Updated handling of range calcs (the rangehalfdam and rangemax tags) to support use of 'nobase'
Updated handling of range calcs (the rangehalfdam and rangemax tags) so that if 'nobase' is used, and no other bonuses apply, the character range tags will be returned empty (as if the item had no range assigned, basically, which is different than a range of 0).
Added bonus$ processing for rof(), shots() and rcl(). As with other such tags, mode may be an issue. This also means that there is a resulting char version of each such tag.
GCA will now determine a charreach() tag for items with reach() tags. GCA does not calculate this tag, it simply builds it if there are any bonuses to reach.
Important: Reach() is mode specific in many cases--any changes or bonuses to reach would be applied equally to *all* values for all modes. However, the special case substitution $modetag(), described for b263 will work here as well to help mitigate this, if different values are needed for different modes. In addition, GCA supports the use of the new $functions (see below) in the construction of the charreach() tag.
Added bonus$ processing for rof(), shots() and rcl(). As with other such tags, mode may be an issue. This also means that there is a resulting char version of each such tag.
Added bonus$ processing for rof(), shots() and rcl(). As with other such tags, mode may be an issue. This also means that there is a resulting char version of each such tag.
GCA will now use the skillused() tag to determine the best skill used for the item. It will store the trait used in the charskillused() tag (sometimes it's an attribute). It will store the skill level, adjusted by any bonuses, for the trait to be used, in the charskillscore() tag. Bonuses that apply specifically to the skill level when making use of a particular weapon would be targetted at ::skillscore.
GCA will now use the skillused() tag to determine the best skill used for the item. It will store the trait used in the charskillused() tag (sometimes it's an attribute). It will store the skill level, adjusted by any bonuses, for the trait to be used, in the charskillscore() tag. Bonuses that apply specifically to the skill level when making use of a particular weapon would be targetted at ::skillscore.
GCA will now adjust charskillscore() if minst() is more than the character's ST.
* Added support for applying bonuses to 'baseweight' and 'weight' tags of items. Baseweight bonuses are applied to the item itself, before any possible child items are included. Weight bonuses are applied to the total item weight, including children.
* Added support for applying bonuses to 'childrenweights' tag of items. These bonuses are applied to the total weight of all children, before inclusion in the total weight of the item.
* Added support for applying bonuses to 'childrencosts' tag of items. These bonuses are applied to the total cost of all children, before inclusion in the total cost of the item.
* Added support for applying bonuses to 'childpoints' tag of traits. These bonuses are applied to the total points of all children (NOT components), before inclusion in the total points of the item.
* Added support for applying bonuses to 'basecost' and 'cost' tags of items. Basecost bonuses are applied to the item itself, before any possible child items are included. Cost bonuses are applied to the total item cost, including children.
* Added a new math function to the Solver: @textindexedvalue(). The template is like this:
@textindexedvalue( indexitem, (item1, item1value), (item2, item2value) [, (etc...) ] [, ELSE value] )
Basically, it consists of a text item used as an index, followed by any number of (Item, Value) pairs, enclosed in parens as shown. GCA will look at the index item, and do a text comparison (ignoring case) between it and the text item that makes up the first item in each result pair. When it finds a match, it returns the value of that pair, as indicated in the value portion of the pair. So, if you have this example:
@textindexedvalue( "b", ("a", 1), ("b", 2), ("c", 3) )
The Solver would return a value of 2 for the function. (Quotes around the text items aren't required, but don't hurt, and are encouraged when using literal text.) A 0 is returned if no matches are found, unless the last value in the list is an ELSE entry, in which case the value following ELSE is used as the return value for any non-matches. For example:
@textindexedvalue( "d", ("a", 1), ("b", 2), ("c", 3), ELSE 10 )
In this example, the Solver would return a value of 10, because of the ELSE entry.
* Created a special case substitution value/function for use inside of damage calcs. This function is $modetag(), which will return the text value of a tag name included inside the parens, as it applies to the current weapon mode being calculated. For example, a weapon with two modes, one doing 1d cut and one doing 1d-1 imp, would return cut for $modetag(damtype) in mode 1, and imp for $modetag(damtype) in mode 2.
An example of how this works is something like this:
gives(=+@textindexedvalue( $modetag(damtype), ("cut", 1), ("imp", 1) ) to owner::damage$)
which gives a bonus to damage *only* when the damage type is cut or imp. (It does result in the whole ugly formula going into the bonuslist(), which I don't like at all, but see no way around at the moment.)
* The same special case substitution that handles $modetag() will also replace any occurance of %curmode with the number of the mode currently being processed.
* Added a new section to a gives() bonus declaration: ListAs. ListAs allows the writer of the bonus to specify exactly what text will appear in the BonusList() when this bonus is being applied. The ListAs keyword must have a space on each side, and the text for the ListAs section must appear in quotes following the ListAs keyword. ListAs must be the last part of the bonus declaration. Example:
gives(+1 to Spells upto 4 listas "+%value% to 'Eerie Stuff' from '%name%'")
or (what prompted this):
gives(=+@textindexedvalue( $modetag(damtype), ("cut", 1), ("imp", 1) ) to owner::damage$ listas "+1 to cut and impale damage from Fine workmanship")
There are several special case substitution variables available for use in a ListAs section, they are %value% for the current value of the bonus; %stringvalue% for the string value of the bonus; %name% for the name of the trait granting the bonus, and maybe more as necessary.
* Added some $functions. Right now, these are only handled within the Solver, which handles all the math stuff in GCA. What the $functions do is return text values, rather than the numeric values returned by the @functions. We may add special cases where $functions are evaluated for particular tags at particular times, but right now they're limited to within math-enabled areas, which is pretty limiting indeed, since the end result of a math-enabled area is always a number. $Functions are generally evaluated *before* the @functions, but any math enabled portion in $functions may include embedded @functions and other math features normally.
The following $functions now exist:
+ $if() : $if(EXPRESSION then RESULT else ALTRESULT)
this is exactly like the @if() function, except RESULT and ALTRESULT are regular text that is put into the place of the $if function, depending on the result of evaluating the EXPRESSION. If RESULT or ALTRESULT are enclosed in quotes, the quotes will be stripped off before replacing the function with the result.
+ $indexedvalue() : $indexedvalue(INDEX, VALUEITEM1, VALUEITEM2, ETC...)
this is exactly like the @indexedvalue() function, except the VALUEITEM items are text, and may be enclosed in quotes. If the INDEX evaluates to 0, then an empty text value is returned. If INDEX evaluates to a higher index than there are VALUEITEMs, then the last VALUEITEM will be returned. If a VALUEITEM is enclosed in quotes, the quotes will be stripped off before replacing the function with the result.
+ $textindexedvalue() : $textindexedvalue( INDEXITEM, (ITEM1, ITEM1VALUE), (ITEM2, ITEM2VALUE), (ETC...) [, else ELSEVALUE] )
this is exactly like the @textindexedvalue function, except the ITEMxVALUE items are text, in addition to the ITEMx values being text. If INDEXITEM is not found among the ITEMx entries, an empty text value is returned, unless an else portion is included, in which case the ELSEVALUE is returned. If the return value is enclosed in quotes, they are stripped off before the return value replaces the function.
+ $solver() : $solver( EXPRESSION )
this function allows for actually solving a math expression using the Solver, which may be handy, especially if the text function is being processed outside of the normal math areas. Sometimes, you need to be sure that something will return a numeric result, even if it's going to be used in a text function. This allows for that.