//-----------------------------------------------------------------------------
// BattleManager
//
// The static class that manages battle progress.
/**
 * The static class that manages battle progress.
 *
 * @namespace
 */
function BattleManager() {
    throw new Error("This is a static class");
}
/**
 * Set up the battle
 *
 * @static
 * @param {number} troopId - The troop ID to fight
 * @param {boolean} canEscape - If the player can escape from the battle
 * @param {boolean} canLose - If the player can lose the battle without gameover
 */
BattleManager.setup = function(troopId, canEscape, canLose) {
    this.initMembers();
    this._canEscape = canEscape;
    this._canLose = canLose;
    $gameTroop.setup(troopId);
    $gameScreen.onBattleStart();
    this.makeEscapeRatio();
};
/**
 * Initializes battle parameters
 *
 * @static
 */
BattleManager.initMembers = function() {
    this._phase = "";
    this._inputting = false;
    this._canEscape = false;
    this._canLose = false;
    this._battleTest = false;
    this._eventCallback = null;
    this._preemptive = false;
    this._surprise = false;
    this._currentActor = null;
    this._actionForcedBattler = null;
    this._mapBgm = null;
    this._mapBgs = null;
    this._actionBattlers = [];
    this._subject = null;
    this._action = null;
    this._targets = [];
    this._logWindow = null;
    this._spriteset = null;
    this._escapeRatio = 0;
    this._escaped = false;
    this._rewards = {};
    this._tpbNeedsPartyCommand = true;
};
/**
 * Check if the battle system is Tpb (wait or active)
 *
 * @static
 * @return {boolean} True if battle system is tpb
 */
BattleManager.isTpb = function() {
    return $dataSystem.battleSystem >= 1;
};
/**
 * Check if the battle system is Active Tpb
 *
 * @static
 * @return {boolean} True if battle system is active tpb
 */
BattleManager.isActiveTpb = function() {
    return $dataSystem.battleSystem === 1;
};
/**
 * Check if the battle is just a test battle
 *
 * @static
 * @return {boolean} True if battle test
 */
BattleManager.isBattleTest = function() {
    return this._battleTest;
};
/**
 * Set the battle test parameter for test battles
 *
 * @static
 * @param {boolean} battleTest - If the battle is a test battle or not
 */
BattleManager.setBattleTest = function(battleTest) {
    this._battleTest = battleTest;
};
/**
 * Sets a callback function for when the battle is over
 *
 * @static
 * @param {Function} callback - Callback function to call when the battle ends
 */
BattleManager.setEventCallback = function(callback) {
    this._eventCallback = callback;
};
/**
 * Sets the battle log window
 *
 * @static
 * @param {Window} logWindow - The battle log window
 */
BattleManager.setLogWindow = function(logWindow) {
    this._logWindow = logWindow;
};
/**
 * Sets the battle spriteset
 *
 * @static
 * @param {Spriteset} spriteset - The battle spriteset
 */
BattleManager.setSpriteset = function(spriteset) {
    this._spriteset = spriteset;
};
/**
 * Handling for when the encounter starts
 *
 * @static
 */
BattleManager.onEncounter = function() {
    this._preemptive = Math.random() < this.ratePreemptive();
    this._surprise = Math.random() < this.rateSurprise() && !this._preemptive;
};
/**
 * Get the preemptive rate
 *
 * @static
 * @return {number} The preemptive rate of the party
 */
BattleManager.ratePreemptive = function() {
    return $gameParty.ratePreemptive($gameTroop.agility());
};
/**
 * Get the surprise rate
 *
 * @static
 * @return {number} The surprise rate of the party
 */
BattleManager.rateSurprise = function() {
    return $gameParty.rateSurprise($gameTroop.agility());
};
/**
 * Save the currently playing BGM and BGS. Used to replay them later once battle ends.
 *
 * @static
 */
