Affordability Preview - MSUTeam/MSU GitHub Wiki
- Description
- onAffordablePreview
- modifyPreviewField
- modifyPreviewProperty
- addPreviewApplicableFunction
- Example
Thanks to the flexibility of the base values saving feature in MSU, it is possible to implement skills which incrementally modify the Action Point and Fatigue costs of other skills based on their usage. For example, let's imagine a case where every use of the Thrust skill reduces the Fatigue Cost of the Shieldwall skill by 15% or each tile moved reduces the Action Point cost of the next attack by 1.
This leads to an issue: while the player is previewing a movement or the use of a skill, the UI updates the affordabilitiy preview of other skills based on their current costs and not the cost that will be after completing the previewed action. This can be misleading for the player as a skill which would have been affordable after the previewed action appears as unaffordable until the action is actually taken. MSU solves this problem by allowing you to specify in such skills how they should modify the affordability preview.
function onAffordablePreview( _skill, _movementTile )
// _skill is a BB object
// _movementTIle is a C++ tile object
While a player is previewing the use of a skill, the previewed skill will be passed as _skill
and _movementTile
will be null. While the player is previewing a movement, the furthest possible tile that is affordable to be moved to in the currently attempted movement is passed as _movementTile
and _skill
will be null.
This function is called for all skills whenever a preview is initiated as long as the ExpandedSkillTooltips
MSU Setting is enabled. You can use this function to modify the affordability preview of skills.
this.modifyPreviewField( _skill, _field, _newChange, _multiplicative )
// _skill is the skill whose preview affordability is to be changed
// _field is a string that is a key in the m table of _skill
// _newChange should be an integer, float or boolean
// _multiplicative is a boolean
This function can be used during onAffordablePreview to modify the value of _field
in the m
table of _skill
for the preview affordability of _skill
. It is entirely the modder's responsibility to provide the correctly calculated values for _newChange
. If _multiplicative
is true then the changes are applied multiplicatively, otherwise additively. See Example.
this.modifyPreviewProperty( _skill, _field, _newChange, _multiplicative )
// _skill is the skill whose preview affordability is to be changed
// _field is a string that is a key in ::Const.CharacterProperties
// _newChange should be an integer, float or boolean
// _multiplicative is a boolean
This function can be used during onAffordablePreview to modify the value of _field
in the CurrentProperties
of the character for the preview affordability of _skill
. It is entirely the modder's responsibility to provide the correctly calculated values for _newChange
. If _multiplicative
is true then the changes are applied multiplicatively, otherwise additively. See Example.
::MSU.Skills.addPreviewApplicableFunction( _name )
// _name is a string which is the name of a function in skill.nut
Makes this function subject to MSU's affordability preview modifications. This is essential, for example, for mods which may want to add new kinds of affordability calculation functions e.g. <skill>.isAffordableBasedOnMana()
etc.
Let's say we have a perk called MSU-Shot which reduces the Action Point cost of Aimed Shot by 1 every time it is used. We can accomplish this as follows:
// MSU-Shot modifies the ActionPointCost of Aimed Shot based on how many times it has been used
function onAfterUpdate( _properties )
{
local aimedShot = this.getContainer().getSkillById("actives.aimed_shot");
if (aimedShot != null)
{
aimedShot.m.ActionPointCost -= this.m.UseCount;
}
}
// Now we do the same thing in onAffordablePreview of MSU-Shot to modify the preview cost of Aimed Shot
function onAffordablePreview( _skill, _movementTile )
{
if (_skill != null && _skill == this) // i.e. the player is previewing the use of MSU-Shot
{
local aimedShot = this.getContainer().getSkillById("actives.aimed_shot");
if (aimedShot != null)
{
// set the preview to reduce the ActionPointCost based on current use count + 1
this.modifyPreviewField(aimedShot, "ActionPointCost", -(this.m.UseCount + 1), false);
}
}
}
Let's say we have a perk called MSU-Assault which reduces the Action Point cost of every melee attack skill by 1 and Fatigue cost by 10% for every 2 tiles moved. However, upon using a skill, any current bonus should be reset. In order to apply these changes to the affordability preview of such skills, we write the following code in the MSU-Assault script:
// MSU-Assault modifies the ActionPointCost and FatigueCostMult of certain skills in its onAfterUpdate function
function onAfterUpdate( _properties )
{
local bonus = this.getContainer().getActor().getTile().getDistanceTo(this.m.StartingTile) / 2;
foreach (skill in this.getContainer().getSkillsByFunction(@(skill) skill.isAttack() && !skill.isRanged()))
{
skill.m.ActionPointCost += -bonus;
skill.m.FatigueCostMult *= 1.0 - bonus * 0.1;
}
}
// Then we simply do the same thing in the onAffordablePreview function of MSU-Assault but use the predicted bonus
function onAffordablePreview ( _skill, _movementTile )
{
// If the character is previewing a movement, apply the predicted bonus to the preview
if (_movementTile != null)
{
local bonus = _movementTile.getDistanceTo(this.m.StartingTile) / 2;
foreach (skill in this.getContainer().getSkillsByFunction(@(skill) skill.isAttack() && !skill.isRanged()))
{
this.modifyPreviewField(skill, "ActionPointCost", -bonus, false);
this.modifyPreviewField(skill, "FatigueCostMult", 1 - bonus * 0.1, true);
}
}
// If the character is previewing a skill usage, reset any current bonus
if (_skill != null)
{
foreach (skill in this.getContainer().getSkillsByFunction(@(skill) skill.isAttack() && !skill.isRanged()))
{
this.modifyPreviewField(skill, "ActionPointCost", 0, false);
this.modifyPreviewField(skill, "FatigueCostMult", 1, true);
}
}
}