520 lines
17 KiB
JavaScript
520 lines
17 KiB
JavaScript
//=============================================================================
|
||
// IIIBattleResult.js
|
||
// ----------------------------------------------------------------------------
|
||
// (C) 2022 III
|
||
// This software is released under the MIT License.
|
||
// http://opensource.org/licenses/mit-license.php
|
||
// ----------------------------------------------------------------------------
|
||
/*:ja
|
||
* @target MZ
|
||
* @plugindesc バトルリザルトシーンの拡張、NUNU_Reslt.jsを参考にカスタマイズしております。
|
||
* @author ズワイKANI
|
||
*/
|
||
|
||
(() => {
|
||
// ----------------------------------------------------------------
|
||
// Scene_Battle
|
||
//
|
||
const _Scene_Battle_createAllWindows =
|
||
Scene_Battle.prototype.createAllWindows;
|
||
Scene_Battle.prototype.createAllWindows = function () {
|
||
_Scene_Battle_createAllWindows.call(this);
|
||
//BeforeStatueMemo.call(this);
|
||
this.createResultWindow();
|
||
};
|
||
|
||
Scene_Battle.prototype.createResultWindow = function () {
|
||
var win = new Window_Result();
|
||
this.addWindow(win);
|
||
this._resultWindow = win;
|
||
};
|
||
|
||
// const BeforeStatueMemo = function()
|
||
// {
|
||
// var state = [
|
||
// $gameActors.actor(1).param(0), //hp
|
||
// $gameActors.actor(1).param(1), //mp
|
||
// $gameActors.actor(1).paramBase(2), //atk
|
||
// $gameActors.actor(1).param(3), //def
|
||
// $gameActors.actor(1).param(4), //matk
|
||
// $gameActors.actor(1).param(6), //agi
|
||
// ];
|
||
|
||
// //for(i=0; i < 7; i++){ console.log(state[i]);}
|
||
// return state;
|
||
// }
|
||
|
||
ImageManager.clearFromUrl = function (delUrl) {
|
||
const cache = this._cache;
|
||
for (const url in cache) {
|
||
if (url == delUrl) {
|
||
cache[url].destroy();
|
||
delete cache[url];
|
||
break;
|
||
}
|
||
}
|
||
};
|
||
|
||
// ----------------------------------------------------------------
|
||
// BattleManager
|
||
const _BattleManager_startBattle = BattleManager.startBattle;
|
||
BattleManager.startBattle = function () {
|
||
_BattleManager_startBattle.call(this);
|
||
this._totalTurn = 0;
|
||
};
|
||
|
||
const _BattleManager_startTurn = BattleManager.startTurn;
|
||
BattleManager.startTurn = function () {
|
||
_BattleManager_startTurn.call(this);
|
||
this._totalTurn++;
|
||
};
|
||
|
||
const _BattleManager_gainDropItems = BattleManager.gainDropItems;
|
||
BattleManager.gainDropItems = function () {
|
||
// 瞬殺ボーナス対象のアイテムがあればドロップに追加
|
||
if (this._totalTurn <= 1 && this._rewards.items.length > 0) {
|
||
const targetItems = this._rewards.items.filter((x) => x.meta.BattleB);
|
||
for (const item of targetItems) {
|
||
this._rewards.items.push(item);
|
||
}
|
||
}
|
||
|
||
// 通常の付与処理
|
||
_BattleManager_gainDropItems.call(this);
|
||
};
|
||
|
||
const _BattleManager_processVictory = BattleManager.processVictory;
|
||
BattleManager.processVictory = function () {
|
||
// 通常のバトル勝利時の処理
|
||
$gameParty.removeBattleStates();
|
||
$gameParty.performVictory();
|
||
this.playVictoryMe();
|
||
this.replayBgmAndBgs();
|
||
this.makeRewards();
|
||
const resultInfo = new ResultInfo();
|
||
|
||
// this.displayVictoryMessage();
|
||
// this.displayRewards();
|
||
this.gainRewards();
|
||
resultInfo.UpdateActorInfo();
|
||
|
||
this.endBattle(0);
|
||
|
||
// リザルトウインドウ開く
|
||
const scn = SceneManager._scene;
|
||
const resultWindow = scn?._resultWindow;
|
||
resultWindow?.start(resultInfo);
|
||
};
|
||
|
||
const _BattleManager_updateBattleEnd = BattleManager.updateBattleEnd;
|
||
BattleManager.updateBattleEnd = function () {
|
||
const scn = SceneManager._scene;
|
||
const resultWindow = scn?._resultWindow;
|
||
const resultWindowExists = !!resultWindow;
|
||
if (resultWindowExists == false) {
|
||
_BattleManager_updateBattleEnd.call(this);
|
||
return;
|
||
}
|
||
if (resultWindow.active || resultWindow.isClosing()) {
|
||
return;
|
||
}
|
||
_BattleManager_updateBattleEnd.call(this);
|
||
};
|
||
|
||
// ----------------------------------------------------------------
|
||
// Game_Actor
|
||
//
|
||
const _Game_Actor_prototype_shouldDisplayLevelUp =
|
||
Game_Actor.prototype.shouldDisplayLevelUp;
|
||
Game_Actor.prototype.shouldDisplayLevelUp = function () {
|
||
//return _Game_Actor_prototype_shouldDisplayLevelUp.call(this);
|
||
return false; //経験値獲得時のレベルアップ表示は無し
|
||
};
|
||
|
||
// ----------------------------------------------------------------
|
||
// ResultInfo
|
||
// バトル報酬、Actorの報酬獲得前後の情報など保持
|
||
//
|
||
class ResultInfo {
|
||
constructor() {
|
||
this.exp = BattleManager._rewards.exp;
|
||
this.gold = BattleManager._rewards.gold;
|
||
this.items = BattleManager._rewards.items;
|
||
this._actorInfos = [];
|
||
for (const actor of $gameParty.allMembers()) {
|
||
this._actorInfos[actor.actorId()] = {
|
||
actorId: actor.actorId(),
|
||
actorName: actor.name(),
|
||
beforeLevel: actor.level,
|
||
afterLevel: actor.level,
|
||
beforeSkills: actor.skills(),
|
||
isLevelUp: false,
|
||
learnSkills: null,
|
||
};
|
||
}
|
||
}
|
||
|
||
UpdateActorInfo() {
|
||
for (const actor of $gameParty.allMembers()) {
|
||
const info = this._actorInfos[actor.actorId()];
|
||
if (!info) continue;
|
||
info.afterLevel = actor.level;
|
||
info.isLevelUp = info.beforeLevel < info.afterLevel;
|
||
info.learnSkills = actor.findNewSkills(info.beforeSkills);
|
||
}
|
||
}
|
||
// 連想配列だけど気にせずループ関数使っちゃう
|
||
ExistsLevelUp() {
|
||
return this._actorInfos.some((info) => info && info.isLevelUp);
|
||
}
|
||
GetLevelUpActorInfos() {
|
||
return this._actorInfos.filter((info) => info && info.isLevelUp);
|
||
}
|
||
ExistsSkillLearn() {
|
||
return this._actorInfos.some((info) => info && info.learnSkills != null);
|
||
}
|
||
GetLearnSkillActorInfos() {
|
||
return this._actorInfos.filter(
|
||
(info) => info && info.learnSkills != null
|
||
);
|
||
}
|
||
}
|
||
|
||
// ----------------------------------------------------------------
|
||
// リザルトウインドウ
|
||
//
|
||
class Window_Result extends Window_Base {
|
||
static AutoProcessFrame = 30 * 1; // 自動でリザルト進行する間隔(フレーム数)
|
||
|
||
constructor() {
|
||
// ウインドウ座標・サイズ
|
||
var rect = new Rectangle(
|
||
50,
|
||
50,
|
||
Graphics.width / 2,
|
||
Graphics.height / 2 + 100
|
||
);
|
||
super(rect);
|
||
|
||
// 非表示・非アクティブにしておく
|
||
this.openness = 0;
|
||
this.deactivate();
|
||
|
||
// このクラスで利用するメンバの初期化
|
||
this._canRepeat = true; //OKボタンの押しっぱなしを受け付けるかどうか
|
||
this._resultInfo = null;
|
||
this._processStep = 0;
|
||
this._processFinish = false;
|
||
this._autoProcessWaitFrame = Window_Result.AutoProcessFrame;
|
||
|
||
// ウインドウの表示基本設定をセットアップ
|
||
this.setupWindowDefaultSetting();
|
||
|
||
//state
|
||
this._beforeParams = this.GetActorParams();
|
||
}
|
||
isOpenAndActive() {
|
||
return this.isOpen() && this.visible && this.active;
|
||
}
|
||
isOkTriggered() {
|
||
return this._canRepeat ? Input.isRepeated("ok") : Input.isTriggered("ok");
|
||
}
|
||
isCancelTriggered() {
|
||
return Input.isRepeated("cancel");
|
||
}
|
||
|
||
/** リザルトウインドウ表示基本設定 */
|
||
setupWindowDefaultSetting() {
|
||
// ウインドウの基本表示設定
|
||
this.cursorVisible = false; // カーソルは非表示に
|
||
this.upArrowVisible = false; // 上下の矢印は非表示に
|
||
this.downArrowVisible = false;
|
||
//this.padding = 0; // パディング・マージン(枠内背景はスケールされちゃうのでこれで0にしても画面いっぱいにはならない)
|
||
//this.margin = 0;
|
||
|
||
// ウインドウ画像変更したい場合はここで変更
|
||
this.windowSkin = ImageManager.loadSystem("Window_pop");
|
||
// ウインドウ枠非表示にする場合はfalseに
|
||
//this.frameVisible = false;
|
||
// ウインドウ枠内背景を非表示にする場合は透明度を0にする
|
||
this.backOpacity = 255;
|
||
|
||
const delUrl =
|
||
"img/pictures/BattlePic/" +
|
||
Utils.encodeURI("UI_ButtleResulte") +
|
||
".png";
|
||
ImageManager.clearFromUrl(delUrl);
|
||
|
||
// ウインドウ枠内に常駐する画像出したければ↓のように読み込み(使用画像に含まれないので注意)
|
||
this.contentsBack = ImageManager.loadBitmap(
|
||
"img/pictures/BattlePic/",
|
||
"UI_ButtleResulte"
|
||
);
|
||
this.contentsBack.x = 50;
|
||
this.contentsBack.y = 50;
|
||
}
|
||
|
||
/** リザルトウインドウ処理開始 */
|
||
start(resultInfo) {
|
||
this._resultInfo = resultInfo;
|
||
this._processStep = 0;
|
||
this._processFinish = false;
|
||
this._autoProcessWaitFrame = Window_Result.AutoProcessFrame;
|
||
this.open();
|
||
this.activate();
|
||
}
|
||
|
||
/** リザルトウインドウ処理終了 */
|
||
finish() {
|
||
this.close();
|
||
this.deactivate();
|
||
}
|
||
|
||
/** リザルト進捗更新 */
|
||
updateProcess() {
|
||
this._processStep++;
|
||
if (this._processFinish) {
|
||
this.finish();
|
||
}
|
||
}
|
||
|
||
/** 毎フレーム更新処理 */
|
||
update() {
|
||
super.update();
|
||
|
||
if (this.isOpenAndActive() == false) {
|
||
return; //ウインドウが開いてなければ何もしない
|
||
}
|
||
|
||
this._autoProcessWaitFrame--;
|
||
|
||
// 入力あったかどうか
|
||
let anyInput =
|
||
this.isOkTriggered() ||
|
||
this.isCancelTriggered() ||
|
||
TouchInput.isClicked() ||
|
||
TouchInput.isCancelled();
|
||
|
||
// 自動進行できるかどうか
|
||
let autoProcess =
|
||
this._processFinish == false && this._autoProcessWaitFrame < 0;
|
||
|
||
// リザルトプロセス進行
|
||
if (anyInput || autoProcess) {
|
||
this.updateProcess();
|
||
this._autoProcessWaitFrame = Window_Result.AutoProcessFrame;
|
||
}
|
||
|
||
// 表示更新
|
||
this.refresh();
|
||
}
|
||
|
||
/** 表示更新 */
|
||
refresh() {
|
||
if (!this.contents) return;
|
||
this.contents.clear();
|
||
|
||
const exp = this._resultInfo.exp;
|
||
const gold = this._resultInfo.gold;
|
||
const items = this._resultInfo.items;
|
||
let textX = this.padding;
|
||
let textY = this.padding;
|
||
const textH = 40;
|
||
|
||
const existsItems = items != null;
|
||
const existsLevelUp = this._resultInfo.ExistsLevelUp();
|
||
const existsSkillLearn = this._resultInfo.ExistsSkillLearn();
|
||
|
||
// 見出し
|
||
//this.drawText(TextManager.victory.format($gameParty.name()), 0, textY, this.width, "center");
|
||
this.drawText("Victory!", textX, textY, this.width, "center");
|
||
textY += textH / 2;
|
||
this.drawText(
|
||
"----------------------------------------------",
|
||
0,
|
||
textY,
|
||
this.width,
|
||
"center"
|
||
);
|
||
textY += textH;
|
||
|
||
// 経験値
|
||
if (this._processStep >= 1) {
|
||
const expText = TextManager.obtainExp.format(exp, TextManager.exp);
|
||
this.drawText(expText, textX, textY, this.width, "left");
|
||
textY += textH;
|
||
}
|
||
|
||
// お金
|
||
if (this._processStep >= 2) {
|
||
const goldText = TextManager.obtainGold.format(gold);
|
||
if (gold != 0) {
|
||
this.drawText(
|
||
this.convertEscapeCharacters(goldText),
|
||
textX,
|
||
textY,
|
||
this.width,
|
||
"left"
|
||
);
|
||
textY += textH;
|
||
}
|
||
this._processFinish = !existsItems;
|
||
}
|
||
|
||
// アイテム
|
||
if (this._processStep >= 3 && existsItems) {
|
||
// 瞬殺ボーナス有効か
|
||
const enableBonus = BattleManager._totalTurn <= 1;
|
||
|
||
// 同種・同idのアイテムはまとめる
|
||
const recieveItems = {};
|
||
for (const item of items) {
|
||
const key = `${item.itypeId}_${item.id}`;
|
||
if (!recieveItems[key]) {
|
||
recieveItems[key] = { item: item, count: 0 };
|
||
}
|
||
recieveItems[key].count++;
|
||
}
|
||
|
||
//
|
||
for (const [_, recieveItem] of Object.entries(recieveItems)) {
|
||
const item = recieveItem.item;
|
||
const count = recieveItem.count;
|
||
|
||
// 瞬殺ボーナスでの追加の場合、
|
||
const isBonusItem = enableBonus && item.meta.BattleB;
|
||
const bonusText = isBonusItem ? "(Bonus!)" : "";
|
||
if (item.itypeId == 1) {
|
||
this.drawTextEx(
|
||
`\\}\\*item[${item.id}] x${count} GET!${bonusText}\\{`,
|
||
textX,
|
||
textY,
|
||
this.width
|
||
);
|
||
} else {
|
||
this.drawTextEx(
|
||
`\\}\\*weapon[${item.id}] x${count} GET!${bonusText}\\{`,
|
||
textX,
|
||
textY,
|
||
this.width
|
||
);
|
||
}
|
||
//let itemText = TextManager.obtainItem.format(item.name);
|
||
//this.drawText(itemText, 0, textY, this.width, "center");
|
||
//this.drawTextEx("\\}\\*item["+item.id+"]"+" 入手!\\{",textX,textY,this.width);
|
||
textY += textH;
|
||
}
|
||
this._processFinish = !existsLevelUp;
|
||
}
|
||
|
||
// レベルアップ
|
||
if (this._processStep >= 4 && existsLevelUp) {
|
||
textY = 72;
|
||
const actorInfos = this._resultInfo.GetLevelUpActorInfos();
|
||
//const lv = this._resultInfo;
|
||
for (const info of actorInfos) {
|
||
const lvUpText = TextManager.levelUp.format(
|
||
info.actorName,
|
||
TextManager.level,
|
||
info.afterLevel
|
||
);
|
||
this.drawTextEx(
|
||
lvUpText +
|
||
" " +
|
||
info.beforeLevel +
|
||
" → \\c[27]" +
|
||
info.afterLevel +
|
||
"\\c[0]",
|
||
textX + this.width / 2,
|
||
textY,
|
||
this.width,
|
||
"left"
|
||
);
|
||
}
|
||
|
||
textY += textH;
|
||
|
||
this.DrawParamText(textX + this.width / 2, textY, textH);
|
||
this.DrawParams(
|
||
this._beforeParams,
|
||
textX + this.width / 2 + this.width / 8,
|
||
textY,
|
||
textH
|
||
);
|
||
this.DrawParamsEx(
|
||
this.GetActorParams(),
|
||
textX + this.width / 2 + this.width / 4,
|
||
textY,
|
||
textH
|
||
);
|
||
|
||
this._processFinish = !existsSkillLearn;
|
||
}
|
||
|
||
// スキル習得
|
||
if (this._processStep >= 5 && existsSkillLearn) {
|
||
const actorInfos = this._resultInfo.GetLearnSkillActorInfos();
|
||
for (const info of actorInfos) {
|
||
for (const skill of info.learnSkills) {
|
||
const learnSkilltext = TextManager.obtainSkill.format(skill.name);
|
||
this.drawText(learnSkilltext, textX, textY, this.width, "center");
|
||
textY += textH;
|
||
}
|
||
}
|
||
this._processFinish = true;
|
||
}
|
||
}
|
||
|
||
GetActorParams() {
|
||
return [
|
||
$gameActors.actor(1).param(0), //hp
|
||
$gameActors.actor(1).param(1), //mp
|
||
$gameActors.actor(1).paramBase(2), //atk
|
||
$gameActors.actor(1).param(3), //def
|
||
$gameActors.actor(1).param(4), //matk
|
||
$gameActors.actor(1).param(6), //agi
|
||
];
|
||
}
|
||
|
||
DrawParams(params, x, y, h) {
|
||
params.forEach((p, index) => {
|
||
this.drawText(p, x + 48, y + h * index, this.width, "left");
|
||
}, this);
|
||
}
|
||
|
||
DrawParamsEx(params, x, y, h) {
|
||
params.forEach((p, index) => {
|
||
this.drawTextEx(
|
||
"\\c[27]" + p + "\\c[0]",
|
||
x + 48,
|
||
y + h * index,
|
||
this.width,
|
||
"left"
|
||
);
|
||
}, this);
|
||
}
|
||
|
||
DrawParamText(x, y, h) {
|
||
this.drawText(TextManager.param(0), x, y + h * 0, this.width, "left");
|
||
this.drawText(TextManager.param(1), x, y + h * 1, this.width, "left");
|
||
this.drawText(TextManager.param(2), x, y + h * 2, this.width, "left");
|
||
this.drawText(TextManager.param(3), x, y + h * 3, this.width, "left");
|
||
this.drawText(TextManager.param(4), x, y + h * 4, this.width, "left");
|
||
this.drawText(TextManager.param(6), x, y + h * 5, this.width, "left");
|
||
this.drawText(
|
||
$dataSystemTexts.Battle_UPG,
|
||
x,
|
||
y + h * 6,
|
||
this.width,
|
||
"left"
|
||
);
|
||
|
||
this.drawText("→", x + x / 2 + 8, y + h * 0, this.width, "left");
|
||
this.drawText("→", x + x / 2 + 8, y + h * 1, this.width, "left");
|
||
this.drawText("→", x + x / 2 + 8, y + h * 2, this.width, "left");
|
||
this.drawText("→", x + x / 2 + 8, y + h * 3, this.width, "left");
|
||
this.drawText("→", x + x / 2 + 8, y + h * 4, this.width, "left");
|
||
this.drawText("→", x + x / 2 + 8, y + h * 5, this.width, "left");
|
||
}
|
||
}
|
||
})();
|