-
Notifications
You must be signed in to change notification settings - Fork 4
Skill Base Values
In vanilla BB, skills are often tightly coupled, so if one skill wants to modify a parameter in another skill, the two are tightly coupled via a function. Secondly, in vanilla BB, many parameters of skills cannot be changed in increments e.g. ActionPointCost
. If a skill changes its ActionPointCost
via an increment e.g. += 1
during its onUpdate
or onAfterUpdate
function, then the value of the ActionPointCost
will continue to increase indefinitely every time that function is called.
Let's take a random attack skill, Thrust, as an example. Let's say we have a skill that modifies the AP cost of Thrust by -1. The way to do this in vanilla would be:
function onAfterUpdate( _properties )
{
this.m.ActionPointCost = this.getContainer().hasSkill("ourSkill") ? 3 : 4;
}
Such a value is very hard for modders to modify without changing the entire onAfterUpdate
function.
MSU's Automated Resetting feature allows overcoming both of these problems in an elegant way, allowing you to write clean code for example like this:
// in ourSkill
function onAfterUpdate( _properties )
{
local thrust = this.getContainer().getSkillByID("actives.thrust");
if (thrust != null)
{
thrust.m.ActionPointCost -= 1;
}
}
This method keeps things encapsulated. Thrust doesn't need to know anything about whether ourSkill
exists or not. Furthermore, it allows modders to modify the parameters of Thrust without breaking compatibility.
MSU stores the base values of a skill's m
table immediately when a container is assigned to the skill via the setContainer
function (which happens during the skill container's add
function). MSU provides several functions to reset the m
table of a skill back to its base values.
- Soft reset
- Hard reset
- Resetting a particular field
<skill>.softReset();
This function resets the following fields of the skill's m
table, but more fields can be added or removed by modders.
- ActionPointCost
- FatigueCost
- FatigueCostMult
- MinRange
- MaxRange
softReset()
is automatically called during the update()
function of the skill_container
before any skills' onUpdate
or onAfterUpdate
are called.
<skill>.hardReset( _exclude = null );
// _exclude is an array of strings which are keys in a skill's m table
This function is never automatically called, but can be manually called to reset every value in the m
table back to its original value except the Order
, Type
, and IsNew
fields and any field names passed in the optional _exclude
array.
<skill>.resetField( _field );
// _field is a string which is a key in the skill's m table
This function can be used to reset a particular field back to its base value e.g. <skill>.resetField(“Description”)
.
<skill>.getBaseValue( _field );
// _field is a string which is a key in the skill's m table
Returns the stored base value of the _field
slot in the skill's m
table.
<skill>.setBaseValue( _field, _value );
// _field is a string which is a key in the skill's m table
// _value can be any data type
Sets the stored base value of the _field
slot in the skill's m
table to _value
.
-
softReset()
is called for all skills during the skill_container'supdate()
function before any skill'sonUpdate
is called. - The
HitChanceBonus
,AdditionalAccuracy
andAdditionalHitChance
fields of a skill are reset during a call to the skill container'sbuildPropertiesForUse
function using this skill. This allows other skills to modify these fields of the skill in increments without having to worry about infinite runaway changes. As these values are used in the generation of tooltips as well, this helps ensure that the tooltips are properly generated.
This system allows changing a value in a skill’s m table in increments rather than assigning it particular values, which opens up possibilities for flexible and compatible modding. For example, now you can do:
function onAfterUpdate( _properties )
{
this.m.ActionPointCost -= 1;
}
In the original game, doing this will cause the action point cost of the skill to continue to reduce indefinitely on every call to this function. However, with the MSU resetting system, this will ensure that the skill’s action point cost is only reduced by 1 compared to its base cost. Another mod can then hook the same function and add or subtract from the cost in further increments.
Skills in Battle Brothers are updated in the order of their SkillOrder
. Imagine we have two skills:
- Skill A with
this.m.SkillOrder = this.Const.SkillOrder.First
- Skill B with
this.m.SkillOrder = this.Const.SkillOrder.Any
Whenever the skill_container runs its update()
or buildPropertiesForUse
(which calls the onAnySkillUsed
function in skills) functions, the respective functions are called on the skills in the order of their SkillOrder
. Hence, skill A will update before skill B in the above example.
If you want skill A to modify something in skill B after skill B’s update, you would have to change the order of skill A to be something later than that of skill B e.g. set skill A’s order to this.Const.SkillOrder.Last
. Usually this is quite doable. However, there may be cases where you absolutely want skill A to be updated before skill B but still want skill A to be able to change something in skill B when skill B is updated. MSU allows you to do this via the scheduleChange
function.
Multiple changes to the same skill can be scheduled by using the function multiple times. Scheduled changes are executed in the update()
function of skill_container after the onAfterUpdate
functions for all skills have run.
<skill>.scheduleChange( _field, _change, _set = false );
// _field is a string which is a key in the skill's m table
// _change can be a string, boolean or integer depending on the type of the field's value
// _set is a boolean
If _set
is true
, sets the value of _field
to _change
and if false
and if _field
points to an integer or string value, adds _change
to the value of _field
.
The following code is written in skill A and will reduce the action point cost of skill B by 1 even if skill A updates before skill B:
function onUpdate( _properties )
{
skillB.scheduleChange(“ActionPointCost”, -1);
}
- NOTE: MSU guarantees backwards compatibility for documented features and code only. Undocumented features/code of MSU may be changed at any time without notice, so we advise against using/referencing such code in your projects.
- For bug reports or feature requests, please create issues.
- If you would like to join the team, write to us at msu.team@protonmail.com.