BattleManager.saveBgmAndBgs = function() {
    this._mapBgm = AudioManager.saveBgm();
    this._mapBgs = AudioManager.saveBgs();
};
/**
 * Starts playing the battle BGM
 *
 * @static
 */
BattleManager.playBattleBgm = function() {
    AudioManager.playBgm($gameSystem.battleBgm());
    AudioManager.stopBgs();
};
/**
 * Starts playing the battle victory ME
 *
 * @static
 */
BattleManager.playVictoryMe = function() {
    AudioManager.playMe($gameSystem.victoryMe());
};
/**
 * Starts playing the battle defeat ME
 *
 * @static
 */
BattleManager.playDefeatMe = function() {
    AudioManager.playMe($gameSystem.defeatMe());
};
/**
 * Replays the saved BGM and BGS
 *
 * @static
 */
BattleManager.replayBgmAndBgs = function() {
    if (this._mapBgm) {
        AudioManager.replayBgm(this._mapBgm);
    } else {
        AudioManager.stopBgm();
    }
    if (this._mapBgs) {
        AudioManager.replayBgs(this._mapBgs);
    }
};
/**
 * Sets up the escape ratio for the battle
 *
 * @static
 */
BattleManager.makeEscapeRatio = function() {
    this._escapeRatio = (0.5 * $gameParty.agility()) / $gameTroop.agility();
};
/**
 * Updates the battle
 *
 * @static
 * @param {boolean} timeActive - Whether time is currently active for the battle
 */
BattleManager.update = function(timeActive) {
    if (!this.isBusy() && !this.updateEvent()) {
        this.updatePhase(timeActive);
    }
    if (this.isTpb()) {
        this.updateTpbInput();
    }
};
/**
 * Updates the battle phase
 *
 * @static
 * @param {boolean} timeActive - Whether time is currently active for the battle
 */
BattleManager.updatePhase = function(timeActive) {
    switch (this._phase) {
        case "start":
            this.updateStart();
            break;
        case "turn":
            this.updateTurn(timeActive);
            break;
        case "action":
            this.updateAction();
            break;
        case "turnEnd":
            this.updateTurnEnd();
            break;
        case "battleEnd":
            this.updateBattleEnd();
            break;
    }
};
/**
 * Updates battle events
 *
 * @static
 * @return {boolean} Returns false when aborting battle
 */
BattleManager.updateEvent = function() {
    switch (this._phase) {
        case "start":
        case "turn":
        case "turnEnd":
            if (this.isActionForced()) {
                this.processForcedAction();
                return true;
            } else {
                return this.updateEventMain();
            }
    }
    return this.checkAbort();
};
/**
 * Updates main battle events
 *
 * @static
 * @return {boolean} Returns true when events are running
 */
BattleManager.updateEventMain = function() {
    $gameTroop.updateInterpreter();
    $gameParty.requestMotionRefresh();
    if ($gameTroop.isEventRunning() || this.checkBattleEnd()) {
        return true;
    }
    $gameTroop.setupBattleEvent();
    if ($gameTroop.isEventRunning() || SceneManager.isSceneChanging()) {
        return true;
    }
    return false;
};
/**
 * Check if the battle is currently busy
 *
 * @static
 * @return {boolean} Returns true when the battle is busy
 */
BattleManager.isBusy = function() {
    return (
        $gameMessage.isBusy() ||
        this._spriteset.isBusy() ||
        this._logWindow.isBusy()
    );
};
/**
 * Updates input for TPB battle system
 *
 * @static
 */
BattleManager.updateTpbInput = function() {
    if (this._inputting) {
        this.checkTpbInputClose();
    } else {
        this.checkTpbInputOpen();
    }
};
/**
 * Handles when TPB input closes
 *
 * @static
 */
BattleManager.checkTpbInputClose = function() {
    if (!this.isPartyTpbInputtable() || this.needsActorInputCancel()) {
        this.cancelActorInput();
        this._currentActor = null;
        this._inputting = false;
    }
};
/**
 * Handles when TPB input opens
 *
 * @static
 */
