//============================================================================= // 防御の効果を拡張するプラグイン // FTKR_ExGuardEffect.js // プラグインNo : 79 // 作成者 : フトコロ // 作成日 : 2018/04/15 // 最終更新日 : 2020/09/08 // バージョン : v1.0.2 //============================================================================= var Imported = Imported || {}; Imported.FTKR_EGF = true; var FTKR = FTKR || {}; FTKR.EGF = FTKR.EGF || {}; //============================================================================= /*: @plugindesc v1.0.2 Plugin that expands the effectiveness of defense @author Futokoro @url https://github.com/munokura/futokoro-MV-plugins @license MIT License @help English Help Translator: munokura This is an unofficial English translation of the plugin help, created to support global RPG Maker users. Feedback is welcome to improve translation quality (see: https://github.com/munokura/futokoro-MV-plugins ). Original plugin by Futokoro. Please check the URL below for the latest version of the plugin. URL https://github.com/futokoro/RPGMaker ----- ----------------------------------------------------------------------------- Overview ----------------------------------------------------------------------------- With this plugin installed, a defense check is performed when taking damage. If the check is successful, you will be able to defend even without using the defense command. The defense check uses a defense rate dedicated to this plugin. *This is separate from the defense damage rate. This defense rate can be set by adding the following tag to the Note field of an actor, class, equipment, state, or enemy. x : Sets the defense rate value. 0 = 0%, 100 = 100%. This can be entered in script format. The final defense rate is the sum of the defense rates of all the character's traits. If the defense check is successful, the motion when taking damage will change to a defense motion. (*1) In addition, the damage sound effects and battle log message (*2) can be configured using plugin parameters. (*1) In this state, damage motions are not displayed during defense. To return to the original damage motions, change the setting of the plugin parameter Disable Damage Motion. (*2) Battle log messages will not be displayed if the plugin parameter is left blank. This message will also be displayed when a defense command is executed. The amount of damage received during defense is calculated using the following formula. This calculation is the same when a defense command is executed. Damage Amount = Damage Amount Before Guard ÷ (Damage Reduction Value × Traits's Guard Damage Rate) Damage Reduction Value: The value set in the plugin parameter Guard Effect Value ---------------------------------------------------------------------------- Setup Method ----------------------------------------------------------------------------- 1. Add this plugin to the "Plugin Manager." ---------------------------------------------------------------------------- License for this Plugin ---------------------------------------------------------------------------- This plugin is released under the MIT License. Copyright (c) 2020 Futokoro http://opensource.org/licenses/mit-license.php Plugin Publisher https://github.com/futokoro/RPGMaker/blob/master/README.md ----------------------------------------------------------------------------- Change History ----------------------------------------------------------------------------- v1.0.2 - 2020/09/08: Bug Fixes 1. Fixed an issue where defense was being performed even when HP was recovered. v1.0.1 - 2020/02/11: Bug Fixes 1. Fixed the default value of the plugin parameter Disable Damage Motion. 2. Fixed an issue where the defense rate setting was calculated twice as high. 3. Avoided a conflict with FTKR_ExSvMotion. v1.0.0 - 2018/04/15: First version created ----------------------------------------------------------------------------- @param Guard Effect Value @desc Sets the damage reduction value when defense is successful. @default 2 @type number @min 1 @decimals 2 @param Disable Damage Motion @desc If the defense is successful, the damage animation will not be performed. @default true @type boolean @on Do not run @off Execute @param Actor Guard Text @desc Sets the text displayed in the battle log when an actor successfully defends. @default %1は攻撃を防御した! @param Actor Guard Damage SE @desc Specifies the damage sound effect when an actor's defense is successful. @default {"name":"Damage5","volume":"90","pitch":"100","pan":"0"} @type struct @param Enemy Guard Text @desc Sets the text displayed in the battle log when an enemy successfully defends. @default %1に攻撃を防御された! @param Enemy Guard Damage SE @desc Specifies the damage sound effect when an enemy's defense is successful. @default {"name":"Damage4","volume":"90","pitch":"100","pan":"0"} @type struct @param TRAIT_GUARD_RATE @desc Do not change this unless it causes a conflict with another plugin. @default 101 @type number @min 0 */ /*~struct~sound: @param name @desc Specifies the name of the SE. @default Damage4 @type file @require 1 @dir audio/se @param volume @desc Specifies the volume of the SE. @default 90 @type number @max 100 @param pitch @desc Specifies the pitch of the SE. @default 100 @type number @min 50 @max 150 @param pan @desc Specifies the phase of the SE. @default 0 @type number @min -100 @max 100 */ /*:ja @plugindesc v1.0.2 防御の効果を拡張するプラグイン @author Futokoro @url https://github.com/munokura/futokoro-MV-plugins @license MIT License @help ----------------------------------------------------------------------------- 概要 ----------------------------------------------------------------------------- このプラグインを導入すると、ダメージを受けるときに防御判定を行い 判定に成功すると、防御コマンドを使用していなくても防御できるようになります。 <防御判定> 防御判定には、このプラグイン専用の防御率を使用します。 ※防御ダメージ率とは別です。 この防御率は、アクターやクラス、装備、ステート、エネミーのメモ欄に 以下のタグを記載すると設定できます。 x : 防御率の値を設定します。0 = 0%、100 = 100% です。 スクリプト形式で入力できます。 そのキャラのすべての特徴の防御率を合計した値が、最終的な防御率になります。 <判定に成功すると> 防御判定に成功すると、ダメージを受けたときのモーションが 防御モーションに変わります。(*1) また、この時のダメージSEや、バトルログのメッセージ(*2)を プラグインパラメータで設定できます。 (*1) この状態では、防御中はダメージモーションを表示しません。 元のダメージモーションに戻したい場合は、プラグインパラメータ Disable Damage Motion の設定を変えてください。 (*2) バトルログのメッセージは、プラグインパラメータを空欄にすると表示しません。 また、このメッセージは、防御コマンド実行時も表示します。 <防御時のダメージ量> 防御時に、受けるダメージ量は以下の計算式で算出します。 この計算は、防御コマンド実行時も同じです。 ダメージ量 = 防御前のダメージ量 ÷ (ダメージ低減値 × 特徴の防御ダメージ率) ダメージ低減値:プラグインパラメータ Guard Effect Value で設定した値 ----------------------------------------------------------------------------- 設定方法 ----------------------------------------------------------------------------- 1.「プラグインマネージャー(プラグイン管理)」に、本プラグインを追加して ください。 ----------------------------------------------------------------------------- 本プラグインのライセンスについて(License) ----------------------------------------------------------------------------- 本プラグインはMITライセンスのもとで公開しています。 This plugin is released under the MIT License. Copyright (c) 2020 Futokoro http://opensource.org/licenses/mit-license.php プラグイン公開元 https://github.com/futokoro/RPGMaker/blob/master/README.md ----------------------------------------------------------------------------- 変更来歴 ----------------------------------------------------------------------------- v1.0.2 - 2020/09/08 : 不具合修正 1. HP回復時にも防御を実行していた不具合を修正。 v1.0.1 - 2020/02/11 : 不具合修正 1. プラグインパラメータDisable Damage Motionの初期値を修正。 2. 防御率の設定値が2倍に計算される不具合を修正。 3. FTKR_ExSvMotionとの競合回避。 v1.0.0 - 2018/04/15 : 初版作成 ----------------------------------------------------------------------------- @param Guard Effect Value @desc 防御が成功した時のダメージ低減値を設定します。 @default 2 @type number @min 1 @decimals 2 @param Disable Damage Motion @desc 防御が成功した時はダメージモーションを実行しない。 @default true @type boolean @on 実行しない @off 実行する @param Actor Guard Text @desc アクターの防御が成功した時のバトルログの表示テキストを設定します。 @default %1は攻撃を防御した! @param Actor Guard Damage SE @desc アクターの防御が成功した時のダメージSEを指定します。 @default {"name":"Damage5","volume":"90","pitch":"100","pan":"0"} @type struct @param Enemy Guard Text @desc エネミーの防御が成功した時のバトルログの表示テキストを設定します。 @default %1に攻撃を防御された! @param Enemy Guard Damage SE @desc エネミーの防御が成功した時のダメージSEを指定します。 @default {"name":"Damage4","volume":"90","pitch":"100","pan":"0"} @type struct @param TRAIT_GUARD_RATE @desc 他のプラグインと競合を起こす場合以外は変更しないでください。 @default 101 @type number @min 0 */ /*~struct~sound:ja @param name @desc SEの名前を指定します。 @default Damage4 @type file @require 1 @dir audio/se @param volume @desc SEの音量を指定します。 @default 90 @type number @max 100 @param pitch @desc SEのピッチを指定します。 @default 100 @type number @min 50 @max 150 @param pan @desc SEの位相を指定します。 @default 0 @type number @min -100 @max 100 */ (function () { var paramParse = function (obj) { return JSON.parse(JSON.stringify(obj, paramReplace)); } var paramReplace = function (key, value) { try { return JSON.parse(value || null); } catch (e) { return value; } }; var convertEscapeCharacters = function (text) { if (text == null) text = ''; var window = SceneManager._scene._windowLayer.children[0]; return window ? window.convertEscapeCharacters(text) : text; }; var setArgStr = function (arg) { return convertEscapeCharacters(arg); }; var setArgNum = function (arg) { try { return Number(eval(setArgStr(arg))); } catch (e) { return 0; } }; //objのメモ欄から の値を読み取って返す var readObjectMeta = function (obj, metacodes) { if (!obj) return false; var match = {}; metacodes.some(function (metacode) { var metaReg = new RegExp('<' + metacode + ':[ ]*(.+)>', 'i'); match = metaReg.exec(obj.note); return match; }); return match ? match[1] : ''; }; //============================================================================= // 自作関数(グローバル) //============================================================================= FTKR.gameData = FTKR.gameData || { user: null, target: null, item: null, number: 0, }; if (!FTKR.setGameData) { FTKR.setGameData = function (user, target, item, number) { FTKR.gameData = { user: user || null, target: target || null, item: item || null, number: number || 0 }; }; } if (!FTKR.evalFormula) { FTKR.evalFormula = function (formula) { var datas = FTKR.gameData; try { var s = $gameSwitches._data; var v = $gameVariables._data; var a = datas.user; var b = datas.target; var item = datas.item; var number = datas.number; if (b) var result = b.result(); var value = eval(formula); if (isNaN(value)) value = 0; return value; } catch (e) { console.error(e); return 0; } }; } //============================================================================= // プラグイン パラメータ //============================================================================= var parameters = PluginManager.parameters('FTKR_ExGuardEffect'); FTKR.EGF = { guardEffectValue: Number(parameters['Guard Effect Value'] || 1), disableDamageMotion: !!paramParse(parameters['Disable Damage Motion']), actorGuard: parameters['Actor Guard Text'] || '', actorGuardDamageSe: paramParse(parameters['Actor Guard Damage SE']), enemyGuard: parameters['Enemy Guard Text'] || '', enemyGuardDamageSe: paramParse(parameters['Enemy Guard Damage SE']), }; Game_BattlerBase.TRAIT_GUARD_RATE = +(paramParse(parameters['TRAIT_GUARD_RATE'])); //============================================================================= // DataManager //============================================================================= var _EGF_DatabaseLoaded = false; var _EGF_DataManager_isDatabaseLoaded = DataManager.isDatabaseLoaded; DataManager.isDatabaseLoaded = function () { if (!_EGF_DataManager_isDatabaseLoaded.call(this)) return false; if (!_EGF_DatabaseLoaded) { this.egfEffectNoteTags($dataActors); this.egfEffectNoteTags($dataClasses); this.egfEffectNoteTags($dataWeapons); this.egfEffectNoteTags($dataArmors); this.egfEffectNoteTags($dataEnemies); this.egfEffectNoteTags($dataStates); _EGF_DatabaseLoaded = true; } return true; }; DataManager.egfEffectNoteTags = function (group) { for (var n = 1; n < group.length; n++) { var obj = group[n]; var value = readObjectMeta(obj, ['EGF_GUARD_RATE', 'EGF_防御率']); if (value) { obj.traits.push(this.setObjTrait(Game_BattlerBase.TRAIT_GUARD_RATE, value, 0)); } } }; DataManager.setObjTrait = function (code, value, dataId) { return { code: code, value: value, dataId: dataId }; }; //============================================================================= // SoundManager //============================================================================= SoundManager.playEnemyGuardDamage = function () { AudioManager.playStaticSe(FTKR.EGF.enemyGuardDamageSe); }; SoundManager.playActorGuardDamage = function () { AudioManager.playStaticSe(FTKR.EGF.actorGuardDamageSe); }; //============================================================================= // Game_Action //============================================================================= var _EGF_Game_Action_applyGuard = Game_Action.prototype.applyGuard; Game_Action.prototype.applyGuard = function (damage, target) { var result = target.result(); result.guarded = this.canGuard(damage, target); if (result.guarded) { return this.makeGuardDamage(damage, target); } else { return _EGF_Game_Action_applyGuard.call(this, damage, target); } }; Game_Action.prototype.canGuard = function (damage, target) { return damage > 0 && Math.random() < this.itemGuard(target); }; Game_Action.prototype.itemGuard = function (target) { return target.isGuard() ? 1 : target.guardRate(); }; Game_Action.prototype.makeGuardDamage = function (damage, target) { return damage / (this.guardEffectValue(target) * target.grd); }; Game_Action.prototype.guardEffectValue = function (target) { return FTKR.EGF.guardEffectValue; }; //============================================================================= // Game_BattlerBase //============================================================================= Game_BattlerBase.prototype.guardRate = function () { return this.traitsSumAllEval(Game_BattlerBase.TRAIT_GUARD_RATE) / 100; }; Game_BattlerBase.prototype.traitsSumAllEval = function (code) { FTKR.setGameData(this); return this.traits(code).reduce(function (r, trait) { return r + FTKR.evalFormula(trait.value); }, 0); }; //============================================================================= // Game_Battler //============================================================================= Game_Battler.prototype.performGuardDamage = function () { }; Game_Battler.prototype.guardDamageMotion = function () { return FTKR.EGF.disableDamageMotion ? 'guard' : 'damage'; }; //============================================================================= // Game_Actor //============================================================================= Game_Actor.prototype.performGuardDamage = function () { Game_Battler.prototype.performGuardDamage.call(this); if (this.isSpriteVisible()) { var motion = this.guardDamageMotion(); this.requestMotion(motion); } SoundManager.playActorGuardDamage(); }; //============================================================================= // Game_Enemy //============================================================================= Game_Enemy.prototype.performGuardDamage = function () { Game_Battler.prototype.performGuardDamage.call(this); SoundManager.playEnemyGuardDamage(); this.requestEffect('blink'); }; //============================================================================= // Game_ActionResult //============================================================================= var _EGF_Game_ActionResult_clear = Game_ActionResult.prototype.clear; Game_ActionResult.prototype.clear = function () { _EGF_Game_ActionResult_clear.call(this); this.guarded = false; }; Game_ActionResult.prototype.isGuard = function () { return this.isHit() && this.guarded; }; //============================================================================= // Window_BattleLog //============================================================================= var _EGF_Window_BattleLog_displayDamage = Window_BattleLog.prototype.displayDamage; Window_BattleLog.prototype.displayDamage = function (target) { _EGF_Window_BattleLog_displayDamage.call(this, target); if (target.result().guarded) { this.displayGuard(target); } }; Window_BattleLog.prototype.displayGuard = function (target) { var fmt; fmt = target.isActor() ? FTKR.EGF.actorGuard : FTKR.EGF.enemyGuard; if (fmt) this.push('addText', fmt.format(target.name())); }; var _EGF_Window_BattleLog_performDamage = Window_BattleLog.prototype.performDamage; Window_BattleLog.prototype.performDamage = function (target) { if (target.result().guarded) { target.performGuardDamage(); } else { _EGF_Window_BattleLog_performDamage.call(this, target); } }; }());//EOF