DoubleX RMMV Linked Battlers
#1
DoubleX RMMV Linked Battlers

Version: v1.00d

Introduction

* Lets users set some states to let their owners share some stats

Prerequisites

* Some Javascript coding proficiency to fully utilize this plugin

Script

Code:
/*============================================================================

 *    ## Plugin Info                                                          
 *----------------------------------------------------------------------------
 *    # Plugin Name                                                           
 *      DoubleX RMMV Linked Battlers                                          
 *----------------------------------------------------------------------------
 *    # Terms Of Use                                                          
 *      You shall keep this plugin's Plugin Info part's contents intact       
 *      You shalln't claim that this plugin's written by anyone other than    
 *      DoubleX or his aliases                                                
 *      None of the above applies to DoubleX or his aliases                   
 *----------------------------------------------------------------------------
 *    # Prerequisites                                                         
 *      Abilities:                                                            
 *      1. Some Javascript coding proficiency to fully utilize this plugin    
 *----------------------------------------------------------------------------
 *    # Links                                                                 
 *      This plugin:                                                          
 *      1. http://pastebin.com/wemL2xFW                                       
*      Mentioned Patreon Supporters:
*      https://www.patreon.com/posts/71738797
 *----------------------------------------------------------------------------
 *    # Author                                                                
 *      DoubleX                                                               
 *----------------------------------------------------------------------------
 *    # Changelog                                                             
 *      v1.00d(GMT 1500 29-1-2016):                                           
 *      1. Fixed undefined g in Proto[func[0]] bug                            
 *      2. Fixed passing getter instead of its name to linkedBattlersStateId  
 *      3. Fixed calling getter via this[getter] instead of this.getter       
 *      4. Fixed state.linkedBattlers instead of state.meta.linkedBattlers bug
 *      5. Fixed adding 2 Arrays instead of concatenating them bug            
 *      6. Fixed undefined battler isStateAdded bug                           
 *      7. Fixed linked battlers' stats being possible to be non-integer bug  
 *      8. Only the target will collapse when some others die at the same time
 *      v1.00c(GMT 1400 31-12-2015):                                          
 *      1. Fixed writing getter contents directly instead of using String bug
 *      v1.00b(GMT 1100 28-12-2015):                                          
 *      1. Fixed unintentionally declaring global variable in strict mode bug
 *      2. Fixed using new Function and class instead of eval and prototype   
 *      v1.00a(GMT 1400 23-12-2015):                                          
 *      1. 1st version of this plugin finished                                
 *============================================================================*/
/*:
 * @plugindesc Lets users set some states to let their owners share some stats
 * @author DoubleX
 *
 * @help
 * You're supposed to edit the plugin js file directly to set notetag values
 *============================================================================
 *    ## Notetag Info                                                         
 *----------------------------------------------------------------------------
 *    # State Notetags:                                                       
 *      1. <linked battlers: LBCX, LBSX, LBWX>                                
 *         - Sets all owners of this state meeting LBCX to share stats        
 *           included in LBSX with weight LBWX applied to each of them when   
 *           any included stat of any included battler changes                
 *         - Only the 1st applicable notetag of the state with the highest    
 *           priority will be applied to the stat change of the linked battler
 *         - If a linked battler can't take all of that battler's share of the
 *           original stat change due to hitting the min/max stat value, thost
 *           not being taken by that battler will be shared by the rest of the
 *           linked battlers also                                             
 *         - The battler originally having a stat to be changed is the last   
 *           linked battler taking the change not shared by any other ones    
 *         - LBCX can be set in Linked Battler Condition Functions            
 *         - LBSX can be set in Linked Battler Stat Functions                 
 *         - LBWX can be set in Linked Battler Weight Functions               
 *============================================================================
 *    ## Plugin Call Info                                                     
 *----------------------------------------------------------------------------
 *    # Configuration manipulations                                           
 *      1. DoubleX_RMMV.Linked_Battlers.prop                                  
 *         - Returns the property prop under DoubleX_RMMV.Linked_Battlers     
 *      2. DoubleX_RMMV.Linked_Battlers.prop = function                       
 *         - Sets the property prop under DoubleX_RMMV.Linked_Battlers as     
 *           function which will be bound to the battler upon use             
 *         - No DoubleX_RMMV.Linked_Battlers.prop change will be saved        
 *    # State manipulations                                                   
 *      All meta.linkedBattlers changes can be saved if                       
 *      DoubleX RMMV Dynamic Data is used                                     
 *      1. meta.linkedBattlers                                                
 *         - Returns an Array of all LBCX-LBSX-LBWX triples, each in the form
 *           of [LBCX, LBSX, LBWX]                                            
 *      2. meta.linkedBattlers = [[LBCX, LBSX, LBWX], [LBCX, LBSX, LBWX], ...]
 *         - Resets the Array of all LBCX-LBSX-LBWX triples, each in the form
 *           of [LBCX, LBSX, LBWX], stored sequentially in that Array         
 *      3. meta.linkedBattlers[i] = [LBCX, LBSX, LBWX]                        
 *         - Sets the (i + 1)th LBCX-LBSX-LBWX triple as LBCX-LBSX-LBWX       
 *============================================================================
 */