BattleManager.checkTpbInputOpen = function() {
    if (this.isPartyTpbInputtable()) {
        if (this._tpbNeedsPartyCommand) {
            this._inputting = true;
            this._tpbNeedsPartyCommand = false;
        } else {
            this.selectNextCommand();
        }
    }
};
/**
 * Check if TPB can accept input
 *
 * @static
 * @return {boolean} True if TPB can accept input
 */
BattleManager.isPartyTpbInputtable = function() {
    return $gameParty.canInput() && this.isTpbMainPhase();
};
/**
 * Check if need to allow to cancel from the current actor
 *
 * @static
 * @return {boolean} True if can cancel from actor
 */
BattleManager.needsActorInputCancel = function() {
    return this._currentActor && !this._currentActor.canInput();
};
/**
 * Check if it is a main TPB phase
 *
 * @static
 * @return {boolean} True if main phase
 */
BattleManager.isTpbMainPhase = function() {
    return ["turn", "turnEnd", "action"].includes(this._phase);
};
/**
 * Check if currently inputting
 *
 * @static
 * @return {boolean} True if inputting
 */
BattleManager.isInputting = function() {
    return this._inputting;
};
/**
 * Check if currently in the turn phase
 *
 * @static
 * @return {boolean} True if in turn phase
 */
BattleManager.isInTurn = function() {
    return this._phase === "turn";
};
/**
 * Check if currently in the turn end phase
 *
 * @static
 * @return {boolean} True if in turn end phase
 */
BattleManager.isTurnEnd = function() {
    return this._phase === "turnEnd";
};
/**
 * Check if currently in the aborting phase
 *
 * @static
 * @return {boolean} True if aborting
 */
BattleManager.isAborting = function() {
    return this._phase === "aborting";
};
/**
 * Check if currently in the battle end phase
 *
 * @static
 * @return {boolean} True if battle end phase
 */
BattleManager.isBattleEnd = function() {
    return this._phase === "battleEnd";
};
/**
 * Check if the battle can be escaped from
 *
 * @static
 * @return {boolean} True if can escape
 */
BattleManager.canEscape = function() {
    return this._canEscape;
};
/**
 * Check if the battle can be lost without gameover
 *
 * @static
 * @return {boolean} True if can lose
 */
BattleManager.canLose = function() {
    return this._canLose;
};
/**
 * Check if the battle is escaped
 *
 * @static
 * @return {boolean} True if escaped
 */
BattleManager.isEscaped = function() {
    return this._escaped;
};
/**
 * Get the current actor
 *
 * @static
 * @return {Game_Actor|null} The current selected actor, or null if no current actor
 */
BattleManager.actor = function() {
    return this._currentActor;
};
/**
 * Handling for the start of the battle
 *
 * @static
 */
BattleManager.startBattle = function() {
    this._phase = "start";
    $gameSystem.onBattleStart();
    $gameParty.onBattleStart(this._preemptive);
    $gameTroop.onBattleStart(this._surprise);
    this.displayStartMessages();
};
/**
 * Displays the messages shown at the start of the battle
 *
 * @static
 */
BattleManager.displayStartMessages = function() {
    for (const name of $gameTroop.enemyNames()) {
        $gameMessage.add(TextManager.emerge.format(name));
    }
    if (this._preemptive) {
        $gameMessage.add(TextManager.preemptive.format($gameParty.name()));
    } else if (this._surprise) {
        $gameMessage.add(TextManager.surprise.format($gameParty.name()));
    }
};
/**
 * Starts the input phase of battle
 *
 * @static
 */
BattleManager.startInput = function() {
    this._phase = "input";
    this._inputting = true;
    $gameParty.makeActions();
    $gameTroop.makeActions();
    this._currentActor = null;
    if (this._surprise || !$gameParty.canInput()) {
        this.startTurn();
    }
};
/**
 * Gets the input action
 *
 * @static
 * @return {Game_Action|null} The Game Action input if current actor exists, else null
 */
