pastime/js/plugins/NRP_CountTimeBattle.js
2026-03-15 16:45:22 -05:00

1955 lines
64 KiB
JavaScript
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

//=============================================================================
// NRP_CountTimeBattle.js
//=============================================================================
/*:
* @target MV MZ
* @plugindesc v1.233 Change the battle system to CTB.
* @author Takeshi Sunagawa (http://newrpg.seesaa.net/)
* @base NRP_VisualTurn
* @orderBefore NRP_VisualTurn
* @url http://newrpg.seesaa.net/article/472859369.html
*
* @help This is a so-called CTB (Count Time Battle).
* One by one, the actions will be turned in proportion to the agility.
* With that, each battler will possess a turn individually.
*
* This plugin does not display order by itself.
* Please use it in combination with NRP_VisualTurn.js.
* http://newrpg.seesaa.net/article/472840225.html
*
* -------------------------------------------------------------------
* [Notice]
* -------------------------------------------------------------------
* If the state "Auto-removal Timing" is "Action End",
* the effect will expire at the individual's turn.
* In the case of "Turn End", the effect
* is determined in everyone's turn.
* Basically, "Action End" is easier to use.
*
* Speed values entered from the editor are in %.
* Speed100 technique is +100%. This means twice as fast.
* Speed -50 is 1/2 times faster.
* Below -100, the turn will be almost no turn.
*
* Be sure to change the Guard Skill setting that is in the default.
* If Speed is left at 2000, it will be "my turn all the time".
* Also, "Action End" is recommended for Auto-removal of guard state.
*
* It does not support multiple actions by the actor.
*
* The fight and escape party commands are not initially displayed.
* They are displayed when Cancel is pressed.
*
* For more information, please see below.
* http://newrpg.seesaa.net/article/472859369.html
*
* -------------------------------------------------------------------
* [Note of States]
* -------------------------------------------------------------------
* You can change the target's waiting time
* by entering the following in the note field of the state.
* A value of 100 is the waiting time for one turn of the target.
* Formulas and negative values are also valid.
*
* ◆<SetWt:[Number]>
* Change the target waiting time.
*
* ◆<AddWt:[Number]>
* Add up the waiting time for the target.
*
* [Sample]
* <AddWt:50>
* Delays the target's action for 1/2 turn.
* This is the so-called delay attack.
*
* <SetWt:0>
* The target's waiting time is reduced to 0
* and the action is taken immediately.
* However, it is meaningless even
* if it is applied to the user of the skill,
* because the turn will elapse immediately after this.
* If you want the user to perform continuous action,
* set the Speed of the skill to 2000.
* (※Refer to: Continuous action skill)
*
* <SetWt:-500>
* Changes the target's waiting time to -5 turns.
* In other words, you will be able to move unilaterally about 5 times.
*
* Note that these effects occur only when a state is applied.
* Therefore, they cannot be applied on top of each other
* if the same state is still applied.
* If "Auto-removal Timing" is set to "Turn End" for a single turn,
* the stacking can be done instantly.
*
* Conversely, if "Auto-removal Timing"
* is set to one turn of "Action End",
* an anomaly such as "delay that cannot be stacked
* until the enemy acts once" can be created for the purpose.
*
* ◆<DeadCTBTurn>
* The dead state will still appear in the order of action.
* Assume a special state that will be revived
* after a certain amount of time.
*
* ◆<ExpiredTurnStart>
* For a state whose Auto-removal Timing is Action End,
* this causes the state's Auto-removal to occur
* at the start of the turn (at the start of input).
* This is useful for guard and other situations
* where you want the effect to expire at the start of input.
*
* -------------------------------------------------------------------
* [Note (actor, enemy, class, equipment, state, skill, item)]
* -------------------------------------------------------------------
* In the note of the object that holds the trait,
* please include the following.
* For skills, this is a passive skill
*
* <StartWt:[Number]>
* Change the waiting time (Base:100)
* at the start of battle to the specified value.
* For example, if <StartWt:0>, the action is taken immediately.
* If <StartWt:200>, the start of action is delayed by one turn.
*
* -------------------------------------------------------------------
* [Note of Skills]
* -------------------------------------------------------------------
* <ReviveWt:[Number]>
* For the revive skill, set the waiting time (Base: 100) when reviving.
* If <ReviveWt:50>, the action starts in 1/2 turn.
*
* -------------------------------------------------------------------
* [Continuous action skill]
* -------------------------------------------------------------------
* If the Speed of a skill is set to 2000 (MAX),
* it will perform a series of actions without time elapsing.
* This is useful for creating auxiliary skills, etc.,
* that trigger instantaneous effects.
*
* -------------------------------------------------------------------
* [Conflict Information]
* -------------------------------------------------------------------
* Because it is fundamentally changing the flow of battle,
* it will conflict with plug-ins that touch that area.
* For reference, plugins with larger impact tend to move more easily
* if they are placed on the upper side.
* ※This is just a trend. It is not certain.
*
* Overrides the following functions. Please be careful of conflicts.
* I think it's more stable if you put it on top as much as possible.
* - Scene_Battle.prototype.commandFight
* - BattleManager.startInput()
* - BattleManager.selectNextCommand
* - BattleManager.selectPreviousCommand
* - BattleManager.makeActionOrders
* - BattleManager.startTurn
* - BattleManager.processTurn
* - BattleManager.endTurn
* - BattleManager.updateTurnEnd
* - BattleManager.getNextSubject
* - BattleManager.processEscape
* - Game_Party.prototype.requestMotionRefresh
* - Game_Battler.prototype.onAllActionsEnd
* - Game_Battler.prototype.performActionEnd()
* - Game_Enemy.prototype.meetsTurnCondition
* - Game_Action.prototype.speed
* - Window_BattleLog.prototype.startTurn
* (The following are MZ only)
* - Game_Battler.prototype.turnCount
* - BattleManager.endAction
*
* -------------------------------------------------------------------
* [Terms]
* -------------------------------------------------------------------
* There are no restrictions.
* Modification, redistribution freedom, commercial availability,
* and rights indication are also optional.
* The author is not responsible,
* but will deal with defects to the extent possible.
*
* @------------------------------------------------------------------
* @ [Plugin Parameters]
* @------------------------------------------------------------------
*
* @param <Basic>
*
* @param number
* @parent <Basic>
* @type number
* @default 9
* @desc The number of battler to calculate the turn order.
* This is the number of battler to be displayed. default 9.
*
* @param calcGuardCommand
* @parent <Basic>
* @type boolean
* @default true
* @desc When the cursor is hovered over a guard command, the order display is calculated according to speed.
*
* @param showActionUser
* @parent <Basic>
* @type boolean
* @default true
* @desc When selecting an action, the current actor is displayed at the top.
*
* @param notPartyMotionRefresh
* @parent <Basic>
* @type boolean
* @default true
* @desc Don't do motion updates for party. The process for turn-based systems, so it should not be necessary for CTB.
*
* @param <Battle Start>
*
* @param showPartyCommand
* @parent <Battle Start>
* @type select
* @option 0:None @value 0
* @option 1:Display @value 1
* @option 2:OnlyEnemyFirst @value 2
* @default 0
* @desc How to display party commands at the start of a battle.
*
* @param actorStartRandomWt
* @parent <Battle Start>
* @type string
* @default 0
* @desc Distribute the actors' initial wait time by the numerical %.
* Example: 20 distributes 90-110%. 0 if not specified.
*
* @param enemyStartRandomWt
* @parent <Battle Start>
* @type string
* @default 20
* @desc Distribute the enemys' initial wait time by the numerical %.
* Example: 20 distributes 90-110%. 0 if not specified.
*
* @param preemptiveAdvantage
* @parent <Battle Start>
* @type string
* @default 50
* @desc Advantage to actors during a preemptive attack.
* Speed up their turn by the % of the specified number.
*
* @param surpriseAdvantage
* @parent <Battle Start>
* @type string
* @default 50
* @desc Advantage to enemys during a surprise attack.
* Speed up their turn by the % of the specified number.
*
* @param startTurn
* @parent <Battle Start>
* @type select
* @option 0
* @option 1
* @default 1
* @desc Sets the number of turns at the start of battle.
* It is used to determine the enemy's action. default 1. MV's default 0.
*
* @param <Escape>
*
* @param escapePenalty
* @parent <Escape>
* @type string
* @default 25
* @desc Penalty for failure to escape.
* Delays the actor's turn by the % of the specified number.
*
* @param <State&Buf>
*
* @param selfStatePlusTurn
* @parent <State&Buf>
* @type boolean
* @default true
* @desc The state put on self has a +1 continuation turn.
* The timing of the automatic cancellation must be "Action End".
*
* @param selfBufPlusTurn
* @parent <State&Buf>
* @type boolean
* @default true
* @desc The buf put on self has a +1 continuation turn.
* How to deal with a problem whose effect on self quickly disappears.
*
* @param reviveWT
* @parent <State&Buf>
* @type combo
* @option baseWt
* @option wt
* @desc Reset wait time at revive. Formulas allowed.
* baseWt:wait time for one turn, wt:wait time at dead.
*
* @param predictionSkillOrder
* @parent <State&Buf>
* @type boolean
* @default true
* @desc If the order of action changes depending on the skill, it is predicted and displayed.
*
* @param predictionCertain
* @parent predictionSkillOrder
* @type boolean
* @default true
* @desc Only skills with a hit type of certain are subject to prediction.
* If off, everything is enabled.
*/
/*:ja
* @target MV MZ
* @plugindesc v1.233 戦闘システムをCTBへ変更します。
* @author 砂川赳http://newrpg.seesaa.net/
* @base NRP_VisualTurn
* @orderBefore NRP_VisualTurn
* @url http://newrpg.seesaa.net/article/472859369.html
*
* @help いわゆるCTB(カウントタイムバトル)です。
* 敏捷性に比例して、一人ずつ行動が回ってくるようになります。
* それに伴い、各バトラーは個別にターンを保有するようになります。
*
* このプラグイン単体では順序の表示を行いません。
* NRP_VisualTurn.jsと組み合わせて使用してください。
* http://newrpg.seesaa.net/article/472840225.html
*
* -------------------------------------------------------------------
* ■注意点
* -------------------------------------------------------------------
* ステートの自動解除のタイミングが『行動終了時』の場合は
* 個人のターンで効果が切れます。
* 『ターン終了時』の場合は全員のターンで判定されます。
* 基本的には『行動終了時』のほうが使いやすいです。
*
* エディタ上から入力する速度補正の値は%にしています。
* 速度補正100の技は+100%。つまり二倍速ということです。
* 速度補正-50で1/2倍速です。-100以下だとターンがほぼ回らなくなります。
*
* デフォルトにある防御の設定は必ず変えてください。
* 速度補正が2000のままだと「ずっと俺のターン」になります。
* また、防御ステートの自動解除は『行動終了時』を推奨します。
*
* アクターの複数回行動には対応していません。
*
* 戦う、逃げるのパーティコマンドは初期表示しません。
* キャンセルを押すと表示するようになっています。
*
* その他、詳細は以下をご覧ください。
* http://newrpg.seesaa.net/article/472859369.html
*
* -------------------------------------------------------------------
* ■ステートのメモ欄
* -------------------------------------------------------------------
* ステートのメモ欄に以下を記入することで、対象の待ち時間を変更できます。
* 数値は100で対象のターン分の待ち時間となります。
* 数式やマイナス値も有効です。
*
* ◆<SetWt:[数値]>
* 対象の待ち時間を変更します。
*
* ◆<AddWt:[数値]>
* 対象の待ち時間を加算します。
*
* [例]
* <AddWt:50>
* 1/2ターン分、相手の行動を遅らせます。
* いわゆるディレイアタックですね。
*
* <SetWt:0>
* 対象の待ち時間を0にし、即時行動させます。
* ただし、行動者自身にかけても、この直後にターン経過するので無意味です。
* 連続行動をさせたい場合は、スキルの速度補正を2000に設定してください。
* (※参照:連続行動技)
*
* <SetWt:-500>
* 対象の待ち時間を-5ターンに変更します。
* つまり、一方的に5回程度動けるようになります。
*
* なお、これらはステートがかかった際にのみ発生する効果となります。
* そのため、同一のステートがかかったままだと重ねがけできません。
* これは自動解除のタイミングを『ターン終了時』の1ターンにしておけば、
* 即座に重ねられるようになります。
*
* 逆に言えば、自動解除のタイミングを『行動終了時』の1ターンにしておけば、
* 「敵が一度行動するまで重ねられないディレイ」のような異常を狙って作れます。
*
* ◆<DeadCTBTurn>
* 戦闘不能状態でも行動順序に表示されるようになります。
* 一定時間で復活などの特殊なステートを想定しています。
*
* ◆<ExpiredTurnStart>
* 自動解除のタイミングが行動終了時のステートに対して、
* ターン開始時(入力開始時)にステートの自動解除を発生させます。
* 防御など入力開始時に効果を切れさせたい場合に有効です。
*
* -------------------------------------------------------------------
* ■アクター、エネミー、職業、装備、ステート、スキルのメモ欄
* -------------------------------------------------------------------
* 特徴を保有するオブジェクトのメモ欄に以下を記載してください。
* スキルについては覚えているだけで、機能するパッシブスキルとなります。
*
* <StartWt:[数値]>
* 戦闘開始時の待ち時間(基準:100を指定した値に変更します。
* 例えば、<StartWt:0>なら即時行動します。
* <StartWt:200>ならば、1ターン分行動開始が遅れます。
*
* -------------------------------------------------------------------
* ■スキルのメモ欄
* -------------------------------------------------------------------
* <ReviveWt:[数値]>
* 蘇生スキルに対して、蘇生時の待ち時間(基準:100を設定します。
* <ReviveWt:50>ならば、1/2ターンで行動開始します。
*
* -------------------------------------------------------------------
* ■連続行動技
* -------------------------------------------------------------------
* スキルの速度補正を2000MAXにしておくと、
* 時間経過なしで連続行動を行います。
* 瞬時に効果を発動する補助スキルなどの作成に便利です。
*
* -------------------------------------------------------------------
* ■競合情報
* -------------------------------------------------------------------
* 戦闘の流れを根本的に変えているため、
* その辺に触れるプラグインとは競合しまくります。
* 参考までにこういった影響の大きなプラグインほど
* 上側に配置したほうが、動きやすい傾向にあります。
* ※あくまで傾向です。確実ではありません。
*
* 以下の関数を上書きしています。競合にご注意ください。
* なるべく上側に配置したほうが安定すると思います。
* ・Scene_Battle.prototype.commandFight
* ・BattleManager.startInput()
* ・BattleManager.selectNextCommand
* ・BattleManager.selectPreviousCommand
* ・BattleManager.makeActionOrders
* ・BattleManager.startTurn
* ・BattleManager.processTurn
* ・BattleManager.endTurn
* ・BattleManager.updateTurnEnd
* ・BattleManager.getNextSubject
* ・BattleManager.processEscape
* ・Game_Party.prototype.requestMotionRefresh
* ・Game_Battler.prototype.onAllActionsEnd
* ・Game_Battler.prototype.performActionEnd()
* ・Game_Enemy.prototype.meetsTurnCondition
* ・Game_Action.prototype.speed
* ・Window_BattleLog.prototype.startTurn
* (以下はMZのみ)
* ・Game_Battler.prototype.turnCount
* ・BattleManager.endAction
*
* -------------------------------------------------------------------
* ■利用規約
* -------------------------------------------------------------------
* 特に制約はありません。
* 改変、再配布自由、商用可、権利表示も任意です。
* 作者は責任を負いませんが、不具合については可能な範囲で対応します。
*
* @------------------------------------------------------------------
* @ プラグインパラメータ
* @------------------------------------------------------------------
*
* @param <Basic>
* @text <基本設定>
* @desc 見出しです。
*
* @param number
* @text 計算人数(表示人数)
* @parent <Basic>
* @type number
* @default 9
* @desc ターン順序の計算を行う人数。これが表示される人数になります。
* 指定なしなら9。
*
* @param calcGuardCommand
* @text 防御選択時に計算
* @parent <Basic>
* @type boolean
* @default true
* @desc 防御コマンドにカーソルを合わせた際、速度補正に応じて順序表示の計算を行います。
*
* @param showActionUser
* @text 行動選択時に行動者を表示
* @parent <Basic>
* @type boolean
* @default true
* @desc 行動選択時、先頭に現在の行動者を表示します。
*
* @param notPartyMotionRefresh
* @text 不要なモーション更新削除
* @parent <Basic>
* @type boolean
* @default true
* @desc 行動選択時、全員のモーション更新をやらないようにします。
* ターン制用の処理なのでCTBでは不要なはず……。
*
* @param <Battle Start>
* @text <戦闘開始関連>
* @desc 見出しです。
*
* @param showPartyCommand
* @text パーティコマンドの表示
* @parent <Battle Start>
* @type select
* @option 0:非表示 @value 0
* @option 1:表示 @value 1
* @option 2:敵先制時のみ表示 @value 2
* @default 0
* @desc 戦闘開始時にパーティコマンドを表示する方法です。
*
* @param actorStartRandomWt
* @text 味方の始動時間バラツキ
* @parent <Battle Start>
* @type string
* @default 0
* @desc 味方の初期待ち時間を数値%分だけ分散させます。数式可
* 例20ならば、90110%に分散。指定なしは0。
*
* @param enemyStartRandomWt
* @text 敵の始動時間バラツキ
* @parent <Battle Start>
* @type string
* @default 20
* @desc 敵の初期待ち時間を数値%分だけ分散させます。数式可
* 例20ならば、90110%に分散。指定なしは20。
*
* @param preemptiveAdvantage
* @text 先制時の始動時間ボーナス
* @parent <Battle Start>
* @type string
* @default 50
* @desc 先制攻撃時の特典。数式可
* 指定した数値の%分だけ仲間のターンを早めます。
*
* @param surpriseAdvantage
* @text 奇襲時の始動時間ボーナス
* @parent <Battle Start>
* @type string
* @default 50
* @desc 奇襲時の敵特典。数式可
* 指定した数値の%分だけ敵のターンを早めます。
*
* @param startTurn
* @text 開始ターン数
* @parent <Battle Start>
* @type select
* @option 0
* @option 1
* @default 1
* @desc 戦闘開始時のターン数(敵の行動判定用)を設定します。
* 初期値は1。MVのデフォルトの仕様だと0です。
*
* @param <Escape>
* @text <逃走関連>
* @desc 見出しです。
*
* @param escapePenalty
* @text 逃走時のペナルティ時間
* @parent <Escape>
* @type string
* @default 25
* @desc 逃走失敗時のペナルティ。数式可
* 指定した数値の%分だけ味方のターンを遅らせます。
*
* @param <State&Buf>
* @text <ステート/能力変化>
* @desc 見出しです。
*
* @param selfStatePlusTurn
* @text 自身へのステートターン+1
* @parent <State&Buf>
* @type boolean
* @default true
* @desc 自分にかけたステートは継続ターンを+1します。
* 自動解除のタイミングが『行動終了時』のものが対象です。
*
* @param selfBufPlusTurn
* @text 自身への強化弱体ターン+1
* @parent <State&Buf>
* @type boolean
* @default true
* @desc 自分にかけた強化弱体は継続ターンを+1します。
* 自分にかけた変化が即切れする問題への対処です。
*
* @param reviveWT
* @text 蘇生時のWT
* @parent <State&Buf>
* @type combo
* @option baseWt
* @option wt
* @desc 蘇生時に待ち時間を再設定します。数式可
* baseWt:1ターン分の待ち時間, wt:戦闘不能時の待ち時間
*
* @param predictionSkillOrder
* @text スキルの順序変化を予測
* @parent <State&Buf>
* @type boolean
* @default true
* @desc スキルによって変化する順序を予測し表示します。
*
* @param predictionCertain
* @text 必中のみ予測
* @parent predictionSkillOrder
* @type boolean
* @default true
* @desc 命中タイプが必中のスキルのみ予測の対象とします。
* オフの場合は全て対象とします。
*/
(function() {
"use strict";
function toBoolean(str, def) {
if (str === true || str === "true") {
return true;
} else if (str === false || str === "false") {
return false;
}
return def;
}
function toNumber(str, def) {
return isNaN(str) ? def : +(str || def);
}
function setDefault(str, def) {
if (str == undefined || str == "") {
return def;
}
return str;
}
const parameters = PluginManager.parameters("NRP_CountTimeBattle");
const pNumber = toNumber(parameters["number"], 9);
const pCalcGuardCommand = toBoolean(parameters["calcGuardCommand"], true);
const pShowActionUser = toBoolean(parameters["showActionUser"], true);
const pNotPartyMotionRefresh = toBoolean(parameters["notPartyMotionRefresh"], true);
const pShowPartyCommand = toNumber(parameters["showPartyCommand"], 0);
const pActorStartRandomWt = setDefault(parameters["actorStartRandomWt"], 0);
const pEnemyStartRandomWt = setDefault(parameters["enemyStartRandomWt"], 20);
const pPreemptiveAdvantage = setDefault(parameters["preemptiveAdvantage"], 50);
const pSurpriseAdvantage = setDefault(parameters["surpriseAdvantage"], 50);
const pStartTurn = toNumber(parameters["startTurn"], 1);
const pEscapePenalty = setDefault(parameters["escapePenalty"], 25);
const pSelfStatePlusTurn = toBoolean(parameters["selfStatePlusTurn"], true);
const pSelfBufPlusTurn = toBoolean(parameters["selfBufPlusTurn"], true);
const pReviveWT = setDefault(parameters["reviveWT"]);
const pPredictionSkillOrder = toBoolean(parameters["predictionSkillOrder"], true);
const pPredictionCertain = toBoolean(parameters["predictionCertain"], true);
//-----------------------------------------------------------------------------
// Scene_Battle
//-----------------------------------------------------------------------------
/**
* ●戦闘開始シーン制御
*/
const _Scene_Battle_start = Scene_Battle.prototype.start;
Scene_Battle.prototype.start = function() {
_Scene_Battle_start.apply(this);
// MZ対応
if (Utils.RPGMAKER_NAME == "MV") {
// 表示更新(これがないとTPの初期値が表示されない)
this.refreshStatus();
}
};
/**
* 【上書】パーティコマンドの戦うを選択
*/
Scene_Battle.prototype.commandFight = function() {
const subject = BattleManager._subject;
// アクターのコマンドを呼び出し
if (subject && subject.isActor() && subject.canInput()) {
BattleManager.startInputActor();
return;
}
// 有効なアクターが取得できない場合は次へ
this.selectNextCommand();
};
/**
* ●味方選択キャンセル
*/
const _Scene_Battle_prototype_onActorCancel = Scene_Battle.prototype.onActorCancel;
Scene_Battle.prototype.onActorCancel = function() {
_Scene_Battle_prototype_onActorCancel.call(this);
// 行動予測を戻すために行動順序再計算
BattleManager.makeActionOrders();
};
/**
* ●敵選択キャンセル
*/
const _Scene_Battle_prototype_onEnemyCancel = Scene_Battle.prototype.onEnemyCancel;
Scene_Battle.prototype.onEnemyCancel = function() {
_Scene_Battle_prototype_onEnemyCancel.call(this);
// 行動予測を戻すために行動順序再計算
BattleManager.makeActionOrders();
};
//-----------------------------------------------------------------------------
// BattleManager
//-----------------------------------------------------------------------------
/*
* ●初期化処理
*/
const _BattleManager_initMembers = BattleManager.initMembers;
BattleManager.initMembers = function() {
_BattleManager_initMembers.call(this);
// CTTB判定フラグ
this._isCtb = true;
};
/**
* 【上書】コマンド入力開始
* ※一度だけ呼び出される部分
*/
BattleManager.startInput = function() {
let callPartyCommand = false;
// MVではターン開始直後に付加したステートが表示されないので対応
if (Utils.RPGMAKER_NAME == "MV") {
this.refreshStatus();
}
// パーティコマンドの表示を行う場合
// ※戦闘開始時かつ奇襲ではない場合が条件
if (pShowPartyCommand && this._phase == "start" && !this._surprise) {
callPartyCommand = true;
}
this._phase = 'input';
// MZ対応
this._inputting = true;
this._currentActor = null;
// 行動順序計算
this.makeActionOrders();
// 時間経過
this.timeGoesBy();
// 次の行動者を取得する。
this._subject = this.getNextSubject();
// 行動者の個別ターン加算
this._subject._turnCount++;
// ステートの自動解除
for (const state of this._subject.states()) {
// ステートの自動解除をターン開始時に実行する場合
if (state.meta.ExpiredTurnStart) {
// 残りターンが1以下ならば
if (this._subject._stateTurns[state.id] <= 1 && state.autoRemovalTiming === 1) {
this._subject.removeState(state.id);
}
}
}
// 行動設定
// ※敵なら行動設定、味方なら行動回数などの領域設定
this._subject.makeActions();
// 入力中のアクターをクリアし、パーティコマンドを呼び出す。
if (callPartyCommand) {
// 通常表示の場合
// または、敵先制時のみ表示の条件を満たしている場合
if (pShowPartyCommand == 1
|| pShowPartyCommand == 2 && this._subject.isEnemy()) {
this._actorIndex = -1;
this._currentActor = null;
return;
}
}
// 敵の場合、または味方が入力不可ならターン開始
if (!this._subject.isActor() || !this._subject.canInput()) {
this._actorIndex = -1;
this.startTurn();
return;
}
this.startInputActor();
};
/**
* 【独自】コマンド入力開始(続)
* ※パーティコマンドから戻ってくる際と共有
*/
BattleManager.startInputActor = function() {
// MZ対応
// パーティコマンドから戻った際は空なので再設定
if (!this._currentActor) {
this._currentActor = this._subject;
}
// 先頭の行動者を入力対象に設定
this._actorIndex = this._subject.index();
// 入力可能状態のみ
if (this._subject.canInput()) {
/*
* 【参考情報】
* undecided(未定),inputting(コマンド入力中),waiting(待機中),acting(行動中),done(行動終了)
*/
this._subject.setActionState("inputting"); // ポーズを入力中に変更
}
};
/**
* 【上書】次のコマンド入力へ
*/
BattleManager.selectNextCommand = function() {
do {
/*
* 以下のいずれかの場合はターン開始
* アクターが取得できない。
* アクターではなく敵である。
* アクターのコマンドは全て入力済み。(複数行動を考慮)
*/
if (!this.actor() || !this.actor().isActor() || !this.actor().selectNextCommand()) {
this.startTurn();
break;
}
} while (!this.actor() || !this.actor().isActor() || !this.actor().canInput());
};
/**
* 【上書】前のコマンド入力へ
*/
BattleManager.selectPreviousCommand = function() {
do {
var actor = this.actor();
if (!actor || !actor.selectPreviousCommand()) {
// 入力中のアクターをクリアし、パーティコマンドを呼び出す。
this._actorIndex = -1;
this._currentActor = null; // MZ対応
this._subject.setActionState("undecided");
return;
}
} while (!this.actor().canInput());
};
// makeActionOrders時に現在の行動者を先頭に追加するか
let mAddActionUser = false;
/**
* 【上書】行動順序の作成
*/
BattleManager.makeActionOrders = function() {
// WTとバトラーの組のリスト
const wtBattlers = []
// 一時バトラーリスト
let battlers = [];
/*
* 敵味方全員の生存者リストを作成し、基本WTを計算する。
*/
this.allBattleMembers().forEach(function(battler) {
// 生存者のみに絞る
if (battler.isCtbAlive()) {
// 現在の敏捷性で基本WTを設定する。
battler.makeBaseWt();
// 格納
battlers.push(battler);
}
});
/*
* CTB用の行動順リストを作成していく。
*/
for (const battler of battlers) {
// バトラーをリストが埋まるまで登録していく。
for (let i = 0; i < pNumber; i++) {
// 現在のWTに、次の行動までのWTを加算する。
const tmpWt = battler.wt + (battler.baseWt * i);
/*
* 以下の条件を満たす場合は登録終了。
* 1.現在の行動順リストが埋まっている。
* かつ、末尾のバトラーよりもWTが大きい場合。
*/
if (wtBattlers.length >= pNumber
&& tmpWt >= wtBattlers[pNumber - 1][0]) {
// forループを終了して、次のバトラーへ
break;
}
// 行動順リストの末尾にWTとバトラーの組を追加
wtBattlers.push([tmpWt, battler]);
// WT順でソート実行
wtBattlers.sort((a, b) => a[0] - b[0]);
// 押し出された要素(最後の要素)を削除
if (wtBattlers.length > pNumber) {
wtBattlers.pop();
}
}
}
/*
* 変更前との互換性を保つため、WTを除いたリストも作成
*/
battlers = [];
wtBattlers.forEach(function(wtBattler) {
battlers.push(wtBattler[1]);
});
this._actionBattlers = battlers;
// 先頭に現在の行動者を追加
if (mAddActionUser && this.actor()) {
this._actionBattlers.unshift(this.actor());
this._actionBattlers.pop();
}
};
/**
* 【独自】行動者の速度補正を考慮した上で、行動順序を再計算する。(予測用)
*/
BattleManager.reMakeActionOrders = function() {
const subject = this._subject;
if (!subject) {
return;
}
// 予測を行うかどうか?
const usePrediction = this.isUsePrediction();
// 選択中の対象を取得
let targets = null;
if (usePrediction) {
targets = this.allBattleMembers().filter(m => m.isSelected());
}
// 予測用にWT、ステート、能力変化を設定する。
if (usePrediction) {
for (const target of targets) {
target._tmpWt = target.wt;
target._tmpStates = JsonEx.makeDeepCopy(target._states);
target._tmpBuffs = JsonEx.makeDeepCopy(target._buffs);
}
// スキルによる対象のWT変化を反映する。
this.changeTargetsWtState(targets);
}
// 行動者のWTを一時的に保持
const tmpWt = subject.wt;
// 速度補正を元にWTを一時的に書き換える。
subject.makeSpeed();
// 速度補正後のWTを加算する。
subject.setWt(subject.wt + subject.getAddWt());
// 行動予測時に先頭に行動者を表示するかどうか?
if (subject.action(0) && pShowActionUser) {
mAddActionUser = true;
}
// 行動順序再計算
this.makeActionOrders();
mAddActionUser = false;
// WTを元に戻す。
subject.setWt(tmpWt);
// 予測用のWTを戻す。
if (usePrediction) {
for (const target of targets) {
target.wt = target._tmpWt;
target._states = target._tmpStates;
target._buffs = target._tmpBuffs;
// クリア
delete target._tmpWt;
delete target._tmpStates;
delete target._tmpBuffs;
}
}
}
/**
* 【独自】予測を行うかどうか?
*/
BattleManager.isUsePrediction = function() {
// スキルの順序変化を予測しないならfalse
if (!pPredictionSkillOrder) {
return false;
// 入力時でないならfalse
} else if (!this.isInputting()) {
return false;
}
// スキルが取得できるならfalse
const action = this.inputtingAction();
if (!action || !action.item()) {
return false;
// 範囲がランダムならfalse
} else if (action.isForRandom()) {
return false;
// 必中のみの場合、入力中のスキルが必中でなければ対象外
} else if (pPredictionCertain && !action.isCertainHit()) {
return false;
}
// 予測を行う
return true;
}
/**
* 【独自】スキルによる対象のWT変化を反映する。(予測用)
*/
BattleManager.changeTargetsWtState = function(targets) {
// 入力中のスキルを取得
const action = this.inputtingAction();
if (!action) {
return;
}
const skill = action.item();
if (!skill) {
return;
}
// 対象毎にループ
for (const target of targets) {
// 対象が戦闘不能の場合は範囲が有効かを確認。
if (target.isDead() && !action.isForDeadFriend()) {
continue;
}
// 効果前の敏捷性を保持
const beforeAgi = target.agi;
// スキルに紐づくステートを取得
for (const effect of skill.effects) {
if (!effect.dataId) {
continue;
}
// ステート付加
if (effect.code == Game_Action.EFFECT_ADD_STATE) {
// 既にステートにかかっていない場合
if (!target.isStateAffected(effect.dataId)) {
// ステートによるWT変動を反映
target.changeWtState(effect.dataId);
// ※addStateは余計な処理が走るのでやらない。
target._states.push(effect.dataId);
}
// ステート解除
} else if (effect.code == Game_Action.EFFECT_REMOVE_STATE) {
// 蘇生ならば、蘇生時のWTを反映
if (target.isDead() && effect.dataId === target.deathStateId()) {
target.setReviveWt();
}
const index = target._states.indexOf(effect.dataId);
if (index >= 0) {
target._states.splice(index, 1);
}
// バフ付加
} else if (effect.code == Game_Action.EFFECT_ADD_BUFF) {
// バフが最大に達していない。
if (!target.isMaxBuffAffected(effect.dataId)) {
target._buffs[effect.dataId]++;
target._buffs[effect.dataId] = 2;
}
// デバフ付加
} else if (effect.code == Game_Action.EFFECT_ADD_DEBUFF) {
// デバフが最大に達していない。
if (!target.isMaxDebuffAffected(effect.dataId)) {
target._buffs[effect.dataId]--;
}
// バフ解除
} else if (effect.code == Game_Action.EFFECT_REMOVE_BUFF) {
// バフにかかっている。
if (target.isBuffAffected(effect.dataId)) {
target._buffs[effect.dataId] = 0;
}
// デバフ解除
} else if (effect.code == Game_Action.EFFECT_REMOVE_DEBUFF) {
// デバフにかかっている。
if (target.isDebuffAffected(effect.dataId)) {
target._buffs[effect.dataId] = 0;
}
}
}
// 蘇生
// ※戦闘不能ステートの解除がなくとも。蘇生はできるらしいので対応
if (target.isDead() && action.isForDeadFriend() && action.isRecover()) {
const index = target._states.indexOf(target.deathStateId());
if (index >= 0) {
target._states.splice(index, 1);
}
target.setReviveWt();
}
// 敏捷性が変化した場合はWTも変化させる。
if (target.agi != beforeAgi) {
target.setWt(parseInt(target.wt / (target.agi / beforeAgi)));
}
}
}
/**
* 【独自】時間経過処理
*/
BattleManager.timeGoesBy = function() {
const topWt = this._actionBattlers[0].wt;
if (topWt > 0) {
// 先頭行動者のWTが0になるように、全バトラーのWTを減算。
for (const battler of this.allBattleMembers()) {
// 生存者のみに絞る
if (battler.isCtbAlive()) {
battler.setWt(battler.wt - topWt);
}
}
}
}
/**
* 【上書】ターン開始処理
*/
BattleManager.startTurn = function() {
this._phase = 'turn';
// 不要につき削除(余計なモーション変更が入る)
// this.clearActor();
$gameTroop.increaseTurn();
// 不要につき削除
// this.makeActionOrders();
$gameParty.requestMotionRefresh();
this._logWindow.startTurn();
// MZ対応
this._inputting = false;
};
/**
* 【上書】戦闘行動の処理
*/
BattleManager.processTurn = function() {
var subject = this._subject;
var action = subject.currentAction();
if (action) {
action.prepare();
if (action.isValid()) {
this.startAction();
}
subject.removeCurrentAction();
} else {
// BattleManager.endTurnで行うため不要
// subject.onAllActionsEnd();
// this.refreshStatus();
// this._logWindow.displayAutoAffectedStatus(subject);
// this._logWindow.displayCurrentState(subject);
// this._logWindow.displayRegeneration(subject);
// this._subject = this.getNextSubject();
// 状態を未確定に
// ※スキルが未設定の場合、BattleManager.endActionが
// 呼ばれないパターンもあるので強制的に調整する。
subject.setActionState('undecided');
// CTBなので即ターン終了
this.endTurn();
}
};
/**
* ●行動開始
*/
const _BattleManager_startAction = BattleManager.startAction;
BattleManager.startAction = function() {
// 元の処理
_BattleManager_startAction.apply(this);
// 実行した行動の速度を計算する。
this._subject.makeSpeed();
};
/**
* 【上書】ターン終了処理
*/
BattleManager.endTurn = function() {
this._phase = 'turnEnd';
this._preemptive = false;
this._surprise = false;
const subject = this._subject;
// 行動者の現在WTに加算WTを加算する。
subject.setWt(subject.wt + subject.getAddWt());
// AddWt == 0 の場合は連続行動なのでターン経過なしとする。
if (subject.getAddWt() > 0) {
// 個別のターン終了処理
subject.onTurnEnd();
// デフォルトと異なりonAllActionsEndをonTurnEndの下に配置する。
// 自動解除が『行動終了時』となっているステートを1ターン目から処理するため。
subject.onAllActionsEnd();
this.refreshStatus();
this._logWindow.displayAutoAffectedStatus(subject);
this._logWindow.displayRegeneration(subject);
// 他のバトラーについても、自動解除が『ターン終了時』となっているステートを処理
this.allBattleMembers().forEach(function(battler) {
// 重複しないように行動者は除く
if (battler != subject) {
battler.onEveryTurnEnd();
this.refreshStatus();
this._logWindow.displayAutoAffectedStatus(battler);
this._logWindow.displayRegeneration(battler);
}
}, this);
}
if (this.isForcedTurn()) {
this._turnForced = false;
}
// BattleManager.startInputへ戻る。
};
/**
* 【上書】ターン更新
* ※MZ1.4.0の更新により処理が変更されたため、
*  endAllBattlersTurnを呼ばないように上書き。
*/
BattleManager.updateTurnEnd = function() {
this.startInput();
};
/**
* 【上書】次の行動主体の取得
* 行動順序リストの次に来るバトラーを取得する。
* 現在パーティにいないアクターを取得した場合index が nil, バトルイベ
* ントでの離脱直後などに発生)は、それをスキップする。
*/
BattleManager.getNextSubject = function() {
// MZ対応
this._currentActor = null;
for (;;) {
var battler = this._actionBattlers[0];
if (!battler) {
return null;
}
if (battler.isBattleMember() && battler.isCtbAlive()) {
// MZ対応
if (battler.isActor()) {
this._currentActor = battler;
}
return battler;
}
}
};
/**
* 【上書】逃走実行時
*/
BattleManager.processEscape = function() {
$gameParty.performEscape();
SoundManager.playEscape();
var success = this._preemptive ? true : (Math.random() < this._escapeRatio);
if (success) {
this.displayEscapeSuccessMessage();
this._escaped = true;
this.processAbort();
} else {
this.displayEscapeFailureMessage();
this._escapeRatio += 0.1;
$gameParty.clearActions();
// 逃走失敗のペナルティを設定
this.setEscapePenalty();
// 即ターン終了
this.endTurn();
// this.startTurn();
// モーション停止
const subject = this._subject;
subject.setActionState('undecided');
}
return success;
};
/**
* 【独自】逃走失敗時のペナルティ
*/
BattleManager.setEscapePenalty = function() {
// 逃走失敗のペナルティを設定
$gameParty.aliveMembers().forEach(function(battler) {
// 失敗した当人以外のWTを加算する。
if (battler != BattleManager._subject) {
// 基本WT * ペナルティ% / 100
battler.setWt(battler.wt + parseInt(battler.baseWt * eval(pEscapePenalty) / 100));
}
});
};
//-----------------------------------------------------------------------------
// Game_BattlerBase
//-----------------------------------------------------------------------------
/**
* ●パラメータの追加
*/
Object.defineProperties(Game_BattlerBase.prototype, {
// WT待ち時間
wt: { get: function() { return this._wt; }, set: function(val) { this._wt = val; }, configurable: true },
// 基本WT基本待ち時間
baseWt: { get: function() { return this._baseWt; }, configurable: true },
});
/**
* 【独自】自動解除が『ターン終了時』となっているステートの効果ターンを経過させる。
*/
Game_BattlerBase.prototype.updateStateEveryTurns = function() {
this._states.forEach(function(stateId) {
// 自動解除が『ターン終了時』のステートを対象とする。
if ($dataStates[stateId].autoRemovalTiming == 2 && this._stateTurns[stateId] > 0) {
this._stateTurns[stateId]--;
}
}, this);
};
/**
* ●ステート有効ターン初期設定
*/
const _Game_BattlerBase_prototype_resetStateCounts = Game_BattlerBase.prototype.resetStateCounts;
Game_BattlerBase.prototype.resetStateCounts = function(stateId) {
// 元処理呼び出し
_Game_BattlerBase_prototype_resetStateCounts.apply(this, arguments);
// 対象者が行動者自身の場合は有効ターン+1
// そうしておかないと、行動終了と同時にターン経過してしまうため。
if (pSelfStatePlusTurn && this == BattleManager._subject) {
// 自動解除が『行動終了時』のステートを対象とする。
if ($dataStates[stateId].autoRemovalTiming == 1) {
this._stateTurns[stateId]++;
}
}
};
/**
* ●能力変化有効ターンの設定
*/
const _Game_BattlerBase_overwriteBuffTurns = Game_BattlerBase.prototype.overwriteBuffTurns;
Game_BattlerBase.prototype.overwriteBuffTurns = function(paramId, turns) {
_Game_BattlerBase_overwriteBuffTurns.apply(this, arguments);
// 対象者が行動者自身の場合は有効ターン+1
// そうしておかないと、行動終了と同時にターン経過してしまうため。
if (pSelfBufPlusTurn && this == BattleManager._subject) {
// 同じパラメータの多重がけで、
// 二重にターンが加算されないよう設定ターンの場合のみに限定
if (this._buffTurns[paramId] == turns) {
this._buffTurns[paramId]++;
}
}
};
/**
* ●ステート追加(WT変動の実装)
*/
const _Game_BattlerBase_prototype_addNewState = Game_BattlerBase.prototype.addNewState;
Game_BattlerBase.prototype.addNewState = function(stateId) {
// ステートによるWT変動
this.changeWtState(stateId);
// 元の処理
_Game_BattlerBase_prototype_addNewState.apply(this, arguments);
};
/**
* 【独自】ステートによるWT変動
*/
Game_BattlerBase.prototype.changeWtState = function(stateId) {
// eval参照用
const a = BattleManager._subject;
const b = this;
/*
* WT設定値を元にWTを変化
*/
// <SetWt:number>があれば、その値(%)を設定
if ($dataStates[stateId].meta.SetWt) {
const wtRate = eval($dataStates[stateId].meta.SetWt) / 100;
this.setWt(this.baseWt * wtRate);
// <AddWt:number>があれば、その値(%)を加算
} else if ($dataStates[stateId].meta.AddWt) {
const addWtRate = eval($dataStates[stateId].meta.AddWt) / 100;
this.setWt(this.wt + this.baseWt * addWtRate);
}
};
/**
* 【独自】WTの設定
*/
Game_BattlerBase.prototype.setWt = function(wt) {
this._wt = wt;
};
/**
* 【独自】CTBの順序表示および時間更新を行うか?
*/
Game_BattlerBase.prototype.isCtbAlive = function() {
if (this.isAlive()) {
return true;
}
// 戦闘不能時でも順序表示する場合
for (const stateId of this._states) {
const state = $dataStates[stateId]
if (state.meta.DeadCTBTurn) {
return true;
}
}
return false;
};
/**
* ●蘇生時
*/
const _Game_BattlerBase_revive = Game_BattlerBase.prototype.revive;
Game_BattlerBase.prototype.revive = function() {
_Game_BattlerBase_revive.apply(this, arguments);
// 蘇生時のWT設定
this.setReviveWt();
};
/**
* 【独自】蘇生時のWT設定
*/
Game_BattlerBase.prototype.setReviveWt = function() {
// 戦闘時以外は無効
if (!$gameParty.inBattle()) {
return;
}
const baseWt = this.baseWt;
// スキルに蘇生WTの指定があるなら優先
const action = BattleManager.inputtingAction() || BattleManager._action;
if (action) {
const item = action.item();
if (item && item.meta.ReviveWt) {
// WTを再設定
this.setWt(baseWt * eval(item.meta.ReviveWt) / 100);
return;
}
}
// 共通の設定
if (pReviveWT != null) {
// WTを再設定
this.setWt(eval(pReviveWT));
}
}
//-----------------------------------------------------------------------------
// Game_Battler
//-----------------------------------------------------------------------------
/**
* ●戦闘開始時
* ※バトラー変数の初期化
*/
const _Game_Battler_onBattleStart = Game_Battler.prototype.onBattleStart;
Game_Battler.prototype.onBattleStart = function() {
// 元処理実行
_Game_Battler_onBattleStart.apply(this, arguments);
// CTBターンの初期化
this.initCtbTurn();
};
/**
* 【独自】CTBターンの初期化
*/
Game_Battler.prototype.initCtbTurn = function() {
// 初期ターンの設定
this._turnCount = pStartTurn - 1;
// 基本WTを設定する。
this.makeBaseWt();
// WTの初期値として基本WTを設定する。
let wt = this._baseWt;
let startRandomWt = 0;
// アクター
if (this.isActor()) {
startRandomWt = eval(pActorStartRandomWt);
// 先制攻撃の場合はWT減算
if (BattleManager._preemptive) {
// - WT * 先制攻撃特典% / 100
wt -= parseInt(wt * eval(pPreemptiveAdvantage) / 100);
}
// 敵キャラ
} else {
startRandomWt = eval(pEnemyStartRandomWt);
// 不意打ちの場合はWT半減
if (BattleManager._surprise) {
// - WT * 奇襲特典% / 100
wt -= parseInt(wt * eval(pSurpriseAdvantage) / 100);
}
}
// 初期WT<StartWt>の設定がある場合
// WTの合計を求める。
let startWtSum = 0;
const traitObjects = getTraitObjects(this);
for (const object of traitObjects) {
const startWtMeta = object.meta.StartWt;
if (startWtMeta != null) {
startWtSum += eval(startWtMeta) - 100;
}
}
// 0以外なら設定があったと判断
if (startWtSum != 0) {
wt = Math.max(0, wt * (100 + startWtSum) / 100);
this.setWt(wt);
return;
}
// 初期WTを分散値に従って設定する。
// 例分散値が20の場合
// 100 - (20 / 2) + [020未満の乱数] → 90110未満の乱数を作成
const r = 100 - (startRandomWt / 2) + Math.random() * startRandomWt;
wt = parseInt(wt * r / 100);
this.setWt(wt);
};
/**
* 【上書】アクション終了時
*/
Game_Battler.prototype.performActionEnd = function() {
// 元のターン制ではdoneだが、違和感あるので変える。
// this.setActionState('done');
this.setActionState('undecided');
};
/**
* 【上書】行動終了時
*/
Game_Battler.prototype.onAllActionsEnd = function() {
// onTurnEndと処理がかぶるので注釈化
// 消しておかないと毒などの数値表示が消える。
// this.clearResult();
this.removeStatesAuto(1);
this.removeBuffsAuto();
};
/**
* 【独自】自動解除が『ターン終了時』となっているステートを処理するためのターン終了処理
*/
Game_Battler.prototype.onEveryTurnEnd = function() {
this.clearResult();
this.updateStateEveryTurns();
this.removeStatesAuto(2);
};
/**
* 【MZのみ関数上書】
* ●個別ターン数の取得
*/
Game_Battler.prototype.turnCount = function() {
return this._turnCount;
};
/**
* 【独自】基本WTを計算する。
*/
Game_Battler.prototype.makeBaseWt = function() {
// 敏捷性が以下ならNumber型の最大値たぶん9007199254740991を設定
if (this.agi <= 0) {
this._baseWt = Number.MAX_SAFE_INTEGER;
return;
}
// 100000 / 敏捷性
this._baseWt = parseInt(100000 / this.agi);
};
/**
* 【独自】速度補正つき加算WTを取得する。
*/
Game_Battler.prototype.getAddWt = function() {
let addWt = 100000;
// speedが有効ならspeed値を使用する。
if (this._speed > 0) {
addWt = parseInt(100000 / this._speed);
// なければagiを参照する。
} else {
// 敏捷性が以下ならNumber型の最大値たぶん9007199254740991を設定
if (this.agi <= 0) {
return Number.MAX_SAFE_INTEGER;
}
addWt = parseInt(100000 / this.agi);
}
return addWt;
};
//-----------------------------------------------------------------------------
// Game_Party
//-----------------------------------------------------------------------------
if (pNotPartyMotionRefresh) {
/**
* 【上書】パーティ全員のモーションリフレッシュ
*/
Game_Party.prototype.requestMotionRefresh = function() {
for (const actor of this.members()) {
const sprite = getSprite(actor);
if (!sprite) {
return;
}
const motion = sprite._motion;
// モーションの指定がない。
// またはループモーションが設定されている場合のみリフレッシュ
// ※ダメージや回避などのモーションが途中で終わってしまうため。
if (!motion || motion.loop) {
actor.requestMotionRefresh();
}
}
};
}
/**
* ●バトラーからスプライトを取得する。
*/
function getSprite(battler) {
const spriteset = getSpriteset();
if (!spriteset) {
return undefined;
}
const sprites = spriteset.battlerSprites();
return sprites.find(function(sprite) {
return sprite._battler == battler;
});
}
/**
* ●現在の画面のSpritesetを取得する。
*/
function getSpriteset() {
return SceneManager._scene._spriteset;
}
//-----------------------------------------------------------------------------
// Sprite_Actor
//-----------------------------------------------------------------------------
/**
* ●アクターの位置調整
*/
const _Sprite_Actor_updateTargetPosition = Sprite_Actor.prototype.updateTargetPosition;
Sprite_Actor.prototype.updateTargetPosition = function() {
if (this._actor.isInputting()) {
// 通常は前進処理が呼び出されるが、不要なので何もしない
// this.stepForward();
return;
}
_Sprite_Actor_updateTargetPosition.apply(this, arguments);
};
//-----------------------------------------------------------------------------
// Game_Action
//-----------------------------------------------------------------------------
/**
* 【上書】行動速度の計算
* 速度補正を%化
*/
Game_Action.prototype.speed = function() {
const agi = this.subject().agi;
// バラつきをなくす
let speed = agi;
// var speed = agi + Math.randomInt(Math.floor(5 + agi / 4));
if (this.item()) {
// 速度補正MAX(2000)の場合は速度無限に(時間経過がなくなる)
if (this.item().speed >= 2000) {
return Infinity;
}
// 速度補正を%化
speed += parseInt(speed * this.item().speed / 100);
// speed += this.item().speed;
}
if (this.isAttack()) {
// 速度補正MAX(2000)の場合は速度無限に(時間経過がなくなる)
if (this.subject().attackSpeed() >= 2000) {
return Infinity;
}
// 速度補正を%化
speed += parseInt(speed * this.subject().attackSpeed() / 100);
// speed += this.subject().attackSpeed();
}
// 速度が0だと無効扱いになるので最低でも1とする。
if (speed < 1) {
speed = 1;
}
return speed;
};
/**
* ●各種効果
* 効果前後で敏捷性の変化を監視し、変化があればWTを調整する。
*/
const _Game_Action_prototype_applyItemEffect = Game_Action.prototype.applyItemEffect;
Game_Action.prototype.applyItemEffect = function(target, effect) {
// 効果前の敏捷性を保持
const beforeAgi = target.agi;
// 元の処理
_Game_Action_prototype_applyItemEffect.apply(this, arguments);
// 敏捷性が0以下なら処理しない
if (beforeAgi <= 0) {
return;
}
if (target.agi != beforeAgi) {
// 敏捷性が変化したので、WTも変化させる。
target.setWt(parseInt(target.wt / (target.agi / beforeAgi)));
// スピードも更新
// ※これをやらないと自身へステートを付加した際に反映されない。
target._speed = this.speed();
}
}
//-----------------------------------------------------------------------------
// Game_Enemy
//-----------------------------------------------------------------------------
/**
* 【上書】敵の行動条件合致判定[ターン数]
*/
Game_Enemy.prototype.meetsTurnCondition = function(param1, param2) {
// グループのターンではなく、行動者の個別ターンを参照する。
var n = this.turnCount();
// var n = $gameTroop.turnCount();
if (param2 === 0) {
return n === param1;
} else {
return n > 0 && n >= param1 && n % param2 === param1 % param2;
}
};
//-----------------------------------------------------------------------------
// Window_BattleLog
//-----------------------------------------------------------------------------
/**
* 【上書】ターン開始
*/
Window_BattleLog.prototype.startTurn = function() {
// ウェイトをかけているだけなので削除
// CTBでは全行動がターン開始なのでテンポ悪化を防ぐため。
// this.push('wait');
};
//-----------------------------------------------------------------------------
// Window_BattleActor
//-----------------------------------------------------------------------------
/**
* ●アクターの選択変更時
*/
const _Window_BattleActor_select = Window_BattleActor.prototype.select;
Window_BattleActor.prototype.select = function(index) {
_Window_BattleActor_select.apply(this, arguments);
// 非表示時は処理しない。
// ※select処理は戦闘終了時に毎フレーム実行されるので対処
if (!this.visible) {
return;
}
// 対象変更時、行動予測のために行動順序再計算
BattleManager.reMakeActionOrders();
};
//-----------------------------------------------------------------------------
// Window_BattleEnemy
//-----------------------------------------------------------------------------
/**
* ●敵の選択変更時
*/
const _Window_BattleEnemy_select = Window_BattleEnemy.prototype.select;
Window_BattleEnemy.prototype.select = function(index) {
_Window_BattleEnemy_select.apply(this, arguments);
// 非表示時は処理しない。
// ※select処理は戦闘終了時に毎フレーム実行されるので対処
if (!this.visible) {
return;
}
// 対象変更時、行動予測のために行動順序再計算
BattleManager.reMakeActionOrders();
};
//-----------------------------------------------------------------------------
// Window_ActorCommand
//-----------------------------------------------------------------------------
if (pCalcGuardCommand) {
/*
* Window_ActorCommand.prototype.refreshCursorが未定義の場合は事前に定義
* ※これをしておかないと以後のWindow_Selectable側への追記が反映されない。
*/
if (Window_ActorCommand.prototype.refreshCursor == Window_Selectable.prototype.refreshCursor) {
Window_ActorCommand.prototype.refreshCursor = function() {
Window_Selectable.prototype.refreshCursor.apply(this, arguments);
}
}
/**
* ●カーソルのリフレッシュ
*/
const _Window_ActorCommand_refreshCursor = Window_ActorCommand.prototype.refreshCursor;
Window_ActorCommand.prototype.refreshCursor = function() {
_Window_ActorCommand_refreshCursor.apply(this, arguments);
const index = this._index;
// 選択項目が存在しない場合は終了
if (!this._list || !this._list[index]) {
return;
// 入力中でない場合は終了
// ※行動確定後に再度更新が走らないようにするための措置
} else if (!BattleManager.isInputting()) {
return;
}
const actor = this.actor();
// 現在の行動情報を保持
const keepActions = actor._actions;
actor.clearActions();
// 防御
if (this.commandSymbol(index) == "guard") {
const action = new Game_Action(actor);
action.setGuard();
// アクターに防御をセット
actor.setAction(0, action);
}
// 行動予測のために行動順序再計算
BattleManager.reMakeActionOrders();
// 行動情報を元に戻す。
actor._actions = keepActions;
// 速度は0に初期化しておく。
// ※逃げる選択時に使用されるので、これがないと無限行動になる。
actor._speed = 0;
};
}
//-----------------------------------------------------------------------------
// MZ対応
//-----------------------------------------------------------------------------
if (Utils.RPGMAKER_NAME == "MZ") {
/**
* エラーにしないため空の関数を定義
*/
BattleManager.refreshStatus = function() {
};
/**
* ●MVの関数をそのまま定義
*/
BattleManager.isForcedTurn = function () {
return this._turnForced;
};
/**
* 【上書】アクション終了時
*/
BattleManager.endAction = function() {
this._logWindow.endAction(this._subject);
this._phase = "turn";
// 不要な終了処理を注釈化
// if (this._subject.numActions() === 0) {
// this.endBattlerActions(this._subject);
// this._subject = null;
// }
};
//-----------------------------------------------------------------------------
// MV対応
//-----------------------------------------------------------------------------
} else {
/**
* ●仲間の追加
*/
const _Game_Party_addActor = Game_Party.prototype.addActor;
Game_Party.prototype.addActor = function(actorId) {
// 仲間が追加可能な場合
if (!this._actors.contains(actorId)) {
_Game_Party_addActor.apply(this, arguments);
// 戦闘中の場合
if (this.inBattle()) {
const actor = $gameActors.actor(actorId);
if (this.battleMembers().includes(actor)) {
// 戦闘開始処理を実行
actor.onBattleStart();
}
}
return;
}
// 追加できない場合はそのまま
_Game_Party_addActor.apply(this, arguments);
};
}
// ----------------------------------------------------------------------------
// 共通関数
// ----------------------------------------------------------------------------
/**
* ●特徴を保持するオブジェクトを取得
*/
function getTraitObjects(battler) {
// メモ欄を参照するオブジェクトを全取得
let traitObjects = battler.traitObjects();
// パッシブスキルが有効な場合は連結
// ※通常はアクターのみ
if (battler.skills) {
traitObjects = traitObjects.concat(battler.skills());
}
return traitObjects;
}
})();