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

590 lines
21 KiB
JavaScript

//=============================================================================
// RPGツクールMZ - LL_EquipQuickChange.js v1.2.0
//-----------------------------------------------------------------------------
// ルルの教会 (Lulu's Church)
// https://nine-yusha.com/
//
// URL below for license details.
// https://nine-yusha.com/plugin/
//=============================================================================
/*:
* @target MZ
* @plugindesc 「今すぐ装備」コマンドを実装します。
* @author ルルの教会
* @url https://nine-yusha.com/plugin-quickequip/
*
* @help LL_EquipQuickChange.js
*
* 対象の装備品を誰に装備するか選択するウィンドウを表示します。
* 装備品入手時に、いわゆる「今すぐ装備する」コマンドを実装できます。
* プラグインコマンドで実行してください。
*
* プラグインコマンド:
* 武器装備選択: 対象の武器を選択し、装備切替画面を表示します。
* 防具装備選択: 対象の防具を選択し、装備切替画面を表示します。
* ※対象の装備品を所持していない場合、プラグインコマンドは無視されます。
*
* 利用規約:
* ・著作権表記は必要ございません。
* ・利用するにあたり報告の必要は特にございません。
* ・商用・非商用問いません。
* ・R18作品にも使用制限はありません。
* ・ゲームに合わせて自由に改変していただいて問題ございません。
* ・プラグイン素材としての再配布(改変後含む)は禁止させていただきます。
*
* 作者: ルルの教会
* 作成日: 2022/8/18
*
* @param shopSettings
* @text ショップ連動設定
* @desc ※この項目は使用しません
*
* @param shopEnabled
* @text 装備品購入時に自動表示
* @desc ショップで装備品を購入した時に装備切替画面を表示します。
* @default true
* @type boolean
* @parent shopSettings
*
* @param shopDisabledswitchId
* @text 購入時無効化スイッチID
* @desc ショップで装備品を購入した時、
* このスイッチがONの時は装備切替画面を一時的に表示しません。
* @type switch
* @parent shopSettings
*
* @param shopMultipleEquip
* @text 複数購入時に連続選択
* @desc ショップで装備品を複数購入した場合に、
* 購入数分選択画面を繰り返し表示します。
* @default false
* @type boolean
* @parent shopSettings
*
* @param iniInfoText
* @text 質問メッセージ
* @desc 「質問メッセージ」の文言設定です。
* @default 装備しますか?
* @type string
*
* @param iniEquipNgText
* @text 装備不可メッセージ
* @desc 「装備不可」の文言設定です。
* @default 装備できません。
* @type string
*
* @param iniCancelText
* @text キャンセルコマンド名
* @desc 「キャンセル」コマンドの文言設定です。
* @default 装備しない
* @type string
*
* @command changeWeapon
* @text 武器装備選択
* @desc 対象の武器を選択し、装備切替画面を表示します。
* 対象の装備品を所持していない場合、このコマンドは無視されます。
*
* @arg weaponId
* @text 武器ID
* @desc 変更対象の武器を選択します。
* @type weapon
*
* @arg infoText
* @text 質問メッセージ
* @desc 「質問文」の文言設定です。
* @default 装備しますか?
* @type string
*
* @arg gainCount
* @text 獲得数
* @desc この回数分選択画面を繰り返し表示します。
* パーティ人数を上回った場合、パーティ人数が上限となります。
* @default 1
* @min 1
* @max 99
* @type number
*
* @command changeArmor
* @text 防具装備選択
* @desc 対象の防具を選択し、装備切替画面を表示します。
* 対象の装備品を所持していない場合、このコマンドは無視されます。
*
* @arg armorId
* @text 防具ID
* @desc 変更対象の防具を選択します。
* @type armor
*
* @arg infoText
* @text 質問メッセージ
* @desc 「質問文」の文言設定です。
* @default 装備しますか?
* @type string
*
* @arg gainCount
* @text 獲得数
* @desc この回数分選択画面を繰り返し表示します。
* パーティ人数を上回った場合、パーティ人数が上限となります。
* @default 1
* @min 1
* @max 99
* @type number
*/
(() => {
"use strict";
const pluginName = "LL_EquipQuickChange";
const parameters = PluginManager.parameters(pluginName);
const shopEnabled = eval(parameters["shopEnabled"] || "true");
const shopDisabledswitchId = Number(parameters["shopDisabledswitchId"] || 0);
const shopMultipleEquip = eval(parameters["shopMultipleEquip"] || "false");
const iniInfoText = String(parameters["iniInfoText"] || "装備しますか?");
const iniEquipNgText = String(parameters["iniEquipNgText"] || "装備できません。");
const iniCancelText = String(parameters["iniCancelText"] || "装備しない");
// 独自変数定義
let infoText = "";
let exGoods = null;
let exPurchaseOnly = null;
let exBuyWindowLastIndex = 0;
let exBuyCount = 1;
PluginManager.registerCommand(pluginName, "changeWeapon", args => {
const weaponId = Number(args.weaponId || null);
if (weaponId) {
// 対象装備品を所持しているか?
if ($gameParty.hasItem($dataWeapons[weaponId], true)) {
// 武器情報を取得
ExEquipTargetItem.set($dataWeapons[weaponId]);
// 文言をセット
infoText = String(args.infoText || "");
// ショップ判定オフ
exGoods = null;
exPurchaseOnly = null;
exBuyWindowLastIndex = 0;
exBuyCount = Number(args.gainCount || 1);
// 装備選択画面へ
SceneManager.push(Scene_EquipQuickChange);
} else {
console.log(pluginName + ": 対象の装備品を所持していなかったため、コマンドがスキップされました");
}
}
});
PluginManager.registerCommand(pluginName, "changeArmor", args => {
const armorId = Number(args.armorId || null);
if (armorId) {
// 対象装備品を所持しているか?
if ($gameParty.hasItem($dataArmors[armorId], true)) {
// 防具情報を取得
ExEquipTargetItem.set($dataArmors[armorId]);
// 文言をセット
infoText = String(args.infoText || "");
// ショップ判定オフ
exGoods = null;
exPurchaseOnly = null;
exBuyWindowLastIndex = 0;
exBuyCount = Number(args.gainCount || 1);
// 装備選択画面へ
SceneManager.push(Scene_EquipQuickChange);
} else {
console.log(pluginName + ": 対象の装備品を所持していなかったため、コマンドがスキップされました");
}
}
});
//-----------------------------------------------------------------------------
// ExEquipTargetItem
//
class ExEquipTargetItem {
constructor() {
this.item = null;
}
static get() {
return this.item;
}
static set(item) {
this.item = item;
}
static getSlotId() {
return this.item.etypeId - 1;
}
static getEtypeId() {
return this.item.etypeId;
}
}
//-----------------------------------------------------------------------------
// Scene_EquipQuickChange
//
// 対象の装備品と変更する独自のシーンを追加定義します。
function Scene_EquipQuickChange() {
this.initialize(...arguments);
}
Scene_EquipQuickChange.prototype = Object.create(Scene_MenuBase.prototype);
Scene_EquipQuickChange.prototype.constructor = Scene_EquipQuickChange;
Scene_EquipQuickChange.prototype.initialize = function() {
Scene_MenuBase.prototype.initialize.call(this);
this._equipCount = $gameParty.size() < exBuyCount ? $gameParty.size() : exBuyCount;
};
Scene_EquipQuickChange.prototype.start = function() {
Scene_MenuBase.prototype.start.call(this);
this._statusWindow.refresh();
};
Scene_EquipQuickChange.prototype.helpAreaHeight = function() {
return this.calcWindowHeight(2, false);
};
Scene_EquipQuickChange.prototype.create = function() {
Scene_MenuBase.prototype.create.call(this);
this.createHelpWindow();
this.createInfoWindow();
this.createStatusWindow();
this.createCommandWindow();
this._helpWindow.setText(this.helpWindowText());
this.infoWindowSetText();
};
Scene_EquipQuickChange.prototype.createInfoWindow = function() {
const rect = this.infoWindowRect();
this._infoWindow = new Window_Help(rect);
this.addWindow(this._infoWindow);
};
Scene_EquipQuickChange.prototype.infoWindowRect = function() {
const wx = this.isRightInputMode() ? this.statusWindowRect().width : 0;
const wy = this.mainAreaTop();
const ww = Graphics.boxWidth - this.statusWindowRect().width;
const wh = this.calcWindowHeight(2, false);
return new Rectangle(wx, wy, ww, wh);
};
Scene_EquipQuickChange.prototype.createStatusWindow = function() {
const rect = this.statusWindowRect();
this._statusWindow = new Window_EquipStatusQuickChange(rect);
this.addWindow(this._statusWindow);
};
Scene_EquipQuickChange.prototype.statusWindowRect = function() {
const ww = this.statusWidth();
const wh = this.mainAreaHeight();
const wx = this.isRightInputMode() ? 0 : Graphics.boxWidth - ww;
const wy = this.mainAreaTop();
return new Rectangle(wx, wy, ww, wh);
};
Scene_EquipQuickChange.prototype.createCommandWindow = function() {
const rect = this.commandWindowRect();
const commandWindow = new Window_EquipQuickActor(rect);
commandWindow.setHandler("ok", this.checkPopScene.bind(this));
commandWindow.setHandler("cancel", this.popScene.bind(this));
commandWindow.setStatusWindow(this._statusWindow);
this.addWindow(commandWindow);
this._commandWindow = commandWindow;
};
Scene_EquipQuickChange.prototype.commandWindowRect = function() {
const ww = Graphics.boxWidth - this.statusWindowRect().width;
const wh = this.mainAreaHeight() - this._helpWindow.height;
const wx = this.isRightInputMode() ? Graphics.boxWidth - ww : 0;
const wy = this.mainAreaTop() + this._helpWindow.height;
return new Rectangle(wx, wy, ww, wh);
};
Scene_EquipQuickChange.prototype.helpWindowText = function() {
const targetItem = ExEquipTargetItem.get();
return targetItem.description;
};
Scene_EquipQuickChange.prototype.infoWindowSetText = function() {
const targetItem = ExEquipTargetItem.get();
const width = this._infoWindow.innerWidth;
const y2 = this._infoWindow.lineHeight();
const numberWidth = this._infoWindow.textWidth(":00");
const equipCount = this._equipCount;
this._infoWindow.drawItemName(targetItem, 0, 0, width - numberWidth);
this._infoWindow.drawText(":", width - numberWidth, 0, this._infoWindow.textWidth(":"), "right");
this._infoWindow.drawText(equipCount, width - numberWidth + this._infoWindow.textWidth(":"), 0, this._infoWindow.textWidth("00"), "right");
this._infoWindow.drawText(infoText, 0, y2, width);
};
Scene_EquipQuickChange.prototype.statusWidth = function() {
return 312;
};
Scene_EquipQuickChange.prototype.popScene = function() {
SceneManager.pop();
// ショップ判定
if (exGoods !== null) {
SceneManager.prepareNextScene(exGoods, exPurchaseOnly);
SceneManager._nextScene.buyWindowFocusOn();
}
};
Scene_EquipQuickChange.prototype.checkPopScene = function() {
// 装備回数が0になったら終了
this._equipCount -= 1;
if (this._equipCount > 0) {
this._commandWindow.activate();
this._commandWindow.refresh();
this._statusWindow.refresh();
this._infoWindow.refresh();
this.infoWindowSetText();
} else {
this.popScene();
}
};
//-----------------------------------------------------------------------------
// Window_EquipStatusQuickChange
//
// The window for displaying parameter changes on the equipment screen.
function Window_EquipStatusQuickChange() {
this.initialize(...arguments);
}
Window_EquipStatusQuickChange.prototype = Object.create(Window_EquipStatus.prototype);
Window_EquipStatusQuickChange.prototype.constructor = Window_EquipStatusQuickChange;
Window_EquipStatusQuickChange.prototype.initialize = function(rect) {
Window_EquipStatus.prototype.initialize.call(this, rect);
};
Window_EquipStatusQuickChange.prototype.refreshDisabled = function() {
this.contents.clear();
if (this._actor) {
const nameRect = this.itemLineRect(0);
this.drawActorName(this._actor, nameRect.x, 0, nameRect.width);
this.drawActorFace(this._actor, nameRect.x, nameRect.height);
this.drawAllParamsDisabled();
}
};
Window_EquipStatusQuickChange.prototype.drawAllParamsDisabled = function() {
const x = this.itemPadding();
const y = this.paramY(0);
const width = this.innerWidth - this.itemPadding() * 2;
this.changeTextColor(ColorManager.powerDownColor());
// 装備不可
this.drawText(iniEquipNgText, x, y, width);
};
//-----------------------------------------------------------------------------
// Window_EquipQuickActor
//
// 装備を変更する対象アクターを選択するウィンドウです。
function Window_EquipQuickActor() {
this.initialize(...arguments);
}
Window_EquipQuickActor.prototype = Object.create(Window_Command.prototype);
Window_EquipQuickActor.prototype.constructor = Window_EquipQuickActor;
Window_EquipQuickActor.prototype.initialize = function(rect) {
Window_Command.prototype.initialize.call(this, rect);
};
Window_EquipQuickActor.prototype.makeCommandList = function() {
this.addPartyMembers();
};
Window_EquipQuickActor.prototype.addPartyMembers = function() {
const _this = this;
const targetItem = ExEquipTargetItem.get();
const slotId = ExEquipTargetItem.getSlotId();
this.addCommand(iniCancelText, "cancel");
$gameParty.members().forEach(function(item) {
if (item.canEquip(targetItem) && item.isEquipChangeOk(slotId)) {
_this.addCommand(item._name, item._actorId, true);
} else {
_this.addCommand(item._name, item._actorId, false);
}
});
};
Window_EquipQuickActor.prototype.drawItem = function(index) {
const actorName = this.commandName(index);
const equippedName = this.equippedName(index);
const rect = this.itemLineRect(index);
const equippedWidth = this.equippedWidth();
const actorNameWidth = rect.width - equippedWidth;
this.resetTextColor();
this.changePaintOpacity(this.isCommandEnabled(index));
this.drawText(actorName, rect.x, rect.y, actorNameWidth, "left");
this.drawItemName(equippedName, rect.x + actorNameWidth, rect.y, equippedWidth);
};
Window_EquipQuickActor.prototype.equippedWidth = function() {
return 240;
};
Window_EquipQuickActor.prototype.equippedName = function(index) {
const symbol = this.commandSymbol(index);
const value = this.getEquippedItem(symbol);
return value ? value : null;
};
Window_EquipQuickActor.prototype.getEquippedItem = function(symbol) {
const actor = $gameActors.actor(symbol);
const slotId = ExEquipTargetItem.getSlotId();
return actor ? actor.equips()[slotId] : null;
};
Window_EquipQuickActor.prototype.setStatusWindow = function(statusWindow) {
this._statusWindow = statusWindow;
this.refreshActor();
};
Window_EquipQuickActor.prototype.cursorUp = function(wrap) {
Window_Selectable.prototype.cursorUp.call(this, wrap);
this.refreshActor();
};
Window_EquipQuickActor.prototype.cursorDown = function(wrap) {
Window_Selectable.prototype.cursorDown.call(this, wrap);
this.refreshActor();
};
Window_EquipQuickActor.prototype.onTouchSelect = function(trigger) {
Window_Selectable.prototype.onTouchSelect.call(this, trigger);
this.refreshActor();
};
Window_EquipQuickActor.prototype.refreshActor = function() {
const index = this.index();
const symbol = this.commandSymbol(index);
if (this._statusWindow) {
// キャンセルの場合
if (symbol === "cancel") {
this._statusWindow.contents.clear();
return;
}
const actor = $gameActors.actor(symbol);
const targetItem = ExEquipTargetItem.get();
const slotId = ExEquipTargetItem.getSlotId();
this._statusWindow.setActor(actor);
// 装備後のパラメータを表示
if (actor.canEquip(targetItem) && actor.isEquipChangeOk(slotId)) {
const actorTmp = JsonEx.makeDeepCopy(actor);
actorTmp.forceChangeEquip(slotId, targetItem);
this._statusWindow.setTempActor(actorTmp);
} else {
this._statusWindow.refreshDisabled();
}
}
};
Window_EquipQuickActor.prototype.processOk = function() {
if (this.isCurrentItemEnabled()) {
this.playOkSound();
this.equipChange();
this.deactivate();
this.callOkHandler();
} else {
this.playBuzzerSound();
}
};
Window_EquipQuickActor.prototype.equipChange = function() {
const index = this.index();
const symbol = this.commandSymbol(index);
// キャンセルの場合
if (symbol === "cancel") return;
const targetItem = ExEquipTargetItem.get();
const etypeId = ExEquipTargetItem.getEtypeId();
$gameActors.actor(symbol).changeEquipById(etypeId, targetItem.id);
};
Window_EquipQuickActor.prototype.playOkSound = function() {
const index = this.index();
const symbol = this.commandSymbol(index);
// 決定音 or 装備音
symbol === "cancel" ? SoundManager.playOk() : SoundManager.playEquip();
};
//-----------------------------------------------------------------------------
// Scene_Shop を拡張
//
const _Scene_Shop_initialize = Scene_Shop.prototype.initialize;
Scene_Shop.prototype.initialize = function() {
_Scene_Shop_initialize.apply(this, arguments);
this._buyWindowFocus = false;
};
const _Scene_Shop_create = Scene_Shop.prototype.create;
Scene_Shop.prototype.create = function() {
_Scene_Shop_create.apply(this, arguments);
this.buyWindowFocus();
};
Scene_Shop.prototype.buyWindowFocusOn = function() {
this._buyWindowFocus = true;
};
Scene_Shop.prototype.buyWindowFocus = function() {
if (!this._buyWindowFocus) return;
this._commandWindow.deactivate();
this._buyWindow.setMoney(this.money());
this._buyWindow.show();
this._buyWindow.activate();
this._statusWindow.show();
// カーソルを合わせる
if (exBuyWindowLastIndex > 0) {
this._buyWindow.forceSelect(exBuyWindowLastIndex);
}
};
const _Scene_Shop_onNumberOk = Scene_Shop.prototype.onNumberOk;
Scene_Shop.prototype.onNumberOk = function() {
// 購入かつ装備品の場合
if (this._commandWindow.currentSymbol() === "buy" && this._item.etypeId) {
// ショップ連動設定が有効の場合
if (shopEnabled && !$gameSwitches.value(shopDisabledswitchId)) {
this.gotoEquipQuickChange();
return;
}
}
_Scene_Shop_onNumberOk.apply(this, arguments);
}
Scene_Shop.prototype.gotoEquipQuickChange = function() {
SoundManager.playShop();
this.doBuy(this._numberWindow.number());
// 装備情報を取得
const targetItem = this._item;
ExEquipTargetItem.set(targetItem);
// 文言をセット
infoText = iniInfoText;
// ショップ情報を保持
exGoods = this._goods;
exPurchaseOnly = this._purchaseOnly;
exBuyWindowLastIndex = this._buyWindow.index();
exBuyCount = shopMultipleEquip ? this._numberWindow.number() : 1;
// 装備選択画面へ
SceneManager.push(Scene_EquipQuickChange);
}
})();