"use strict";
var DoubleX_RMMV = DoubleX_RMMV || {};
DoubleX_RMMV["Linked Battlers"] = "v1.00d";

/*============================================================================
 *    ## Plugin Configurations                                                
 *       You only need to edit this part as it's about what this plugin does  
 *----------------------------------------------------------------------------*/

DoubleX_RMMV.Linked_Battlers = {

    /*------------------------------------------------------------------------
     *    Linked Battler Condition Functions                                  
     *    - Setups LBCX used by <linked battlers: LBCX, LBSX, LBWX>           
     *------------------------------------------------------------------------*/
    /* LBCX are used in functions included in LINKED_STATS
     * LBCX are functions that will be bound to battler calling them upon use
     * LBCX names can only use alphanumeric characters
     * Each linked battler besides the caller can be referenced by battler
     * The caller will always pass LBCX even when it's supposed to fail
     * The below LBCX are examples added to help you set your LBCX
     * You can freely use, rewrite and/or delete these examples
     */

    // Sets the linked battler condition to include all linked battlers
    LBC1: function(battler) { return true; },

    /* Sets the linked battler condition to include all and no linked battlers
     * if switch with id x is on and off respectively
     */
    LBC2: function(battler) { return $gameSwitches.value(x); },

    // Adds new LBCX here
    

    /*------------------------------------------------------------------------
     *    Linked Battler Stat Functions                                       
     *    - Setups LBSX used by <linked battlers: LBCX, LBSX, LBWX>           
     *------------------------------------------------------------------------*/
    /* LBSX are used in functions included in LINKED_STATS
     * LBSX are functions that will be bound to battlers upon use
     * LBSX names can only use alphanumeric characters
     * It must return an Array, which should include all strings of getter
     * functions of each stat to be included
     * The below LBSX are examples added to help you set your LBSX
     * You can freely use, rewrite and/or delete these examples
     */

    // Sets the linked battler stat to include hp, mp and tp
    LBS1: function() { return ["hp", "mp", "tp"]; },

    // Sets the linked battler stat to include nothing
    LBS2: function() { return []; },

    // Adds new LBSX here
    

    /*------------------------------------------------------------------------
     *    Linked Battler Weight Functions                                     
     *    - Setups LBWX used by <linked battlers: LBCX, LBSX, LBWX>           
     *------------------------------------------------------------------------*/
    /* LBWX are used in functions included in LINKED_STATS
     * LBWX are functions that will be bound to battlers upon use
     * LBWX names can only use alphanumeric characters
     * It must return a Number
     * No stat change will take place for any linked battler if the sum of all
     * weights of all linked battlers is 0
     * Each linked battler besides the caller can be referenced by battler
     * The below LBWX are examples added to help you set your LBWX
     * You can freely use, rewrite and/or delete these examples
     */

    // Sets the linked battler weight to be the same for all linked battlers
    LBW1: function(battler) { return 1; },

    /* Sets the linked battler weight to be multiplied by x if the linked
     * battler is the one having a stat to be changed
     */
    LBW2:  function(battler) { return battler === this ? x : 1; },

    // Adds new LBWX here
    

    /* Sets the battler functions to be used by linked battlers
     * Its property names must be the battler stat getter function names
     * Its values must be Arrays, each containing the battler stat setter
     * function name, the index of the argument as the original new stat value
     * in the stat setter function argument list, and each linked battler's
     * min/max stat value
     * All battler functions as min/max stat value must be referenced by this
     * All the included battler stat getter functions will be extended
     */
    LINKED_STATS: {

      /* General form:
       * FunctionClass: {
       *     getter: ["setter", statArgIndex, "statMin", "statMax"]
       * }
       */

      Game_BattlerBase: {
        /* General form:
         * getter: ["setter", statArgIndex, "statMin", "statMax"]
         */
        hp: ["setHp", 0, "0", "this.mhp"],
        mp: ["setMp", 0, "0", "this.mmp"],
        tp: ["setTp", 0, "0", "this.maxTp()"]
        // Adds new functions here
        
      }

      // Adds new classes here
      

    }

}; // DoubleX_RMMV.Linked_Battlers

