You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

1438 lines
48 KiB
JavaScript

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

/*:
@plugindesc 战斗变更为ATB。
@author うなぎおおとろ(twitter https://twitter.com/unagiootoro8388)
@param waitCommandSelection
@type boolean
@default false
@desc
trueを指定すると、コマンド選択中はゲージの進行を停止します。
@param waitSelectSkillOrItem
@text 等待选择技能项目
@type boolean
@default true
@desc
trueを指定すると、スキルまたはアイテム選択中はゲージの進行を停止します。
@param waitAnimation
@text 等待动画
@type boolean
@default true
@desc
trueを指定すると、アニメーション再生中はゲージの進行を停止します。
@param drawEnemyUnderGauge
@text drawEnemyUnderGauge
@type boolean
@default true
@desc
trueを指定すると、エネミーにもゲージを表示します。
@param baseGaugeSpeed
@type number
@default 5
@desc
ゲージが溜まる速さを指定します。値が大きくなるほど早くなります。
@param maxActionCount
@type number
@default 3
@desc
1ターンで行動可能な行動回数の最大値を指定します。
@param baseSkillWaitGaugeSpeed
@type number
@default 3
@desc
スキル発動待機時のゲージが溜まる速さを指定します。値が大きくなるほど早くなります。
@param fastForward
@type number
@default 2
@desc
Shiftキーが押されている間、ゲージ進行を早送りするスピードを設定します。
@param enableChangeSelectActor
@text 启用ChangeSelectactor
@type boolean
@default false
@desc
trueを設定すると、pageupボタンで選択中のアクターを切り替えられるようになります。
@param enableYEP_BattleEngineCore
@text 启用YEP_BattleEngineCore
@type boolean
@default false
@desc
YEP_BattleEngineCoreとの競合を解決します。
@help
【备注栏中可设置的项目】
在技能的笔记栏里
<SkillWait>
在技能发动之前让角色待机一下
在状态的备注栏中
<IntervalGainHp gainValue=増加値 duration=時間間隔> 血量间隔回复
这样在赋予状态的期间对于duration的每个经过时间只有在gainValue中指定的值HP增加。gainValue中所述修改相应参数的值。
【ライセンス】
此插件在MIT许可证条件下可用。
*/
const ATBConfig = {};
const ATBAlias = {};
{
"use strict";
const param = PluginManager.parameters("ATB");
ATBConfig.waitCommandSelection = (param["waitCommandSelection"] === "true" ? true : false);
ATBConfig.waitSelectSkillOrItem = (param["waitSelectSkillOrItem"] === "true" ? true : false);
ATBConfig.waitAnimation = (param["waitAnimation"] === "true" ? true : false);
ATBConfig.drawEnemyUnderGauge = (param["drawEnemyUnderGauge"] === "true" ? true : false);
ATBConfig.baseGaugeSpeed = parseInt(param["baseGaugeSpeed"]);
ATBConfig.maxActionCount = parseInt(param["maxActionCount"]);
ATBConfig.baseSkillWaitGaugeSpeed = parseInt(param["baseSkillWaitGaugeSpeed"]);
ATBConfig.fastForward = parseInt(param["fastForward"]);
ATBConfig.enableChangeSelectActor = (param["enableChangeSelectActor"] === "true" ? true : false);
ATBConfig.enableYEP_BattleEngineCore = (param["enableYEP_BattleEngineCore"] === "true" ? true : false);
ATBConfig.drawUnderGauge = false;
class ATBTimer {
constructor(maxValue) {
this._maxValue = maxValue;
this._speed = 1;
this._value = 0;
}
set value(_value) {
this._value = _value;
if (this._value > this._maxValue) this.toFull();
if (this._value < 0) this._value = 0;
}
get value() {
return this._value;
}
isTimeout() {
return this._value === this._maxValue;
}
changeSpeed(speed) {
this._speed = speed;
}
increment(fastForwardSpeed = 1) {
this._value += this._speed * ATBConfig.baseGaugeSpeed * fastForwardSpeed;
if (this._value > this._maxValue) this._value = this._maxValue;
}
clear() {
this._value = 0;
}
}
class ATBGauge {
static get PURPOSE_TIME() {
return "PURPOSE_TIME";
}
static get PURPOSE_SKILL_WAIT() {
return "PURPOSE_SKILL_WAIT";
}
constructor(battler) {
this._battler = battler;
this._timer = new ATBTimer(ATBManager.GAUGE_MAX);
this._purpose = ATBGauge.PURPOSE_TIME;
this._stop = false;
this._clearWait = false;
this._quick = false;
battler.setGauge(this);
}
set purpose(_purpose) {
this._purpose = _purpose;
}
get purpose() {
return this._purpose;
}
set value(_value) {
if (_value < ATBManager.GAUGE_MAX) this._clearWait = false;
this._timer.value = _value;
}
get value() {
return this._timer.value;
}
battler() {
return this._battler;
}
changeSpeed(speed, maxActionCount) {
if (maxActionCount && speed > ATBConfig.maxActionCount) speed = ATBConfig.maxActionCount;
this._timer.changeSpeed(speed);
}
toFull() {
this._timer.value = ATBManager.GAUGE_MAX;
}
isFull() {
if (this._stop) return false;
if (this._clearWait) return false;
return this._timer.isTimeout();
}
increment(fastForwardSpeed = 1) {
if (this._stop) return;
if (this._clearWait) return;
if (!this.isUsable()) return;
if (this._quick) {
this.toFull();
return;
}
this._timer.increment(fastForwardSpeed);
}
isUsable() {
if (this._battler.isDead()) return false;
if (!this._battler.canMove()) return false;
return true;
}
toClearWait() {
this._clearWait = true;
}
clear() {
this._timer.clear();
this._clearWait = false;
}
stop() {
this._stop = true;
}
resume() {
this._stop = false;
}
isStop() {
return this._stop === true;
}
isActionEnd() {
return !this._clearWait;
}
startQuick() {
this._quick = true;
}
endQuick() {
this._quick = false;
}
}
class ActorGauge extends ATBGauge {
constructor(battler) {
super(battler);
this._commandSelecting = false;
this._commandSelected = false;
if (ATBConfig.drawUnderGauge) BattleManager.spriteset().createGaugeLine(battler);
}
setCommandSelecting(commandSelecting) {
this._commandSelecting = commandSelecting;
}
isCommandSelecting() {
return this._commandSelecting;
}
setCommandSelected(commandSelected) {
this._commandSelected = commandSelected;
}
isCommandSelected() {
return this._commandSelected;
}
commandSelectCancel() {
this._commandSelecting = false;
this._commandSelected = false;
}
}
class EnemyGauge extends ATBGauge {
constructor(battler) {
super(battler);
if (ATBConfig.drawEnemyUnderGauge) BattleManager.spriteset().createGaugeLine(battler);
}
}
class GainHpTimer extends ATBTimer {
constructor(maxValue, gainValue, battler, stateId) {
super(maxValue);
this._gainValue = gainValue;
this._battler = battler;
this._stateId = stateId;
}
battler() {
return this._battler;
}
stateId() {
return this._stateId;
}
increment(fastForwardSpeed = 1) {
super.increment(fastForwardSpeed);
if (this.isTimeout()) {
this._battler.gainHp(this._gainValue);
this.clear();
}
}
}
class ATBManager {
static get GAUGE_MAX() {
return 1000;
}
constructor() {
this._holdAllBattleMembers = [];
this._turnDurationTimer = new ATBTimer(ATBManager.GAUGE_MAX);
this._timers = [this._turnDurationTimer];
this._canActionMembers = [];
this._gauges = [];
this._wait = {};
}
startBattle() {
this.createGauges();
}
startTurn() {
this.createGauges();
this.makeSpeed();
}
updateTurn() {
for (let gauge of this._gauges) {
if (gauge.battler().isDead()) gauge.value = 0;
if (gauge.isFull()) {
if (gauge.purpose === ATBGauge.PURPOSE_TIME) gauge.battler().makeActions();
this._canActionMembers.push(gauge.battler());
gauge.toClearWait();
}
}
}
updateGauge() {
if (!this.isActive()) return;
if (Graphics.frameCount % 2 === 0) return;
if ($gameTroop.isEventRunning()) return;
for (let timer of this._timers) {
timer.increment(this.fastForwardSpeed());
}
for (let gauge of this._gauges) {
gauge.increment(this.fastForwardSpeed());
}
BattleManager.refreshStatus();
}
fastForwardSpeed() {
if (Input.isPressed("shift")) return ATBConfig.fastForward;
return 1;
}
endTurn() {
this._turnDurationTimer.clear();
}
toActive(factor) {
this._wait[factor] = false;
}
toWait(factor) {
this._wait[factor] = true;
}
isActive() {
for (let factor in this._wait) {
if (this._wait[factor]) return false;
}
return true;
}
createGauges() {
const members = BattleManager.allBattleMembers();
for (let battler of members) {
if (this._holdAllBattleMembers.indexOf(battler) === -1) {
this._holdAllBattleMembers.push(battler);
if (battler instanceof Game_Actor) {
this._gauges.push(new ActorGauge(battler));
} else {
this._gauges.push(new EnemyGauge(battler));
}
}
}
for (let battler of this._holdAllBattleMembers) {
if (members.indexOf(battler) === -1) {
let i = this._holdAllBattleMembers.indexOf(battler);
this._holdAllBattleMembers.splice(i, 1);
i = this._gauges.indexOf(battler.gauge())
this._gauges.splice(i, 1);
}
}
}
endAction(battler) {
battler.gauge().clear();
let i = this._canActionMembers.indexOf(battler);
if (i >= 0) this._canActionMembers.splice(i, 1);
if (battler.gauge().purpose === ATBGauge.PURPOSE_SKILL_WAIT) this.endSkillWait(battler);
}
cancelAction(battler) {
this.endAction(battler);
battler.updateStateTurns(1);
battler.removeStatesAuto(1);
}
resetGaugeSpeed(battler, speed = battler.speed(), maxActionCount = ATBConfig.maxActionCount) {
let speeds = [];
for (let gauge of this._gauges) {
speeds.push(gauge.battler().speed());
}
const minSpeed = Math.min(...speeds);
const gaugeSpeed = speed / minSpeed;
battler.gauge().changeSpeed(gaugeSpeed, maxActionCount);
}
makeSpeed() {
let speeds = [];
for (let gauge of this._gauges) {
gauge.battler().makeSpeed();
speeds.push(gauge.battler().speed());
}
const minSpeed = Math.min(...speeds);
let i = 0;
for (let gauge of this._gauges) {
if (gauge.purpose === ATBGauge.PURPOSE_TIME) {
let gaugeSpeed = speeds[i] / minSpeed;
gauge.changeSpeed(gaugeSpeed, ATBConfig.maxActionCount);
}
i++;
}
}
isEndTurn() {
return this._turnDurationTimer.isTimeout();
}
startSkillWait(battler) {
battler.gauge().clear();
const action = battler.currentAction();
let skillWaitSpeed = (battler.speed() + action.item().speed);
if (battler.currentAction().isAttack()) skillWaitSpeed += battler.attackSpeed();
this.resetGaugeSpeed(battler, skillWaitSpeed * ATBConfig.baseSkillWaitGaugeSpeed, null);
battler.gauge().purpose = ATBGauge.PURPOSE_SKILL_WAIT;
}
endSkillWait(battler) {
battler.gauge().clear();
this.resetGaugeSpeed(battler);
battler.gauge().purpose = ATBGauge.PURPOSE_TIME;
}
getNextSubject() {
for (let i = 0; i < this._canActionMembers.length; i++) {
let subject = this._canActionMembers[i];
if (!subject.gauge().isStop()) {
this._canActionMembers.splice(i, 1);
return subject;
}
}
return null;
}
getNextHighPrioritySubject() {
for (let i = 0; i < this._canActionMembers.length; i++) {
let subject = this._canActionMembers[i];
if (subject instanceof Game_Actor && subject.gauge().isCommandSelected()
|| subject instanceof Game_Enemy
|| !subject.canInput()) {
this._canActionMembers.splice(i, 1);
return subject;
}
}
return null;
}
addNextSubject(subject) {
this._canActionMembers.unshift(subject);
}
changeNextActor(currentActor, reverse = false) {
const cycleFild = (array, start, lambda) => {
for (let i = start; i < array.length; i++) {
if (lambda(array[i])) return array[i];
}
for (let i = 0; i < start - 1; i++) {
if (lambda(array[i])) return array[i];
}
return null;
}
const currentActorIdx = this._canActionMembers.indexOf(currentActor);
if (currentActorIdx === -1) return null;
let nextActors = this._canActionMembers.filter(member => member instanceof Game_Actor);
if (reverse) {
nextActors = nextActors.sort((a, b) => $gameParty.members().indexOf(b) - $gameParty.members().indexOf(a));
} else {
nextActors = nextActors.sort((a, b) => $gameParty.members().indexOf(a) - $gameParty.members().indexOf(b));
}
const nextActor = cycleFild(nextActors, nextActors.indexOf(currentActor) + 1, (actor) => {
if (actor === currentActor) return false;
if (!actor.gauge().isCommandSelected()
&& actor.canInput()
&& actor.gauge().purpose === ATBGauge.PURPOSE_TIME) {
return true;
}
return false;
});
if (!nextActor) return null;
const nextActorIdx = this._canActionMembers.indexOf(nextActor);
this._canActionMembers[currentActorIdx] = nextActor;
this._canActionMembers.splice(nextActorIdx, 1);
this._canActionMembers.push(currentActor);
return nextActor;
}
escapeFailed() {
this._turnDurationTimer.clear();
this._canActionMembers = [];
for (let actor of $gameParty.members()) {
this.cancelAction(actor);
}
for (let enemy of $gameTroop.members()) {
enemy.gauge().toFull();
}
}
surprise() {
for (let gauge of this._gauges) {
if (!(gauge.battler() instanceof Game_Enemy)) continue;
gauge.toFull();
}
}
preemptive() {
for (let gauge of this._gauges) {
if (!(gauge.battler() instanceof Game_Actor)) continue;
gauge.toFull();
}
}
addStateApply(battler, stateId) {
const state = $dataStates[stateId];
// ステートに行動制約がある場合
if (state.restriction > 0) {
this.endAction(battler);
if (battler instanceof Game_Actor) battler.gauge().commandSelectCancel();
}
this.applyReduceGaugeState(battler, state);
this.applyIntervalGainHp(battler, state);
this.applyCancelActionState(battler, state);
this.startQuickState(battler, state);
}
eraseStateApply(battler, stateId) {
const state = $dataStates[stateId];
// ステートに行動制約がある場合
if (state.restriction > 0) {
this.endAction(battler);
if (battler instanceof Game_Actor) battler.gauge().commandSelectCancel();
}
this.endIntervalGainHp(battler, state);
this.endQuickState(battler, state);
}
applyReduceGaugeState(battler, state) {
let matchData;
if (state._reduceGauge === undefined) {
if (matchData = state.note.match(/<\s*ReduceGauge\s+value=(\d+)\s*>/)) {
state._reduceGauge = parseInt(matchData[1]);
} else {
state._reduceGauge = null;
}
}
if (state._reduceGauge) {
battler.gauge().value -= state._reduceGauge;
battler.eraseState(state.id);
}
}
applyIntervalGainHp(battler, state) {
let matchData;
if (state._intervalGainHp === undefined) {
if (matchData = state.note.match(/<\s*IntervalGainHp\s+gainValue=(\-?\d+)\s+duration=(\d+)\s*>/)) {
state._intervalGainHp = [parseInt(matchData[1]), parseInt(matchData[2])];
} else {
state._intervalGainHp = null;
state._intervalGainHp
}
}
if (state._intervalGainHp) {
this._timers.push(new GainHpTimer(state._intervalGainHp[1], state._intervalGainHp[0], battler, state.id));
}
}
endIntervalGainHp(battler, state) {
if (!state._intervalGainHp) return;
let i = 0;
for (let timer of this._timers) {
if (timer instanceof GainHpTimer && timer.battler() === battler && timer.stateId() === state.id) break;
i++;
}
this._timers.splice(i, 1);
}
applyCancelActionState(battler, state) {
if (state._cancelAction === undefined) {
if (state.note.match(/<\s*CancelAction\s*>/)) {
state._cancelAction = true;
} else {
state._cancelAction = false;
}
}
if (state._cancelAction) {
this.cancelAction(battler);
battler.eraseState(state.id);
}
}
startQuickState(targetBattler, state) {
if (state._quick === undefined) {
if (state.note.match(/<\s*Quick\s*>/)) {
state._quick = true;
} else {
state._quick = false;
}
}
if (!state._quick) return;
for (let battler of BattleManager.allBattleMembers()) {
if (battler === targetBattler) {
battler.gauge().startQuick();
} else {
battler.gauge().stop();
}
}
}
endQuickState(targetBattler, state) {
if (!state._quick) return;
for (let battler of BattleManager.allBattleMembers()) {
if (battler === targetBattler) {
battler.gauge().endQuick();
} else {
battler.gauge().resume();
}
}
}
}
/* class Game_BattlerBase */
ATBAlias._Game_BattlerBase_clearStates = Game_BattlerBase.prototype.clearStates;
Game_BattlerBase.prototype.clearStates = function() {
if (SceneManager._scene instanceof Scene_Battle) {
for (let stateId of this._states) {
BattleManager.eraseStateApply(this, stateId);
}
}
ATBAlias._Game_BattlerBase_clearStates.call(this);
};
ATBAlias._Game_BattlerBase_addNewState = Game_BattlerBase.prototype.addNewState;
Game_BattlerBase.prototype.addNewState = function(stateId) {
ATBAlias._Game_BattlerBase_addNewState.call(this, stateId);
if (SceneManager._scene instanceof Scene_Battle) {
BattleManager.addStateApply(this, stateId);
}
};
ATBAlias._Game_BattlerBase_eraseState = Game_BattlerBase.prototype.eraseState;
Game_BattlerBase.prototype.eraseState = function(stateId) {
ATBAlias._Game_BattlerBase_eraseState.call(this, stateId);
if (SceneManager._scene instanceof Scene_Battle) {
BattleManager.eraseStateApply(this, stateId);
}
};
// timing 1: 行動終了時
// timing 2: ターン終了時
Game_BattlerBase.prototype.updateStateTurns = function(timing = 2) {
for (let stateId of this._states) {
if (this._stateTurns[stateId] > 0) {
let state = $dataStates[stateId];
if (state.autoRemovalTiming === timing) this._stateTurns[stateId]--;
}
}
};
/* class Game_Battler */
ATBAlias._Game_Battler_initMembers = Game_Battler.prototype.initMembers;
Game_Battler.prototype.initMembers = function() {
ATBAlias._Game_Battler_initMembers.call(this);
this._gauge = null;
};
Game_Battler.prototype.getSprite = function() {
for (let sprite of BattleManager._spriteset.battlerSprites()) {
if (sprite._battler === this) return sprite;
}
return null;
};
Game_Battler.prototype.setGauge = function(gauge) {
return this._gauge = gauge;
};
Game_Battler.prototype.gauge = function() {
return this._gauge;
};
// 行動終了時のステート解除判定後にステート経過ターンを更新する
ATBAlias._Game_Battler_onAllActionsEnd = Game_Battler.prototype.onAllActionsEnd;
Game_Battler.prototype.onAllActionsEnd = function() {
ATBAlias._Game_Battler_onAllActionsEnd.call(this);
this.updateStateTurns(1);
};
// 行動完了時にdoneさせない
Game_Battler.prototype.performActionEnd = function() {
this.setActionState("undecided");
};
// speedの生成にactionを用いない
Game_Battler.prototype.makeSpeed = function() {
this._speed = this.agi + Math.randomInt(Math.floor(5 + this.agi / 4));
this._speed += this.attackSpeed();
};
/* class Game_Actor */
ATBAlias._Game_BattlerBase_die = Game_BattlerBase.prototype.die;
Game_Actor.prototype.die = function() {
this.gauge().commandSelectCancel();
BattleManager._atbManager.endAction(this);
ATBAlias._Game_BattlerBase_die.call(this);
};
/* class Game_Item */
Game_Item.prototype.isSkillWait = function() {
const skill = this.object();
if (!skill) return null;
if (skill._skillWait === undefined) {
if (skill.note.match(/<\s*SkillWait\s*>/)) {
skill._skillWait = true;
} else {
skill._skillWait = false;
}
}
return skill._skillWait;
};
/* class Game_Action */
Game_Action.prototype.isSkillWait = function() {
return this._item.isSkillWait();
};
/* singleton class BattleManager */
ATBAlias._BattleManager_initMembers = BattleManager.initMembers;
BattleManager.initMembers = function() {
ATBAlias._BattleManager_initMembers.call(this);
this._turnStarted = false;
this._beforeActionFinish = false;
this._turnStartReserve = false;
this._atbManager = new ATBManager();
};
BattleManager.spriteset = function() {
return this._spriteset;
}
BattleManager.startInputPhase = function() {
this._phase = "input";
};
BattleManager.setActor = function(actor) {
this._actorIndex = $gameParty.members().indexOf(actor);
};
ATBAlias._BattleManager_startBattle = BattleManager.startBattle;
BattleManager.startBattle = function() {
ATBAlias._BattleManager_startBattle.call(this);
this._atbManager.startBattle();
if (this._surprise) {
this._atbManager.surprise();
} else if (this._preemptive) {
this._atbManager.preemptive();
}
};
// startInput時は、すぐにターンを開始する
BattleManager.startInput = function() {
this.startTurn();
};
ATBAlias._BattleManager_startTurn = BattleManager.startTurn;
BattleManager.startTurn = function() {
if (this._turnStarted) {
this._phase = "turn";
this._logWindow.startTurn();
} else {
if (ATBConfig.enableYEP_BattleEngineCore) {
this._enteredEndPhase = false;
this._phase = "turn";
$gameTroop.increaseTurn();
$gameParty.onTurnStart();
$gameTroop.onTurnStart();
this._performedBattlers = [];
this.makeActionOrders();
$gameParty.requestMotionRefresh();
this._logWindow.startTurn();
} else {
ATBAlias._BattleManager_startTurn.call(this);
}
this._atbManager.toActive("turn");
this._atbManager.startTurn();
this._turnStarted = true;
}
};
BattleManager.updateTurn = function() {
// CTBの場合は、BattleManager.updateTurn内でゲージを更新する
if (ATBConfig.waitCommandSelection) {
this._atbManager.updateGauge();
}
this._atbManager.updateTurn();
$gameParty.requestMotionRefresh();
if (!this._subject) {
this._subject = this.getNextSubject();
}
if (this._subject) {
if (this._subject instanceof Game_Actor) {
const nextHighPrioritySubject = this._atbManager.getNextHighPrioritySubject();
if (nextHighPrioritySubject) {
this._atbManager.addNextSubject(this._subject);
this._subject = nextHighPrioritySubject;
}
}
this.processTurn();
}
if ((this._phase === "input" || this._phase === "turn") && this._atbManager.isEndTurn()) {
this._atbManager.endTurn();
this.endTurn();
}
};
// clearActorを無効化する
BattleManager.clearActor = function() {
};
BattleManager.beforeAction = function(action) {
const gauge = this._subject.gauge();
if (gauge.purpose === ATBGauge.PURPOSE_SKILL_WAIT) {
if (this._subject instanceof Game_Actor) gauge.setCommandSelected(true);
this._beforeActionFinish = true;
} else if (this._subject instanceof Game_Actor && !gauge.isCommandSelected()) {
if (!(this._subject.isConfused() && !action._forcing)) {
this.setActor(this._subject);
this.startInputPhase();
} else {
gauge.setCommandSelected(true);
}
} else if (action.isSkillWait()) {
this._atbManager.startSkillWait(this._subject);
this._subject.setActionState("waiting");
} else {
this._beforeActionFinish = true;
}
};
BattleManager.afterAction = function() {
this._atbManager.toActive("turn");
if (this._subject instanceof Game_Actor && this._subject.gauge().purpose === ATBGauge.PURPOSE_TIME) {
this._subject.gauge().setCommandSelected(false);
}
};
BattleManager.processTurn = function() {
if (ATBConfig.enableYEP_BattleEngineCore) this._processTurn = true;
const subject = this._subject;
const action = subject.currentAction();
if (action) {
if (!this._beforeActionFinish) {
this.beforeAction(action);
}
if (this._beforeActionFinish) {
action.prepare();
if (action.isValid()) {
this.startAction();
} else {
this._atbManager.endAction(this._subject);
}
this._beforeActionFinish = false;
subject.removeCurrentAction();
} else if (this._subject.gauge().purpose === ATBGauge.PURPOSE_SKILL_WAIT) {
this._beforeActionFinish = false;
this.afterAction();
this._subject = this.getNextSubject();
}
} else {
this.afterAction();
subject.onAllActionsEnd();
this.refreshStatus();
this._logWindow.displayAutoAffectedStatus(subject);
this._logWindow.displayCurrentState(subject);
this._logWindow.displayRegeneration(subject);
this._subject = this.getNextSubject();
}
if (ATBConfig.enableYEP_BattleEngineCore) this._processTurn = false;
};
ATBAlias._BattleManager_startAction = BattleManager.startAction;
BattleManager.startAction = function() {
if (this._subject instanceof Game_Actor) {
if (this._subject.gauge().isCommandSelected()) {
if (ATBConfig.waitAnimation) this._atbManager.toWait("turn");
ATBAlias._BattleManager_startAction.call(this);
}
} else {
if (ATBConfig.waitCommandSelection || ATBConfig.waitAnimation) {
this._atbManager.toWait("turn");
}
ATBAlias._BattleManager_startAction.call(this);
}
};
ATBAlias._BattleManager_endAction = BattleManager.endAction;
BattleManager.endAction = function() {
ATBAlias._BattleManager_endAction.call(this);
this._atbManager.endAction(this._subject);
};
ATBAlias._BattleManager_endTurn = BattleManager.endTurn;
BattleManager.endTurn = function() {
if (ATBConfig.enableYEP_BattleEngineCore) {
if (this.isTurnBased() && this._enteredEndPhase) {
this._phase = "turnEnd";
this._preemptive = false;
this._surprise = false;
return;
}
this._enteredEndPhase = true;
Yanfly.BEC.BattleManager_endTurn.call(this);
BattleManager.refreshAllMembers();
this.actor().gauge().commandSelectCancel();
this._turnStarted = false;
} else {
ATBAlias._BattleManager_endTurn.call(this);
this._turnStarted = false;
}
};
BattleManager.selectNextCommand = function() {
this.actor().gauge().setCommandSelected(true);
this.actor().gauge().setCommandSelecting(false);
this.toActiveSelectSkillOrItem();
this.startTurnReserve();
};
BattleManager.getNextSubject = function() {
if (this._subject && this._subject.gauge().isActionEnd()) {
return null;
}
return this._atbManager.getNextSubject();
};
BattleManager.processEscape = function() {
$gameParty.performEscape();
SoundManager.playEscape();
const success = this._preemptive ? true : (Math.random() < this._escapeRatio);
if (success) {
this.displayEscapeSuccessMessage();
this._escaped = true;
this.processAbort();
} else {
this.displayEscapeFailureMessage();
this._escapeRatio += 0.1;
this.endPause();
this.startTurnReserve();
this._atbManager.escapeFailed();
this.actor().gauge().commandSelectCancel();
if (this._subject instanceof Game_Actor && this._phase === "input") {
this._subject = null;
}
}
return success;
};
ATBAlias._BattleManager_isInputting = BattleManager.isInputting;
BattleManager.isInputting = function() {
return ATBAlias._BattleManager_isInputting.call(this) && !this._turnStartReserve;
};
BattleManager.update = function() {
if (ATBConfig.enableChangeSelectActor) this.updateChangeSelectActor();
if (ATBConfig.enableYEP_BattleEngineCore) {
if (!this.isBusy() && !this.updateEvent()) {
switch (this._phase) {
case "start":
this.startInput();
break;
case "input":
case "turn":
this.startTurnAwait();
this.updateTurn();
break;
case "action":
this.updateAction();
break;
case "phaseChange":
this.updatePhase();
break;
case "actionList":
this.updateActionList()
break;
case "actionTargetList":
this.updateActionTargetList()
break;
case "turnEnd":
this.updateTurnEnd();
break;
case "battleEnd":
this.updateBattleEnd();
break;
}
}
} else {
if (!this.isBusy() && !this.updateEvent()) {
switch (this._phase) {
case "start":
this.startInput();
break;
// ATBの場合は、input phaseの間でもターン更新を行う
case "input":
case "turn":
this.startTurnAwait();
this.updateTurn();
break;
case "action":
this.updateAction();
break;
case "turnEnd":
this.updateTurnEnd();
break;
case "battleEnd":
this.updateBattleEnd();
break;
}
}
}
// バトルイベントを実行する場合、アクターコマンド選択中を解除する
if ($gameTroop.isEventRunning()) this.actor().gauge().setCommandSelecting(false);
};
BattleManager.updateChangeSelectActor = function() {
if (!this._subject) return;
const actorCommandWindow = SceneManager._scene._actorCommandWindow;
if (actorCommandWindow.active) {
if (Input.isTriggered("pageup")) {
this.changeSelectActor();
} else if (Input.isTriggered("pagedown")) {
this.changeSelectActor(true);
}
}
};
BattleManager.changeSelectActor = function(reverse = false) {
const scene = SceneManager._scene;
const currentActor = this.actor();
if (!currentActor) return;
let nextActor = null;
if (this._subject instanceof Game_Actor
&& this._subject === currentActor
&& this._subject.canInput()
&& this._subject.gauge().purpose === ATBGauge.PURPOSE_TIME
&& !this._subject.gauge().isActionEnd()) {
this._atbManager.addNextSubject(this._subject);
nextActor = this._atbManager.changeNextActor(currentActor, reverse);
this._subject = this._atbManager.getNextSubject();
if (!nextActor) return;
currentActor.gauge().commandSelectCancel();
this.setActor(nextActor);
} else {
nextActor = this._atbManager.changeNextActor(currentActor, reverse);
if (!nextActor) return;
currentActor.gauge().commandSelectCancel();
scene.updateActorCommandWindow();
this.setActor(nextActor);
scene.startActorCommandSelection();
}
};
// アクターコマンドの選択が完了してからターンを開始するようにする
BattleManager.startTurnReserve = function() {
if (this._subject && !this._subject.gauge().isActionEnd()) {
this._turnStartReserve = true;
SceneManager._scene.changeInputWindow();
} else {
this.startTurn();
this._turnStarted = true;
}
};
BattleManager.startTurnAwait = function() {
if (this._phase === "battleEnd") return;
if (this._subject && this._subject.gauge().isActionEnd) {
if (this._turnStartReserve) {
this._turnStartReserve = false;
this.startTurn();
}
}
};
BattleManager.updateGauge = function() {
this._atbManager.updateGauge();
};
BattleManager.startPause = function() {
this._atbManager.toWait("pause");
};
BattleManager.endPause = function() {
this._atbManager.toActive("pause");
};
BattleManager.toActiveSelectSkillOrItem = function() {
this._atbManager.toActive("selectSkillOrItem");
};
BattleManager.toWaitSelectSkillOrItem = function() {
this._atbManager.toWait("selectSkillOrItem");
};
BattleManager.addStateApply = function(battler, stateId) {
this._atbManager.addStateApply(battler, stateId);
};
BattleManager.eraseStateApply = function(battler, stateId) {
this._atbManager.eraseStateApply(battler, stateId);
};
/* class Scene_Battle */
ATBAlias._Scene_Battle_update = Scene_Battle.prototype.update;
Scene_Battle.prototype.update = function() {
ATBAlias._Scene_Battle_update.call(this);
this.updateActorCommandWindow();
};
Scene_Battle.prototype.updateBattleProcess = function() {
// CTBの場合は、BattleManager.updateTurn内でゲージを更新する
if (!ATBConfig.waitCommandSelection) {
if (ATBConfig.enableYEP_BattleEngineCore) {
switch (BattleManager._phase) {
case "input":
case "turn":
case "action":
case "phaseChange":
case "actionList":
case "actionTargetList":
BattleManager.updateGauge();
}
} else {
switch (BattleManager._phase) {
case "input":
case "turn":
case "action":
BattleManager.updateGauge();
}
}
}
if (!this.isAnyInputWindowActive() || BattleManager.isAborting() ||
BattleManager.isBattleEnd()) {
BattleManager.update();
if (!BattleManager.actor() || !BattleManager.actor().gauge().isCommandSelected()) {
this.changeInputWindow();
}
}
};
Scene_Battle.prototype.updateActorCommandWindow = function() {
if (BattleManager.actor() && !BattleManager.actor().gauge().isCommandSelecting()) {
this._actorCommandWindow.close();
this._skillWindow.hide();
this._itemWindow.hide();
this._actorWindow.hide();
this._enemyWindow.hide();
}
};
// ターンを再開する
Scene_Battle.prototype.commandFight = function() {
BattleManager.endPause();
BattleManager.actor().gauge().setCommandSelecting(false);
this.changeInputWindow();
};
// キャンセルでパーティウィンドウに戻す
Scene_Battle.prototype.selectPreviousCommand = function() {
this.startPartyCommandSelection();
};
// パーティコマンド選択時はポーズする
ATBAlias._Scene_Battle_startPartyCommandSelection = Scene_Battle.prototype.startPartyCommandSelection;
Scene_Battle.prototype.startPartyCommandSelection = function() {
BattleManager.startPause();
if (ATBConfig.enableYEP_BattleEngineCore) {
Yanfly.BEC.Scene_Battle_startPartyCommandSelection.call(this);
} else {
ATBAlias._Scene_Battle_startPartyCommandSelection.call(this);
}
};
ATBAlias._Scene_Battle_startActorCommandSelection = Scene_Battle.prototype.startActorCommandSelection;
Scene_Battle.prototype.startActorCommandSelection = function() {
if (ATBConfig.enableYEP_BattleEngineCore) {
if (!BattleManager.actor().gauge().isCommandSelecting()) {
Yanfly.BEC.Scene_Battle_startActorCommandSelection.call(this);
this._statusWindow.refresh();
BattleManager.actor().gauge().setCommandSelecting(true);
}
} else {
if (!BattleManager.actor().gauge().isCommandSelecting()) {
ATBAlias._Scene_Battle_startActorCommandSelection.call(this);
BattleManager.actor().gauge().setCommandSelecting(true);
}
}
};
Scene_Battle.prototype.changeInputWindow = function() {
if (BattleManager.isInputting()) {
if (BattleManager.actor()) {
this.startActorCommandSelection();
} else {
BattleManager.startTurn();
}
} else {
// アクターウィンドウの選択が終了すると、アクターウィンドウを閉じる
if (BattleManager.actor() && !BattleManager.actor().gauge().isCommandSelecting()) {
this.endCommandSelection();
}
}
};
// ATB時は、ステータスウィンドウを移動しないようにする
ATBAlias._Scene_Battle_updateWindowPositions = Scene_Battle.prototype.updateWindowPositions;
Scene_Battle.prototype.updateWindowPositions = function() {
statusX = this._partyCommandWindow.width;
if (this._statusWindow.x < statusX) {
this._statusWindow.x += 16;
if (this._statusWindow.x > statusX) {
this._statusWindow.x = statusX;
}
}
if (this._statusWindow.x > statusX) {
this._statusWindow.x -= 16;
if (this._statusWindow.x < statusX) {
this._statusWindow.x = statusX;
}
}
};
// ATB時は、パーティコマンドが開いているとき以外は時間を進める
ATBAlias._Scene_Battle_isAnyInputWindowActive = Scene_Battle.prototype.isAnyInputWindowActive;
Scene_Battle.prototype.isAnyInputWindowActive = function() {
if (ATBConfig.waitCommandSelection) {
return ATBAlias._Scene_Battle_isAnyInputWindowActive.call(this);
}
return this._partyCommandWindow.active;
};
ATBAlias._Scene_Battle_commandSkill = Scene_Battle.prototype.commandSkill;
Scene_Battle.prototype.commandSkill = function() {
if (!ATBConfig.waitCommandSelection && ATBConfig.waitSelectSkillOrItem) {
BattleManager.toWaitSelectSkillOrItem();
}
ATBAlias._Scene_Battle_commandSkill.call(this);
};
ATBAlias._Scene_Battle_commandItem = Scene_Battle.prototype.commandItem;
Scene_Battle.prototype.commandItem = function() {
if (!ATBConfig.waitCommandSelection && ATBConfig.waitSelectSkillOrItem) {
BattleManager.toWaitSelectSkillOrItem();
}
ATBAlias._Scene_Battle_commandItem.call(this);
};
ATBAlias._Scene_Battle_onSkillCancel = Scene_Battle.prototype.onSkillCancel;
Scene_Battle.prototype.onSkillCancel = function() {
if (!ATBConfig.waitCommandSelection && ATBConfig.waitSelectSkillOrItem) {
BattleManager.toActiveSelectSkillOrItem();
}
ATBAlias._Scene_Battle_onSkillCancel.call(this);
};
ATBAlias._Scene_Battle_onItemCancel = Scene_Battle.prototype.onItemCancel;
Scene_Battle.prototype.onItemCancel = function() {
if (!ATBConfig.waitCommandSelection && ATBConfig.waitSelectSkillOrItem) {
BattleManager.toActiveSelectSkillOrItem();
}
ATBAlias._Scene_Battle_onItemCancel.call(this);
};
/* class Window_BattleStatus */
ATBAlias._Window_BattleStatus_drawGaugeAreaWithTp = Window_BattleStatus.prototype.drawGaugeAreaWithTp;
Window_BattleStatus.prototype.drawGaugeAreaWithTp = function(rect, actor) {
if (ATBConfig.drawUnderGauge) {
ATBAlias._Window_BattleStatus_drawGaugeAreaWithTp.call(this, rect, actor);
} else {
this.drawActorHp(actor, rect.x + 0, rect.y, 108 * 0.8);
this.drawActorMp(actor, rect.x + 123 * 0.8, rect.y, 96 * 0.8);
this.drawActorTp(actor, rect.x + 234 * 0.8, rect.y, 96 * 0.8);
this.drawActorCt(actor, rect.x + 334 * 0.8, rect.y, 96 * 0.8);
}
};
ATBAlias._Window_BattleStatus_drawGaugeAreaWithoutTp = Window_BattleStatus.prototype.drawGaugeAreaWithoutTp;
Window_BattleStatus.prototype.drawGaugeAreaWithoutTp = function(rect, actor) {
if (ATBConfig.drawUnderGauge) {
ATBAlias._Window_BattleStatus_drawGaugeAreaWithoutTp.call(this, rect, actor);
} else {
ATBAlias._Window_BattleStatus_drawGaugeAreaWithoutTp.call(this, rect, actor);
this.drawActorCt(actor, rect.x + 234, rect.y, 96);
}
};
Window_BattleStatus.prototype.drawActorCt = function(actor, x, y, width) {
width = width || 96;
const gauge = actor.gauge();
let color1, color2;
if (gauge && gauge.purpose === ATBGauge.PURPOSE_TIME) {
color1 = this.textColor(30);
color2 = this.textColor(31);
} else {
color1 = this.textColor(2);
color2 = this.textColor(2);
}
const ctValue = Math.floor(gauge ? gauge.value : 0);
const ctRate = ctValue / ATBManager.GAUGE_MAX;
this.drawGauge(x, y, width, ctRate, color1, color2);
this.changeTextColor(this.systemColor());
this.drawText("CT", x, y, 44);
this.changeTextColor(this.normalColor());
};
class Sprite_GaugeLine extends Sprite {
get GAUGE_WIDTH() { return 50 };
get GAUGE_HEIGHT() { return 5 };
initialize(battler) {
const bitmap = new Bitmap(this.GAUGE_WIDTH, this.GAUGE_HEIGHT);
super.initialize(bitmap);
this._battler = battler;
this._battlerSprite = battler.getSprite();
}
update() {
super.update();
if (BattleManager._phase !== "start") {
if (this._battler instanceof Game_Actor) {
this.x = this._battlerSprite.x - 24;
this.y = this._battlerSprite.y;
} else {
this.x = this._battlerSprite.x - this._battlerSprite.width / 4;
this.y = this._battlerSprite.y;
}
this.drawGauge(this._battler.gauge());
}
}
drawGauge(gauge) {
let width = 0;
if (gauge.battler() instanceof Game_Enemy && gauge.battler().isDead()) {
this.bitmap.clear();
return;
}
if (gauge) {
const ctRate = gauge.value / ATBManager.GAUGE_MAX;
width = this.bitmap.width * ctRate;
}
this.bitmap.fillRect(0, 0, this.bitmap.width, this.bitmap.height, "#000000");
if (gauge.purpose === ATBGauge.PURPOSE_SKILL_WAIT) {
this.bitmap.fillRect(0, 0, width, this.bitmap.height, BattleManager._statusWindow.textColor(2));
} else {
this.bitmap.fillRect(0, 0, width, this.bitmap.height, BattleManager._statusWindow.textColor(31));
}
}
}
/* class Spriteset_Battle */
Spriteset_Battle.prototype.createGaugeLine = function(battler) {
this._baseSprite.addChild(new Sprite_GaugeLine(battler));
};
// クラス名のエイリアス
ATBAlias.ATBTimer = ATBTimer;
ATBAlias.ATBGauge = ATBGauge;
ATBAlias.ActorGauge = ActorGauge;
ATBAlias.EnemyGauge = EnemyGauge;
ATBAlias.ATBManager = ATBManager;
ATBAlias.Sprite_GaugeLine = Sprite_GaugeLine;
};