//============================================================================= // DrainExtend.js // ---------------------------------------------------------------------------- // (C)2017 Triacontane // This software is released under the MIT License. // http://opensource.org/licenses/mit-license.php // ---------------------------------------------------------------------------- // Version // 1.2.0 2020/04/29 計算式中でローカル変数[a][b]を使えるよう修正 // 1.1.0 2020/04/29 吸収HPの有効率を設定できる機能を追加 // 各種メモ欄にJavaScript計算式を使用できる機能を追加 // 1.0.2 2017/02/07 端末依存の記述を削除 // 1.0.0 2017/01/17 初版 // ---------------------------------------------------------------------------- // [Blog] : https://triacontane.blogspot.jp/ // [Twitter]: https://twitter.com/triacontane/ // [GitHub] : https://github.com/triacontane/ //============================================================================= /*: @url https://triacontane.blogspot.com/ @plugindesc Absorption Extension Plugin @author Triacontane @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/triacontane-MV-plugins ). Original plugin by Triacontane. Please check the latest official version at: https://triacontane.blogspot.com ----- Expands the specifications for the "HP Absorption" and "MP Absorption" damage types. 1. Absorption rates can be specified to recover N% of the damage dealt. 2. Additional MP or TP can be recovered for HP damage. 3. Additional HP or TP can be recovered for MP damage. 4. Messages and sound effects can be changed for normal damage. 5. Absorption, where HP absorption is capped at the opponent's remaining HP, can be removed. Set the damage type of a skill or item to "HP Absorption" or "MP Absorption." Then enter the following in the Note field. # HP absorption rate will be [150]%. # MP absorption rate will be [50]%. # TP absorption rate will be [50]%. # Message displayed during attack. # HP absorption will exceed the opponent's remaining HP. In addition to control characters, JavaScript expressions can be used in the Note field. The following variables can also be used in the expression. a: Attacker b: Target *1 If you want to recover only MP in response to HP absorption, set the HP absorption rate to 0. You can set the effectiveness for the target of the absorption attack. This does not affect the damage dealt. Specify the following in the Note field of the database with the feature. # Absorption rate will be [50%]. This plugin does not have any plugin commands. Terms of Use: You may modify and redistribute this plugin without permission from the author, and there are no restrictions on its use (commercial, 18+, etc.). This plugin is now yours. @param RecoverSe @desc Plays recovery sound effect when absorption is successful. @type boolean @default false */ /*:ja @plugindesc 吸収拡張プラグイン @author トリアコンタン @param 回復効果音 @desc 吸収成功時に回復効果音を演奏します。 @default false @type boolean @help ダメージタイプの「HP吸収」および「MP吸収」の仕様を拡張します。 1. 吸収率を指定して与えたダメージのN%回復をなどが可能 2. HPダメージに対してMPやTPを追加で回復することが可能 3. MPダメージに対してHPやTPを追加で回復することが可能 4. 通常ダメージ時のメッセージと効果音に変更可能 5. HP吸収の上限が相手の残HPになる吸収の仕様を撤廃可能 スキルもしくはアイテムのダメージタイプを「HP吸収」もしくは「MP吸収」 にしてからメモ欄に以下の通り記述してください。 # HPの吸収率が[150]%になります。 # 同上 # MPの吸収率が[50]%になります。 # 同上 # TPの吸収率が[50]%になります。 # 同上 # メッセージが攻撃時メッセージになります。 # 同上 # HP吸収が相手の残HPを超えるようになります。 # 同上 メモ欄の値は制御文字に加えてJavaScript計算式が使用できます。 さらに計算式中では以下の変数が使えます。 a : 攻撃者 b : 対象者 ※1 HP吸収に対してMPのみ回復させたい場合、HPの吸収率を0に指定してください。 吸収攻撃を受ける側に有効度を設定できます。与えるダメージには影響しません。 特徴を有するデータベースのメモ欄に以下の通り指定してください。 # 吸収率が[50%]になります。 # 同上 このプラグインにはプラグインコマンドはありません。 利用規約: 作者に無断で改変、再配布が可能で、利用形態(商用、18禁利用等) についても制限はありません。 このプラグインはもうあなたのものです。 */ (function () { 'use strict'; var pluginName = 'DrainExtend'; var metaTagPrefix = 'DE_'; //============================================================================= // ローカル関数 // プラグインパラメータやプラグインコマンドパラメータの整形やチェックをします //============================================================================= var getParamString = function (paramNames) { if (!Array.isArray(paramNames)) paramNames = [paramNames]; for (var i = 0; i < paramNames.length; i++) { var name = PluginManager.parameters(pluginName)[paramNames[i]]; if (name) return name; } return ''; }; var getParamBoolean = function (paramNames) { var value = getParamString(paramNames).toUpperCase(); return value === 'ON' || value === 'TRUE'; }; var getMetaValue = function (object, name) { var metaTagName = metaTagPrefix + (name ? name : ''); return object.meta.hasOwnProperty(metaTagName) ? object.meta[metaTagName] : undefined; }; var getMetaValues = function (object, names) { if (!Array.isArray(names)) return getMetaValue(object, names); for (var i = 0, n = names.length; i < n; i++) { var value = getMetaValue(object, names[i]); if (value !== undefined) return value; } return undefined; }; var convertEscapeCharacters = function (text) { if (text == null) text = ''; var windowLayer = SceneManager._scene._windowLayer; return windowLayer ? windowLayer.children[0].convertEscapeCharacters(text) : text; }; //============================================================================= // パラメータの取得と整形 //============================================================================= var param = {}; param.recoverSe = getParamBoolean(['RecoverSe', '回復効果音']); //============================================================================= // Game_BattlerBase // 吸収の有効率を設定します。 //============================================================================= Game_BattlerBase.prototype.getDrainEffectiveRate = function (subject) { var rate = null; var a = subject; var b = this; this.traitObjects().forEach(function (traitObj) { var meta = getMetaValues(traitObj, ['EffectiveRate', '有効率']); if (meta) { rate = Math.max(rate || 0, eval(convertEscapeCharacters(meta)) / 100); } }); return rate !== null ? rate : 1.0; }; //============================================================================= // Game_Action // 吸収の仕様を拡張します。 //============================================================================= var _Game_Action_isDrain = Game_Action.prototype.isDrain; Game_Action.prototype.isDrain = function () { if (this._temporaryDisableDrain) { this._temporaryDisableDrain = false; return false; } return _Game_Action_isDrain.apply(this, arguments); }; Game_Action.prototype.getDrainExtendMeta = function (paramNames) { return getMetaValues(this.item(), paramNames); }; Game_Action.prototype.getHpDrainRate = function (original) { var rate = this.getDrainRate(['PercentageHP', 'HP吸収率']); return rate !== undefined ? rate / 100 : (original ? 1 : undefined); }; Game_Action.prototype.getMpDrainRate = function (original) { var rate = this.getDrainRate(['PercentageMP', 'MP吸収率']); return rate !== undefined ? rate / 100 : (original ? 1 : undefined); }; Game_Action.prototype.getTpDrainRate = function () { var rate = this.getDrainRate(['PercentageTP', 'TP吸収率']); return rate !== undefined ? rate / 100 : undefined; }; Game_Action.prototype.getDrainRate = function (metaParams) { var rate = convertEscapeCharacters(this.getDrainExtendMeta(metaParams)); var a = this.subject(); var b = this._drainTarget; return rate ? eval(rate) : undefined; }; Game_Action.prototype.isDrainMessageAttack = function () { return !!this.getDrainExtendMeta(['AttackMessage', '攻撃メッセージ']); }; Game_Action.prototype.isDrainLimitOver = function () { return !!this.getDrainExtendMeta(['LimitOver', '上限突破']); }; var _Game_Action_apply = Game_Action.prototype.apply; Game_Action.prototype.apply = function (target) { if (this.isDrainMessageAttack()) { this._temporaryDisableDrain = true; } this._drainTarget = target; return _Game_Action_apply.apply(this, arguments); }; var _Game_Action_executeHpDamage = Game_Action.prototype.executeHpDamage; Game_Action.prototype.executeHpDamage = function (target, value) { if (this.isDrainLimitOver()) this._temporaryDisableDrain = true; _Game_Action_executeHpDamage.apply(this, arguments); }; var _Game_Action_gainDrainedHp = Game_Action.prototype.gainDrainedHp; Game_Action.prototype.gainDrainedHp = function (value) { this.gainDrainedParam(value, 'hp'); }; var _Game_Action_gainDrainedMp = Game_Action.prototype.gainDrainedMp; Game_Action.prototype.gainDrainedMp = function (value) { this.gainDrainedParam(value, 'mp'); }; Game_Action.prototype.gainDrainedParam = function (value, originalType) { var effectiveRate = this._drainTarget.getDrainEffectiveRate(this.subject()); var hpRate = this.getHpDrainRate(originalType === 'hp'); if (hpRate !== undefined) { var hpValue = Math.floor(value * hpRate * effectiveRate); if (hpValue !== 0) { _Game_Action_gainDrainedHp.call(this, hpValue); } } var mpRate = this.getMpDrainRate(originalType === 'mp'); if (mpRate !== undefined) { var mpValue = Math.floor(value * mpRate * effectiveRate); if (mpValue !== 0) { _Game_Action_gainDrainedMp.call(this, mpValue); } } var tpRate = this.getTpDrainRate(); if (tpRate !== undefined) { var tpValue = Math.floor(value * tpRate * effectiveRate); if (tpValue !== 0) { this.gainDrainedTp(tpValue); } } }; Game_Action.prototype.gainDrainedTp = function (value) { if (this.isDrain()) { var gainTarget = this.subject(); if (this._reflectionTarget !== undefined) { gainTarget = this._reflectionTarget; } gainTarget.gainTp(value); } }; //============================================================================= // Window_BattleLog // 吸収時に回復効果音を演奏します。 //============================================================================= var _Window_BattleLog_displayDamage = Window_BattleLog.prototype.displayDamage; Window_BattleLog.prototype.displayDamage = function (target) { _Window_BattleLog_displayDamage.apply(this, arguments); if (this.isNeedDrainRecoverSe(target.result())) { this.push('performRecovery', target); } }; Window_BattleLog.prototype.isNeedDrainRecoverSe = function (result) { return param.recoverSe && !result.missed && !result.evaded && result.drain; }; })();