magical-girls-runa-and-nanami/js/plugins/CGPT_state.js
2026-03-07 11:25:22 -06:00

163 lines
6.9 KiB
JavaScript
Raw Permalink Blame History

This file contains ambiguous Unicode characters

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

/*:
* @target MZ
* @plugindesc 現在のステートを画面左下に表示するプラグインアイコン丸い背景付き、行間空白調整、スイッチ31対応、戦闘画面対応
* @author しろやぶ featCGPT
*
* @help
* このプラグインは、アクターの現在のステートを画面左下に最大5つまで表示します。
* 特徴:
* - ステートは下から順に表示され、解除時にリストを詰めて表示。
* - ステート名の前にアイコンを表示。
* - ステート名ごとに角丸背景を描画し、文字間に空白を追加。
* - スイッチ31がONのときのみ表示されます。
* - 戦闘画面にも対応しています。
*
*/
(() => {
const maxStates = 5; // 表示するステートの最大数
const stateLineHeight = 32; // ステートの行高さ
const stateFontSize = 18; // フォントサイズ
const stateBackgroundColor = "rgba(255, 255, 255, 0.3)"; // 背景色
const backgroundPadding = 3; // 背景の上下の余白
const cornerRadius = 6; // 背景の角の丸み
const windowWidth = 270; // ウィンドウの横幅
const windowHeight = 192; // ウィンドウの高さ
const stateWindowX = 900; // ウィンドウのX座標
const stateWindowY = 540; // ウィンドウのY座標
const displaySwitchID = 31; // 表示を制御するスイッチID
// 段ごとのテキストY座標のオフセット全て-5に設定
const textYOffset = [-5, -5, -5, -5, -5];
class StateDisplayWindow extends Window_Base {
constructor() {
super(new Rectangle(stateWindowX, stateWindowY, windowWidth, windowHeight));
this.opacity = 0; // 背景を透明にする
this._actor = null;
}
setActor(actor) {
this._actor = actor;
this.refresh();
}
refresh() {
this.contents.clear();
// スイッチ31がOFFの場合は描画しない
if (!this._actor || !$gameSwitches.value(displaySwitchID)) {
this.visible = false;
return;
}
this.visible = true; // スイッチがONの場合、ウィンドウを表示
// 現在のステートリストを取得し、最大数を制限
const states = this._actor.states().slice(0, maxStates);
const totalStates = states.length;
// 各ステートを描画(下から順に)
states.forEach((state, index) => {
const y = (totalStates - index - 1) * stateLineHeight;
this.drawState(state, y, index); // indexを渡して段ごとのオフセットを適用
});
}
drawState(state, y, index) {
const iconScale = 0.8; // アイコンのスケール
const iconWidth = ImageManager.iconWidth * iconScale;
const iconHeight = ImageManager.iconHeight * iconScale;
const textX = iconWidth + 6; // アイコンの右隣のテキスト開始位置
const bgHeight = stateFontSize + backgroundPadding * 2; // 背景の高さ
// 背景を描画
this.drawRoundedRect(0, y + (stateLineHeight - bgHeight) / 2, this.contents.width, bgHeight, cornerRadius, stateBackgroundColor);
// 背景中央の基準点を計算
const centerY = y + (stateLineHeight - bgHeight) / 2 + bgHeight / 2;
// アイコンのY座標を計算
const iconY = centerY - iconHeight / 2;
// テキストのY座標段ごとのオフセットを適用
const textY = iconY + (textYOffset[index] || 0); // 指定がない場合はデフォルト0
// アイコンを描画
this.drawIcon(state.iconIndex, 3, iconY, iconScale);
// フォントサイズを設定
this.contents.fontSize = stateFontSize;
// ステート名を描画
this.drawText(state.name, textX, textY, this.contents.width - textX);
}
drawRoundedRect(x, y, width, height, radius, color) {
const ctx = this.contents.context;
ctx.save();
ctx.fillStyle = color;
ctx.beginPath();
ctx.moveTo(x + radius, y);
ctx.lineTo(x + width - radius, y);
ctx.quadraticCurveTo(x + width, y, x + width, y + radius);
ctx.lineTo(x + width, y + height - radius);
ctx.quadraticCurveTo(x + width, y + height, x + width - radius, y + height);
ctx.lineTo(x + radius, y + height);
ctx.quadraticCurveTo(x, y + height, x, y + height - radius);
ctx.lineTo(x, y + radius);
ctx.quadraticCurveTo(x, y, x + radius, y);
ctx.closePath();
ctx.fill();
ctx.restore();
}
drawIcon(iconIndex, x, y, scale = 1) {
const bitmap = ImageManager.loadSystem("IconSet");
const iconWidth = ImageManager.iconWidth;
const iconHeight = ImageManager.iconHeight;
const sx = (iconIndex % 16) * iconWidth;
const sy = Math.floor(iconIndex / 16) * iconHeight;
this.contents.blt(bitmap, sx, sy, iconWidth, iconHeight, x, y, iconWidth * scale, iconHeight * scale);
}
update() {
super.update();
if (this._actor) {
this.refresh();
}
}
}
const _Scene_Map_createAllWindows = Scene_Map.prototype.createAllWindows;
Scene_Map.prototype.createAllWindows = function() {
_Scene_Map_createAllWindows.call(this);
this.createStateDisplayWindow();
};
Scene_Map.prototype.createStateDisplayWindow = function() {
this._stateDisplayWindow = new StateDisplayWindow();
this._stateDisplayWindow.setActor($gameParty.leader()); // パーティリーダーを対象
this.addWindow(this._stateDisplayWindow);
};
const _Scene_Battle_createAllWindows = Scene_Battle.prototype.createAllWindows;
Scene_Battle.prototype.createAllWindows = function() {
_Scene_Battle_createAllWindows.call(this);
this.createStateDisplayWindow();
};
Scene_Battle.prototype.createStateDisplayWindow = function() {
this._stateDisplayWindow = new StateDisplayWindow();
this._stateDisplayWindow.setActor($gameParty.leader()); // パーティリーダーを対象
this.addWindow(this._stateDisplayWindow);
};
const _Game_Actor_refresh = Game_Actor.prototype.refresh;
Game_Actor.prototype.refresh = function() {
_Game_Actor_refresh.call(this);
if (SceneManager._scene._stateDisplayWindow) {
SceneManager._scene._stateDisplayWindow.setActor(this);
}
};
})();