BattleManager.inputtingAction = function() {
    return this._currentActor ? this._currentActor.inputtingAction() : null;
};
/**
 * Selects the next command
 *
 * @static
 */
BattleManager.selectNextCommand = function() {
    if (this._currentActor) {
        if (this._currentActor.selectNextCommand()) {
            return;
        }
        this.finishActorInput();
    }
    this.selectNextActor();
};
/**
 * Selects the next actor
 *
 * @static
 */
BattleManager.selectNextActor = function() {
    this.changeCurrentActor(true);
    if (!this._currentActor) {
        if (this.isTpb()) {
            this.changeCurrentActor(true);
        } else {
            this.startTurn();
        }
    }
};
/**
 * Selects the previous command
 *
 * @static
 */
BattleManager.selectPreviousCommand = function() {
    if (this._currentActor) {
        if (this._currentActor.selectPreviousCommand()) {
            return;
        }
        this.cancelActorInput();
    }
    this.selectPreviousActor();
};
/**
 * Selects the previous actor
 *
 * @static
 */
BattleManager.selectPreviousActor = function() {
    if (this.isTpb()) {
        this.changeCurrentActor(true);
        if (!this._currentActor) {
            this._inputting = $gameParty.canInput();
        }
    } else {
        this.changeCurrentActor(false);
    }
};
/**
 * Changes the currently selected actor
 *
 * @static
 * @param {boolean} forward - If the select moves forward through the battle actors
 */
BattleManager.changeCurrentActor = function(forward) {
    const members = $gameParty.battleMembers();
    let actor = this._currentActor;
    for (;;) {
        const currentIndex = members.indexOf(actor);
        actor = members[currentIndex + (forward ? 1 : -1)];
        if (!actor || actor.canInput()) {
            break;
        }
    }
    this._currentActor = actor ? actor : null;
    this.startActorInput();
};
/**
 * Handles start of actor input
 *
 * @static
 */
BattleManager.startActorInput = function() {
    if (this._currentActor) {
        this._currentActor.setActionState("inputting");
        this._inputting = true;
    }
};
/**
 * Handles end of actor input
 *
 * @static
 */
BattleManager.finishActorInput = function() {
    if (this._currentActor) {
        if (this.isTpb()) {
            this._currentActor.startTpbCasting();
        }
        this._currentActor.setActionState("waiting");
    }
};
/**
 * Handles cancelling of actor input
 *
 * @static
 */
BattleManager.cancelActorInput = function() {
    if (this._currentActor) {
        this._currentActor.setActionState("undecided");
    }
};
/**
 * Handles updating for the start phase of battle
 *
 * @static
 */
BattleManager.updateStart = function() {
    if (this.isTpb()) {
        this._phase = "turn";
    } else {
        this.startInput();
    }
};
/**
 * Starts the turn phase of the battle
 *
 * @static
 */
BattleManager.startTurn = function() {
    this._phase = "turn";
    $gameTroop.increaseTurn();
    $gameParty.requestMotionRefresh();
    if (!this.isTpb()) {
        this.makeActionOrders();
        this._logWindow.startTurn();
        this._inputting = false;
    }
};
/**
 * Update the turn phase of the battle
 *
 * @static
 * @param {boolean} timeActive - If battle time is active
 */
BattleManager.updateTurn = function(timeActive) {
    $gameParty.requestMotionRefresh();
    if (this.isTpb() && timeActive) {
        this.updateTpb();
    }
    if (!this._subject) {
        this._subject = this.getNextSubject();
    }
    if (this._subject) {
        this.processTurn();
    } else if (!this.isTpb()) {
        this.endTurn();
    }
};
/**
 * Update for TPB
 *
 * @static
 */
BattleManager.updateTpb = function() {
    $gameParty.updateTpb();
    $gameTroop.updateTpb();
    this.updateAllTpbBattlers();
    this.checkTpbTurnEnd();
};
/**
 * Update all battlers for TPB
 *
 * @static
 */