/*============================================================================
 *    ## Plugin Implementations                                               
 *       You need not edit this part as it's about how this plugin works      
 *----------------------------------------------------------------------------
 *    # Plugin Support Info:                                                  
 *      1. Prerequisites                                                      
 *         - Decent Javascript coding proficiency to fully comprehend this    
 *           plugin                                                           
 *      2. Function documentation                                             
 *         - The 1st part describes why this function's rewritten/extended for
 *           rewritten/extended functions or what the function does for new   
 *           functions                                                        
 *         - The 2nd part describes what the arguments of the function are    
 *         - The 3rd part informs which version rewritten, extended or created
 *           this function                                                    
 *         - The 4th part informs whether the function's rewritten or new     
 *         - The 5th part informs whether the function's a real or potential  
 *           hotspot                                                          
 *         - The 6th part describes how this function works for new functions
 *           only, and describes the parts added, removed or rewritten for    
 *           rewritten or extended functions only                             
 *         Example:                                                           
 * /*----------------------------------------------------------------------
 *  *    Why rewrite/extended/What this function does                      
 *  *----------------------------------------------------------------------*/
/* // arguments: What these arguments are                                     
 * functionName = function(arguments) { // Version X+; Hotspot                
 *     // Added/Removed/Rewritten to do something/How this function works     
 *     functionContents                                                       
 *     //                                                                     
 * } // functionName                                                          
 *----------------------------------------------------------------------------*/

(function(LB) {

    LB.DataManager = {};
    var DM = LB.DataManager;

    DM.isDatabaseLoaded = DataManager.isDatabaseLoaded;
    DataManager.isDatabaseLoaded = function() {
        // Rewritten
        return DM.isDatabaseLoaded.apply(this, arguments) && DM.loadAllNotes();
        //
    }; // DataManager.isDatabaseLoaded

    DM.loadAllNotes = function() {
        $dataStates.forEach(function(data) {
            if (data) { DM.loadStateNotes(data); }
        });
        return true;
    }; // DM.loadAllNotes

    // data: The data to have its notetags read
    DM.loadStateNotes = function(data) {
        var regExp = /< *linked +battlers *: *(\w+) *, *(\w+) *, *(\w+) *>/i;
        data.meta.linkedBattlers = [];
        var linkedBattlers = data.meta.linkedBattlers;
        // Stores all LBCX-LBSX-LBWX triples in 1 single Array sequentially
        data.note.split(/[\r\n]+/).forEach(function(line) {
            if (!line.match(regExp)) { return; }
            linkedBattlers.push([RegExp.$1, RegExp.$2, RegExp.$3]);
        });
        //
    }; // DM.loadStateNotes

    LB.Game_BattlerBase = {};
    var GBB = LB.Game_BattlerBase, gf = "getLinkedBattlers";

    GBB[gf] = function(stateId, cond) {
        var aliveMems = $gameParty.aliveMembers();
        return aliveMems.concat($gameTroop.aliveMembers()).filter(function(mem) {
            return mem.isStateAffected(stateId) && LB[cond].call(this, mem);
        }, this);
    }; // GBB[gf]

    GBB.linkedBattlersStateId = function(stat) {
        if (!this._states) { return null; }
        var linkedBattlers, states = this.states();
        // Returns the (1st applicable LBCX-LBSX-LBWX triple and state id) pair
        for (var index = 0, length = states.length; index < length; index++) {
            linkedBattlers = states[index].meta.linkedBattlers;
            for (var i = 0, l = linkedBattlers.length; i < l; i++) {
                if (LB[linkedBattlers[i][1]].call(this).indexOf(stat) >= 0) {
                    return [linkedBattlers[i], states[index].id];
                }
            }
        }
        //
        return null;
    }; // GBB.linkedBattlersStateId

    var Proto, Klass, func;
    for (var k in LB.LINKED_STATS) {
        if (!LB.LINKED_STATS.hasOwnProperty(k)) { continue; }
        LB[k] = LB[k] || {}; // Ensures container GBB won't be rewritten
        Proto = eval(k + ".prototype"); // Actual class prototype
        Klass = LB.LINKED_STATS[k]; // Class name as string
        for (var g in Klass) {
            if (!Klass.hasOwnProperty(g)) { continue; }
            func = Klass[g]; // ["setter", statArgIndex, "statMin", "statMax"]

            /*----------------------------------------------------------------
             *    Extends all stat setter functions to have shared stat change
             *----------------------------------------------------------------*/
            LB[k][func[0]] = Proto[func[0]];
            Proto[func[0]] = new Function ([
                "var LB = DoubleX_RMMV.Linked_Battlers;",
                "var lBSI = LB.Game_BattlerBase.linkedBattlersStateId;",
                "this._linkedBattler = lBSI.call(this, '" + g + "');",
                "if (this._linkedBattler) {",
                "    return LB." + k + "." + gf + g + ".apply(this, arguments);",
                "}",
                "LB." + k + "." + func[0] + ".apply(this, arguments);",
            ].join("\n")); // Proto[func[0]]

            /*----------------------------------------------------------------
             *    Redistributes the stat change to all found linked battlers  
             *----------------------------------------------------------------*/
            LB[k][gf + g] = new Function ([
                "var LB = DoubleX_RMMV.Linked_Battlers;",
                "var GBB = LB.Game_BattlerBase;",
                "var lB = this._linkedBattler[0];",
                "var stateId = this._linkedBattler[1];",
                "var mems = GBB." + gf + ".call(this, stateId, lB[0]);",
                "var index = mems.indexOf(this);",
                "if (index >= 0) { mems.splice(index, 1); }",
                "mems.push(this);",
                "var weights = mems.map(function(mem) {",
                "    return LB[lB[2]].call(this, mem);",
                "}, this);",
                "var weightSum = weights.reduce(function(a, b) {",
                "    return a + b;",
                "}, 0);",
                "if (weightSum === 0) { return; }",
                "var statDiff = arguments[" + func[1] + "] - this." + g + ";",
                "var statChange, newStat, minStat, maxStat;",
                "for (var i = 0, l = mems.length; i < l; i++) {",
                "    statChange = statDiff * weights[i] / weightSum;",
                "    statChange = Math.trunc(statChange);",
                "    newStat = mems[i]." + g + " + statChange;",
                "    minStat = LB." + k + ".min" + g + ".call(mems[i]);",
                "    maxStat = LB." + k + ".max" + g + ".call(mems[i]);",
                "    if (newStat < minStat) {",
                "        statChange = mems[i]." + g + " - minStat;",
                "        arguments[" + func[1] + "] = minStat;",
                "    } else if (newStat > maxStat) {",
                "        statChange = maxStat - mems[i]." + g + ";",
                "        arguments[" + func[1] + "] = maxStat;",
                "    } else {",
                "        arguments[" + func[1] + "] = newStat;",
                "    }",
                "    LB." + k + "." + func[0] + ".apply(mems[i], arguments);",
                "    statDiff -= statChange;",
                "    weightSum -= weights[i];",
                "}",
            ].join("\n")); // LB[k][gf + g]

            // Returns the minimum stat value
            LB[k]["min" + g] = new Function("return " + func[2] + ";");

            // Returns the maximum stat value
            LB[k]["max" + g] = new Function("return " + func[3] + ";");

        }
    }

})(DoubleX_RMMV.Linked_Battlers);

/*============================================================================*/

FAQ

* None so far

Credits and Thanks

* None

Author's Notes

* None so far

Terms and Conditions

* You shall keep this plugin's Plugin Info part's contents intact
* You shalln't claim that this plugin's written by anyone other than DoubleX or his aliases
* None of the above applies to DoubleX or his aliases

Changelog

v1.00d(GMT 1500 29-1-2016):
1. Fixed undefined g in Proto[func[0]] bug
2. Fixed passing getter instead of its name to linkedBattlersStateId
3. Fixed calling getter via this[getter] instead of this.getter
4. Fixed state.linkedBattlers instead of state.meta.linkedBattlers bug
5. Fixed adding 2 Arrays instead of concatenating them bug
6. Fixed undefined battler isStateAdded bug
7. Fixed linked battlers' stats being possible to be non-integer bug
8. Only the target will collapse when some others die at the same time
v1.00c(GMT 1400 31-12-2015):
1. Fixed writing getter contents directly instead of using String bug
v1.00b(GMT 0200 27-12-2015):
1. Fixed unintentionally declaring global variable in strict mode bug
2. Fixed using new Function and class instead of eval and prototype
v1.00a(GMT 1400 23-12-2015):
1. 1st version of this script finished
My RMVXA/RMMV/RMMZ scripts/plugins:
http://rpgmaker.net/users/DoubleX/scripts/
Reply }
#2
Updates
v1.00b(GMT 0200 27-12-2015):
1. Fixed unintentionally declaring global variable in strict mode bug
2. Fixed using new Function and class instead of eval and prototype
My RMVXA/RMMV/RMMZ scripts/plugins:
http://rpgmaker.net/users/DoubleX/scripts/
Reply }
#3
Updates
v1.00c(GMT 1400 31-12-2015):
1. Fixed writing getter contents directly instead of using String bug
My RMVXA/RMMV/RMMZ scripts/plugins:
http://rpgmaker.net/users/DoubleX/scripts/
Reply }
#4
Updates
v1.00d(GMT 1500 29-1-2016):
1. Fixed undefined g in Proto[func[0]] bug
2. Fixed passing getter instead of its name to linkedBattlersStateId
3. Fixed calling getter via this[getter] instead of this.getter
4. Fixed state.linkedBattlers instead of state.meta.linkedBattlers bug
5. Fixed adding 2 Arrays instead of concatenating them bug
6. Fixed undefined battler isStateAdded bug
7. Fixed linked battlers' stats being possible to be non-integer bug
8. Only the target will collapse when some others die at the same time
My RMVXA/RMMV/RMMZ scripts/plugins:
http://rpgmaker.net/users/DoubleX/scripts/
Reply }


Possibly Related Threads…
Thread Author Replies Views Last Post
   DoubleX RMMV Popularized ATB Compatibility DoubleX 16 23,236 12-26-2022, 06:17 AM
Last Post: DoubleX
   DoubleX RMMV Confusion Edit DoubleX 3 7,651 09-09-2022, 11:12 AM
Last Post: DoubleX
   DoubleX RMMV Popularized ATB Clock DoubleX 2 6,490 03-25-2022, 01:04 PM
Last Post: DoubleX
   DoubleX RMMV Status Bars Compatibility DoubleX 0 1,922 02-06-2022, 07:56 AM
Last Post: DoubleX
   DoubleX RMMV Popularized ATB Bar DoubleX 3 8,572 05-19-2021, 06:10 AM
Last Post: DoubleX
   DoubleX RMMV Skill Hotkeys DoubleX 2 6,022 02-13-2021, 04:59 AM
Last Post: DoubleX
   DoubleX RMMZ Skill Item Cooldown DoubleX 4 6,150 02-07-2021, 04:11 PM
Last Post: DoubleX
   DoubleX RMMZ Skill Item Triggers DoubleX 3 5,588 12-26-2020, 04:00 PM
Last Post: DoubleX
   DoubleX RMMZ TPBS Configurations Edit DoubleX 3 5,687 12-25-2020, 12:30 PM
Last Post: DoubleX
   DoubleX RMMV Superlative ATB DoubleX 2 4,476 12-11-2020, 02:25 PM
Last Post: DoubleX



Users browsing this thread: 1 Guest(s)