Should be used instead of #346 because this implements it in a way where the affordability preview is inherently usable in all pre-existing functions instead of introducing new functions.
Contains a few perf and refactor changes. But primarily:
Implements a new affordability preview system which is based on strategically placed update calls to skill_container while flipping a Boolean inside actor. This allows modders to check that an actor is previewing by accessing that Boolean from anywhere.
Moves the older preview system to a conditional hook system to improve efficiency as no one should be using that anymore.
The meat of this PR is the singular feat commit so you may wanna look at the diff of that commit to understand how the new system works.
This is a massive improvement over the current Affordability Preview system we have in MSU which I implemented in #88. That system is convoluted to work with from the user's perspective and is also limited in certain aspects. The new system is far more intuitive and in fact covers some edge cases which the old system failed in.
Old System (the one this PR deprecates):
Basically requires you to use modifyPreviewField and modifyPreviewProperty functions from inside a skill's onAffordablePreview function. The parameters of those functions are convoluted to work with.
The system calculates the overall change by first "undoing" the change from the skill in its onUpdate, onAfterUpdate, and executeScheduledChanges functions and then applies the new change.
A major limitation of this system is that the changes are applied at the end, so during the affordability preview function you don't have access to the values of other skills which would be in the regular update order by the time this skill's function comes up.
New System:
Basically any function can check for the actor's previewing state and therefore we can do a lot of powerful things. This allows directly checking for previewing within the onUpdate, onAfterUpdate and even any other function.
This makes the system very straightforward.
On the back end the system achieves this by strategically placing extra updates of the skill_container while flipping a Boolean in actor to switch between previewing and regular updates. This is probably less "efficient" than the old system but honestly this is better and I wish I had done it this way the first time around.
Example:
Let's say I have a skill which after at least 2 tiles reduces the AP cost of all attacks by 1. But this effect expires when you use any skill.
Old System usage:
function onAfterUpdate( _properties )
{
if (this.getContainer().getActor().getTile().getDistanceTo(this.m.StartingTile) >= 2)
{
foreach (skill in this.getContainer().getAllSkillsOfType(::Const.SkillType.Active))
{
if (skill.isAttack() && skill.m.ActionPointCost > 1) // Notice we only want to decrease the AP cost if it is 2 or more
skill.m.ActionPointCost -= 1;
}
}
}
function onAffordablePreview( _skill, _movementTile )
{
// The character is previewing the usage of a skill, so we want to remove the AP cost reduction
if (_skill != null)
{
foreach (skill in this.getContainer().getAllSkillsOfType(::Const.SkillType.Active))
{
this.modifyPreviewField(skill, "ActionPointCost", 0, false);
}
}
// The character is previewing a movement, so we want to apply the AP cost reduction if applicable
else if (_movementTile != null)
{
// If we have already traveled at least 2 tiles this turn, we don't want to reduce the AP cost further
if (this.getContainer().getActor().getTile().getDistanceTo(this.m.StartingTile) >= 2)
return;
if (_movementTile.getDistanceTo(this.getContainer().getActor().getTile()) >= 2)
{
foreach (skill in this.getContainer().getAllSkillsOfType(::Const.SkillType.Active))
{
// Notice there is no way for us to first check here if the skill's AP cost
// is actually 2 or more at this point in the update cycle, because this onAffordablePreview function
// doesn't work like that
if (skill.isAttack())
this.modifyPreviewField(skill, "ActionPointCost", -1 , false);
}
}
}
}
New System:
function onAfterUpdate( _properties )
{
local actor = this.getContainer().getActor();
local isValid = false;
if (actor.isPreviewing())
{
isValid = actor.getPreviewMovement() != null && actor.getPreviewMovement().End.getDistanceTo(this.m.StartingTile) >= 2;
}
else
{
isValid = actor.getTile().getDistanceTo(this.m.StartingTile) >= 2;
}
if (isValid)
{
foreach (skill in this.getContainer().getAllSkillsOfType(::Const.SkillType.Active))
{
if (skill.isAttack() && skill.m.ActionPointCost > 1) // Notice we only want to decrease the AP cost if it is 2 or more
skill.m.ActionPointCost -= 1;
}
}
}
Help needed:
One thing that I need Taro/Enduriel to improve in this system is that if the affordability preview would make a skill that is currently unaffordable affordable again, then we need to convey this information somehow. Currently, that skill's icon stays black&white because the vanilla affordability preview system only considers the case of currently affordable skills potentially becoming unaffordable and hence puts a "prohibited" icon on them. It does not expect currently unaffordable skills to become affordable. An idea for this case could be to put a green check mark on such skills to counter the red prohibited sign.
Relevant functions for achieving this are:
// in `turnsequencebar_module.js`:
TacticalScreenTurnSequenceBarModule.prototype.addSkillToList
TacticalScreenTurnSequenceBarModule.prototype.updateEntitySkillsPreview
// in `turn_sequence_bar.nut:`
setActiveEntityCostsPreview
resetActiveEntityCostsPreview
Should be used instead of #346 because this implements it in a way where the affordability preview is inherently usable in all pre-existing functions instead of introducing new functions.
Contains a few perf and refactor changes. But primarily:
update
calls to skill_container while flipping a Boolean inside actor. This allows modders to check that an actor is previewing by accessing that Boolean from anywhere.The meat of this PR is the singular
feat
commit so you may wanna look at the diff of that commit to understand how the new system works.This is a massive improvement over the current Affordability Preview system we have in MSU which I implemented in #88. That system is convoluted to work with from the user's perspective and is also limited in certain aspects. The new system is far more intuitive and in fact covers some edge cases which the old system failed in.
Old System (the one this PR deprecates):
modifyPreviewField
andmodifyPreviewProperty
functions from inside a skill'sonAffordablePreview
function. The parameters of those functions are convoluted to work with.onUpdate
,onAfterUpdate
, andexecuteScheduledChanges
functions and then applies the new change.New System:
onUpdate
,onAfterUpdate
and even any other function.skill_container
while flipping a Boolean inactor
to switch between previewing and regular updates. This is probably less "efficient" than the old system but honestly this is better and I wish I had done it this way the first time around.Example: Let's say I have a skill which after at least 2 tiles reduces the AP cost of all attacks by 1. But this effect expires when you use any skill.
Old System usage:
New System:
Help needed: One thing that I need Taro/Enduriel to improve in this system is that if the affordability preview would make a skill that is currently unaffordable affordable again, then we need to convey this information somehow. Currently, that skill's icon stays black&white because the vanilla affordability preview system only considers the case of currently affordable skills potentially becoming unaffordable and hence puts a "prohibited" icon on them. It does not expect currently unaffordable skills to become affordable. An idea for this case could be to put a green check mark on such skills to counter the red prohibited sign.
Relevant functions for achieving this are: