Guest User

Liquid_EnemyEnmity.js (v1.12)

a guest
Nov 6th, 2015
126
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. //=============================================================================
  2. // Liquid Engine - Enemy Enmity
  3. // Liquid_EnemyEnmity.js
  4. //=============================================================================
  5. var Imported = Imported || {};
  6. Imported.Liquid_EnemyEnmity = true;
  7.  
  8. var Liquid = Liquid || {};
  9. Liquid.Enmity = Liquid.Enmity || {};
  10.  
  11. //=============================================================================
  12. /*:
  13.  * @plugindesc v1.12 (Requires YEP_BattleEngineCore.js and YEP_BattleCoreAI.js) Basic functions are
  14.  * added to the Battle Engine and AI Engine to support Enemy Enmity and MMO styled aggro.
  15.  *
  16.  * @author Liquidize
  17.  *
  18.  *
  19.  * @param Max Enmity
  20.  * @desc The maximum value enmity can reach?
  21.  * @default 50000
  22.  *
  23.  * @param Allow Negative
  24.  * @desc Allow Enmity to go into negative values? If false enmity will not change if the end result is below 0, unless enmity is above 0 in which case enmity becomes 0.
  25.  * @default false
  26.  *
  27.  * @param Default Enmity
  28.  * @desc Amount of enmity each battler starts with against all targets, at the begining of a battle.
  29.  * @default 50
  30.  *
  31.  * @param Window X
  32.  * @default (Graphics.boxWidth / 2) - 150
  33.  * @desc The x position of the enmity window.
  34.  *
  35.  * @param Window Y
  36.  * @default 100
  37.  * @desc The y position of the enmity window.
  38.  *
  39.  * @param Face Icon Width
  40.  * @default 48
  41.  * @desc The width in pixels of your face icons.
  42.  *
  43.  * @param Face Icon Height
  44.  * @default 48
  45.  * @desc The height in pixels of your face icons.
  46.  *
  47.  * @param Icon Sheet
  48.  * @default faceicons
  49.  * @desc The icon sheet containing your face icons.
  50.  *
  51.  * @help
  52.  * v1.0 (Requires YEP_BattleEngineCore.js and YEP_BattleCoreAI.js) Basic functions are
  53.  * added to the Battle Engine and AI Engine to support Enemny Enmity and MMO styled aggro.
  54.  * Special thanks to Yanfly for creating an awesome Battle and AI plugin system!
  55.  *
  56.  *
  57.  * USAGE
  58.  *=================================================================================
  59.  * ENMITY Increase/Decreasing:
  60.  * Skills are able to add or decrease the amount of enmity an user has against a
  61.  * target, in the same fashion you change HP,MP or TP. See below.
  62.  *
  63.  * ENMITY +X: target
  64.  * ENMITY -X: target
  65.  * ENMITY +X%: target
  66.  * ENMITY -X%: target
  67.  * ENMITY +VARIABLE X: target
  68.  * ENMITY -VARIABLE X: target
  69.  * ENMITY +VARIABLE X%: target
  70.  * ENMITY -VARIABLE X%: target
  71.  * ------------------------------------------------------------------------------
  72.  * Target(s) gains Enmity towards the user equal to X values. Percentages can be used,
  73.  * but it is based off the MaxEnmity property.
  74.  * -------------------------------------------------------------------------------
  75.  * Usage Example: enmity +5000: user
  76.  *                enmity -variable 50: target
  77.  *                enmity +10%: target
  78.  *                enmity -variable 10: user
  79.  * ===============================================================================
  80.  * Item,Actor,Class,State Tags:
  81.  * Items,Actors,Classes,and States are capable of having some tags as well. These
  82.  * tags are as follows.
  83.  *
  84.  * <Null Enmity Gain> - If an actor,class,or state has this tag, the target(s) are
  85.  * unable to gain enmity against this attacker.
  86.  *
  87.  * <Enmity Rate: +/-x> - If an actor,class,state,weapon,or armor has this tag the
  88.  * rating of enmity gained against the battler with said thing will be increased or
  89.  * decreased by the corresponding value + 1.0 (the base rating)
  90.  *
  91.  * Example:
  92.  * <Enmity Rate: +1.58> - Will give the battler an enmity rating of 2.58.
  93.  *
  94.  * <Bonus Enmity: +/-x> - If an actor,class,state,weapon,or armor has this tag
  95.  * the amount of enmity added on after calculating enmity gain is value x.
  96.  *
  97.  * Example:
  98.  * <Bonus Enmity: +50> - Will give the target 50 additional enmity against the attacker.
  99.  *
  100.  * ===============================================================================
  101.  * Enmity in Battle CoreAI
  102.  * Using enmity to actually target things in battle core ai, is the same as using
  103.  * any other parameter to target something.
  104.  *
  105.  *      Highest Enmity       Selects the target with the highest enmity against the battler.
  106.  *      Lowest Enmity        Selects the target with the lowest enmity against the battler.
  107.  *------------------------------------------------------------------------------
  108.  * Usage Example:
  109.  *                State !== Courage: Cowardice, Lowest Enmity
  110.  *
  111.  * =============================================================================
  112.  * Face Icons
  113.  * Using the Emnity Window Face Icon system is fairly simple. First put an icon
  114.  * sheet in your img/system folder, and call it whatever you want. It has to be
  115.  * a png though. Following that, go into the parameters, and change the value of
  116.  * the Icon Sheet parameter to the name of your file (excluding the .png part).
  117.  * After that, depending on the size of the icons in your icon sheet you may need
  118.  * to change the Face Icon Width and Face Icon Height parameters. Then in the actors
  119.  * database, add a <battleIcon:x> notetag to the notes field. The x value of this
  120.  * notetag is the ID in the icon sheet of the icon you want to use for the face.
  121.  * The ID can be found by starting in the top left corner of your icon sheet,
  122.  * whatever icon is the first in the top left that is ID 0, the icon to the right
  123.  * is ID 1, the ID to the right of 1 is 2. Following that pattern till you get to
  124.  * the edge of the top right corner and go down a row. So for example if
  125.  * your iconsheet is 480x480 and your icons are 48x48 pixels each, there will be
  126.  * 10 icons per row, starting with 0 (top left corner) and below 0 is 10.
  127.  * This logic only works if your icon sheet is 10x the size of your icons individaul
  128.  * width though. But simply remember, the top left icon in the icon sheet will always
  129.  * be 0. Then depending on the size of your icon sheet, go from there.
  130.  *
  131.  * =============================================================================
  132.  * Plugin Commands
  133.  * To change the faceicon dynamically, through an event use the following plugin
  134.  * command.
  135.  *
  136.  * EnmityFace actorid faceid
  137.  *
  138.  * Where actorid is the id of the actor in the database, and faceid is the id of the
  139.  * faceicon you want to use in the icon sheet.
  140.  *
  141.  * =============================================================================
  142.  * Change Log:
  143.  *            1.12:
  144.  *                 - Reverted a fix I attempted to not require overwriting Yanfly
  145.  *                   AI manager functions.
  146.  *            1.1: - Added Enmity Window (Shows who has the most enmity against
  147.  *                  the selected target Most->Least (left to right)).
  148.  *                 - Changed how enmity is stored.
  149.  *                 - Added new enmity tags.
  150.  *                 - No longer directly overwrites Yanflys functions.
  151.  *                 - Added plugin command to change battler face icon dynamically.
  152.  *            1.0: Finished script.
  153.  *          
  154.  *==============================================================================
  155.  */
  156. //==============================================================================
  157.  
  158. // Check if required plugins have been imported.
  159. if (Imported.YEP_BattleAICore && Imported.YEP_BattleEngineCore) {
  160.  
  161.     // EnmityWindow object, located in this namespace.
  162.     Liquid.Enmity.EnmityWindow = null;
  163.    
  164.     //==============================================================================
  165.     // Parameters
  166.     //==============================================================================
  167.     Liquid.Parameters = PluginManager.parameters('Liquid_EnemyEnmity');
  168.     Liquid.Param = Liquid.Param || {};
  169.  
  170.     Liquid.Param.MaxEnmity = Number(Liquid.Parameters['Max Enmity']);
  171.     Liquid.Param.AllowNegativeEmn = Liquid.Parameters['Allow Negative'];
  172.     Liquid.Param.DefaultEnmity = Number(Liquid.Parameters['Default Enmity']);
  173.     Liquid.Param.WindowX = String(Liquid.Parameters['Window X']);
  174.     Liquid.Param.WindowY = String(Liquid.Parameters['Window Y']);
  175.     Liquid.Param.FaceIconWidth = Number(Liquid.Parameters['Face Icon Width']);
  176.     Liquid.Param.FaceIconHeight = Number(Liquid.Parameters['Face Icon Height']);
  177.     Liquid.Param.IconSheet = String(Liquid.Parameters['Icon Sheet']);
  178.    
  179.     //==================================================================================
  180.     // Database Manager
  181.     //==================================================================================
  182.    
  183.     Liquid.Enmity.DataManager_isDatabaseLoaded = DataManager.isDatabaseLoaded;
  184.  
  185.     DataManager.isDatabaseLoaded = function () {
  186.         if (!Liquid.Enmity.DataManager_isDatabaseLoaded.call(this)) return false;
  187.         this.processEnmityNotetags($dataStates);
  188.         this.processEnmityNotetags($dataClasses);
  189.         this.processEnmityNotetags($dataWeapons);
  190.         this.processEnmityNotetags($dataArmors);
  191.         this.processEnmityNotetags($dataEnemies);
  192.         this.processEnmityNotetags($dataActors);
  193.         return true;
  194.     };
  195.  
  196.     DataManager.processEnmityNotetags = function (group) {
  197.         var enmratenote = /<(?:ENMITY RATE|enm rate):[ ]([-+]?[0-9]*\.?[0-9]+)>/i;
  198.         var bonusenmnote = /<(?:BONUS ENMITY|bonus enm):[ ](\d+)>/i;
  199.         for (var n = 1; n < group.length; n++) {
  200.             var obj = group[n];
  201.             var notedata = obj.note.split(/[\r\n]+/);
  202.  
  203.             obj.enmityRate = 0.0;
  204.             obj.bonusEnmity = 0;
  205.             obj.nullEnmity = false;
  206.  
  207.             for (var i = 0; i < notedata.length; i++) {
  208.                 var line = notedata[i];
  209.                 if (line.match(enmratenote)) {
  210.                     obj.enmityRate = parseFloat(RegExp.$1);
  211.                 } else if (line.match(bonusenmnote)) {
  212.                     obj.bonusEnmity = parseInt(RegExp.$1);
  213.                 } else if (line.match(/<(?:Null Enmity Gain)>/i)) {
  214.                     obj.nullEnmity = true;
  215.                 }
  216.             }
  217.         }
  218.     };
  219.  
  220.     //==============================================================================
  221.     // Battle Manager - Yanfly Battle Engine Integration
  222.     //==============================================================================
  223.    
  224.     // Store original functions that we plan to manipulate.
  225.     Liquid.Enmity.BattleManager_processActionSequence = BattleManager.processActionSequence;
  226.     Liquid.Enmity.BattleManager_setup = BattleManager.setup;
  227.     Liquid.Enmity.BattleManager_processVictory = BattleManager.processVictory;
  228.     Liquid.Enmity.BattleManager_processEscape = BattleManager.processEscape;
  229.     Liquid.Enmity.BattleManager_processAbort = BattleManager.processAbort;
  230.     Liquid.Enmity.BattleManager_processDefeat = BattleManager.processDefeat;
  231.    
  232.     // For defeat,abort,victory, and escape. We reset the enmity table.
  233.     BattleManager.processDefeat = function () {
  234.         $gameParty.removeEnmity();
  235.         Liquid.Enmity.BattleManager_processDefeat.call(this);
  236.     };
  237.  
  238.  
  239.     BattleManager.processAbort = function () {
  240.         $gameParty.removeEnmity();
  241.         Liquid.Enmity.BattleManager_processAbort.call(this);
  242.     };
  243.  
  244.     BattleManager.processEscape = function () {
  245.         $gameParty.removeEnmity();
  246.         Liquid.Enmity.BattleManager_processEscape.call(this);
  247.     };
  248.  
  249.     BattleManager.processVictory = function () {
  250.         $gameParty.removeEnmity();
  251.         Liquid.Enmity.BattleManager_processVictory.call(this);
  252.     };
  253.    
  254.     // When the battle starts, setup default enmity table.
  255.     BattleManager.setup = function (troopId, canEscape, canLose) {
  256.  
  257.         Liquid.Enmity.BattleManager_setup.call(this, troopId, canEscape, canLose);
  258.  
  259.         var party = $gameParty.members();
  260.         var troop = $gameTroop.members();
  261.        
  262.         // Build base/default enmity table for all Game_Enemies in the Troop.
  263.         for (var i = 0; i < troop.length; i++) {
  264.             troop[i]._enmitytable = [];
  265.             // Build Base Enmity table against all actors in $gameParty.
  266.             for (var a = 0; a < party.length; a++) {
  267.                 var enmityObj = { "enmity": Liquid.Param.DefaultEnmity, "battler": party[a] };
  268.                 troop[i]._enmitytable[party[a].index()] = enmityObj;
  269.             }
  270.         }
  271.         // Build base enmity for all Game_Actors in Party.
  272.         for (var i = 0; i < party.length; i++) {
  273.             party[i]._enmitytable = [];
  274.             // Build base enmity for all game enemies in troop.
  275.             for (var e = 0; e < troop.length; e++) {
  276.                 var enmityObj = { "enmity": Liquid.Param.DefaultEnmity, "battler": troop[e] };
  277.                 party[i]._enmitytable[troop[e].index()] = enmityObj;
  278.             }
  279.         }
  280.     };
  281.  
  282.     // Process action sequences. Modifying Enmity if needed, as determined
  283.     // by the Yanfly Battle Engine Melody.
  284.     BattleManager.processActionSequence = function (actionName, actionArgs) {
  285.         // ENMITY +/- VALUE
  286.         if (actionName.match(/ENMITY[ ](.*)/i)) {
  287.             return this.actionEnmityModify(actionName, actionArgs);
  288.         }
  289.         return Liquid.Enmity.BattleManager_processActionSequence.call(this,
  290.             actionName, actionArgs);
  291.     };
  292.  
  293.     // Actually modify the enmity targets.
  294.     BattleManager.actionEnmityModify = function (actionName, actionArgs) {
  295.         var targets = this.makeActionTargets(actionArgs[0]);
  296.         if (targets.length < 1) return false;
  297.         var change;
  298.         var percent;
  299.         if (actionName.match(/ENMITY[ ]([+-])(?:VARIABLE|VAR)[ ](\d+)/i)) {
  300.             change = parseInt($gameVariables.value(parseInt(RegExp.$2)));
  301.             if (String(RegExp.$1) === '-') change *= -1;
  302.             percent = false;
  303.         } else if (actionName.match(/ENMITY[ ]([+-])(?:VARIABLE|VAR)[ ](\d+)([%ï¼…])/i)) {
  304.             change = parseInt($gameVariables.value(parseInt(RegExp.$2)));
  305.             if (String(RegExp.$1) === '-') change *= -1;
  306.             percent = true;
  307.         } else if (actionName.match(/ENMITY[ ]([\+\-]\d+)([%ï¼…])/i)) {
  308.             change = parseInt(RegExp.$1);
  309.             percent = true;
  310.         } else if (actionName.match(/ENMITY[ ]([\+\-]\d+)/i)) {
  311.             change = parseInt(RegExp.$1);
  312.             percent = false;
  313.         } else {
  314.             return false;
  315.         }
  316.         var value;
  317.         targets.forEach(function (target) {
  318.             target.clearResult();
  319.             value = percent ? ((change / 100) * target.getEnmity(this._subject)) : change;
  320.             target.gainEnmity(this._subject, value);
  321.         }, this);
  322.         return true;
  323.     };
  324.  
  325.  
  326.     //==============================================================================
  327.     // AIManager - Yanfly Battle AI Core Integration
  328.     //==============================================================================
  329.  
  330.     // store a copy of the original AIManager Functions.
  331.     Liquid.Enmity.AIManager_setProperTarget = AIManager.setProperTarget;
  332.     Liquid.Enmity.AIManager_getParamId = AIManager.getParamId;
  333.  
  334.  
  335.    
  336.  
  337.     // Overwrites Yanflys AIManager.getParamId() to include Enmity.
  338.     AIManager.getParamId = function (string) {
  339.         Liquid.Enmity.AIManager_getParamId.call(this, string);
  340.         string = string.toUpperCase()
  341.         switch (string) {
  342.             case 'MAXHP':
  343.             case 'MAX HP':
  344.                 return 0;
  345.                 break;
  346.             case 'MAXMP':
  347.             case 'MAX MP':
  348.             case 'MAXSP':
  349.             case 'MAX SP':
  350.                 return 1;
  351.                 break;
  352.             case 'ATK':
  353.             case 'STR':
  354.                 return 2;
  355.                 break;
  356.             case 'DEF':
  357.                 return 3;
  358.                 break;
  359.             case 'MAT':
  360.             case 'INT':
  361.             case 'SPI':
  362.                 return 4;
  363.                 break;
  364.             case 'MDF':
  365.             case 'RES':
  366.                 return 5;
  367.                 break;
  368.             case 'AGI':
  369.             case 'SPD':
  370.                 return 6;
  371.                 break;
  372.             case 'LUK':
  373.                 return 7;
  374.                 break;
  375.             case 'HP':
  376.                 return 8;
  377.                 break;
  378.             case 'MP':
  379.             case 'SP':
  380.                 return 9;
  381.                 break;
  382.             case 'HP%':
  383.                 return 10;
  384.                 break;
  385.             case 'MP%':
  386.             case 'SP%':
  387.                 return 11;
  388.                 break;
  389.             case 'LEVEL':
  390.             case 'LV':
  391.             case 'LVL':
  392.                 return 12;
  393.                 break;
  394.             case 'ENMITY':
  395.             case 'ENM':
  396.             case 'EN':
  397.                 return 13;
  398.                 break;
  399.         }
  400.         return -1;
  401.     };
  402.  
  403.     // Overwrites Yanflys AIManager.setProperTarget() function to include enmity.
  404.     AIManager.setProperTarget = function (group) {
  405.         Liquid.Enmity.AIManager_setProperTarget.call(this, group);
  406.         var action = this.action();
  407.         var randomTarget = group[Math.floor(Math.random() * group.length)];
  408.         if (group.length <= 0) return action.setTarget(randomTarget.index());
  409.         var line = this._aiTarget.toUpperCase();
  410.         if (line.match(/HIGHEST[ ](.*)/i)) {
  411.             var param = this.getParamId(String(RegExp.$1));
  412.             if (param < 0) return action.setTarget(randomTarget.index());
  413.             if (param === 8) return this.setHighestHpFlatTarget(group);
  414.             if (param === 9) return this.setHighestMpFlatTarget(group);
  415.             if (param === 10) return this.setHighestHpRateTarget(group);
  416.             if (param === 11) return this.setHighestMpRateTarget(group);
  417.             if (param === 12) return this.setHighestLevelTarget(group);
  418.             if (param === 13) return this.setHighestEnmityTarget(group);
  419.             if (param > 13) return action.setTarget(randomTarget.index());
  420.             this.setHighestParamTarget(group, param);
  421.         } else if (line.match(/LOWEST[ ](.*)/i)) {
  422.             var param = this.getParamId(String(RegExp.$1));
  423.             if (param < 0) return action.setTarget(randomTarget.index());
  424.             if (param === 8) return this.setLowestHpFlatTarget(group);
  425.             if (param === 9) return this.setLowestMpFlatTarget(group);
  426.             if (param === 10) return this.setLowestHpRateTarget(group);
  427.             if (param === 11) return this.setLowestMpRateTarget(group);
  428.             if (param === 12) return this.setLowestLevelTarget(group);
  429.             if (param === 13) return this.setLowestEnmityTarget(group);
  430.             if (param > 13) return action.setTarget(randomTarget.index());
  431.             this.setHighestParamTarget(group, param);
  432.         } else {
  433.             this.setRandomTarget(group);
  434.         }
  435.     };
  436.  
  437.     // Pick the target with the highest enmity against this battler.
  438.     AIManager.setHighestEnmityTarget = function (group) {
  439.         var maintarget = group[Math.floor(Math.random() * group.length)];
  440.         var subject = this.battler();
  441.  
  442.         for (var i = 0; i < group.length; ++i) {
  443.             var target = group[i];
  444.             if (subject.getEnmity(target) > subject.getEnmity(maintarget)) {
  445.                 maintarget = target;
  446.             }
  447.         }
  448.         this.action().setTarget(maintarget.index())
  449.     };
  450.  
  451.     // Pick the target with the lowest enmity against this target.
  452.     AIManager.setLowestEnmityTarget = function (group) {
  453.         var maintarget = group[Math.floor(Math.random() * group.length)];
  454.         var subject = this.battler();
  455.  
  456.         for (var i = 0; i < group.length; ++i) {
  457.             var target = group[i];
  458.             if (subject.getEnmity(target) < subject.getEnmity(maintarget)) {
  459.                 maintarget = target;
  460.             }
  461.         }
  462.         this.action().setTarget(maintarget.index())
  463.     };
  464.  
  465.     //================================================================================
  466.     // Game_Party
  467.     //================================================================================
  468.     Game_Party.prototype.removeEnmity = function () {
  469.         this.members().forEach(function (actor) {
  470.             actor._enmitytable = [];
  471.         });
  472.     };
  473.  
  474.     //================================================================================
  475.     // Game_Actor - adds icon property.
  476.     //================================================================================
  477.  
  478.     Liquid.Enmity.Game_Actor_initMembers = Game_Actor.prototype.initMembers;
  479.  
  480.     Game_Actor.prototype.initMembers = function () {
  481.         Liquid.Enmity.Game_Actor_initMembers.call(this);
  482.         this._battleicon = 0;
  483.     };
  484.  
  485.     Game_Actor.prototype.battleIcon = function () {
  486.  
  487.         if (this._battleicon > 0) {
  488.             return this._battleicon;
  489.         }
  490.  
  491.         if (this.actor().meta.battleIcon) {
  492.             return Number(this.actor().meta.battleIcon);
  493.         }
  494.  
  495.         return 0;
  496.  
  497.     }
  498.  
  499.     //================================================================================
  500.     // Game_Battler - adds a enmitytable property, and methods to change it.
  501.     //================================================================================
  502.  
  503.     Liquid.Enmity.Game_Battler_initMembers = Game_Battler.prototype.initMembers;
  504.    
  505.     // Initialize the Game_Battler, and gives it the enmitytable value.
  506.     Game_Battler.prototype.initMembers = function () {
  507.         Liquid.Enmity.Game_Battler_initMembers.call(this);
  508.         this._enmitytable = [];
  509.     };
  510.  
  511.     // Exposes the enmity table publically.
  512.     Object.defineProperty(Game_Battler.prototype, 'enmitytable', {
  513.         get: function () {
  514.             return this._enmitytable;
  515.         },
  516.         configurable: true
  517.     });
  518.  
  519.     // Gets whether or not this Game_Battler can nullify all enmity gain.
  520.     // it only takes a single Null Enmity tag to nullify all enmity gain
  521.     Game_Battler.prototype.getNullEnmityStatus = function () {
  522.         if (this.isActor()) {
  523.             if ($dataActors[this._actorId].nullEnmity) return true;
  524.             for (var i = 0; i < this._equips.length; i++) {
  525.                 if (this._equips[i].itemId()) {
  526.                     if (this._equips[i].isWeapon()) {
  527.                         if ($dataWeapons[this._equips[i].itemId()].nullEnmity) return true;
  528.                     }
  529.                     else {
  530.                         if ($dataArmors[this._equips[i].itemId()].nullEnmity) return true;
  531.                     }
  532.                 }
  533.             }
  534.             if ($dataClasses[this._classId].nullEnmity) return true;
  535.         }
  536.         else {
  537.             if ($dataEnemies[this._enemyId].nullEnmity) return true;
  538.         }
  539.  
  540.         for (var i = 0, l = this._states.length; i < l; i++) {
  541.             if ($dataStates[this._states[i]].nullEnmity) return true;
  542.         }
  543.         return false;
  544.  
  545.     };
  546.  
  547.     // Gets the effective enmity bonus for this battler
  548.     // from all enmity bonus tags. A base enmity bonus of 0
  549.     // is returned (no additional enmity gain from tags)
  550.     // if no tags are found.
  551.     Game_Battler.prototype.getEffectiveEnmityBonus = function () {
  552.         var bonus = 0;
  553.  
  554.         if (this.isActor()) {
  555.             bonus += $dataActors[this._actorId].bonusEnmity;
  556.             for (var i = 0; i < this._equips.length; i++) {
  557.                 if (this._equips[i].itemId()) {
  558.                     if (this._equips[i].isWeapon()) {
  559.                         bonus += $dataWeapons[this._equips[i].itemId()].bonusEnmity;
  560.                     }
  561.                     else {
  562.                         bonus += $dataArmors[this._equips[i].itemId()].bonusEnmity;
  563.  
  564.                     }
  565.                 }
  566.             }
  567.             bonus += $dataClasses[this._classId].bonusEnmity;
  568.         }
  569.         else {
  570.  
  571.             bonus += $dataEnemies[this._enemyId].bonusEnmity;
  572.         }
  573.  
  574.         for (var i = 0, l = this._states.length; i < l; i++) {
  575.  
  576.             bonus += $dataStates[this._states[i]].bonusEnmity;
  577.         }
  578.         return bonus;
  579.     };
  580.  
  581.     // Get the effective (total) enmity rating bonus from
  582.     // all Enmity Rating tags, that this battler could have
  583.     // if no additional tags are found, all battles have a rating of 1.0
  584.     // (100% base) enmity gain.
  585.     Game_Battler.prototype.getEffectiveEnmityRating = function () {
  586.         var rating = 1.0;
  587.  
  588.         if (this.isActor()) {
  589.             rating += $dataActors[this._actorId].enmityRate;
  590.             for (var i = 0; i < this._equips.length; i++) {
  591.                 if (this._equips[i].itemId()) {
  592.                     if (this._equips[i].isWeapon()) {
  593.                         rating += $dataWeapons[this._equips[i].itemId()].enmityRate;
  594.                     }
  595.                     else {
  596.                         rating += $dataArmors[this._equips[i].itemId()].enmityRate;
  597.                     }
  598.                 }
  599.             }
  600.             rating += $dataClasses[this._classId].enmityRate;
  601.         }
  602.         else {
  603.             rating += $dataEnemies[this._enemyId].enmityRate;
  604.         }
  605.  
  606.         for (var i = 0, l = this._states.length; i < l; i++) {
  607.             rating += $dataStates[this._states[i]].enmityRate;
  608.         }
  609.         return rating;
  610.     };
  611.  
  612.     // Gives this Game_Battle enmity, the attacker argument is the attacker (subject of the action).
  613.     // the value is the amount to change by.
  614.     Game_Battler.prototype.gainEnmity = function (attacker, value) {
  615.        
  616.         // You can't gain enmity against an ally, thats silly!
  617.         if (attacker.isActor() && this.isActor()) return;
  618.         if (attacker.isEnemy() && this.isEnemy()) return;
  619.  
  620.         // Prepare a new Enmity object to add to the enmity table if need be.
  621.         var enmityObj = {};
  622.         enmityObj.battler = attacker;
  623.        
  624.         // if attacker can nullify enmity gain, don't bother processing
  625.         if (attacker.getNullEnmityStatus() == true) {
  626.             return;
  627.         }
  628.  
  629.         // rate to multiply by.
  630.         var rate = attacker.getEffectiveEnmityRating();
  631.         // end bonus to add.
  632.         var bonus = attacker.getEffectiveEnmityBonus();
  633.         // calculate final enmity gain.
  634.         var enmity = (value * rate) + bonus;
  635.        
  636.         // supply the enmity gain value to the enmity object.
  637.         enmityObj.enmity = enmity;
  638.          
  639.         // if when we add this enmity, the enmity of the attacker goes higher than max
  640.         // just set it to max value.
  641.         if (enmity + this.getEnmity(attacker) > Liquid.Param.MaxEnmity) {
  642.             this._enmitytable[attacker.index()].enmity = Liquid.Param.MaxEnmity;
  643.             return;
  644.         }
  645.        
  646.         // if we dont allow negative enmity, and this change will make the enmity of the
  647.         // target go into the negatives, set it to 0.
  648.         if (!eval(Liquid.Param.AllowNegativeEmn) && enmity + this.getEnmity(attacker) < 0) {
  649.             this._enmitytable[attacker.index()].enmity = 0;
  650.             return;
  651.         }
  652.  
  653.         // if the subject of this attacker doesn't exists in the enmity table, we add them
  654.         // else we just add the new enmity change to existing enmity.
  655.         if (typeof (this._enmitytable[this.getEnmityId(attacker)]) === 'undefined') {
  656.             this._enmitytable[this.getEnmityId(attacker)] = enmityObj;
  657.         } else {
  658.             this._enmitytable[this.getEnmityId(attacker)].enmity += enmity;
  659.         }
  660.     };
  661.  
  662.     // Get the index of the attacker in the enmity table
  663.     // we sort the table by highest to lowest so the
  664.     // simple method of storing their index from their unit
  665.     // as the index in the table doesn't work.
  666.     // if the attacker isn't in the table, we just return 1 higher
  667.     // than the max in the table.
  668.     Game_Battler.prototype.getEnmityId = function (attacker) {
  669.         var id = 0;
  670.         for (var i = 0; i < this._enmitytable.length; i++) {
  671.             id = i;
  672.             if (this._enmitytable[i].battler.index() == attacker.index()) {
  673.                 return id;
  674.             }
  675.         }
  676.         return id + 1;
  677.     };
  678.  
  679.     // Gets the amount of enmity an attacker has against this battler,
  680.     // if it's undefined or not a number, return 0.
  681.     Game_Battler.prototype.getEnmity = function (attacker) {
  682.         // if the attacker is friendly, return 0.
  683.         // you can't gain enmity against friendlies, thats
  684.         // silly.
  685.         if (this.isActor() && attacker.isActor()) return 0;
  686.         if (this.isEnemy() && attacker.isEnemy()) return 0;
  687.  
  688.         var enmity = Number(this._enmitytable[this.getEnmityId(attacker)].enmity);
  689.         if (Number.isNaN(enmity)) {
  690.             return 0;
  691.         }
  692.         return enmity;
  693.     };
  694.  
  695.     //================================================================================
  696.     // Scene_Battle
  697.     //================================================================================
  698.    
  699.     // Store the values of functions we plan to manipulate to call later.
  700.     Liquid.Enmity.Scene_Battle_createAllWindows = Scene_Battle.prototype.createAllWindows;
  701.     Liquid.Enmity.Scene_Battle_selectEnemySelection = Scene_Battle.prototype.selectEnemySelection;
  702.     Liquid.Enmity.Scene_Battle_onEnemyOk = Scene_Battle.prototype.onEnemyOk;
  703.     Liquid.Enmity.Scene_Battle_onEnemyCancel = Scene_Battle.prototype.onEnemyCancel;
  704.    
  705.     // Overwrite the selectEnemyFunction (and then call the original)
  706.     // to refresh the Enmity Window, and hide the battle log (it covers the window)
  707.     Scene_Battle.prototype.selectEnemySelection = function () {
  708.         Liquid.Enmity.Scene_Battle_selectEnemySelection.call(this);
  709.         this._enmityWindow.refresh();
  710.         this._enmityWindow.show();
  711.         this._enmityWindow.activate();
  712.         this._logWindow.hide();
  713.     };
  714.  
  715.     // When we have selected an enemy, reshow the battle log
  716.     // thus hiding the enmity window.
  717.     Scene_Battle.prototype.onEnemyOk = function () {
  718.         this._enmityWindow.hide();
  719.         this._logWindow.show();
  720.         Liquid.Enmity.Scene_Battle_onEnemyOk.call(this);
  721.     };
  722.    
  723.     // When we cancel selection also hide the enmity window.
  724.     Scene_Battle.prototype.onEnemyCancel = function () {
  725.         Liquid.Enmity.Scene_Battle_onEnemyCancel.call(this);
  726.         this._enmityWindow.hide();
  727.         this._logWindow.show();
  728.     };
  729.    
  730.     // Overwrite the createAllWindows function, to put this window
  731.     // below all other windows, so we don't hide any important information.
  732.     // this also create the Enmity Window.
  733.     Scene_Battle.prototype.createAllWindows = function () {
  734.         this._enmityWindow = new Window_EnmityList(0, Graphics.boxHeight / 2);
  735.         this.addWindow(this._enmityWindow);
  736.         Liquid.Enmity.Scene_Battle_createAllWindows.call(this);
  737.         this._enmityWindow.x = eval(Liquid.Param.WindowX);
  738.         this._enmityWindow.y = eval(Liquid.Param.WindowY);
  739.         Liquid.Enmity.EnmityWindow = this._enmityWindow;
  740.  
  741.     };
  742.    
  743.     //================================================================================
  744.     // Window_BattleEnemy Extensions
  745.     //================================================================================
  746.  
  747.     // Store a value of the original select function, before we overwrite.
  748.     Liquid.Enmity.Window_BattleEnemy_select = Window_BattleEnemy.prototype.select;
  749.    
  750.     // Call the original select method, and then execute ours.
  751.     // this is used to update the enmity window with the new
  752.     // enemy we are showing enmity for.
  753.     Window_BattleEnemy.prototype.select = function (index) {
  754.         Liquid.Enmity.Window_BattleEnemy_select.call(this, index);
  755.         if (Liquid.Enmity.EnmityWindow) {
  756.             Liquid.Enmity.EnmityWindow.refresh(this.enemy());
  757.         }
  758.     };
  759.    
  760.     //================================================================================
  761.     // Window_Base Extensions
  762.     //================================================================================
  763.    
  764.     // Function to draw battle face icons, store in a faceicons sprite sheet from
  765.     // the system folder.
  766.     Window_Base.prototype.drawBattlerFaceIcon = function (iconIndex, x, y) {
  767.         var bitmap = ImageManager.loadSystem(Liquid.Param.IconSheet);
  768.         var pw = Liquid.Param.FaceIconWidth; // all faces are 48px in width by default
  769.         var ph = Liquid.Param.FaceIconHeight; // all faces are 48px in height by default
  770.         var sx = iconIndex % 16 * pw;
  771.         var sy = Math.floor(iconIndex / 16) * ph;
  772.         this.contents.blt(bitmap, sx, sy, pw, ph, x, y);
  773.     };
  774.    
  775.     //================================================================================
  776.     // Enmity_Window - Window to show enmity from highest to lowest.
  777.     //================================================================================
  778.    
  779.     // Window_Enmity object initializer
  780.     function Window_EnmityList() {
  781.         this.initialize.apply(this, arguments);
  782.     }
  783.    
  784.     // Set the prototype and consturtor.
  785.     Window_EnmityList.prototype = Object.create(Window_Base.prototype);
  786.     Window_EnmityList.prototype.constructor = Window_EnmityList;
  787.  
  788.     // Initialize function
  789.     Window_EnmityList.prototype.initialize = function (x, y) {
  790.         var width = this.windowWidth();
  791.         var height = this.windowHeight();
  792.         Window_Base.prototype.initialize.call(this, x, y, width, height);
  793.         this.opacity = 0;
  794.         this.refresh();
  795.         this.hide();
  796.     };
  797.  
  798.     Window_EnmityList.prototype.windowWidth = function () {
  799.         return Liquid.Param.FaceIconWidth * this.maxFaces();
  800.     };
  801.  
  802.  
  803.     Window_EnmityList.prototype.windowHeight = function () {
  804.         // We used 96, because the window "border" is 48px
  805.         // and the face icons are 48px so if we use any lower
  806.         // the faces don't show fully/at all.
  807.         return Liquid.Param.FaceIconHeight * 2;
  808.     };
  809.  
  810.     // When opened refresh!
  811.     Window_EnmityList.prototype.open = function () {
  812.         this.refresh();
  813.     };
  814.  
  815.     // Max faces to show on the enmity bar.
  816.     Window_EnmityList.prototype.maxFaces = function () {
  817.         return 8;
  818.     };
  819.  
  820.     // Refresh the enmity bar and show the faces in order of highest to lowest
  821.     // enmity.
  822.     Window_EnmityList.prototype.refresh = function (enemy) {
  823.         this.contents.clear();
  824.         if (enemy && enemy._enmitytable) {
  825.             this.drawBackground(0, 0, this.width, Liquid.Param.FaceIconHeight);
  826.             var enmitytable = enemy._enmitytable.sort(function (a, b) { return b['enmity'] - a['enmity']; });;
  827.             var drawX = 0;
  828.             for (var k in enmitytable) {
  829.                 if (typeof enmitytable[k] !== 'function') {
  830.                     if (enmitytable[k].battler.isActor()) {
  831.                         this.drawBattlerFaceIcon(enmitytable[k].battler.battleIcon(), drawX, 0);
  832.                         drawX += Liquid.Param.FaceIconWidth;
  833.                     }
  834.  
  835.                 }
  836.             }
  837.         }
  838.     };
  839.  
  840.     // draw a dark background.
  841.     Window_EnmityList.prototype.drawBackground = function (x, y, width, height) {
  842.         var color1 = this.dimColor1();
  843.         var color2 = this.dimColor2();
  844.         this.contents.gradientFillRect(x, y, width / 2, height, color2, color1);
  845.         this.contents.gradientFillRect(x + width / 2, y, width / 2, height, color1, color2);
  846.     };
  847.    
  848.     //================================================================================
  849.     // Command Processor
  850.     //================================================================================
  851.    
  852.     var Liquid_Enmity_Game_Interpreter_pluginCommand =
  853.  
  854.         Game_Interpreter.prototype.pluginCommand;
  855.  
  856.     Game_Interpreter.prototype.pluginCommand = function (command, args) {
  857.  
  858.         Liquid_Enmity_Game_Interpreter_pluginCommand.call(this, command, args);
  859.  
  860.         if (command === "EnmityFace") {
  861.             if (args.length === 2) {
  862.                 if (Number.isNaN(args[0]) == false) {
  863.                     if (Number.isNaN(args[1]) == false) {
  864.                         $gameActors.actor(args[0])._battleicon = args[1];
  865.                     }
  866.                     else {
  867.  
  868.                         if (args[1] === 'reset') {
  869.                             $gameActors.actor(args[0])._battleicon = 0;
  870.                         }
  871.                     }
  872.                 }
  873.             }
  874.         }
  875.  
  876.     };
  877.  
  878.        
  879.     //================================================================================
  880.     // End of File
  881.     //================================================================================
  882. };
Advertisement
Add Comment
Please, Sign In to add comment