BattleManager.updateAllTpbBattlers = function() {
    for (const battler of this.allBattleMembers()) {
        this.updateTpbBattler(battler);
    }
};
/**
 * Update a specific battler for TPB
 *
 * @static
 * @param {Game_Battler} battler - The battler to update
 */
BattleManager.updateTpbBattler = function(battler) {
    if (battler.isTpbTurnEnd()) {
        battler.onTurnEnd();
        battler.startTpbTurn();
        this.displayBattlerStatus(battler, false);
    } else if (battler.isTpbReady()) {
        battler.startTpbAction();
        this._actionBattlers.push(battler);
    } else if (battler.isTpbTimeout()) {
        battler.onTpbTimeout();
        this.displayBattlerStatus(battler, true);
    }
};
/**
 * Check for if TPB turn should end
 *
 * @static
 */
BattleManager.checkTpbTurnEnd = function() {
    if ($gameTroop.isTpbTurnEnd()) {
        this.endTurn();
    }
};
/**
 * Processing for the turn phase of battle
 *
 * @static
 */
BattleManager.processTurn = function() {
    const subject = this._subject;
    const action = subject.currentAction();
    if (action) {
        action.prepare();
        if (action.isValid()) {
            this.startAction();
        }
        subject.removeCurrentAction();
    } else {
        this.endAction();
        this._subject = null;
    }
};
/**
 * Handling for the end of the battler's actions
 *
 * @static
 * @param {Game_Battler} battler - The battler ending their actions
 */
BattleManager.endBattlerActions = function(battler) {
    battler.setActionState(this.isTpb() ? "undecided" : "done");
    battler.onAllActionsEnd();
    battler.clearTpbChargeTime();
    this.displayBattlerStatus(battler, true);
};
/**
 * Set the phase to turn end
 *
 * @static
 */
BattleManager.endTurn = function() {
    this._phase = "turnEnd";
    this._preemptive = false;
    this._surprise = false;
};
/**
 * Update for when phase is turn end
 *
 * @static
 */
BattleManager.updateTurnEnd = function() {
    if (this.isTpb()) {
        this.startTurn();
    } else {
        this.endAllBattlersTurn();
        this.startInput();
    }
};
/**
 * Ends each battler's turn
 *
 * @static
 */
BattleManager.endAllBattlersTurn = function() {
    for (const battler of this.allBattleMembers()) {
        battler.onTurnEnd();
        this.displayBattlerStatus(battler, false);
    }
};
/**
 * Displays the battler's status in the log window
 *
 * @static
 * @param {Game_Battler} battler - The battler to display
 * @param {boolean} current - If displays current state too
 */
BattleManager.displayBattlerStatus = function(battler, current) {
    this._logWindow.displayAutoAffectedStatus(battler);
    if (current) {
        this._logWindow.displayCurrentState(battler);
    }
    this._logWindow.displayRegeneration(battler);
};
/**
 * Get the next subject
 *
 * @static
 * @return {Game_Battler|null} The battler that is the next subject, can be null if none exist
 */
BattleManager.getNextSubject = function() {
    for (;;) {
        const battler = this._actionBattlers.shift();
        if (!battler) {
            return null;
        }
        if (battler.isBattleMember() && battler.isAlive()) {
            return battler;
        }
    }
};
/**
 * Gets all the battle members (troops and party)
 *
 * @static
 * @return {Array} Array of all the battle members
 */
BattleManager.allBattleMembers = function() {
    return $gameParty.battleMembers().concat($gameTroop.members());
};
/**
 * Determine the orders actions will execute
 *
 * @static
 */
BattleManager.makeActionOrders = function() {
    const battlers = [];
    if (!this._surprise) {
        battlers.push(...$gameParty.battleMembers());
    }
    if (!this._preemptive) {
        battlers.push(...$gameTroop.members());
    }
    for (const battler of battlers) {
        battler.makeSpeed();
    }
    battlers.sort((a, b) => b.speed() - a.speed());
    this._actionBattlers = battlers;
};
/**
 * Start a battle action
 *
 * @static
 */
BattleManager.startAction = function() {
    const subject = this._subject;
    const action = subject.currentAction();
    const targets = action.makeTargets();
    this._phase = "action";
    this._action = action;
    this._targets = targets;
    subject.cancelMotionRefresh();
    subject.useItem(action.item());
    this._action.applyGlobal();
    this._logWindow.startAction(subject, action, targets);
};
/**
 * Update for a battle action
 *
 * @static
 */
BattleManager.updateAction = function() {
    const target = this._targets.shift();
    if (target) {
        this.invokeAction(this._subject, target);
    } else {
        this.endAction();
    }
};
/**
 * End a battle action
 *
 * @static
 */
BattleManager.endAction = function() {
    this._logWindow.endAction(this._subject);
    this._phase = "turn";
    if (this._subject.numActions() === 0) {
        this.endBattlerActions(this._subject);
        this._subject = null;
    }
};
/**
 * Invokes an action
 *
 * @static
 * @param {Game_Battler} subject - The action's subject
 * @param {Game_Battler} target - The action's target
 */
BattleManager.invokeAction = function(subject, target) {
    this._logWindow.push("pushBaseLine");
    if (Math.random() < this._action.itemCnt(target)) {
        this.invokeCounterAttack(subject, target);
    } else if (Math.random() < this._action.itemMrf(target)) {
        this.invokeMagicReflection(subject, target);
    } else {
        this.invokeNormalAction(subject, target);
    }
    subject.setLastTarget(target);
    this._logWindow.push("popBaseLine");
};
/**
 * Invokes a normal action
 *
 * @static
 * @param {Game_Battler} subject - The action's subject
 * @param {Game_Battler} target - The action's target
 */
BattleManager.invokeNormalAction = function(subject, target) {
    const realTarget = this.applySubstitute(target);
    this._action.apply(realTarget);
    this._logWindow.displayActionResults(subject, realTarget);
};
/**
 * Invokes a counter attack
 *
 * @static
 * @param {Game_Battler} subject - The action's subject
 * @param {Game_Battler} target - The action's target
 */
BattleManager.invokeCounterAttack = function(subject, target) {
    const action = new Game_Action(target);
    action.setAttack();
    action.apply(subject);
    this._logWindow.displayCounter(target);
    this._logWindow.displayActionResults(target, subject);
};
/**
 * Invokes a magic reflection
 *
 * @static
 * @param {Game_Battler} subject - The action's subject
 * @param {Game_Battler} target - The action's target
 */
BattleManager.invokeMagicReflection = function(subject, target) {
    this._action._reflectionTarget = target;
    this._logWindow.displayReflection(target);
    this._action.apply(subject);
    this._logWindow.displayActionResults(target, subject);
};
/**
 * Check if there is a substitute that will replace the target
 *
 * @static
 * @param {Game_Battler} target - The original target
 * @return {Game_Battler} The new target (possibly just the original target if no substitute found)
 */
BattleManager.applySubstitute = function(target) {
    if (this.checkSubstitute(target)) {
        const substitute = target.friendsUnit().substituteBattler(target);
        if (substitute) {
            this._logWindow.displaySubstitute(substitute, target);
            return substitute;
        }
    }
    return target;
};
/**
 * Check if should try to substitute the target
 *
 * @static
 * @param {Game_Battler} target - The original target
 * @return {boolean} True if should attempt to substitute
 */
BattleManager.checkSubstitute = function(target) {
    return target.isDying() && !this._action.isCertainHit();
};
/**
 * Check if action is forced
 *
 * @static
 * @return {boolean} True if action is forced
 */
BattleManager.isActionForced = function() {
    return !!this._actionForcedBattler;
};
/**
 * Force an action for a battler
 *
 * @static
 * @param {Game_Battler} battler - The battler to force an action
 */
BattleManager.forceAction = function(battler) {
    if (battler.numActions() > 0) {
        this._actionForcedBattler = battler;
        this._actionBattlers.remove(battler);
    }
};
/**
 * Process a forced action
 *
 * @static
 */
BattleManager.processForcedAction = function() {
    if (this._actionForcedBattler) {
        if (this._subject) {
            this.endBattlerActions(this._subject);
        }
        this._subject = this._actionForcedBattler;
        this._actionForcedBattler = null;
        this.startAction();
        this._subject.removeCurrentAction();
    }
};
/**
 * Set the battle phase to aborting
 *
 * @static
 */
BattleManager.abort = function() {
    this._phase = "aborting";
};
/**
 * Check if the battle is over (escaped, game party dead, troop dead, etc).
 *
 * @static
 * @return {boolean} True if the battle is over
 */
BattleManager.checkBattleEnd = function() {
    if (this._phase) {
        if ($gameParty.isEscaped()) {
            this.processPartyEscape();
            return true;
        } else if ($gameParty.isAllDead()) {
            this.processDefeat();
            return true;
        } else if ($gameTroop.isAllDead()) {
            this.processVictory();
            return true;
        }
    }
    return false;
};
/**
 * Check if the battle is aborting
 *
 * @static
 * @return {boolean} True if aborting the battle
 */
BattleManager.checkAbort = function() {
    if (this.isAborting()) {
        this.processAbort();
        return true;
    }
    return false;
};
/**
 * Processing for a battle victory
 *
 * @static
 */
BattleManager.processVictory = function() {
    $gameParty.removeBattleStates();
    $gameParty.performVictory();
    this.playVictoryMe();
    this.replayBgmAndBgs();
    this.makeRewards();
    this.displayVictoryMessage();
    this.displayRewards();
    this.gainRewards();
    this.endBattle(0);
};
/**
 * Processing for an escape attempt
 *
 * @static
 * @return {boolean} True if the escape succeeded
 */
BattleManager.processEscape = function() {
    $gameParty.performEscape();
    SoundManager.playEscape();
    const success = this._preemptive || Math.random() < this._escapeRatio;
    if (success) {
        this.onEscapeSuccess();
    } else {
        this.onEscapeFailure();
    }
    return success;
};
/**
 * When an escape attempt succeeds
 *
 * @static
 */
BattleManager.onEscapeSuccess = function() {
    this.displayEscapeSuccessMessage();
    this._escaped = true;
    this.processAbort();
};
/**
 * When an escape attempt fails
 *
 * @static
 */
BattleManager.onEscapeFailure = function() {
    $gameParty.onEscapeFailure();
    this.displayEscapeFailureMessage();
    this._escapeRatio += 0.1;
    if (!this.isTpb()) {
        this.startTurn();
    }
};
/**
 * Processing for the party escape
 *
 * @static
 * @since Version 1.4.0
 */
BattleManager.processPartyEscape = function() {
    this._escaped = true;
    this.processAbort();
};
/**
 * Processing for aborting the battle
 *
 * @static
 */
BattleManager.processAbort = function() {
    $gameParty.removeBattleStates();
    this._logWindow.clear();
    this.replayBgmAndBgs();
    this.endBattle(1);
};
/**
 * Processing for a battle defeat
 *
 * @static
 */
BattleManager.processDefeat = function() {
    this.displayDefeatMessage();
    this.playDefeatMe();
    if (this._canLose) {
        this.replayBgmAndBgs();
    } else {
        AudioManager.stopBgm();
    }
    this.endBattle(2);
};
/**
 * Handles ending the battle
 *
 * @static
 * @param {number} result - The result of the battle. 0 = win, 1 = escape, 2 = loss
 */
