//============================================================================= // スキル対抗プラグイン // FTKR_SkillCounter.js // プラグインNo : 5 // 作成者 : フトコロ // 作成日 : 2017/02/21 // 最終更新日 : 2017/04/29 // バージョン : v1.0.6 //============================================================================= var Imported = Imported || {}; Imported.FTKR_SCT = true; var FTKR = FTKR || {}; FTKR.SCT = FTKR.SCT || {}; //============================================================================= /*: * @plugindesc v1.0.6 相手のスキルに対抗して効果を変えるプラグイン * @author フトコロ * * @help *----------------------------------------------------------------------------- * 概要 *----------------------------------------------------------------------------- * 1. スキルのパラメータを指定して、その条件に合うスキルを * 無効化・吸収・反射します。 * * 2. スキルのダメージタイプを指定して、その条件に合うダメージの効果を変えます。 * * 3. 上記1と2のタグ設定の有効条件を設定できます。 * 攻撃側と防御側のパラメータを比較して無効化・吸収・反射するかどうかを * 設定できます。 * * ※本プラグインには、プラグインパラメータとプラグインコマンドはありません。 * * *----------------------------------------------------------------------------- * 設定方法 *----------------------------------------------------------------------------- * 1.「プラグインマネージャー(プラグイン管理)」に、本プラグインを追加して * ください。 * * *----------------------------------------------------------------------------- * スキルの無効化 *----------------------------------------------------------------------------- * スキルのパラメータを指定して、その条件に合うスキルを無効化します。 * ここでの無効化とは、「命中しなかった」ことを意味します。 * * 対象:アクター、クラス、装備、ステート、エネミー * * <スキルID無効化: x> * :スキルIDが x のスキルを無効化します。 * * * <スキルタイプ無効化: x> * :スキルタイプIDが x のスキルを無効化します。 * :スキルタイプIDは、データベースのタイプで設定した番号です。 * * * <ダメージタイプ無効化: x> * :ダメージタイプが x のスキルを無効化します。 * :x は以下の番号を指定してください。 * : 1 - HPダメージ * : 2 - MPダメージ * : 3 - HP回復 * : 4 - MP回復 * : 5 - HP吸収 * : 6 - MP吸収 * * * <属性無効化: x> * :属性IDが x のスキルを無効化します。 * :属性IDは、データベースのタイプで設定した番号です。 * * * <命中タイプ無効化: x> * :命中タイプが x のスキルを無効化します。 * :x は以下の番号を指定してください。 * : 1 - 必中 * : 2 - 物理攻撃 * : 3 - 魔法攻撃 * * * 例) * <スキルID無効化: 10> * :スキルID 10 のスキルを無効化 * * なお、以下のようにカンマ(,)を使って複数の条件を指定することができます。 * <スキルID無効化: 10,11> * :スキルID 10 と 11 のスキルを無効化 * * *----------------------------------------------------------------------------- * スキルの吸収 *----------------------------------------------------------------------------- * スキルのパラメータを指定して、その条件に合うスキルを吸収します。 * * 対象:アクター、クラス、装備、ステート、エネミー * * <スキルID吸収: x> * :スキルIDが x のスキルを吸収します。 * * * <スキルタイプ吸収: x> * :スキルタイプIDが x のスキルを吸収します。 * :スキルタイプIDは、データベースのタイプで設定した番号です。 * * * <属性吸収: x> * :属性IDが x のスキルを吸収します。 * :属性IDは、データベースのタイプで設定した番号です。 * * * <命中タイプ吸収: x> * :命中タイプが x のスキルを吸収します。 * :x は以下の番号を指定してください。 * : 1 - 必中 * : 2 - 物理攻撃 * : 3 - 魔法攻撃 * * 例) * <スキルID吸収: 10> * :スキルID 10 のスキルを吸収 * * なお、以下のようにカンマ(,)を使って複数の条件を指定することができます。 * <スキルID吸収: 10,11> * :スキルID 10 と 11 のスキルを吸収 * * *----------------------------------------------------------------------------- * スキルの反射 *----------------------------------------------------------------------------- * スキルのパラメータを指定して、その条件に合うスキルを反射します。 * * 対象:アクター、クラス、装備、ステート、エネミー * * <スキルID反射: x> * :スキルIDが x のスキルを反射します。 * * * <スキルタイプ反射: x> * :スキルタイプIDが x のスキルを反射します。 * :スキルタイプIDは、データベースのタイプで設定した番号です。 * * * <ダメージタイプ反射: x> * :ダメージタイプが x のスキルを反射します。 * :x は以下の番号を指定してください。 * : 1 - HPダメージ * : 2 - MPダメージ * : 3 - HP回復 * : 4 - MP回復 * : 5 - HP吸収 * : 6 - MP吸収 * * * <属性反射: x> * :属性IDが x のスキルを反射します。 * :属性IDは、データベースのタイプで設定した番号です。 * * * <命中タイプ反射: x> * :命中タイプが x のスキルを反射します。 * :x は以下の番号を指定してください。 * : 1 - 必中 * : 2 - 物理攻撃 * : 3 - 魔法攻撃 * * 例) * <スキルID反射: 10> * :スキルID 10 のスキルを反射 * * なお、以下のようにカンマ(,)を使って複数の条件を指定することができます。 * <スキルID反射: 10,11> * :スキルID 10 と 11 のスキルを反射 * * *----------------------------------------------------------------------------- * ダメージタイプの変更 *----------------------------------------------------------------------------- * 相手のスキルの効果を、ダメージなら回復に、回復ならダメージに変換するタグを * 使用できます。 * * 対象:アクター、クラス、装備、ステート、エネミー * * <ダメージ反転: type> * :受けた'type'のダメージ(吸収含む)を回復に変えます。 * :type に使用できるコードは、以下です。 * : Hp - Hp系のダメージを回復にします。 * : Mp - Mp系のダメージを回復にします。 * 入力例) * * : HpダメージとMpダメージを両方回復にします。 * * * * <回復反転: type> * :受けた'type'の回復をダメージに変えます。 * :type に使用できるコードは、以下です。 * : Hp - Hp系の回復をダメージにします。 * : Mp - Mp系の回復をダメージにします。 * 入力例) * * : Hp回復とMp回復を両方ダメージにします。 * * *----------------------------------------------------------------------------- * 設定したタグの有効条件 *----------------------------------------------------------------------------- * 以下のノートタグを追記することで、無効化・吸収・反射・ダメージ反転タグの * 有効条件を設定することができます。 * * * 条件式 * * * [条件式(eval) の値について] * 条件式(eval)は、ダメージ計算式のように、計算式を入力することで、 * 固定値以外の値を使用することができます。以下のコードを使用できます。 * a.param - 攻撃側のパラメータを参照します。(a.atk で攻撃側の攻撃力) * b.param - 防御側のパラメータを参照します。(b.atk で防御側の攻撃力) * s[x] - スイッチID x の状態を参照します。 * v[x] - 変数ID x の値を参照します。 * * * 入力例) * スイッチID1 が ON の時にタグが有効になる。 * * s[1] * * * * [複数の条件を設定する場合] * 以下の2種類の入力例は同じ意味です。 * * 1. 縦に複数の条件式を並べる * * 条件式1 * 条件式2 * * * 1. '&&'を使用して横に複数の条件式を並べる * * 条件式1 && 条件式2 * * * *----------------------------------------------------------------------------- * 本プラグインのライセンスについて(License) *----------------------------------------------------------------------------- * 本プラグインはMITライセンスのもとで公開しています。 * This plugin is released under the MIT License. * * Copyright (c) 2017 Futokoro * http://opensource.org/licenses/mit-license.php * * *----------------------------------------------------------------------------- * 変更来歴 *----------------------------------------------------------------------------- * * v1.0.6 - 2017/04/29 : 条件式にセルフ変数を使用できるように見直し。 * v1.0.5 - 2017/04/23 : ヘルプ修正 * v1.0.4 - 2017/04/23 : 日本語タグ追加、ヘルプ修正、内部処理見直し * v1.0.3 - 2017/04/23 : 不具合修正 * v1.0.2 - 2017/04/23 : 機能追加 * v1.0.1 - 2017/04/14 : 微修正 * v1.0.0 - 2017/02/21 : 初版作成 * *----------------------------------------------------------------------------- */ //============================================================================= //============================================================================= // プラグイン パラメータ //============================================================================= FTKR.SCT.parameters = PluginManager.parameters('FTKR_SkillCounter.js'); //============================================================================= // 自作関数(グローバル) //============================================================================= 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; } }; } //配列の中身が数字なら数値に変換する Array.prototype.numOrStr = function() { return this.map( function(elm, i) { return isNaN(parseInt(elm)) ? elm : parseInt(elm); }); }; //文字列の配列をtext用の正規表現オブジェクトの配列に変換する Array.prototype.convertEntrapmentRegArray = function() { return this.map(function(str) { return { a:new RegExp('<' + str + '>', 'i'), b:new RegExp('<\/' + str + '>', 'i') }; }); }; //正規表現オブジェクトの配列とdataをテストする Array.prototype.testRegs = function(data, prop) { return this.some(function(reg) { return prop ? reg[prop].test(data) : reg.test(data); }); }; //objのメモ欄から の値を読み取って配列で返す var readSplitMeta = function(obj, metacode) { var metaReg = new RegExp('<' + metacode + ':[ ]*(.+)>', 'i'); if(obj.note.match(metaReg)) { var result = (RegExp.$1).replace(/\s/g, ""); return result.split(',').numOrStr(); } return []; }; // textの形式のメタデータを読み取ってtextを返す var readEntrapmentCodeToText = function(obj, codeTitles) { notes = codeTitles.convertEntrapmentRegArray(); var notedata = obj.note.split(/[\r\n]+/); var setMode = 'none'; for (var i = 0; i < notedata.length; i++) { var line = notedata[i]; if (notes.testRegs(line, 'a')) { var text = ''; setMode = 'read'; } else if (notes.testRegs(line, 'b')) { setMode = 'none'; } else if (setMode === 'read') { text += line + ';'; } } return text; }; // textを条件式に使える状態に変換する var convertTextToConditions = function(text) { var result = ''; if (text) { var datas = text.split(';'); datas.forEach(function(data, i) { result += data; if (datas[i+1]) result += ')&&('; }); result = '(' + result + ')'; } return result; }; //============================================================================= // Game_Action //============================================================================= DataManager.getItemMetaSplit = function(item, metacode) { return item && this.evalSctFormula(item) ? readSplitMeta(item, metacode) : []; }; DataManager.getItemsMetaSplitTotal = function(items, metacode) { var result = []; items.forEach( function(item) { Array.prototype.push.apply(result, this.getItemMetaSplit(item, metacode)); },this); return result; }; //targetが持つ、metacodeで指定したタグの値を配列にして返す DataManager.getItemsMetaArray = function(target, metacode) { var result = []; if(target.isActor()) { return result.concat( this.getItemMetaSplit(target.actor(), metacode), this.getItemMetaSplit($dataClasses[target.actor().classId], metacode), this.getItemsMetaSplitTotal(target.equips(), metacode), this.getItemsMetaSplitTotal(target.states(), metacode) ); } else if(target.isEnemy()) { return result.concat( this.getItemMetaSplit(target.enemy(), metacode), this.getItemsMetaSplitTotal(target.states(), metacode) ); } return result; }; DataManager.convertSctEnableConditions = function(obj) { return convertTextToConditions(readEntrapmentCodeToText(obj, ['SCT 有効条件', 'SCT ENABLE'])); }; DataManager.evalSctFormula = function(obj, subject, target) { var formula = this.convertSctEnableConditions(obj); if (!formula) return true; return FTKR.evalFormula(formula); }; //============================================================================= // Game_Action //============================================================================= Game_Action.prototype.checkSkillData = function(target, metacodes, data) { FTKR.setGameData(this.subject(), target, this.item()); return metacodes.some(function(metacode){ return DataManager.getItemsMetaArray(target, metacode).contains(data); },this); }; //------------------------------------------------------------------------ // スキルのパラメータと対象のメタデータを比較 //------------------------------------------------------------------------ Game_Action.prototype.sctSkillId = function(target, skill, metacode) { return this.isSkill() && this.checkSkillData(target, metacode, skill.id); }; Game_Action.prototype.sctSkillType = function(target, skill, metacode) { return this.isSkill() && this.checkSkillData(target, metacode, skill.stypeId); }; Game_Action.prototype.sctDamageType = function(target, damage, metacode) { return this.checkSkillData(target, metacode, damage.type); }; Game_Action.prototype.sctElementId = function(target, damage, metacode) { var attackElements = this.subject().attackElements(); if(!attackElements.length) attackElements = []; var elementIds = damage.elementId < 0 ? attackElements : [damage.elementId]; var eflag = elementIds.filter( function(eid) { return this.checkSkillData(target, metacode, eid); },this); return eflag.length ? true : false; }; Game_Action.prototype.sctHitType = function(target, skill, metacode) { return this.checkSkillData(target, metacode, skill.hitType); }; //------------------------------------------------------------------------ // スキルの無効化処理 //------------------------------------------------------------------------ FTKR.SCT.Game_Action_itemHit = Game_Action.prototype.itemHit; Game_Action.prototype.itemHit = function(target) { var result = FTKR.SCT.Game_Action_itemHit.call(this, target); return this.checkMetaInvalid(target, this.item()) ? 0 : result; }; Game_Action.prototype.checkMetaInvalid = function(target, skill) { return this.sctSkillId(target, skill, ['InvalidSkillId', 'スキルID無効化']) || this.sctSkillType(target, skill, ['InvalidSkillType', 'スキルタイプ無効化']) || this.sctDamageType(target, skill.damage, ['InvalidDamageType', 'ダメージタイプ無効化']) || this.sctElementId(target, skill.damage, ['InvalidElementId', '属性無効化']) || this.sctHitType(target, skill, ['InvalidHitType', '命中タイプ無効化']); }; //------------------------------------------------------------------------ // スキルの吸収・ダメージ反転処理 //------------------------------------------------------------------------ FTKR.SCT.Game_Action_executeDamage = Game_Action.prototype.executeDamage; Game_Action.prototype.executeDamage = function(target, value) { value = this.sctReversDamageType(target, value); FTKR.SCT.Game_Action_executeDamage.call(this, target, value); }; Game_Action.prototype.sctReversDamageType = function(target, value) { return this.checkReversDamageType(target) ? value * -1 : value; }; Game_Action.prototype.checkReversDamageType = function(target) { return (this.isHpRecover() && this.checkSkillData(target, ['ReversRecover', '回復反転'], 'Hp')) || (this.isHpEffect() && (this.checkSkillData(target, ['ReversDamage', 'ダメージ反転'], 'Hp') || this.checkMetaDrain(target, this.item()))) || (this.isMpRecover() && this.checkSkillData(target, ['ReversRecover', '回復反転'], 'Mp')) || (this.isMpEffect() && (this.checkSkillData(target, ['ReversDamage', 'ダメージ反転'], 'Mp') || this.checkMetaDrain(target, this.item()))); }; Game_Action.prototype.checkMetaDrain = function(target, skill) { return this.sctSkillId(target, skill, ['DrainSkillId', 'スキルID吸収']) || this.sctSkillType(target, skill, ['DrainSkillType', 'スキルタイプ吸収']) || this.sctElementId(target, skill.damage, ['DrainElementId', '属性吸収']) || this.sctHitType(target, skill, ['DrainHitType', '命中タイプ吸収']); }; //------------------------------------------------------------------------ // スキルの反射処理 //------------------------------------------------------------------------ FTKR.SCT.Game_Action_itemMrf = Game_Action.prototype.itemMrf; Game_Action.prototype.itemMrf = function(target) { return this.checkMetaReflection(target, this.item()) || FTKR.SCT.Game_Action_itemMrf.call(this, target); }; Game_Action.prototype.checkMetaReflection = function(target, skill) { return this.sctSkillId(target, skill, ['ReflectionSkillId', 'スキルID反射']) || this.sctSkillType(target, skill, ['ReflectionSkillType', 'スキルタイプ反射']) || this.sctDamageType(target, skill.damage, ['ReflectionDamageType', 'ダメージタイプ反射']) || this.sctElementId(target, skill.damage, ['ReflectionElementId', '属性反射']) || this.sctHitType(target, skill, ['ReflectionHitType', '命中タイプ反射']); };