- Joined
- Jan 2, 2014
- Messages
- 1,787
- Reaction score
- 939
- First Language
- Chinese
- Primarily Uses
- N/A
This topic aims to share my understanding about unison skill/item plugins and explore some ways to write some of them designed for respective battle systems.
The 1st post focuses on covering stuffs that can be common to all unison skill/item plugins, while each subsequent post will concentrate on using examples to explore the implementation of unison skill/item plugins into each specific battle system.
When reading this post, you're assumed to have at least decent battle related plugin development proficiency(experienced plugin developer having written dozens of decent battle related plugins with decent code qualities), although those not being this capable yet can still follow at least some of the contents, albeit with extra efforts
Definitions
Unison Skill/Item Cost Implementations
To let different Unison Battlers pay different skill/item costs, some new configurations can be added(DoubleX RMMV Unison Item Config v101b):
And the below implementations can be added(DoubleX RMMV Unison Item Config v101b):
Unison Skill/Item Action Slot Implementations
Unison Skill/Item Damage Formula
Notetags -
Configurations -
Which can be implemented this way(DoubleX RMMV Unison Item Config v101b):
Battle Log Window
Which can be implemented like this(DoubleX RMMV Unison Item Config v101b):
Unison Skill/Item Plugin Structure
The 1st post focuses on covering stuffs that can be common to all unison skill/item plugins, while each subsequent post will concentrate on using examples to explore the implementation of unison skill/item plugins into each specific battle system.
When reading this post, you're assumed to have at least decent battle related plugin development proficiency(experienced plugin developer having written dozens of decent battle related plugins with decent code qualities), although those not being this capable yet can still follow at least some of the contents, albeit with extra efforts
Definitions
An Unison Skill/Item is a skill/item needing more than 1 battlers to use it together.
Unison Battlers for an Unison Skill/Item are all those needed to use that skill/item together.
At the players' level, all Unison Battlers will behave like using the same Unison Skill/Item at the exact same frames.
The below 2 videos showcases what the above means:
DoubleX RMMV Unison Item Default
DoubleX RMMV Unison Item YEP_X_BattleSysCTB
So it's natural to think of an Unison Skill/Item to be inputted by 1 of the Unison Battlers and executed by all of them.
Due to the below 2 of the most fundamental Scene_Battle based battle foundations(you can try to break them if you feel/think you're a gifted plugin developer
), however(too advanced to be explained here):
1. Only 1 battler can execute actions at the exact same frame.
2. Only 1 action can be executed at the exact same frame.
Only 1 of the Unison Battlers will actually use the Unison Skill/Item.
As in the default RMMV battle system, the one inputting the skill/item is the one executing that skill/item, Unison Skills/Items should behave the same here. This lead to the below definitions:
1. The Unison Invoker of an Unison Skill/Item is the Unison Battler actually inputting and executing the Unison Skill/Item.
2. The Unison Invokees of an Unison Skill/Item are the Unison Battlers other than the Unison Invoker.
Unison Skill/Item Cost/Action Slot Mechanisms
As mentioned in Definitions, only the Unison Invoker is actually inputting and using the Unison Skill/Item, so only that battler will pay an action slot and the cost of that skill/item if nothing else's changed.
But as Unison Skill/Item is one needing all Unison Battlers to use it together, all Unison Invokees should pay an action slot and the cost of that skill/item too, in order to use it.
Unison Battler Recognitions
Recognizing the Unison Battlers for an Unison Skill/Item can be as simple as letting unison skill/item plugin users to add a new skill/item notetag like this(DoubleX RMMV Unison Item Config v101b):
* 1. <unison item actors: ids>
* - Sets the list of id of actors needed for the skill/item as ids
* , is used to separate the actor id in ids
* E.g.:
* <unison item actors: 1> means actor with id 1 is needed to use it
* <unison item actors: 4, 2> means actors with id 4 and 2 are
* needed to use it
* - All actors included in ids needs to be inputable, able to use the
* skills/item and pay its cost
* - All unison actors will pay the unison skill costs after using it
* - Only actors included in ids can select the skill/item
* - If ids only contains 1 actor id, this notetag will become only
* letting the actor with that actor id to use the skill/item
Unison Battlers for an Unison Skill/Item are all those needed to use that skill/item together.
At the players' level, all Unison Battlers will behave like using the same Unison Skill/Item at the exact same frames.
The below 2 videos showcases what the above means:
DoubleX RMMV Unison Item Default
DoubleX RMMV Unison Item YEP_X_BattleSysCTB
So it's natural to think of an Unison Skill/Item to be inputted by 1 of the Unison Battlers and executed by all of them.
Due to the below 2 of the most fundamental Scene_Battle based battle foundations(you can try to break them if you feel/think you're a gifted plugin developer
1. Only 1 battler can execute actions at the exact same frame.
2. Only 1 action can be executed at the exact same frame.
Only 1 of the Unison Battlers will actually use the Unison Skill/Item.
As in the default RMMV battle system, the one inputting the skill/item is the one executing that skill/item, Unison Skills/Items should behave the same here. This lead to the below definitions:
1. The Unison Invoker of an Unison Skill/Item is the Unison Battler actually inputting and executing the Unison Skill/Item.
2. The Unison Invokees of an Unison Skill/Item are the Unison Battlers other than the Unison Invoker.
Unison Skill/Item Cost/Action Slot Mechanisms
As mentioned in Definitions, only the Unison Invoker is actually inputting and using the Unison Skill/Item, so only that battler will pay an action slot and the cost of that skill/item if nothing else's changed.
But as Unison Skill/Item is one needing all Unison Battlers to use it together, all Unison Invokees should pay an action slot and the cost of that skill/item too, in order to use it.
Unison Battler Recognitions
Recognizing the Unison Battlers for an Unison Skill/Item can be as simple as letting unison skill/item plugin users to add a new skill/item notetag like this(DoubleX RMMV Unison Item Config v101b):
* 1. <unison item actors: ids>
* - Sets the list of id of actors needed for the skill/item as ids
* , is used to separate the actor id in ids
* E.g.:
* <unison item actors: 1> means actor with id 1 is needed to use it
* <unison item actors: 4, 2> means actors with id 4 and 2 are
* needed to use it
* - All actors included in ids needs to be inputable, able to use the
* skills/item and pay its cost
* - All unison actors will pay the unison skill costs after using it
* - Only actors included in ids can select the skill/item
* - If ids only contains 1 actor id, this notetag will become only
* letting the actor with that actor id to use the skill/item
Unison Skill/Item Cost Implementations
A natural implementation for the skill/item cost is to ask all Unison Battlers to say the same skill/item cost upon using it(DoubleX RMMV Unison Item Config v100f):
GB.useItem = Game_Battler.prototype.useItem;
Game_Battler.prototype.useItem = function(item) {
// Rewritten to ask all unison invokees to pay the skill/item cost only
if (!DataManager.isSkill(item)) {
return GB.useItem.apply(this, arguments);
} else if (item.meta.unisonItemActors.length <= 1) {
return GB.useItem.apply(this, arguments);
}
item.meta.unisonItemActors.forEach(function(actorId) {
$gameActors.actor(actorId).paySkillCost(item);
});
//
}; // Game_Battler.prototype.useItem
GB.useItem = Game_Battler.prototype.useItem;
Game_Battler.prototype.useItem = function(item) {
// Rewritten to ask all unison invokees to pay the skill/item cost only
if (!DataManager.isSkill(item)) {
return GB.useItem.apply(this, arguments);
} else if (item.meta.unisonItemActors.length <= 1) {
return GB.useItem.apply(this, arguments);
}
item.meta.unisonItemActors.forEach(function(actorId) {
$gameActors.actor(actorId).paySkillCost(item);
});
//
}; // Game_Battler.prototype.useItem
To let different Unison Battlers pay different skill/item costs, some new configurations can be added(DoubleX RMMV Unison Item Config v101b):
* 4. (v1.01a+)<unison item actor mp cost: costs>
* - Sets the list of mp costs needed for each of the corresponding id
* of the unison actor in <unison item actors: ids>
* , is used to separate the mp costs in ids
* E.g.:
* If <unison item actors: 1> is used, then
* <unison item actor mp cost: 5> means actor with id 1 needs to pay
* the 5 mp cost for using the unison skill/item
* If <unison item actors: 4, 2> is used, then
* <unison item actor mp cost: 5, 10> means actor with id 4 and 2
* need to pay the 5 and 10 mp cost respectively for using the
* unison skill/item
* If <unison item actors: 4, 2> is used, then
* <unison item actor mp cost: 5> means actor with id 4 needs to pay
* the 5 mp cost while that with id 2 needs to pay the default
* skill/item mp cost for using the unison skill/item
* - MCR will be applied to the mp costs for all unison actors
* 5. (v1.01a+)<unison item actor tp cost: costs>
* - Sets the list of tp costs needed for each of the corresponding id
* of the unison actor in <unison item actors: ids>
* , is used to separate the tp costs in ids
* E.g.:
* If <unison item actors: 1> is used, then
* <unison item actor tp cost: 5> means actor with id 1 needs to pay
* the 5 tp cost for using the unison skill/item
* If <unison item actors: 4, 2> is used, then
* <unison item actor tp cost: 5, 10> means actor with id 4 and 2
* need to pay the 5 and 10 tp cost respectively for using the
* unison skill/item
* If <unison item actors: 4, 2> is used, then
* <unison item actor tp cost: 5> means actor with id 4 needs to pay
* the 5 tp cost while that with id 2 needs to pay the default
* skill/item tp cost for using the unison skill/item
* - Sets the list of mp costs needed for each of the corresponding id
* of the unison actor in <unison item actors: ids>
* , is used to separate the mp costs in ids
* E.g.:
* If <unison item actors: 1> is used, then
* <unison item actor mp cost: 5> means actor with id 1 needs to pay
* the 5 mp cost for using the unison skill/item
* If <unison item actors: 4, 2> is used, then
* <unison item actor mp cost: 5, 10> means actor with id 4 and 2
* need to pay the 5 and 10 mp cost respectively for using the
* unison skill/item
* If <unison item actors: 4, 2> is used, then
* <unison item actor mp cost: 5> means actor with id 4 needs to pay
* the 5 mp cost while that with id 2 needs to pay the default
* skill/item mp cost for using the unison skill/item
* - MCR will be applied to the mp costs for all unison actors
* 5. (v1.01a+)<unison item actor tp cost: costs>
* - Sets the list of tp costs needed for each of the corresponding id
* of the unison actor in <unison item actors: ids>
* , is used to separate the tp costs in ids
* E.g.:
* If <unison item actors: 1> is used, then
* <unison item actor tp cost: 5> means actor with id 1 needs to pay
* the 5 tp cost for using the unison skill/item
* If <unison item actors: 4, 2> is used, then
* <unison item actor tp cost: 5, 10> means actor with id 4 and 2
* need to pay the 5 and 10 tp cost respectively for using the
* unison skill/item
* If <unison item actors: 4, 2> is used, then
* <unison item actor tp cost: 5> means actor with id 4 needs to pay
* the 5 tp cost while that with id 2 needs to pay the default
* skill/item tp cost for using the unison skill/item
And the below implementations can be added(DoubleX RMMV Unison Item Config v101b):
GBB.skillMpCost = Game_BattlerBase.prototype.skillMpCost;
Game_BattlerBase.prototype.skillMpCost = function(skill) {
// Returns corresponding mp cost in <unison item actor mp cost: costs>
if (this.isActor()) {
var index = skill.meta.unisonItemActors.indexOf(this.actorId());
if (index >= 0) {
var mpCost = skill.meta.unisonItemActorMpCosts[index];
if (!isNaN(mpCost)) { return Math.floor(mpCost * this.mcr); }
}
}
//
return GBB.skillMpCost.apply(this, arguments);
}; // Game_BattlerBase.prototype.skillMpCost
GBB.skillTpCost = Game_BattlerBase.prototype.skillTpCost;
Game_BattlerBase.prototype.skillTpCost = function(skill) {
// Returns corresponding tp cost in <unison item actor tp cost: costs>
if (this.isActor()) {
var index = skill.meta.unisonItemActors.indexOf(this.actorId());
if (index >= 0) {
var tpCost = skill.meta.unisonItemActorTpCosts[index];
if (!isNaN(tpCost)) { return tpCost; }
}
}
//
return GBB.skillTpCost.apply(this, arguments);
}; // Game_BattlerBase.prototype.skillTpCost
Game_BattlerBase.prototype.skillMpCost = function(skill) {
// Returns corresponding mp cost in <unison item actor mp cost: costs>
if (this.isActor()) {
var index = skill.meta.unisonItemActors.indexOf(this.actorId());
if (index >= 0) {
var mpCost = skill.meta.unisonItemActorMpCosts[index];
if (!isNaN(mpCost)) { return Math.floor(mpCost * this.mcr); }
}
}
//
return GBB.skillMpCost.apply(this, arguments);
}; // Game_BattlerBase.prototype.skillMpCost
GBB.skillTpCost = Game_BattlerBase.prototype.skillTpCost;
Game_BattlerBase.prototype.skillTpCost = function(skill) {
// Returns corresponding tp cost in <unison item actor tp cost: costs>
if (this.isActor()) {
var index = skill.meta.unisonItemActors.indexOf(this.actorId());
if (index >= 0) {
var tpCost = skill.meta.unisonItemActorTpCosts[index];
if (!isNaN(tpCost)) { return tpCost; }
}
}
//
return GBB.skillTpCost.apply(this, arguments);
}; // Game_BattlerBase.prototype.skillTpCost
Unison Skill/Item Action Slot Implementations
The goal of implementing the Unison Skill/Item action slot mechanisms is to ensure all Unison Invokees will also pay at least 1 action slot in order to behave like executing the Unison Skill/Item together with the Unison Invoker. However, how this can be implemented heavily depends on the action input mechanisms of the battle system the unison skill/item plugins are working with.
For example:
- In the default RMMV battle system, each Unison Skill/Item will have to reserve some empty action slots from each Unison Invokee by making those action slots inaccessible by the players, thus making those action slots not being able to store actions. It means an Unison Skill/Item can only be usable when all Unison Invokees have enough empty action slots to be reserved by that Unison Skill/Item.
- In an ATB/CTB/ITB system, there will be 2 types of Unison Skills/Items:
1. A Synchronous Unison Skill/Item is an Unison Skill/Item needing all Unison Battlers to have enough empty action slots for it to be inputable.
2. An Asynchronous Unison Skill/Item is an Unison Skill/Item needing any Unison Battlers to have enough empty action slots for it to be inputable, and all Unison Battlers to have enough empty action slots for it to be executed.
For instance, the action slot implementations for a Synchronous Unison Skill/Item in an ATB system where no battler can have more than 1 action slots at the same time(the implementations will be significantly more complicated and convoluted with this restriction removed) can be as simple as checking whether all Unison Battlers are inputable and make all Unison Invokees to become not inputable when the Unison Invoker has inputted the Unison Skill/Item.
These 2 cases are sufficient to show how much the Unison Skill/Item action slot implementations depend on the action input mechanisms of the battle system the unison skill/item plugins are working with. Therefore it's be more desirable to discuss this for each battle system example in each subsequent reply.
(On a side note: All Unison Skills/Items in the default RMMV battle system are Synchronous Unison Skills/Items, as all battlers must completely input all their action slots before any Unison Skill/Item can be executed.)
P.S.: The item usability check in the item window can be outsourced to the battler skill/item usability check this way(DoubleX RMMV Unison Item Config v101b):
UI.Window_ItemList = {};
var WIL = UI.Window_ItemList;
WIL.isEnabled = Window_ItemList.prototype.isEnabled;
Window_ItemList.prototype.isEnabled = function(item) {
// Rewritten to disable unison items when unison conditions aren't met
if (!DataManager.isItem(item)) {
return WIL.isEnabled.apply(this, arguments);
} else if (item.meta.unisonItemActors.length <= 1) {
return WIL.isEnabled.apply(this, arguments);
} else if (SceneManager.scene.constructor !== Scene_Battle) {
return WIL.isEnabled.apply(this, arguments);
}
var actor = BattleManager.actor();
return actor && actor.canUse(item);
//
}; // Window_ItemList.prototype.isEnabled
For example:
- In the default RMMV battle system, each Unison Skill/Item will have to reserve some empty action slots from each Unison Invokee by making those action slots inaccessible by the players, thus making those action slots not being able to store actions. It means an Unison Skill/Item can only be usable when all Unison Invokees have enough empty action slots to be reserved by that Unison Skill/Item.
- In an ATB/CTB/ITB system, there will be 2 types of Unison Skills/Items:
1. A Synchronous Unison Skill/Item is an Unison Skill/Item needing all Unison Battlers to have enough empty action slots for it to be inputable.
2. An Asynchronous Unison Skill/Item is an Unison Skill/Item needing any Unison Battlers to have enough empty action slots for it to be inputable, and all Unison Battlers to have enough empty action slots for it to be executed.
For instance, the action slot implementations for a Synchronous Unison Skill/Item in an ATB system where no battler can have more than 1 action slots at the same time(the implementations will be significantly more complicated and convoluted with this restriction removed) can be as simple as checking whether all Unison Battlers are inputable and make all Unison Invokees to become not inputable when the Unison Invoker has inputted the Unison Skill/Item.
These 2 cases are sufficient to show how much the Unison Skill/Item action slot implementations depend on the action input mechanisms of the battle system the unison skill/item plugins are working with. Therefore it's be more desirable to discuss this for each battle system example in each subsequent reply.
(On a side note: All Unison Skills/Items in the default RMMV battle system are Synchronous Unison Skills/Items, as all battlers must completely input all their action slots before any Unison Skill/Item can be executed.)
P.S.: The item usability check in the item window can be outsourced to the battler skill/item usability check this way(DoubleX RMMV Unison Item Config v101b):
UI.Window_ItemList = {};
var WIL = UI.Window_ItemList;
WIL.isEnabled = Window_ItemList.prototype.isEnabled;
Window_ItemList.prototype.isEnabled = function(item) {
// Rewritten to disable unison items when unison conditions aren't met
if (!DataManager.isItem(item)) {
return WIL.isEnabled.apply(this, arguments);
} else if (item.meta.unisonItemActors.length <= 1) {
return WIL.isEnabled.apply(this, arguments);
} else if (SceneManager.scene.constructor !== Scene_Battle) {
return WIL.isEnabled.apply(this, arguments);
}
var actor = BattleManager.actor();
return actor && actor.canUse(item);
//
}; // Window_ItemList.prototype.isEnabled
Unison Skill/Item Damage Formula
As the Unison Invoker is the only battler actually using the Unison Skill/Item, its damage formula will only use the stats of that battler if nothing else's changed.
But Unison Skills/Items are supposed to be used by all Unison Battlers, so all their stats, not just those of the Unison Invoker, should be used in the damage formula of the Unison Skill/Item.
While the damage formula can be coded to include stats of Unison Invokees as well via $gameActors.actor(actorId).stat, this approach can needlessly and quickly complicate the damage formula.
An alternative of this can be something like these(DoubleX RMMV Unison Item Config v101b):
Parameter -
* @param unisonFunctionRule
* @desc Sets the string of the rule used for setting the user's functions in
* the damage formula of the unison skill/item by using those of all
* unison battlers
* It'll only be used for those functions not having their unison rules
* It must be implemented by function RULES, which must be edited by
* opening the plugin js file directly
* @default avg
But Unison Skills/Items are supposed to be used by all Unison Battlers, so all their stats, not just those of the Unison Invoker, should be used in the damage formula of the Unison Skill/Item.
While the damage formula can be coded to include stats of Unison Invokees as well via $gameActors.actor(actorId).stat, this approach can needlessly and quickly complicate the damage formula.
An alternative of this can be something like these(DoubleX RMMV Unison Item Config v101b):
Parameter -
* @param unisonFunctionRule
* @desc Sets the string of the rule used for setting the user's functions in
* the damage formula of the unison skill/item by using those of all
* unison battlers
* It'll only be used for those functions not having their unison rules
* It must be implemented by function RULES, which must be edited by
* opening the plugin js file directly
* @default avg
Notetags -
* 2. <unison item function rule: rule>
* - Sets the rule of setting user's function in the skill/item's
* damage formula as rule which is implemented by function
* RULES, which must be edited by opening the plugin js file
* directly
* - function must be a battler function name included in
* FUNCTIONS, which must be edited by opening the plugin js file
* directly
* 3. <unison item function actors: ids>
* - Sets user's function in the skill/item's damage formula to use
* its unison item rule to combine those of actors with id included
* in ids
* E.g.:
* <unison item atk actors: 1> means the user's atk in its damage
* formula uses that of actor with id 1 under the skill/item's
* unison rule applied to atk
* <unison item mat actors: 4, 2> means the user's mat in its damage
* formula uses those of actors with id 4 and 2 under the
* skill/item's unison rule applied to mat
* - function must be a battler function name included in
* FUNCTIONS, which must be edited by opening the plugin js file
* directly
* - Sets the rule of setting user's function in the skill/item's
* damage formula as rule which is implemented by function
* RULES, which must be edited by opening the plugin js file
* directly
* - function must be a battler function name included in
* FUNCTIONS, which must be edited by opening the plugin js file
* directly
* 3. <unison item function actors: ids>
* - Sets user's function in the skill/item's damage formula to use
* its unison item rule to combine those of actors with id included
* in ids
* E.g.:
* <unison item atk actors: 1> means the user's atk in its damage
* formula uses that of actor with id 1 under the skill/item's
* unison rule applied to atk
* <unison item mat actors: 4, 2> means the user's mat in its damage
* formula uses those of actors with id 4 and 2 under the
* skill/item's unison rule applied to mat
* - function must be a battler function name included in
* FUNCTIONS, which must be edited by opening the plugin js file
* directly
Configurations -
/* Implements the unison item function rules
* The unison item function rule can be referenced by rule
* The Array of unison item function value of all unison battlers can be
* referneced by vals
* RULES will be bound to the unison invoker upon use
* It must return a Number
*/
RULES: function(rule, vals) {
if (rule === "min") {
return vals.sort(function(a, b) { return a - b; })[0];
} else if (rule === "avg") {
return vals.reduce(function(a, b) { return a + b; }) / vals.length;
} else if (rule === "max") {
return vals.sort(function(a, b) { return b - a; })[0];
}
console.log("The unison item rule " + rule + " isn't implemented");
return 0;
},
/* Sets the battler functions using the unison item rules
* Its property names must be the class of the battler functions
* Its values must be those battler functions as Strings
* All the included battler functions will be extended
*/
FUNCTIONS: {
/* General form:
* class: [
* "battler function name",
* "battler function name",
* "battler function name",
* ...,
* "battler function name"
* ]
*/
Game_BattlerBase: [
"param",
"xparam",
"sparam"
// Adds new battler function names here
]
// Adds new classes here
}
* The unison item function rule can be referenced by rule
* The Array of unison item function value of all unison battlers can be
* referneced by vals
* RULES will be bound to the unison invoker upon use
* It must return a Number
*/
RULES: function(rule, vals) {
if (rule === "min") {
return vals.sort(function(a, b) { return a - b; })[0];
} else if (rule === "avg") {
return vals.reduce(function(a, b) { return a + b; }) / vals.length;
} else if (rule === "max") {
return vals.sort(function(a, b) { return b - a; })[0];
}
console.log("The unison item rule " + rule + " isn't implemented");
return 0;
},
/* Sets the battler functions using the unison item rules
* Its property names must be the class of the battler functions
* Its values must be those battler functions as Strings
* All the included battler functions will be extended
*/
FUNCTIONS: {
/* General form:
* class: [
* "battler function name",
* "battler function name",
* "battler function name",
* ...,
* "battler function name"
* ]
*/
Game_BattlerBase: [
"param",
"xparam",
"sparam"
// Adds new battler function names here
]
// Adds new classes here
}
Which can be implemented this way(DoubleX RMMV Unison Item Config v101b):
UI.Game_Action = {};
var GA = UI.Game_Action;
GA.makeDamageValue = Game_Action.prototype.makeDamageValue;
Game_Action.prototype.makeDamageValue = function(target, critical) {
// Added to set all user functions to use their unison item rules
var item = this.item(), subject = this.subject();
if (subject.isActor() && item.meta.unisonItemActors.length > 1) {
subject.unisonItem = item;
}
//
var value = GA.makeDamageValue.apply(this, arguments);
subject.unisonItem = null; // Added to set all user functions to normal
return value;
}; // Game_Action.prototype.makeDamageValue
var GA = UI.Game_Action;
GA.makeDamageValue = Game_Action.prototype.makeDamageValue;
Game_Action.prototype.makeDamageValue = function(target, critical) {
// Added to set all user functions to use their unison item rules
var item = this.item(), subject = this.subject();
if (subject.isActor() && item.meta.unisonItemActors.length > 1) {
subject.unisonItem = item;
}
//
var value = GA.makeDamageValue.apply(this, arguments);
subject.unisonItem = null; // Added to set all user functions to normal
return value;
}; // Game_Action.prototype.makeDamageValue
Code:
var Proto;
for (var K in UI.FUNCTIONS) {
if (!UI.FUNCTIONS.hasOwnProperty(K)) { continue; }
UI[K] = UI[K] || {}; // Ensures container GBB and GB won't be rewritten
Proto = eval(K + ".prototype"); // Actual class prototype
UI.FUNCTIONS[K].forEach(function(f) {
/*------------------------------------------------------------
* Extends all battler functions using unison item rules
*------------------------------------------------------------*/
UI[K][f] = Proto[f];
Proto[f] = new Function([
"var UI = DoubleX_RMMV.Unison_Item, item = this._unisonItem;",
"if (!item) {",
" return UI." + K + "." + f + ".apply(this, arguments);",
"}",
"var actorIds = item.meta.unisonItemFunctionActors." + f + ";",
"if (!actorIds) {",
" return UI." + K + "." + f + ".apply(this, arguments);",
"}",
"var args = arguments;",
"var vals = actorIds.map(function(actorId) {",
" var actor = $gameActors.actor(actorId);",
" return UI." + K + "." + f + ".apply(actor, args);",
"});",
"var rule = item.meta.unisonItemRules." + f + ";",
"rule = rule || $gameSystem.unisonItem.unisonFunctionRule;",
"return UI.RULES.call(this, rule, vals);",
].join("\n"));
});
}
Battle Log Window
The default RMMV battle log window shows who're using the actions to be executed.
As only the Unison Invoker will actually use the Unison Skill/Item, the default RMMV battle log window will only show the name of the Unison Invoker if nothing else's changed.
So it'd be desirable to let unison skill/item plugin users to change the battle log window to show the name of all Unison Battlers.
1 such example is this(DoubleX RMMV Unison Item Config v101b):
* @param showAllUnisonBattlers
* @desc Sets if the battlelog will show all unison battlers instead of only
* the unison invoker
* @default true
As only the Unison Invoker will actually use the Unison Skill/Item, the default RMMV battle log window will only show the name of the Unison Invoker if nothing else's changed.
So it'd be desirable to let unison skill/item plugin users to change the battle log window to show the name of all Unison Battlers.
1 such example is this(DoubleX RMMV Unison Item Config v101b):
* @param showAllUnisonBattlers
* @desc Sets if the battlelog will show all unison battlers instead of only
* the unison invoker
* @default true
Which can be implemented like this(DoubleX RMMV Unison Item Config v101b):
UI.Window_BattleLog = {};
var WBL = UI.Window_BattleLog;
WBL.performActionStart = Window_BattleLog.prototype.performActionStart;
Window_BattleLog.prototype.performActionStart = function(subject, action) {
// v1.00f+
// Rewritten to ask all unison actor sprites to perform act start
action.item().meta.unisonItemActors.forEach(function(actorId) {
$gameActors.actor(actorId).performActionStart(action);
});
//
}; // Window_BattleLog.prototype.performActionStart
WBL.performAction = Window_BattleLog.prototype.performAction;
Window_BattleLog.prototype.performAction = function(subject, action) {
// v1.00f+
// Rewritten to ask all unison actor sprites to perform act
action.item().meta.unisonItemActors.forEach(function(actorId) {
$gameActors.actor(actorId).performAction(action);
});
//
}; // Window_BattleLog.prototype.performActionStart
WBL.displayAction = Window_BattleLog.prototype.displayAction;
Window_BattleLog.prototype.displayAction = function(subject, item) {
// Rewritten to display all unison actor names if users set so
if (!subject.isActor()) {
return WBL.displayAction.apply(this, arguments);
} else if (!$gameSystem.unisonItem.showAllUnisonBattlers) {
return WBL.displayAction.apply(this, arguments);
} else if (item.meta.unisonItemActors.length <= 1) {
return WBL.displayAction.apply(this, arguments);
}
WBL.displayUnisonAct.call(this, item);
//
}; // Window_BattleLog.prototype.displayAction
WBL.displayUnisonAct = function(item) {
var names = WBL.unisonActorNames(item.meta.unisonItemActors);
var numMethods = this._methods.length;
if (DataManager.isSkill(item)) {
if (item.message1) {
this.push('addText', names + item.message1.format(item.name));
}
if (item.message2) {
this.push('addText', item.message2.format(item.name));
}
} else {
var text = TextManager.useItem.format(names, item.name);
this.push('addText', text);
}
if (this._methods.length === numMethods) { this.push('wait'); }
}; // WBL.displayUnisonAct
WBL.unisonActorNames = function(actorIds) {
var names = "";
for (var index = 0, length = actorIds.length; index < length; index++) {
if (index > 0 && index < length - 1) {
names += ", ";
} else if (index === length - 1) {
names += " and ";
}
names += $gameActors.actor(actorIds[index]).name();
}
return names;
}; // WBL.unisonActorNames
var WBL = UI.Window_BattleLog;
WBL.performActionStart = Window_BattleLog.prototype.performActionStart;
Window_BattleLog.prototype.performActionStart = function(subject, action) {
// v1.00f+
// Rewritten to ask all unison actor sprites to perform act start
action.item().meta.unisonItemActors.forEach(function(actorId) {
$gameActors.actor(actorId).performActionStart(action);
});
//
}; // Window_BattleLog.prototype.performActionStart
WBL.performAction = Window_BattleLog.prototype.performAction;
Window_BattleLog.prototype.performAction = function(subject, action) {
// v1.00f+
// Rewritten to ask all unison actor sprites to perform act
action.item().meta.unisonItemActors.forEach(function(actorId) {
$gameActors.actor(actorId).performAction(action);
});
//
}; // Window_BattleLog.prototype.performActionStart
WBL.displayAction = Window_BattleLog.prototype.displayAction;
Window_BattleLog.prototype.displayAction = function(subject, item) {
// Rewritten to display all unison actor names if users set so
if (!subject.isActor()) {
return WBL.displayAction.apply(this, arguments);
} else if (!$gameSystem.unisonItem.showAllUnisonBattlers) {
return WBL.displayAction.apply(this, arguments);
} else if (item.meta.unisonItemActors.length <= 1) {
return WBL.displayAction.apply(this, arguments);
}
WBL.displayUnisonAct.call(this, item);
//
}; // Window_BattleLog.prototype.displayAction
WBL.displayUnisonAct = function(item) {
var names = WBL.unisonActorNames(item.meta.unisonItemActors);
var numMethods = this._methods.length;
if (DataManager.isSkill(item)) {
if (item.message1) {
this.push('addText', names + item.message1.format(item.name));
}
if (item.message2) {
this.push('addText', item.message2.format(item.name));
}
} else {
var text = TextManager.useItem.format(names, item.name);
this.push('addText', text);
}
if (this._methods.length === numMethods) { this.push('wait'); }
}; // WBL.displayUnisonAct
WBL.unisonActorNames = function(actorIds) {
var names = "";
for (var index = 0, length = actorIds.length; index < length; index++) {
if (index > 0 && index < length - 1) {
names += ", ";
} else if (index === length - 1) {
names += " and ";
}
names += $gameActors.actor(actorIds[index]).name();
}
return names;
}; // WBL.unisonActorNames
Unison Skill/Item Plugin Structure
As mentioned, the Unison Skill/Item action slot implementations depend on the action input mechanisms of the battle system the unison skill/item plugins to work with.
It alone means it'd be more desirable to make an unison skill/item plugin for each specific battle system, rather than 1 trying to target all battle systems, since the Unison Skill/Item action slot implementations is the core Unison Skill/Item mechanism.
On the other hand, some uinson skill/item plugin implementations doesn't depend much on any battle system, like the Unison Skill/Item cost, damage formula and perhaps the battle log window.
It alone implies it'd be more desirable to make an unison skill/item plugin for all battle systems.
Combining, an excellent enough compromise is to make 1 unison skill/item plugin implementing all those common parts, and make 1 unison skill/item plugin for each specific battle system implementing all parts heavily depending on that battle system. All the latters will need the former to work.
As an example:
- DoubleX RMMV Unison Item Config stores all configurations and implements the Unison Skill/Item cost, damage formula and the battle log window.
- DoubleX RMMV Unison Item Default, which needs DoubleX RMMV Unison Item Config and targets the default RMMV battle system, implements the action input mechanisms that works with that battle system.
- DoubleX RMMV Unison Item YEP_X_BattleSysCTB, which DoubleX RMMV Unison Item Config, DoubleX RMMV Unison Item Default(as YEP_X_BattleSysCTB can be disabled on the fly) and targets YEP_X_BattleSysCTB, implements the action input mechanisms that works with that battle system.
That's all for now. Later I'll add subsequent replies showing how unison skill/item plugins can be worked with various battle system examples
It alone means it'd be more desirable to make an unison skill/item plugin for each specific battle system, rather than 1 trying to target all battle systems, since the Unison Skill/Item action slot implementations is the core Unison Skill/Item mechanism.
On the other hand, some uinson skill/item plugin implementations doesn't depend much on any battle system, like the Unison Skill/Item cost, damage formula and perhaps the battle log window.
It alone implies it'd be more desirable to make an unison skill/item plugin for all battle systems.
Combining, an excellent enough compromise is to make 1 unison skill/item plugin implementing all those common parts, and make 1 unison skill/item plugin for each specific battle system implementing all parts heavily depending on that battle system. All the latters will need the former to work.
As an example:
- DoubleX RMMV Unison Item Config stores all configurations and implements the Unison Skill/Item cost, damage formula and the battle log window.
- DoubleX RMMV Unison Item Default, which needs DoubleX RMMV Unison Item Config and targets the default RMMV battle system, implements the action input mechanisms that works with that battle system.
- DoubleX RMMV Unison Item YEP_X_BattleSysCTB, which DoubleX RMMV Unison Item Config, DoubleX RMMV Unison Item Default(as YEP_X_BattleSysCTB can be disabled on the fly) and targets YEP_X_BattleSysCTB, implements the action input mechanisms that works with that battle system.
That's all for now. Later I'll add subsequent replies showing how unison skill/item plugins can be worked with various battle system examples
Last edited by a moderator:

