DoubleX RMMV Substitute Edit
#1
DoubleX RMMV Substitute Edit

Version: v1.00b

Introduction

* Lets you sets conditions determining the battler to substitute

Prerequisites

*Little Javascript coding proficiency to fully utilize this plugin

Script

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

 *    ## Plugin Info                                                          
 *----------------------------------------------------------------------------
 *    # Plugin Name                                                           
 *      DoubleX RMMV Substitute Edit                                          
 *----------------------------------------------------------------------------
 *    # 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. Little Javascript coding proficiency to fully utilize this plugin  
 *----------------------------------------------------------------------------
 *    # Links                                                                 
 *      This plugin:                                                          
 *      1. http://pastebin.com/6TGXWV1w                                       
*      Mentioned Patreon Supporters:
*      https://www.patreon.com/posts/71738797
 *----------------------------------------------------------------------------
 *    # Author                                                                
 *      DoubleX                                                               
 *----------------------------------------------------------------------------
 *    # Changelog                                                             
 *      v1.00b(GMT 1500 21-12-2015):                                          
 *      1. Fixed typos and calling function via call instead of directly bug  
 *      v1.00a(GMT 1500 19-12-2015):                                          
 *      1. 1st version of this plugin finished                                
 *============================================================================*/
/*:
 * @plugindesc Lets you sets conditions determining the battler to substitute
 * @author DoubleX
 *
 * @param substituteMissed
 * @desc Sets if substitutions will take place if the skill/item would miss
 *       This feature's not implemented yet but will possibly be implemented
 * @default false
 *
 * @param substituteEvaded
 * @desc Sets if substitutions will take place if the original target would
 *       evade the skill/item
 *       This feature's not implemented yet but will possibly be implemented
 * @default false
 *
 * @param substituteCountered
 * @desc Sets if substitutions will take place if the original target would
 *       counterattack/reflect the skill/item
 * @default false
 *
 * @param substituteCounter
 * @desc Sets if substitutions will take place if the skill/item's a
 *       counterattack/reflection of that of another action
 *       Might cause infinite counter loop with substituteBattlerCounter
 * @default false
 *
 * @param substituteBattlerMiss
 * @desc Sets if the skill/item can miss the substitute battler
 *       This feature's not implemented yet but will possibly be implemented
 * @default true
 *
 * @param substituteBattlerEvade
 * @desc Sets if the substitute battler can evade the skill/item
 *       This feature's not implemented yet but will possibly be implemented
 * @default true
 *
 * @param substituteBattlerCounter
 * @desc Sets if the substitute battler can counterattack/reflect the
 *       skill/item
 *       Might cause infinite counter loop with substituteCounter
 * @default true
 *
 * @param substituteBattlerFilters
 * @desc Sets the list of filters determining which battler to substitute
 *       Only movable battlers having the substitute flag will be considered
 *       The battlers passing the ith filter will proceed to the (i + 1)th one
 *       If only 1 battler passes the ith filter, all the remaining (i + j)th
 *       ones won't be used
 *       If no battler pass the ith filter, all battlers passing the (i - 1)th
 *       one will proceed to the (i + 1)th one
 *       Available filters:
 *       hpMp0 - The battler having 0 hp/mp
 *       immortal - The battler being immune to death
 *       maxCntMrf - The battler having the maximum cnt/mrf
 *       maxEvaMev - The battler having the maximum eva/mev
 *       maxPdrMdr - The battler having the maximum pdr/mdr
 *       maxHpMp - The battler having the maximum hp/mp
 *       maxGrd - The battler having the maximum grd
 *       maxCev - The battler having the maximum cev
 *       All unavailable filters in the list will be ignored
 *       The battler having the smallest party/troop member index will be the
 *       substitute battler if more than 1 battlers pass all filters in the
 *       list
 * @default hpMp0 immortal maxCntMrf maxEvaMev maxPdrMdr maxHpMp maxGrd maxCev
 *
 * @help
 * The plugin file name must be the same as DoubleX_RMMV.Substitute_Edit_File,
 * which must be edited by editing the plugin js file directly
 * The default value of DoubleX_RMMV.Substitute_Edit_File is
 * DoubleX RMMV Substitute Edit v100b
 *============================================================================
 *    ## Plugin Call Info                                                     
 *----------------------------------------------------------------------------
 *    # Configuration manipulations                                           
 *      1. $gameSystem.substituteEdit.param                                   
 *         - Returns the value of param listed in the plugin manager          
 *      2. $gameSystem.substituteEdit.param = val                             
 *         - Sets the value of param listed in the plugin manager as val      
 *         - All $gameSystem.substituteEdit.param changes will be saved       
 *============================================================================
 */

"use strict";
var DoubleX_RMMV = DoubleX_RMMV || {};
DoubleX_RMMV["Substitute Edit"] = "v1.00b";

// The plugin file name must be the same as DoubleX_RMMV.Substitute_Edit_File
DoubleX_RMMV.Substitute_Edit_File = "DoubleX RMMV Substitute Edit v100b";

/*============================================================================
 *    ## Plugin Implementations                                               
 *       You need not edit this part as it's about how this plugin works      
 *----------------------------------------------------------------------------
 *    # Plugin Support Info:                                                  
 *      1. Prerequisites                                                      
 *         - Some 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                                                          
 *----------------------------------------------------------------------------*/

DoubleX_RMMV.Substitute_Edit = {};
(function(SE) {

    SE.BattleManager = {};
    var BM = SE.BattleManager;

    /*------------------------------------------------------------------------
     *    New public instance variable                                        
     *------------------------------------------------------------------------*/
    // Read by Game_Unit to get the currently executing action
    Object.defineProperty(BattleManager, "action", {
        get: function() { return this._action; },
        configurable: true
    });

    BattleManager.invokeAction = function(subject, target) {
        this._logWindow.push('pushBaseLine');
        BM.invokeAction.call(this, subject, target); // Rewritten
        subject.setLastTarget(target);
        this._logWindow.push('popBaseLine');
        this.refreshStatus();
    }; // BattleManager.invokeAction

    BattleManager.invokeNormalAction = function(subject, target) {
        BM.invokeNormalAction.call(this, subject, target); // Rewritten
        this._logWindow.displayActionResults(subject, realTarget);
    }; // BattleManager.invokeNormalAction

    BM.invokeCounterAttack = BattleManager.invokeCounterAttack;
    BattleManager.invokeCounterAttack = function(subject, target) {
        // Added
        if ($gameSystem.substituteEdit.substituteCounter) {
            return BM.invokeCounterSubstitute.call(this, subject, target);
        }
        //
        BM.invokeCounterAttack.apply(this, arguments);
    }; // BattleManager.invokeCounterAttack

    BM.invokeMagicReflection = BattleManager.invokeMagicReflection;
    BattleManager.invokeMagicReflection = function(subject, target) {
        if ($gameSystem.substituteEdit.substituteCounter) {
            this._logWindow.displayReflection(target);
            BM.invokeNormalAction.call(this, target, subject);
            this._logWindow.displayActionResults(subject, subject);
            return;
        }
        BM.invokeMagicReflection.apply(this, arguments);
    }; // BattleManager.invokeMagicReflection

    BM.invokeAction = function(subject, target) {
        var se = $gameSystem.substituteEdit;
        var substitute = BM.substituteBattler.call(this, target);
        if (se.substituteCountered && substitute !== target) {
            return this.invokeNormalAction(subject, target);
        } else if (Math.random() < this._action.itemCnt(target)) {
            return this.invokeCounterAttack(subject, target);
        } else if (Math.random() < this._action.itemMrf(target)) {
            return this.invokeMagicReflection(subject, target);
        }
        this.invokeNormalAction(subject, target);
    }; // BM.invokeAction

    BM.substituteBattler = function(target) {
        if (!this.checkSubstitute(target)) { return target; }
        return target.friendsUnit().substituteBattler();
    }; // BM.substituteBattler

    BM.invokeNormalAction = function(subject, target) {
        var realTarget;
        if (!$gameSystem.substituteEdit.substituteBattlerCounter) { return; }
        realTarget = this.applySubstitute(target);
        if (realTarget === target) { return; }
        if (Math.random() < this._action.itemCnt(realTarget)) {
            return this.invokeCounterAttack(subject, realTarget);
        } else if (Math.random() < this._action.itemMrf(realTarget)) {
            return this.invokeMagicReflection(subject, realTarget);
        }
        this._action.apply(realTarget);
    }; // BM.invokeNormalAction

    BM.invokeCounterSubstitute = function(subject, target) {
        var lastAct = this._action;
        this._action = new Game_Action(target);
        this._action.setAttack();
        this._logWindow.displayCounter(target);
        BM.invokeNormalAction.call(this, target, subject);
        this._logWindow.displayActionResults(subject, subject);
        this._action = lastAct;
    }; // BM.invokeCounterSubstitute

    SE.Game_System = {};
    var GS = SE.Game_System;

    /*------------------------------------------------------------------------
     *    New public instance variable                                        
     *------------------------------------------------------------------------*/
    // The storage of all configuration values
    Object.defineProperty(Game_System.prototype, "substituteEdit", {
        get: function() { return this._substituteEdit; },
        configurable: true
    });

    GS.initialize = Game_System.prototype.initialize;
    Game_System.prototype.initialize = function() {
        GS.initialize.apply(this, arguments);
        GS.initSubstituteEditParams.call(this); // Added
    }; // Game_System.prototype.initialize

    GS.initSubstituteEditParams = function() {
        var params, filters;
        this._substituteEdit = {};
        params = PluginManager.parameters(DoubleX_RMMV.Substitute_Edit_File);
        Object.keys(params).forEach(function(param) {
            this._substituteEdit[param] = params[param] === "true";
        }, this);
        filters = params.substituteBattlerFilters.split(/ +/);
        this._substituteEdit.substituteBattlerFilters = filters;
    }; // GS.initSubstituteEditParams

    SE.Game_Action = {};
    var GA = SE.Game_Action;

    /*------------------------------------------------------------------------
     *    Helper function easing checkings in filtering substitute battlers   
     *------------------------------------------------------------------------*/
    GA.effectType = function() {
        return this.isHpEffect() ? "hp" : this.isMpEffect() ? "mp" : null;
    }; // GA.effectType

    /*------------------------------------------------------------------------
     *    Helper function easing checkings in filtering substitute battlers   
     *------------------------------------------------------------------------*/
    GA.hitType = function() {
        return this.isPhysical() ? "pdr" : this.isMagical() ? "mdr" : null;
    }; // GA.hitType

    SE.Game_Unit = {};
    var GU = SE.Game_Unit;

    Game_Unit.prototype.substituteBattler = function() {
        // Rewritten to use all filters in the filter list sequentially as well
        var mems = this.members();
        mems = mems.filter(function(mem) { return mem.isSubstitute(); });
        if (mems.length === 0) { return null; }
        if (mems.length === 1) { return mems[0]; }
        return GU.substituteBattler(mems);
        //
    }; // Game_Unit.prototype.substituteBattler

    // mems: All members that can substitute
    GU.substituteBattler = function(mems) {
        var tempMems, eT = GA.effectType.call(BattleManager.action);
        var hT = GA.hitType.call(BattleManager.action);
        var filters = $gameSystem.substituteEdit.substituteBattlerFilters;
        for (var index = 0, length = filters.length; index < length; index++) {
            tempMems = GU.substituteBattlers(mems, filters[index], eT, hT);
            if (tempMems.length === 1) { return tempMems[0]; }
            if (tempMems.length > 1) { mems = tempMems; }
        }
        return mems[0];
    }; // GU.substituteBattler

    /* mems: All members that can substitute
     * filter: The added filter applied to all members that can substitute
     * effectType: The hp/mp effect type of the currently executing action
     * hitType: The physical/magical hit type of the currently executing action
     */
    GU.substituteBattlers = function(mems, filter, effectType, hitType) {
        // Calls the filter function corresponding to the passed filter
        switch (filter) {
            case "hpMp0": return GU.hpMp0Battlers(mems, effectType);
            case "immortal": return GU.immortalBattlers(mems);
            case "maxCntMrf": return GU.maxCntMrfBattlers(mems, hitType);
            case "maxEvaMev": return GU.maxEvaMevBattlers(mems, hitType);
            case "maxPdrMdr":
                return hitType ? GU.maxParamBattlers(mems, hitType) : mems;
            case "maxHpMp": return GU.maxHpMpBattlers(mems, effectType);
            case "maxGrd": return GU.maxParamBattlers(mems, "grd");
            case "maxCev": return GU.maxParamBattlers(mems, "cev");
            default:
                console.log("Unavailable substitute battler filter " + filter);
                return mems;
        }
        //
    }; // GU.substituteBattlers

    /* mems: All members that can substitute
     * effectType: The hp/mp effect type of the currently executing action
     */
    GU.hpMp0Battlers = function(mems, effectType) {
        if (!effectType) { return mems; }
        return mems.filter(function(mem) { return mem[effectType] === 0; });
    }; // GU.hpMp0Battlers

    // mems: All members that can substitute
    GU.immortalBattlers = function(mems) {
        return mems.filter(function(mem) {
            return mem.isStateResist(mem.deathStateId());
        });
    }; // GU.immortalBattlers

    /* mems: All members that can substitute
     * hitType: The physical/magical hit type of the currently executing action
     */
    GU.maxCntMrfBattlers = function(mems, hitType) {
        var counter = hitType === "pdr" ? "cnt" : "mdr" ? "mrf" : null;
        return counter ? GU.maxParamBattlers(mems, counter) : mems;
    }; // GU.maxCntMrfBattlers

    /* mems: All members that can substitute
     * hitType: The physical/magical hit type of the currently executing action
     */
    GU.maxEvaMevBattlers = function(mems, hitType) {
        var evade = hitType === "pdr" ? "eva" : "mdr" ? "mev" : null;
        return evade ? GU.maxParamBattlers(mems, evade) : mems;
    }; // GU.maxEvaMevBattlers

    /* mems: All members that can substitute
     * effectType: The hp/mp effect type of the currently executing action
     */
    GU.maxHpMpBattlers = function(mems, effectType) {
        return effectType ? GU.maxParamBattlers(mems, effectType) : mems;
    }; // GU.maxHpMpBattlers

    /* mems: All members that can substitute
     * param: The param/ExParam/SpParam used to filter the substitute battler
     */
    GU.maxParamBattlers = function(mems, param) {
        var maxParam = mems.slice(0).sort(function(a, b) {
            return b[param] - a[param];
        })[0][param];
        return mems.filter(function(mem) { return mem[param] === maxParam; });
    }; // GU.maxParamBattlers

})(DoubleX_RMMV.Substitute_Edit);

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

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.00b(GMT 1500 21-12-2015):
1. Fixed typos and calling function via call instead of directly bug
v1.00a(GMT 1500 19-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 1500 21-12-2015):
1. Fixed typos and calling function via call instead of directly bug
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,101 12-26-2022, 06:17 AM
Last Post: DoubleX
   DoubleX RMMV Confusion Edit DoubleX 3 7,623 09-09-2022, 11:12 AM
Last Post: DoubleX
   DoubleX RMMV Popularized ATB Clock DoubleX 2 6,466 03-25-2022, 01:04 PM
Last Post: DoubleX
   DoubleX RMMV Status Bars Compatibility DoubleX 0 1,909 02-06-2022, 07:56 AM
Last Post: DoubleX
   DoubleX RMMV Popularized ATB Bar DoubleX 3 8,561 05-19-2021, 06:10 AM
Last Post: DoubleX
   DoubleX RMMV Skill Hotkeys DoubleX 2 5,989 02-13-2021, 04:59 AM
Last Post: DoubleX
   DoubleX RMMZ Skill Item Cooldown DoubleX 4 6,111 02-07-2021, 04:11 PM
Last Post: DoubleX
   DoubleX RMMZ Skill Item Triggers DoubleX 3 5,556 12-26-2020, 04:00 PM
Last Post: DoubleX
   DoubleX RMMZ TPBS Configurations Edit DoubleX 3 5,661 12-25-2020, 12:30 PM
Last Post: DoubleX
   DoubleX RMMV Superlative ATB DoubleX 2 4,459 12-11-2020, 02:25 PM
Last Post: DoubleX



Users browsing this thread: 3 Guest(s)