The fix wasn’t as bad as I thought, but, there were certainly headaches to be had before said fix was found.
So, what was happening was in the BattleManager.endBattlerActions function. If a character is using a unite skill, there is a a variable inside BattleManager.processTurn to remember the skill.
// Process when an actor finishes their action.
BattleManager.processTurn = function() {
const subject = this._subject;
const action = subject.currentAction();
if (action) {
action.prepare();
if (action.isValid()) {
this.startAction();
if (subject.isUnite()) {
subject.setActionStateUnite("acting");
// The action would be removed from the stack below, but, we still need it for a bit longer.
this.unite = action;
};
};
subject.removeCurrentAction();
} else {
this.endAction();
this._subject = null;
}
};
Since the action is removed from the action queue, my thought was to use the endBattlerActions function to put it back on the queue, even temporarily, and set the involved characters to the “done” state/motion.
// Process when an actor finishes their turn.
BattleManager.endBattlerActions = function(battler) {
// Hey, was there a Unite skill stored earlier?
if (this.unite) {
// Cool. Put it back onto the current actor's queue.
battler._actions.push(unite);
// Have everyone involved get an action state of "done".
// I'm not concerned about the value of `this.isTpd()`, so...
battler.setActionStateUnite("done");
// Remove the action again.
battler.removeCurrentAction();
// Forget this ever happened.
this.unite = undefined;
} else {
// Regular processing.
battler.setActionState(this.isTpb() ? "undecided" : "done");
};
battler.onAllActionsEnd();
battler.clearTpbChargeTime();
this.displayBattlerStatus(battler, true);
};
One problem with this. The line that would put the skill on the stack?
battler._actions.push(unite);
That line puts an entirely different thing in there than what this.unite would put in there.
// Base unite damage formula, replacing "a.atk", "a.mat", or possibly both.
function unite(skill_id, mode=undefined) {
let array = uniteArray(skill_id);
let total = 0;
switch (mode) {
case "physical":
for (let i=0; i<array.length; i++) {
total += $gameActors.actor(array[i]).atk;
};
return total;
case "magical":
for (let i=0; i<array.length; i++) {
total += $gameActors.actor(array[i]).mat;
};
return total;
default:
for (let i=0; i<array.length; i++) {
total += $gameActors.actor(array[i]).atk;
total += $gameActors.actor(array[i]).mat;
};
return total;
};
};
So, while the correct motion/state may be being passed, the check to see if the involved characters would fail, because the return value for the unite function would be undefined in the context it was given.
Suffice it to say, I’ve updated the demo again (again again again again) with this fixed.