Login
Topic: Weapon skills lost on load if multiple skills call unequip and equip in onAdded
Home › Forums › Battle Brothers: Bug Reports › Weapon skills lost on load if multiple skills call unequip and equip in onAdded
- This topic has 0 replies, 1 voice, and was last updated 2 years, 3 months ago by lordmidas.
-
AuthorPosts
-
15. August 2022 at 21:11 #29140lordmidasParticipant
The
add
function ofskill_container
does not check for!skill.isGarbage()
for skills in theSkillsToAdd
array, causing it to return from the function too early if a skill exists inSkillsToAdd
which is garbage. This didn’t use to be an issue because skills inSkillsToAdd
aren’t expected to be garbage, but, it is now possible.Take a look at the vanilla skill
orc_warlord_potion_effect
which callsunequip
and thenequip
on the character’s Mainhand item in itsonAdded
function. This doesn’t cause any issues right now as it is the only skill in the game that does this. However, even if ONE other such skill exists which does the same thing, this will result in the character losing the equipped weapon skills upon loading as saved game. The user will then be required to unequip and re-equip the weapon manually to get the skills.The reason it happens is the following:
1. Upon loading a saved game, the character equips the weapon he was saved with. This adds the weapon’s skills to the character.
2. During skill_container deserialization, the skills are added to the character. This callsonAdded
on all such skills.
3. During theonAdded
function of a skill, the character unequips the weapon. This sets the weapon’s skills currently in theSkills
array of the skill_container toGarbage
.
4. Then the skill callsequip
on the weapon. This adds the weapon’s skills to theSkillsToAdd
array of the character’s skill_container because the skill_container’sIsUpdating
boolean is true during deserialization.
5. Now, imagine we have another skill that does the same process of callingunequip
andequip
in itsonAdded
function.
6. The character again unequips the weapon. This calls<skill_container>.remove( _skill )
function for all the skills of the weapon. As the parameter_skill
is passed by reference, it sets the skills toGarbage
even while they are in theSkillsToAdd
array from point 4.
7. The skill now callsequip
on the weapon. But the skills are not added to the character as they already exist inSkillsToAdd
and the function returns because of the following code (marked by a comment):function add( _skill, _order = 0 ) { if (!_skill.isStacking()) { foreach( i, skill in this.m.Skills ) { if (!skill.isGarbage() && skill.getID() == _skill.getID()) { skill.onRefresh(); return; } } foreach( i, skill in this.m.SkillsToAdd ) { if (skill.getID() == _skill.getID()) { return; // Function returns here } } } _skill.setContainer(this); _skill.setOrder(_skill.getOrder() + _order); if (this.m.IsUpdating) { this.m.SkillsToAdd.push(_skill); } else { this.m.Skills.push(_skill); _skill.onAdded(); _skill.m.IsNew = false; this.m.Skills.sort(this.compareSkillsByOrder); this.update(); } }
8. Then when the skills are added to the character, they get removed during the next
collectGarbage
because they were added asGarbage
.This entire problem can be solved by changing the
if
statement in theforeach
loop that iterates overSkillsToAdd
toif (!skill.isGarbage() && skill.getID() == _skill.getID())
This is NOT solely a modding related bug. It is an oversight in vanilla code which will cause a bug in vanilla game too if any vanilla skill is added which calls
unequip
andequip
in itsonAdded
function. -
AuthorPosts
- You must be logged in to reply to this topic.