BattleManager.endBattle = function(result) {
    this._phase = "battleEnd";
    this.cancelActorInput();
    this._inputting = false;
    if (this._eventCallback) {
        this._eventCallback(result);
    }
    if (result === 0) {
        $gameSystem.onBattleWin();
    } else if (this._escaped) {
        $gameSystem.onBattleEscape();
    }
    $gameTemp.clearCommonEventReservation();
};
/**
 * Update for the end of the battle
 *
 * @static
 */
BattleManager.updateBattleEnd = function() {
    if (this.isBattleTest()) {
        AudioManager.stopBgm();
        SceneManager.exit();
    } else if (!this._escaped && $gameParty.isAllDead()) {
        if (this._canLose) {
            $gameParty.reviveBattleMembers();
            SceneManager.pop();
        } else {
            SceneManager.goto(Scene_Gameover);
        }
    } else {
        SceneManager.pop();
    }
    this._phase = "";
};
/**
 * Create the reward object for the battle (gold, exp, items)
 *
 * @static
 */
BattleManager.makeRewards = function() {
    this._rewards = {
        gold: $gameTroop.goldTotal(),
        exp: $gameTroop.expTotal(),
        items: $gameTroop.makeDropItems()
    };
};
/**
 * Displays the victory message
 *
 * @static
 */
BattleManager.displayVictoryMessage = function() {
    $gameMessage.add(TextManager.victory.format($gameParty.name()));
};
/**
 * Displays the defeat message
 *
 * @static
 */
BattleManager.displayDefeatMessage = function() {
    $gameMessage.add(TextManager.defeat.format($gameParty.name()));
};
/**
 * Displays the escape success message
 *
 * @static
 */
BattleManager.displayEscapeSuccessMessage = function() {
    $gameMessage.add(TextManager.escapeStart.format($gameParty.name()));
};
/**
 * Displays the escape failure message
 *
 * @static
 */
BattleManager.displayEscapeFailureMessage = function() {
    $gameMessage.add(TextManager.escapeStart.format($gameParty.name()));
    $gameMessage.add("\\." + TextManager.escapeFailure);
};
/**
 * Displays the various reward types
 *
 * @static
 */
BattleManager.displayRewards = function() {
    this.displayExp();
    this.displayGold();
    this.displayDropItems();
};
/**
 * Displays the exp reward
 *
 * @static
 */
BattleManager.displayExp = function() {
    const exp = this._rewards.exp;
    if (exp > 0) {
        const text = TextManager.obtainExp.format(exp, TextManager.exp);
        $gameMessage.add("\\." + text);
    }
};
/**
 * Displays the gold reward
 *
 * @static
 */
BattleManager.displayGold = function() {
    const gold = this._rewards.gold;
    if (gold > 0) {
        $gameMessage.add("\\." + TextManager.obtainGold.format(gold));
    }
};
/**
 * Displays the item rewards
 *
 * @static
 */
BattleManager.displayDropItems = function() {
    const items = this._rewards.items;
    if (items.length > 0) {
        $gameMessage.newPage();
        for (const item of items) {
            $gameMessage.add(TextManager.obtainItem.format(item.name));
        }
    }
};
/**
 * Gives the various rewards to the party
 *
 * @static
 */
BattleManager.gainRewards = function() {
    this.gainExp();
    this.gainGold();
    this.gainDropItems();
};
/**
 * Gives the exp to the actors
 *
 * @static
 */
BattleManager.gainExp = function() {
    const exp = this._rewards.exp;
    for (const actor of $gameParty.allMembers()) {
        actor.gainExp(exp);
    }
};
/**
 * Gives the gold to the party
 *
 * @static
 */
BattleManager.gainGold = function() {
    $gameParty.gainGold(this._rewards.gold);
};
/**
 * Gives the reward items to the party
 *
 * @static
 */
BattleManager.gainDropItems = function() {
    const items = this._rewards.items;
    for (const item of items) {
        $gameParty.gainItem(item, 1);
    }
};