SHARE
TWEET

AstfglSCB

Astfgl Aug 19th, 2018 (edited) 373 Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. //===================================================================================
  2. // Astfgl's Shield counter and Break
  3. // Date 19/08/2018
  4. // Free to use non commercially, commercially, repost and
  5. // edit, as long as the final product is kept under the same terms of use.
  6. // Credits required, any of Astfgl, Astgfl (Pierre MATEO), Pierre MATEO
  7. // Credits goes to yanfly for modified parts of battle engine core
  8. // v1.0 19/08: release
  9. // v1.1 21/08 modified shield display modes
  10. // v1.2 25/08 created weakness display, added parameters for shield mode, made weakness display save
  11. // v1.3 25/08 added notetags to actor enemies and states to allow not displaying shield value
  12. // v1.4 04/09 added revealRandomWeakness functions, added option for actors or enemies to not use shields,
  13. // added option to reset known weaknesses after combat.
  14. // Time spent : 8h
  15. //====================================================================================
  16.  
  17. /*:
  18.  * @plugindesc OT Shield and Break System
  19.  * @author Astfgl
  20.  *
  21.  * @param globalMode
  22.  * @text Shield usage
  23.  * @type number
  24.  * @default 0
  25.  * @desc 0-> all, 1-> actors only -> 2 -> enemies only
  26.  
  27.  * @param defaultState
  28.  * @text State Id when shield = 0
  29.  * @type number
  30.  * @default 4
  31.  * @desc Which state will be applied when a battler shield reaches 0.
  32.  *
  33.  * @param defaultElemCutoff
  34.  * @text Elemental weakness cutoff
  35.  * @type number
  36.  * @default 1
  37.  * @desc Attacks must have an elemental value strictly superior to this to remove from the shield counter.
  38.  *
  39.  * @param baseIcon
  40.  * @text Base shield Icon
  41.  * @type number
  42.  * @default 16
  43.  * @desc The icon id to display shields.
  44.  *
  45.  * @param mode
  46.  * @text Shield display mode
  47.  * @type number
  48.  * @default 0
  49.  * @desc 0->number in brackets, 1 -> number in icon
  50.  *
  51.  * @param showWeaknesses
  52.  * @text Show weaknesses below enemy name
  53.  * @type number
  54.  * @default 1
  55.  * @desc 0-> don't show weaknesses, 1 -> show weaknesses
  56.  *
  57.  * @param wIArray
  58.  * @text Weakness Icon Array
  59.  * @default [0,0,0,0,0,0,0,0,0,0]
  60.  * @desc Icons for each elemental weakness, in order from your elements list in the system tab with a leading "0,".
  61.  *
  62.  * @param defautWeaknessIcon
  63.  * @text Undiscovered Weakness icon
  64.  * @type number
  65.  * @default 16
  66.  * @desc The icon id that will be used to display undiscovered weaknesses.
  67.  *
  68.  * @param saveWeakness
  69.  * @text Save weaknesses
  70.  * @type boolean
  71.  * @default true
  72.  * @desc If this parameter is set to false, discovered weaknesses will be reset at battle end.
  73.  *
  74.  *
  75.  * @help
  76.  *Allows you to set up a shield and break system similar to Octopath traveler's
  77.  *Recommended plugins:
  78.  * - Yanfly's Battle engine core
  79.  * - Yanfly's Element core
  80.  * - Yanfly's Buffs and state core
  81.  *It has not been tested without these plugins and thus may not function.
  82.  *
  83.  *==========================================
  84.  * What it does:
  85.  *==========================================
  86.  *In battle, if an attack hits an elemental weakness,
  87.  *it will decrease a shield counter, once that counter reaches 0
  88.  *a state will be applied to the battler.
  89.  *
  90.  *It will reduce the shield counter by 1 for each element of the attack
  91.  *the recipient is weak to.
  92.  *So if your attack deals fire and ice damage and the enemy is weak to both
  93.  *shields will be reduced by 2.
  94.  *
  95.  *Display of the shield amount is done via the battler name in brackets or with an icon.
  96.  *
  97.  *It also creates a weakness icon array below the monster.
  98.  *If the show weakness parameter is set to 1, it will display any element
  99.  *weakness reaching the default cutoff with the icon corresponding to the defined id
  100.  *in the weakness icon array below the battler name.
  101.  *
  102.  *==========================================
  103.  * How to use:
  104.  *==========================================
  105.  *Set max shield notetags:
  106.  *
  107.  *Order for max shield calculation:
  108.  *actor, class, equipment, passive states, states then floored
  109.  *Notetags: <mSh: >, Ex: <mSh: num += 5>
  110.  *
  111.  *Each time calculations are made with the num variable.
  112.  *Ex: num += 5 in actor, num *= 2 in class will result in a max shield of 10
  113.  *The same thing but with a state using num = 1 will result in a max shield of 1
  114.  *
  115.  *Enemies are the same except you remove class and equipment calculations
  116.  *
  117.  *If you don't set anything, battlers have a default shield value of 1.
  118.  *
  119.  *If you want it to function like octopath traveler, I recommend
  120.  *using a state with the cannot move property, set to expire in 2 turns
  121.  *and with the following notetag:
  122.  *<Custom Remove Effect>
  123.  *user._sh = user._mSh;
  124.  *</Custom Remove Effect>
  125.  *This will restore shields to maximum when the broken state expires.
  126.  *
  127.  *==========================================
  128.  * Changing break state
  129.  *==========================================
  130.  *If you want to change what state enemies are inflected with upon break use:
  131.  *<DBS: > in an enemy note box
  132.  *Else it will use what's inside plugin parameters
  133.  *
  134.  *==========================================
  135.  * Modifying enemy shields:
  136.  *==========================================
  137.  * Use the following script calls:
  138.  * (battler).modMaxSh(number)
  139.  * This will add number to max shields, after all other calculations.
  140.  * This bonus will never be reset.
  141.  * Use states for temporary modifications for actors.
  142.  *
  143.  * (battler).changeSh(number), this will withdraw number from current shields
  144.  *
  145.  *All parameters and notetags are evaled
  146.  *
  147.  *==========================================
  148.  * How to setup weakness display array:
  149.  *==========================================
  150.  *
  151.  * The parameter is an array of icon ids with a leading 0.
  152.  * For default projects it would be:
  153.  * [0,physicalIconId,fireIconId,...,darknessIconId]
  154.  *
  155.  *==========================================
  156.  * How to hide shield amount
  157.  *==========================================
  158.  * Use the following notetag in an actor enemy or state notebox:
  159.  * <shieldDisplay:false>
  160.  *
  161.  *==========================================
  162.  * How to make a specific battler not use shields
  163.  *==========================================
  164.  * Use the following notetag in an actor enemy or state notebox:
  165.  * <shieldDisplay:none>
  166.  * This battler will not display his shields and will not suffer
  167.  * from break.
  168.  *==========================================
  169.  * How to reveal weaknesses
  170.  *==========================================
  171.  * Use the following script calls:
  172.  * battler.revealRandomWeakness()
  173.  * to reveal one weakness for an enemy type.
  174.  * Replace battler accordingly with a b user or target in
  175.  * notetags or the damage formula.
  176.  *
  177.  * You can reveal one weakness at random for each enemy type
  178.  * in the troop with the following script call:
  179.  * $gameTroop.revealRandomWeakness();
  180.  *
  181. */
  182. var Astfgl = Astfgl || {};
  183. Astfgl.enemies = Astfgl.enemies || {};
  184. Astfgl.enemies.disWeak = [];
  185.  
  186. (function(){
  187. //get parameters value
  188. var defaultState = eval(PluginManager.parameters("AstfglSCB").defaultState);
  189. var defaultElemCutoff = eval(PluginManager.parameters("AstfglSCB").defaultElemCutoff);
  190. var mode = eval(PluginManager.parameters("AstfglSCB").mode)
  191. var shieldIcon = eval(PluginManager.parameters("AstfglSCB").baseIcon)
  192. var showWeaknesses = eval(PluginManager.parameters("AstfglSCB").showWeaknesses)
  193. var wIArray =  eval(PluginManager.parameters("AstfglSCB").wIArray)
  194. var defautWeaknessIcon = eval(PluginManager.parameters("AstfglSCB").defautWeaknessIcon)
  195. var globalMode = eval(PluginManager.parameters("AstfglSCB").globalMode)
  196. var saveWeakness = eval(PluginManager.parameters("AstfglSCB").saveWeakness)
  197.  
  198. //Weakness setup
  199. var _aliasGAI = Game_Actor.prototype.initialize
  200. Game_Actor.prototype.initialize = function(actorId) {
  201.     _aliasGAI.call(this,actorId);
  202.     if (this._actorId === 0) {return}
  203.     if (globalMode !== 2) {
  204.     this._mShB = 0;
  205.     this._mSh = this.getMaxSh();
  206.     this._sh = this._mSh
  207.     }
  208. };
  209.  
  210. //get max shield value from notetags
  211. Game_Actor.prototype.getMaxSh = function() {
  212.     var num = 0;
  213.     var a = this;
  214.     var user = this;
  215.     var id = this.actorId();
  216.     if ($dataActors[id].meta.mSh) {
  217.         num = eval($dataActors[id].meta.mSh)
  218.     }
  219.     if ($dataClasses[this._classId].meta.mSh) {
  220.         num = eval($dataActors[id].meta.mSh)
  221.     }
  222.     for (let i = 0; i < this._equips.length; i++) {
  223.         var it = this._equips[i];
  224.         if (it._dataClass === "weapon" && it._itemId !== 0) {
  225.             if ($dataWeapons[it._itemId].meta.mSh) {
  226.                 num = eval($dataWeapons[it._itemId].meta.mSh)
  227.             }
  228.  
  229.         }
  230.         if (it._dataClass === "armor" && it._itemId !== 0) {
  231.             if ($dataArmors[it._itemId].meta.mSh) {
  232.                 num = eval($dataArmors[it._itemId].meta.mSh)
  233.             }
  234.  
  235.         }
  236.     }
  237.     if (this._passiveStatesRaw) {
  238.         for (let i = 0; i < this._passiveStatesRaw.length; i ++) {
  239.             if ($dataStates[this._passiveStatesRaw[i]].meta.mSh) {
  240.                 num = eval($dataStates[this._passiveStatesRaw[i]].meta.mSh)
  241.             }
  242.         }
  243.     }
  244.     for (let i = 0; i < this._states.length; i ++) {
  245.         if ($dataStates[this._states[i]].meta.mSh) {
  246.             num = eval($dataStates[this._states[i]].meta.mSh)
  247.         }
  248.     }
  249.     num +=  this._mShB
  250.     num = Math.floor(num)
  251.     if (num === 0 || isNaN(num)) {num = 1}
  252.     return num
  253. }
  254.  
  255. //setup enemies shield
  256. var _aliasGEI = Game_Enemy.prototype.initialize
  257. Game_Enemy.prototype.initialize = function(enemyId, x, y) {
  258.     _aliasGEI.call(this,enemyId, x, y);
  259.     if (this._enemyId === 0) {return};
  260.     if (globalMode !== 1) {
  261.         this._mShB = 0;
  262.         this._mSh = this.getMaxSh()
  263.         this._sh = this._mSh;
  264.     }
  265.     //create known weakness array the first time an enemy is initialized
  266.     if (Astfgl.enemies.disWeak.length === 0) {
  267.         for (let i = 0; i < $dataEnemies.length; i++) {
  268.             var _WI = [];
  269.             for (let i = 0; i < $dataSystem.elements.length; i ++) {
  270.                 _WI.push(0);
  271.             }
  272.         Astfgl.enemies.disWeak.push(_WI)
  273.         }
  274.     }
  275.  
  276. };
  277.  
  278. //get max enemy shield value from enemy and state notetags
  279. Game_Enemy.prototype.getMaxSh = function() {
  280.     var num = 0;
  281.     var a = this;
  282.     var user = this;
  283.     var id = this._enemyId;
  284.     if ($dataEnemies[id].meta.mSh) {
  285.         num = eval($dataEnemies[id].meta.mSh)
  286.     }
  287.     if (this._passiveStatesRaw) {
  288.         for (let i = 0; i < this._passiveStatesRaw.length; i ++) {
  289.             if ($dataStates[this._passiveStatesRaw[i]].meta.mSh) {
  290.                 num = eval($dataStates[this._passiveStatesRaw[i]].meta.mSh)
  291.             }
  292.         }
  293.     }
  294.     for (let i = 0; i < this._states.length; i ++) {
  295.         if ($dataStates[this._states[i]].meta.mSh) {
  296.             num = eval($dataStates[this._states[i]].meta.mSh)
  297.         }
  298.     }
  299.     num += this._mShB;
  300.     num = Math.floor(num)
  301.     if (num === 0 || isNaN(num)) {num = 1}
  302.     return num
  303. }
  304.  
  305. //check for shield display amount
  306. Game_Battler.prototype.checkShieldDisplay = function() {
  307.     var value = true;
  308.     var data;
  309.     if (this.isEnemy()) {data = $dataEnemies[this._enemyId]}
  310.     if (this.isActor()) {data = $dataActors[this.actorId()]}
  311.     if (data.meta.shieldDisplay) {
  312.         if (data.meta.shieldDisplay === "none") {return "none"}
  313.         value = eval(data.meta.shieldDisplay);
  314.     }
  315.     if (!value) {return value}
  316.     if (this._passiveStatesRaw) {
  317.         for (let i = 0; i < this._passiveStatesRaw.length; i ++) {
  318.             if ($dataStates[this._passiveStatesRaw[i]].meta.shieldDisplay) {
  319.                 value = eval($dataStates[this._passiveStatesRaw[i]].meta.shieldDisplay)
  320.                 if (!value) {return value}
  321.             }
  322.         }
  323.     }
  324.     for (let i = 0; i < this._states.length; i ++) {
  325.         if ($dataStates[this._states[i]].meta.shieldDisplay) {
  326.             value = eval($dataStates[this._states[i]].meta.shieldDisplay)
  327.             if (!value) {return value}
  328.         }
  329.     }
  330.     return value
  331. }
  332.  
  333. //store known weaknesses in global array
  334. Game_Enemy.prototype.checkWeaknessDisplay = function (num) {
  335.     if (Astfgl.enemies.disWeak[this._enemyId][num] === 0) {
  336.         Astfgl.enemies.disWeak[this._enemyId][num] = 1
  337.     }
  338. }
  339.  
  340. //Action modifying
  341. var _aliasGAA = Game_Action.prototype.apply
  342. Game_Action.prototype.apply = function(target) {
  343.     _aliasGAA.call(this,target)
  344.     var mod = 0;
  345.     var elements = this.getItemElements();
  346.     for (let i = 0; i < elements.length; i++) {
  347.         if (target.elementRate(elements[i]) > defaultElemCutoff) {
  348.             mod +=1;
  349.             if (!target.isActor()) {
  350.                 target.checkWeaknessDisplay(elements[i])
  351.             }
  352.         }
  353.     }
  354.     target.changeSh(mod);
  355. }
  356.  
  357. Game_Battler.prototype.changeSh = function(num) {
  358.     if (this._sh === 0) {return}
  359.     if (globalMode === 2 && this.isActor()) {return}
  360.     if (globalMode === 1 && this.isEnemy()) {return}
  361.     if (this.checkShieldDisplay() === "none") {return}
  362.     this._sh -= num;
  363.     this._sh = this._sh.clamp(0,this._mSh);
  364.     if (this._sh === 0) {
  365.         if (this.isActor()) {if ($dataActors[this.actorId()].meta.DBS) {defaultState = eval($dataActors[this.actorId()].meta.DBS)}}
  366.         else {if ($dataEnemies[this._enemyId].meta.DBS) {defaultState = eval($dataEnemies[this._enemyId].meta.DBS)}}
  367.         this.addState(defaultState)
  368.     };
  369. }
  370.  
  371. /*
  372. //Modify name function to display shield amount
  373. var _aliasGEN = Game_Enemy.prototype.name
  374. Game_Enemy.prototype.name = function() {
  375.     if ( mode === 0 ) {return _aliasGEN.call(this); }
  376.     return "[" + this._sh + "]" + this.originalName() + (this._plural ? this._letter : '');
  377. }*/
  378.  
  379. //Modify battle window draw name function to display shield amount
  380. var _aliasWBSDAN = Window_BattleStatus.prototype.drawActorName
  381. Window_BattleStatus.prototype.drawActorName = function(actor, x, y, width) {
  382.     if (globalMode === 2 || actor.checkShieldDisplay() === "none") {_aliasWBSDAN.call(this,actor,x,y,width); return}
  383.     width = width || 168;
  384.     this.changeTextColor(this.hpColor(actor));
  385.     if (mode === 1) {
  386.         var fs = this.contents.fontSize
  387.         this.contents.fontSize = Yanfly.Param.BECEnemyFontSize;
  388.         this.drawIcon(shieldIcon,x,y+3)
  389.         if (actor.checkShieldDisplay()) {
  390.             var wd = this.textWidth(String(actor._sh));
  391.             this.drawText(actor._sh, x + 16 - wd/2, y, 40);
  392.         } else {
  393.             var wd = this.textWidth("?");
  394.             this.drawText("?", x + 16 - wd/2, y, 40);
  395.         }
  396.         this.contents.fontSize = fs
  397.         this.drawText(actor.name(), x + 40, y, width - 48);
  398.     } else {
  399.         if (actor.checkShieldDisplay()) {
  400.             this.drawText("["+ actor._sh + "]" + actor.name(), x, y, width);
  401.         } else {
  402.             this.drawText("[?]" + actor.name(), x, y, width);
  403.         }
  404.     }
  405. }
  406.  
  407. //Modify enemy name display
  408. var _aliasWEVSR = Window_EnemyVisualSelect.prototype.refresh
  409. Window_EnemyVisualSelect.prototype.refresh = function() {
  410.     this.contents.clear();
  411.     if (!this._battler) return;
  412.     if (!this._showEnemyName) return;
  413.     if (this._battler.isHidden()) return;
  414.     this._requestRefresh = false;
  415.     this.contents.fontSize = Yanfly.Param.BECEnemyFontSize;
  416.     var text = this._battler.name();
  417.     var wy = this.contents.height - this.lineHeight() * 2;
  418.     if (globalMode !== 1 && this._battler.checkShieldDisplay() !== "none") {
  419.         if (mode === 1) {
  420.                 this.drawIcon(shieldIcon,0,wy+3)
  421.                 if (this._battler.checkShieldDisplay()) {
  422.                     var wd = this.textWidth(String(this._battler._sh));
  423.                     this.drawText(this._battler._sh, 16 - wd/2, wy, 40);
  424.                 } else {
  425.                     var wd = this.textWidth("?");
  426.                     this.drawText("?", 16 - wd/2, wy, 40);
  427.                 }
  428.                 this.drawText(text, 40, wy, this.contents.width, 'left');
  429.         } else {
  430.                 if (this._battler.checkShieldDisplay()) {
  431.                     this.drawText("[" + this._battler._sh + "]" + text, 0, wy, this.contents.width, 'center');
  432.                 } else {
  433.                     this.drawText("[?]" + text, 0, wy, this.contents.width, 'center');
  434.                 }
  435.         }
  436.     } else {
  437.         this.drawText(text, 0, wy, this.contents.width, 'center');
  438.     }
  439.    
  440.     if (showWeaknesses === 1) {
  441.         var elemWeak = [];
  442.         for (let i = 1; i < $dataSystem.elements.length; i++) {
  443.             if (this._battler.elementRate(i) > defaultElemCutoff) {
  444.                 elemWeak.push(i)
  445.             }
  446.         }
  447.         wy = wy + this.lineHeight();
  448.         if (this.width < 32 * elemWeak.length) {
  449.             this.width = 32 * elemWeak.length
  450.             this.contents.width = 32 * elemWeak.length
  451.         }
  452.         var x = 0;
  453.         for (let i = 0; i < elemWeak.length; i++) {
  454.             var iconId = defautWeaknessIcon;
  455.             if (Astfgl.enemies.disWeak[this._battler._enemyId][elemWeak[i]] === 1) {
  456.                 iconId = wIArray[elemWeak[i]];
  457.             }
  458.             this.drawIcon(iconId,x,wy)
  459.             x += 32;
  460.         }
  461.     }
  462.  
  463. };
  464.  
  465. //change window size to display the right width for weaknesses icons
  466. Window_EnemyVisualSelect.prototype.updateWindowSize = function() {
  467.     if (showWeaknesses === 1) {
  468.         var elemWeak = [];
  469.         for (let i = 1; i < $dataSystem.elements.length; i++) {
  470.             if (this._battler.elementRate(i) > defaultElemCutoff) {
  471.                 elemWeak.push(i)
  472.             }
  473.         }
  474.         var num = elemWeak.length * 32;
  475.     } else {
  476.         num = 0;
  477.     }
  478.     var spriteWidth = this._battler.spriteWidth();
  479.     this.contents.fontSize = Yanfly.Param.BECEnemyFontSize;
  480.     if (this._nameTextWidth === undefined) {
  481.       this._nameTextWidth = this.textWidth(this._battler.name());
  482.     }
  483.     var textWidth = this._nameTextWidth;
  484.     textWidth += this.textPadding() * 2;
  485.     var width = Math.max(spriteWidth, textWidth, num) + this.standardPadding() * 2;
  486.     width = Math.ceil(width);
  487.     var height = this._battler.spriteHeight() + this.standardPadding() * 2;
  488.     height = Math.ceil(height);
  489.     height = Math.max(height, this.lineHeight() + this.standardPadding() * 2);
  490.     if (width === this.width && height === this.height) return;
  491.     this.width = width;
  492.     this.height = height;
  493.     this.createContents();
  494.     this._requestRefresh = true;
  495.     this.makeWindowBoundaries();
  496. };
  497.  
  498. // Accessory functions
  499. Game_Battler.prototype.modMaxSh = function (num) {
  500.     if (globalMode === 2 && this.isActor()) {return}
  501.     if (globalMode === 1 && this.isEnemy()) {return}
  502.     this._mShB += num;
  503.     this._mSh = this.getMaxSh();
  504.     this._sh.clamp(0,this._mSh);
  505. }
  506.  
  507. //save and load weakness array
  508. var _aliasDMMSC = DataManager.makeSaveContents
  509. DataManager.makeSaveContents = function() {
  510.     var contents = _aliasDMMSC.call(this)
  511.     contents.astfgl = Astfgl
  512.     return contents
  513. }
  514.  
  515. var _aliasDMESC = DataManager.extractSaveContents
  516. DataManager.extractSaveContents = function(contents) {
  517.     _aliasDMESC.call(this,contents);
  518.     Astfgl = contents.astfgl
  519. }
  520.  
  521. //Reset discovered weakness on battle end
  522. if (saveWeakness) {
  523.     var _aliasBMEB = BattleManager.endBattle
  524.     BattleManager.endBattle = function(result) {
  525.         _aliasBMEB.call(this,result);
  526.         $gameTroop.members().forEach(function(member){
  527.             for (let i=0; i < Astfgl.enemies.disWeak[member._enemyId].length; i++) {
  528.                 Astfgl.enemies.disWeak[member._enemyId][i] = 0
  529.             }
  530.         })
  531.     };
  532. }
  533.  
  534. Game_Enemy.prototype.revealRandomWeakness = function() {
  535.     var member = this;
  536.     var eId = member._enemyId
  537.     var dis = [];
  538.     for (let i = 1; i < $dataSystem.elements.length; i ++){
  539.         if (Astfgl.enemies.disWeak[eId][i] === 0 && member.elementRate(i) > defaultElemCutoff) {dis.push(i)}
  540.     }
  541.     if (dis.length!==0) {
  542.         var num = Math.floor(Math.random() * Math.floor(dis.length));
  543.         Astfgl.enemies.disWeak[eId][dis[num]] = 1;
  544.     }
  545. }
  546.  
  547. Game_Troop.prototype.revealRandomWeakness = function() {
  548.     var ids = []
  549.     this.members().forEach(function(member){
  550.     var eId = member._enemyId
  551.     if (!ids.contains(eId)) {
  552.         var dis = [];
  553.         for (let i = 1; i < $dataSystem.elements.length; i ++){
  554.             if (Astfgl.enemies.disWeak[eId][i] === 0 && member.elementRate(i) > defaultElemCutoff) {dis.push(i)}
  555.         }
  556.         ids.push(eId)
  557.         if (dis.length!==0) {
  558.             var num = Math.floor(Math.random() * Math.floor(dis.length));
  559.             Astfgl.enemies.disWeak[eId][dis[num]] = 1;
  560.         }
  561.     }
  562.     })
  563. }
  564.  
  565.  
  566. })()
RAW Paste Data
We use cookies for various purposes including analytics. By continuing to use Pastebin, you agree to our use of cookies as described in the Cookies Policy. OK, I Understand
 
Top