//============================================================================= // NRP_ChargeSkill.js //============================================================================= /*: * @target MV MZ * @plugindesc v1.022 Create a charge skill. * @author Takeshi Sunagawa (http://newrpg.seesaa.net/) * @url http://newrpg.seesaa.net/article/474413155.html * * @help Create a charge skill. * The charge time and other settings can also be set * in conjunction with the CTB plugin. * You can also use the normal turn system. * * [How to use] * 1. Create the state for charging. (Example settings below) * - Action constraints: any of the 'attacks' * - Release condition: Cancel after the battle is over * - Automatic cancellation: at the end of the action * - Continuation turn: 1 * 2. create a skill for execution. * Enter the following into note and specify the ID of the created state. * * * The charge skill will now work. * If you want to set up more detailed settings, please see below. * * [Items available for skills note] * * Sets the ID of the state for charging. (Required) * * * Set the ID of the skill to start charging. * * * Sets the display name at the start of a charge. * * * Sets the speed compensation at the start of charging. * (In CTB, the length of the charge time.) * * or * Set the value with a sign as shown above. * Calculate the original speed as 100(%). * * * Specify if you want to perform a skill with a different ID. * * * At the start of a charge, ignore the passage of turns, such as states. * * * Change to consume MP/TP at the start of a charge. * * * If the specified formula is satisfied, it is triggered immediately. * * * Do not step forward or display skill names when using skills. * * * Do not display the result of using a skill. * * [Items available for equips/states note] * * The charge speed is compensated by the equipment/state. * * * Applies speed compensation only to specific skill types. * You can specify multiple skill types separated by commas. * * [Items available for states note] * * When a state is added, this unstates the specified number. * * * Set the waiting motion during state. * * [Terms] * There are no restrictions. * Modification, redistribution freedom, commercial availability, * and rights indication are also optional. * The author is not responsible, * but we will respond to defects as far as possible. * * @param chargeTurnException * @type boolean * @default false * @desc At the start of a charge skill, ignore some turn-over processes. * Subject to state & ability change turnover, poison damage, etc. */ /*:ja * @target MV MZ * @plugindesc v1.022 ため技作成用の機能を提供します。 * @author 砂川赳(http://newrpg.seesaa.net/) * @url http://newrpg.seesaa.net/article/474413155.html * * @help ため技を作成します。 * CTBプラグインとの連携によって、チャージタイムなどの設定も可能です。 * ※通常のターン制でも使用できます。 * * ■使用方法 * 1.ため状態用ステートを作成します。(以下、設定例) * ・行動制約:『~を攻撃』のいずれか * ・解除条件:戦闘終了後に解除 * ・自動解除:行動終了時 * ・継続ターン:1 * 2.実行用スキルを作成。 * メモ欄へ以下を記入し、作成したステートのIDを指定します。 * ・ * * これだけでため技が機能します。 * より詳細な設定をしたい場合は以下を参照してください。 * * ◆スキルのメモ欄に使用可能な項目 * :ため状態用ステートのIDを設定する。(必須) * :ため開始演出用スキルのIDを設定する。 * :ため開始時の表示名を設定する。 * :ため開始時の速度補正を設定する。 * (CTBにおいてはため時間の長さ) * または * というように、符号付きで値を設定してください。 * 元の速度を100(%)として計算します。 * :他のIDのスキルを実行したい場合に指定する。 * :ため開始時、ステートなどのターン経過を無視します。 * :MP・TPをため開始時に消費するよう変更する。 * :指定した式を満たす場合、即時発動する。 * :スキル使用時の一歩前進や技名表示を行わない。 * :スキル使用時の結果表示を行わない。 * * ◆装備・ステートのメモ欄に使用可能な項目 * :装備、ステート時のため速度に補正をかける。 * :特定のスキルタイプのみ速度補正をかけます。 * カンマ区切りで複数指定可。 * * ◆ステートのメモ欄に使用可能な項目 * :ステートが追加された際、指定番号のステートを解除する。 * :ステート中の待機モーションを設定する。 * * 【利用規約】 * 特に制約はありません。 * 改変、再配布自由、商用可、権利表示も任意です。 * 作者は責任を負いませんが、不具合については可能な範囲で対応します。 * * @param chargeTurnException * @text チャージターンの経過無効 * @type boolean * @default false * @desc ため技の開始時、一部ターン経過処理を無視します。 * ステート&能力変化のターン経過、毒のダメージ効果などが対象。 */ (function() { "use strict"; function toBoolean(str) { if (str == true) { return true; } return (str == "true") ? true : false; } var parameters = PluginManager.parameters("NRP_ChargeSkill"); var pChargeTurnException = toBoolean(parameters["chargeTurnException"]); /** * ●ため技情報を保有する構造体 */ var ChargeSkill = function() { this.skillId = 0; this.targetIndex = -1; }; /** * ●ステートクリア */ var _Game_BattlerBase_clearStates = Game_BattlerBase.prototype.clearStates; Game_BattlerBase.prototype.clearStates = function() { _Game_BattlerBase_clearStates.call(this); // ステート毎に保有するため技データ this._chargeSkills = {}; }; /** * ●アクション開始 */ var _BattleManager_startAction = BattleManager.startAction; BattleManager.startAction = function() { // ため技開始 startCharge(this._subject); // 行動取得 var action = this._subject.currentAction(); // 行動が取得できなければ終了 // ※ため開始状態(skillId:0)を飛ばすため if (!action.item()) { return; } // 元処理実行 _BattleManager_startAction.call(this); }; /** * ●ため技開始 */ function startCharge(subject) { var a = subject; // eval参照用 var action = subject.currentAction(); var item = action.item(); // ため用ステート var chargeStateId = item.meta.ChargeState; // ChargeStateの設定がなければ、ため技ではない。 if (!chargeStateId) { return; // 既にため状態ならば、普通にスキル実行 } else if (isSkillCast(item, subject)) { // 消費タイミングがため開始時の場合 var chargeCost = item.meta.ChargeCost; if (chargeCost) { // 実行時の消費はなし item._tmpMpCost = 0; item._tmpTpCost = 0; } else { item._tmpMpCost = undefined; item._tmpTpCost = undefined; } return; } // eval参照用 var chargeSpeedRate = getChargeSpeedRate(action); // 即時発動条件を満たしているなら、以降処理せず実行 if (isNoCharge(action, chargeSpeedRate)) { return; } // 数式評価 chargeStateId = eval(chargeStateId); /* * ため開始時と判定 */ chargeSkill(subject, action, chargeStateId, chargeSpeedRate); } /** * ●ため技実行時かどうか? * ※ため終わったスキルを発動するタイミングかを判定 */ function isSkillCast(item, subject) { var a = subject; // eval参照用 // ため用ステート var chargeStateId = item.meta.ChargeState; // ChargeStateの設定がなければ、ため技ではない。 if (chargeStateId) { // 数式評価 chargeStateId = eval(chargeStateId); // 既にため状態ならば、普通にスキル実行 if (a.isStateAffected(chargeStateId)) { return true; } } return false; } /** * ●ため開始技の実行 * ※本来、選択したスキルとは別にため開始スキルを実行する。 */ function chargeSkill(subject, action, chargeStateId, chargeSpeedRate) { var a = subject; // eval参照用 var item = action.item(); var keepActions = subject._actions; // アクション保持用 // ため時の速度補正 action._chargeSpeedRate = chargeSpeedRate; // 行動主体にステートを付加 subject.addState(chargeStateId); // 行動制約によってアクションが解除されるので再設定 subject._actions = keepActions; action = subject.currentAction(); // ステート毎のスキルID配列が未定義の場合は初期化 // ※途中セーブから導入した場合を考慮 if (subject._chargeSkills == undefined) { subject._chargeSkills = {}; } // ため技情報を作成 var chargeSkill = new ChargeSkill(); // スキルIDの指定があるなら設定 if (item.meta.ChargeActionSkill) { chargeSkill.skillId = item.meta.ChargeActionSkill; } else { chargeSkill.skillId = item.id; } chargeSkill.targetIndex = action._targetIndex; // ため用ステートIDに、ため技情報を紐付け subject._chargeSkills[chargeStateId] = chargeSkill; // ため技の表示名 var chargeName = item.meta.ChargeName; // 消費タイミングが『ため開始時』の場合 var chargeCost = item.meta.ChargeCost; if (chargeCost) { // 消費を求めて減算する。 subject._mp -= subject.skillMpCost(item); subject._tp -= subject.skillTpCost(item); } // スキルIDをため用に変更 // ため演出用スキルIDを取得する。 var chargeSkillId = item.meta.ChargeSkill; if (chargeSkillId) { chargeSkillId = eval(chargeSkillId); action.setSkill(chargeSkillId); // 取得できない場合は0を設定 } else { action.setSkill(0); } // ため開始ターンを状態異常などの処理の対象外とする設定 var chargeTurnException = item.meta.ChargeTurnException; // の指定がある場合は優先 if (chargeTurnException != undefined) { if (chargeTurnException) { subject._isChargeTurnException = true; } // 指定がない場合はプラグインパラメータの設定 } else if (pChargeTurnException) { subject._isChargeTurnException = true; } // 表示名変更 setChargeName(chargeName, action, item, subject); } /** * ●ターン終了時 */ var _Game_Battler_onTurnEnd = Game_Battler.prototype.onTurnEnd; Game_Battler.prototype.onTurnEnd = function() { // ため技起動時は独自のターン経過処理を行う if (this._isChargeTurnException) { this._isChargeTurnException = undefined; this.clearResult(); this.updateChargeStateTurns(); return; } // 元処理実行 _Game_Battler_onTurnEnd.call(this); }; /** * 【独自実装】ため技用ステートのみターン更新する。 */ Game_BattlerBase.prototype.updateChargeStateTurns = function() { this._states.forEach(function(stateId) { if (this._stateTurns[stateId] > 0 && this._chargeSkills[stateId]) { this._stateTurns[stateId]--; } }, this); }; /** * ●MP消費処理 */ var _Game_BattlerBase_skillMpCost = Game_BattlerBase.prototype.skillMpCost; Game_BattlerBase.prototype.skillMpCost = function(skill) { // 一時消費MPが設定されているならそちらを参照 if (skill._tmpMpCost != undefined) { return Math.floor(skill._tmpMpCost * this.mcr); } // 元処理実行 return _Game_BattlerBase_skillMpCost.call(this, skill); }; /** * ●TP消費処理 */ var _Game_BattlerBase_skillTpCost = Game_BattlerBase.prototype.skillTpCost; Game_BattlerBase.prototype.skillTpCost = function(skill) { // 一時消費TPが設定されているならそちらを参照 if (skill._tmpTpCost != undefined) { return skill._tmpTpCost; } // 元処理実行 return _Game_BattlerBase_skillTpCost.call(this, skill); }; /** * ●スキル一覧の消費更新 */ var _Window_SkillList_drawSkillCost = Window_SkillList.prototype.drawSkillCost; Window_SkillList.prototype.drawSkillCost = function(skill, x, y, width) { skill._tmpMpCost = undefined; skill._tmpTpCost = undefined; // 元処理実行 _Window_SkillList_drawSkillCost.call(this, skill, x, y, width); }; /** * ●表示技名変更 * ・actionの中身は新しいため演出用スキル * ・itemの中身は元の実行用スキル */ function setChargeName(chargeName, action, item, subject) { // eval参照用 var a = subject; // 表示名変更 if (action.item() && chargeName) { // ブランクならメッセージなし if (chargeName == true) { action.item().name = undefined; // 表示名設定 } else { try { // 式として取得できる場合 action.item().name = eval(chargeName); } catch (e) { // 式でない場合はエラーとなるが、普通に文字列で取得 action.item().name = chargeName; } } } } /** * ●混乱時の動作(強制攻撃系の行動制約) */ var _Game_Action_setConfusion = Game_Action.prototype.setConfusion; Game_Action.prototype.setConfusion = function() { if (this.item()) { // ため技情報があれば、実行スキルを設定 var chargeSkill = getChargeSkill(this.subject()); if (chargeSkill) { var skillId = eval(chargeSkill.skillId); this.setSkill(skillId); this.setTarget(chargeSkill.targetIndex); return; } } _Game_Action_setConfusion.call(this); }; /** * ●ため技情報を取得する。 */ function getChargeSkill(subject) { // ため技情報が存在しない場合は処理終了 if (!subject._chargeSkills || subject._chargeSkills.length == 0) { return; } // ため技ステートを発見した場合、その情報を取得する。 for (let i = 0; i < subject.states().length; i++) { let state = subject.states()[i]; if (subject._chargeSkills[state.id]) { return subject._chargeSkills[state.id]; } } } /** * ●ステート追加 */ var _Game_BattlerBase_prototype_addNewState = Game_BattlerBase.prototype.addNewState; Game_BattlerBase.prototype.addNewState = function(stateId) { // があれば、そのステートを設定 var removeStateVal = $dataStates[stateId].meta.RemoveState; if (removeStateVal) { // ","区切りに対応 var removeStates = removeStateVal.split(","); // 対象のステートIDを除去していく。 removeStates.forEach(function(removeStateId) { this.removeState(Number(removeStateId)); }, this); } // 元の処理 _Game_BattlerBase_prototype_addNewState.apply(this, arguments); }; var _Game_BattlerBase_canPaySkillCost = Game_BattlerBase.prototype.canPaySkillCost; Game_BattlerBase.prototype.canPaySkillCost = function(skill) { // ため技実行時 if (isSkillCast(skill, this)) { // 消費タイミングがため開始時の場合 var chargeCost = skill.meta.ChargeCost; if (chargeCost) { // コストは0として判定 return true; } } // 元処理実行 return _Game_BattlerBase_canPaySkillCost.call(this, skill); }; /** * ●対象設定 */ var _Game_Action_makeTargets = Game_Action.prototype.makeTargets; Game_Action.prototype.makeTargets = function() { // ため技情報があれば、対象を再設定 var chargeSkill = getChargeSkill(this.subject()); if (chargeSkill) { this.setTarget(chargeSkill.targetIndex); let targets = []; // MVの場合 if (Utils.RPGMAKER_NAME == "MV") { // 通常の混乱時の挙動は取らない。 if (this.isForOpponent()) { targets = this.targetsForOpponents(); } else if (this.isForFriend()) { targets = this.targetsForFriends(); } // MZの場合 } else { // 通常の混乱時の挙動は取らない。 if (this.isForEveryone()) { targets.push(...this.targetsForEveryone()); } else if (this.isForOpponent()) { targets.push(...this.targetsForOpponents()); } else if (this.isForFriend()) { targets.push(...this.targetsForFriends()); } } return this.repeatTargets(targets); } // 元処理実行 return _Game_Action_makeTargets.call(this); }; /** * 速度補正計算 */ var _Game_Battler_makeSpeed = Game_Battler.prototype.makeSpeed; Game_Battler.prototype.makeSpeed = function() { _Game_Battler_makeSpeed.call(this); // ため速度補正率が取得できれば計算 var chargeSpeedRate = getChargeSpeedRate(this.currentAction()); // ただし、即時発動時は除外する。 if (chargeSpeedRate && !isNoCharge(this.currentAction(), chargeSpeedRate)) { this._speed *= chargeSpeedRate / 100; } }; /** * ●即時発動かどうか? */ function isNoCharge(action, chargeSpeedRate) { // eval参照用 var item = action.item(); var a = action.subject(); var chargeSpeed = eval(chargeSpeedRate - 100) // 即時発動条件を満たしているなら、以降処理せず実行 var ifNoCharge = item.meta.IfNoCharge; if (ifNoCharge && eval(ifNoCharge)) { return true; } return false; } /** * ●ため速度率を計算 */ function getChargeSpeedRate(action) { // 無効なスキルおよび即時発動なら終了 if (!action || !action.item()) { return undefined; } var item = action.item(); var a = action.subject(); var chargeStateId = item.meta.ChargeState; let chargeSpeed; // ため速度が計算済 if (action._chargeSpeedRate) { return action._chargeSpeedRate; // ため技に該当 } else if (chargeStateId) { chargeStateId = eval(chargeStateId); // 既にため状態ならば処理しない if (a.isStateAffected(chargeStateId)) { return; } /* * ため技開始時 * ※CTB用の行動予測計算処理も含む */ // スキルの速度補正 chargeSpeed = item.meta.ChargeSpeed; if (!chargeSpeed) { chargeSpeed = "0"; } // 符号補正 chargeSpeed = addStartPlus(chargeSpeed); var chargeSpeedRate = eval("100 " + chargeSpeed); // 装備による速度補正加算 if (a.equips) { a.equips().forEach(function(equip) { let chargeSpeed = getItemChargeSpeed(equip, item.stypeId); if (chargeSpeed) { // 符号補正 chargeSpeed = addStartPlus(chargeSpeed); chargeSpeedRate = eval(chargeSpeedRate + " " + chargeSpeed); } }); } // ステートによる速度補正加算 a.states().forEach(function(state) { let chargeSpeed = getItemChargeSpeed(state, item.stypeId); if (chargeSpeed) { // 符号補正 chargeSpeed = addStartPlus(chargeSpeed); chargeSpeedRate = eval(chargeSpeedRate + " " + chargeSpeed); } }); return chargeSpeedRate; } // ため用ステートが見つからない場合は処理終了 return undefined; } /** * ●item(装備およびステート)の溜め速度補正を加算 */ function getItemChargeSpeed(item, stypeId) { if (!item) { return undefined; } let chargeSpeed = item.meta.ChargeSpeed; if (chargeSpeed) { let chargeSkillType = item.meta.ChargeSkillType; if (chargeSkillType) { // ","区切りに対応 var chargeSkillTypes = chargeSkillType.split(","); // スキルタイプに一致があれば取得する。 for (let i = 0; i < chargeSkillTypes.length; i++) { if (chargeSkillTypes[i] == stypeId) { return chargeSpeed; } } // 一致がない場合は何も返さない return undefined; // スキルタイプの指定がない場合は常に取得 } else { return chargeSpeed; } } } /** * ●式の先頭に符号がない場合、+を追加する。 */ function addStartPlus(str) { if (!str.startsWith("+") && !str.startsWith("-") && !str.startsWith("*") && !str.startsWith("/")) { return "+ " + str; } return str; } /** * ●モーション設定 */ var _Sprite_Actor_refreshMotion = Sprite_Actor.prototype.refreshMotion; Sprite_Actor.prototype.refreshMotion = function() { var actor = this._actor; // アクション中は除外 if (actor && !actor.isActing()) { // ステートによって、モーションの指定があれば呼び出す。 for (let i = 0; i < actor.states().length; i++) { let state = actor.states()[i]; let motionName = state.meta.StateMotion; if (motionName) { this.startMotion(motionName); return; } } } // 元処理実行 _Sprite_Actor_refreshMotion.call(this); }; /** * ●アクション名表示 */ var _Window_BattleLog_displayAction = Window_BattleLog.prototype.displayAction; Window_BattleLog.prototype.displayAction = function(subject, item) { // アクション名がなければ非表示 if (!item.name) { return; } // 元処理実行 _Window_BattleLog_displayAction.call(this, subject, item); }; /** * ●アクション開始メッセージ&演出 */ var _Window_BattleLog_startAction = Window_BattleLog.prototype.startAction; Window_BattleLog.prototype.startAction = function(subject, action, targets) { var item = action.item(); // スキルメモ欄にが設定されているなら開始演出を省略 if (item.meta.NoStartAction) { // アニメーションとウェイトだけを残す this.push('showAnimation', subject, targets.clone(), item.animationId); this.push('wait'); return; } // 元処理実行 _Window_BattleLog_startAction.apply(this, arguments); }; /** * ●アクション結果表示 */ var _Window_BattleLog_displayActionResults = Window_BattleLog.prototype.displayActionResults; Window_BattleLog.prototype.displayActionResults = function(subject, target) { if (BattleManager._action) { var item = BattleManager._action.item(); // スキルメモ欄にが設定されているなら結果演出を省略 if (item.meta.NoResult) { return; } } // 元処理実行 _Window_BattleLog_displayActionResults.apply(this, arguments); }; })();