Advertisement
Guest User

Liquid_EnemyEnmity.js (v1.2)

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