/*:
* @target MZ
* @plugindesc Menu principal ultra stylisé - Inspiré Persona 5 + Street Fighter 6
* @author Superagent for Akira1kurusu
* @version 1.4
*
* @param menuColor1
* @text Couleur principale
* @type string
* @default #E8003A
*
* @param menuColor2
* @text Couleur secondaire
* @type string
* @default #1A1A1A
*
* @param accentColor
* @text Couleur accent
* @type string
* @default #FFFFFF
*
* @param paintColor
* @text Couleur effet peinture
* @type string
* @default #FFD700
*
* @param transitionSpeed
* @text Vitesse de transition
* @type number
* @min 5
* @max 60
* @default 18
*
* @help
* UNIQUE MENU v1.4 — Persona 5 x Street Fighter 6
* Gold window agrandie, sous-menus entièrement stylisés.
*/
(() => {
'use strict';
const pluginName = 'UniqueMenu_MZ';
const params = PluginManager.parameters(pluginName);
const COLOR1 = params.menuColor1 || '#E8003A';
const COLOR2 = params.menuColor2 || '#1A1A1A';
const ACCENT = params.accentColor || '#FFFFFF';
const PAINT = params.paintColor || '#FFD700';
const TRANS_SPEED = parseInt(params.transitionSpeed) || 18;
// *** MODIFIÉ POUR TOI ***
const GOLD_H = 96; // hauteur gold window augmentée pour meilleure lisibilité
const BAR_WIDTH = 14;
function getCtx(bmp) {
return bmp && bmp._canvas ? bmp._canvas.getContext('2d') : null;
}
// ============================================================
// UTILITAIRES CANVAS MANQUANTS — À RECOLLER ICI
// ============================================================
// Rectangle oblique
function drawSkewedRect(ctx, x, y, w, h, skew, color, alpha) {
if (alpha === undefined) alpha = 1;
ctx.save();
ctx.globalAlpha = alpha;
ctx.fillStyle = color;
ctx.beginPath();
ctx.moveTo(x + skew, y);
ctx.lineTo(x + w + skew, y);
ctx.lineTo(x + w - skew, y + h);
ctx.lineTo(x - skew, y + h);
ctx.closePath();
ctx.fill();
ctx.restore();
}
// Effet peinture
function drawPaintSplash(ctx, cx, cy, size, color, alpha) {
if (alpha === undefined) alpha = 0.7;
ctx.save();
ctx.globalAlpha = alpha;
ctx.fillStyle = color;
const pts = 8 + Math.floor(Math.random() * 5);
ctx.beginPath();
for (let i = 0; i < pts * 2; i++) {
const ang = (i / (pts * 2)) * Math.PI * 2;
const r = (i % 2 === 0)
? size * (0.7 + Math.random() * 0.5)
: size * (0.3 + Math.random() * 0.3);
const px = cx + Math.cos(ang) * r;
const py = cy + Math.sin(ang) * r;
if (i === 0) ctx.moveTo(px, py);
else ctx.lineTo(px, py);
}
ctx.closePath();
ctx.fill();
ctx.restore();
}
// Traits de vitesse
function drawSpeedLines(ctx, cx, cy, count, length, color, alpha) {
if (alpha === undefined) alpha = 0.12;
ctx.save();
ctx.globalAlpha = alpha;
ctx.strokeStyle = color;
ctx.lineWidth = 1;
for (let i = 0; i < count; i++) {
const ang = (i / count) * Math.PI * 2;
const s = 20 + Math.random() * 30;
const e = s + length * (0.5 + Math.random() * 0.5);
ctx.beginPath();
ctx.moveTo(cx + Math.cos(ang) * s, cy + Math.sin(ang) * s);
ctx.lineTo(cx + Math.cos(ang) * e, cy + Math.sin(ang) * e);
ctx.stroke();
}
ctx.restore();
}
// FOND STYLISÉ — LA FONCTION QUI MANQUE
function drawBg(ctx, w, h, opts) {
opts = opts || {};
const bgAlpha = opts.bgAlpha !== undefined ? opts.bgAlpha : 0.93;
const barColor = opts.barColor || COLOR1;
const barSide = opts.barSide || 'left';
const barSize = opts.barSize || 6;
const splashes = Array.isArray(opts.splashes) ? opts.splashes : [];
const lines = opts.speedLines !== false;
// Fond principal
ctx.save();
ctx.globalAlpha = bgAlpha;
ctx.fillStyle = COLOR2;
ctx.fillRect(0, 0, w, h);
ctx.restore();
// Barre latérale ou supérieure
ctx.save();
ctx.globalAlpha = 1;
ctx.fillStyle = barColor;
if (barSide === 'left') ctx.fillRect(0, 0, barSize, h);
else ctx.fillRect(0, 0, w, barSize);
ctx.restore();
// Effets peinture
for (const s of splashes) {
drawPaintSplash(ctx, s.x, s.y, s.size, s.color, s.alpha);
}
// Traits de vitesse
if (lines) {
drawSpeedLines(ctx, w * 0.85, h * 0.5, 28, h * 0.6, PAINT, 0.05);
}
// Ligne décorative diagonale
ctx.save();
ctx.strokeStyle = COLOR1;
ctx.globalAlpha = 0.18;
ctx.lineWidth = 1.5;
ctx.beginPath();
ctx.moveTo(w * 0.55, 0);
ctx.lineTo(w, h * 0.4);
ctx.stroke();
ctx.restore();
}
// ============================================================
// // Texte style Persona 5
function p5Text(ctx, text, x, y, opts) {
opts = opts || {};
const sz = opts.size || 16;
const color = opts.color || ACCENT;
ctx.save();
ctx.font = `bold ${sz}px "Arial Black", Arial, sans-serif`;
ctx.textBaseline = opts.baseline || 'middle';
ctx.textAlign = opts.align || 'left';
if (opts.shadow !== false) {
ctx.fillStyle = '#000';
ctx.globalAlpha = 0.65;
ctx.fillText(text, x + 2, y + 2);
}
ctx.fillStyle = color;
ctx.globalAlpha = opts.alpha !== undefined ? opts.alpha : 1;
ctx.fillText(text, x, y);
ctx.restore();
}
// Barre de stat style P5 (HP/MP)
function drawStatBar(ctx, x, y, w, h, ratio, fillColor) {
ctx.save();
ctx.fillStyle = '#2a2a2a';
ctx.globalAlpha = 0.9;
ctx.fillRect(x, y, w, h);
ctx.fillStyle = fillColor;
ctx.globalAlpha = 1;
ctx.fillRect(x, y, Math.max(0, w * ratio), h);
ctx.fillStyle = '#ffffff';
ctx.globalAlpha = 0.12;
ctx.fillRect(x, y, Math.max(0, w * ratio), Math.ceil(h / 2));
ctx.restore();
};
// ============================================================
// WINDOW_SKILLLIST
// ============================================================
const _SkillList_init = Window_SkillList.prototype.initialize;
Window_SkillList.prototype.initialize = function (rect) {
_SkillList_init.call(this, rect);
this.opacity = 0;
this.frameVisible = false;
};
const _SkillList_ref = Window_SkillList.prototype.refresh;
Window_SkillList.prototype.refresh = function () {
if (this.contents) {
const ctx = getCtx(this.contents);
if (ctx) {
drawBg(ctx, this.contentsWidth(), this.contentsHeight(), {
barSide: 'left',
barSize: 5,
speedLines: false
});
}
}
_SkillList_ref.call(this);
};
Window_SkillList.prototype.drawItem = function (index) {
const skill = this.itemAt(index);
if (!skill) return;
const rect = this.itemLineRect(index);
const ctx = getCtx(this.contents);
const actor = this._actor;
if (!ctx || !actor) {
Window_Selectable.prototype.drawItem.call(this, index);
return;
}
const enabled = this.isEnabled(skill);
const pad = 4;
const skew = 8;
drawSkewedRect(ctx,
rect.x + pad,
rect.y + pad,
rect.width - pad * 2,
rect.height - pad * 2,
skew,
ACCENT,
enabled ? 0.07 : 0.03
);
this.drawIcon(skill.iconIndex,
rect.x + 8,
rect.y + (rect.height - ImageManager.iconHeight) / 2
);
p5Text(ctx, skill.name.toUpperCase(),
rect.x + 40,
rect.y + rect.height / 2,
{
size: 15,
color: enabled ? ACCENT : '#666',
shadow: true
}
);
const cost = actor.skillMpCost(skill);
const tp = actor.skillTpCost(skill);
if (cost > 0 || tp > 0) {
const label = cost > 0 ? `${cost} MP` : `${tp} TP`;
const lcolor = cost > 0 ? '#5599FF' : '#33DDAA';
ctx.save();
ctx.font = 'bold 12px "Arial Black", Arial, sans-serif';
ctx.textBaseline = 'middle';
ctx.textAlign = 'right';
const lw = ctx.measureText(label).width + 10;
drawSkewedRect(ctx,
rect.x + rect.width - lw - pad - 4,
rect.y + pad + 2,
lw,
rect.height - pad * 2 - 4,
4,
lcolor,
0.2
);
ctx.fillStyle = lcolor;
ctx.globalAlpha = enabled ? 1 : 0.4;
ctx.fillText(label,
rect.x + rect.width - pad - 6,
rect.y + rect.height / 2
);
ctx.restore();
}
};
// ============================================================
// WINDOW_EQUIPSLOT
// ============================================================
const _EquipSlot_init = Window_EquipSlot.prototype.initialize;
Window_EquipSlot.prototype.initialize = function (rect) {
_EquipSlot_init.call(this, rect);
this.opacity = 0;
this.frameVisible = false;
};
const _EquipSlot_ref = Window_EquipSlot.prototype.refresh;
Window_EquipSlot.prototype.refresh = function () {
if (this.contents) {
const ctx = getCtx(this.contents);
if (ctx) {
drawBg(ctx, this.contentsWidth(), this.contentsHeight(), {
barSide: 'left',
barSize: 5,
speedLines: false
});
}
}
_EquipSlot_ref.call(this);
};
Window_EquipSlot.prototype.drawItem = function (index) {
if (!this._actor) return;
const rect = this.itemLineRect(index);
const ctx = getCtx(this.contents);
if (!ctx) {
Window_StatusBase.prototype.drawItem.call(this, index);
return;
}
const slotName = this.slotName(index);
const item = this._actor.equips()[index];
const pad = 4;
const skew = 6;
const isSelected = (index === this.index());
drawSkewedRect(ctx,
rect.x + pad,
rect.y + pad,
rect.width - pad * 2,
rect.height - pad * 2,
skew,
isSelected ? COLOR1 : ACCENT,
isSelected ? 0.35 : 0.06
);
p5Text(ctx,
slotName.toUpperCase(),
rect.x + 10,
rect.y + rect.height / 2,
{
size: 11,
color: COLOR1,
shadow: false
}
);
ctx.save();
ctx.fillStyle = COLOR1;
ctx.globalAlpha = 0.5;
ctx.fillRect(rect.x + 10,
rect.y + rect.height - 3,
rect.width - 20,
1
);
ctx.restore();
if (item) {
this.drawIcon(item.iconIndex,
rect.x + rect.width / 2 - 60,
rect.y + (rect.height - ImageManager.iconHeight) / 2
);
p5Text(ctx,
item.name.toUpperCase(),
rect.x + rect.width / 2 - 36,
rect.y + rect.height / 2,
{
size: 14,
color: isSelected ? PAINT : ACCENT,
shadow: true
}
);
} else {
p5Text(ctx,
'—',
rect.x + rect.width / 2,
rect.y + rect.height / 2,
{
size: 14,
color: '#555',
shadow: false,
align: 'center'
}
);
}
};
// ============================================================
// WINDOW_EQUIPITEM
// ============================================================
const _EquipItem_init = Window_EquipItem.prototype.initialize;
Window_EquipItem.prototype.initialize = function (rect) {
_EquipItem_init.call(this, rect);
this.opacity = 0;
this.frameVisible = false;
};
const _EquipItem_ref = Window_EquipItem.prototype.refresh;
Window_EquipItem.prototype.refresh = function () {
if (this.contents) {
const ctx = getCtx(this.contents);
if (ctx) {
drawBg(ctx, this.contentsWidth(), this.contentsHeight(), {
barSide: 'left',
barSize: 5,
speedLines: false
});
}
}
_EquipItem_ref.call(this);
};
// ============================================================
// WINDOW_STATUS — fiche personnage stylisée
// ============================================================
const _Status_init = Window_Status.prototype.initialize;
Window_Status.prototype.initialize = function (rect) {
_Status_init.call(this, rect);
this.opacity = 0;
this.frameVisible = false;
};
Window_Status.prototype.refresh = function () {
if (!this.contents || !this._actor) return;
this.contents.clear();
const ctx = getCtx(this.contents);
const actor = this._actor;
const w = this.contentsWidth();
const h = this.contentsHeight();
if (!ctx) {
Window_StatusBase.prototype.refresh.call(this);
return;
}
// Fond principal
drawBg(ctx, w, h, {
barSide: 'left',
barSize: 6,
speedLines: true
});
// Splash décoratifs
drawPaintSplash(ctx, w - 40, 40, 45, PAINT, 0.07);
drawPaintSplash(ctx, w - 80, h - 30, 30, COLOR1, 0.06);
// Portrait
const faceW = 144;
const faceH = 144;
this.drawFace(actor.faceName(), actor.faceIndex(), 20, 20, faceW, faceH);
// *** MODIFIÉ POUR TOI : CADRE AGRANDI ***
const framePadX = 14;
const framePadY = 14;
const frameW = faceW + 220; // élargi pour inclure nom + niveau + exp
const frameH = faceH + 150; // plus haut pour inclure barres et séparateurs
ctx.save();
ctx.strokeStyle = COLOR1;
ctx.globalAlpha = 0.85;
ctx.lineWidth = 3;
ctx.strokeRect(framePadX + 6, framePadY + 6, frameW, frameH);
ctx.strokeStyle = PAINT;
ctx.globalAlpha = 0.35;
ctx.lineWidth = 1;
ctx.strokeRect(framePadX + 2, framePadY + 2, frameW + 8, frameH + 8);
ctx.restore();
// Nom + classe
p5Text(ctx, actor.name().toUpperCase(), 180, 30, {
size: 26,
color: ACCENT
});
p5Text(ctx, actor.currentClass().name.toUpperCase(), 182, 60, {
size: 14,
color: COLOR1,
shadow: false
});
// Niveau
ctx.save();
drawSkewedRect(ctx, 178, 74, 90, 26, 6, COLOR1, 0.9);
p5Text(ctx, `LV. ${actor.level}`, 186, 87, {
size: 15,
color: '#000',
shadow: false
});
ctx.restore();
// EXP
const expRate = actor.isMaxLevel()
? 1
: (actor.currentExp() - actor.currentLevelExp()) /
(actor.nextLevelExp() - actor.currentLevelExp());
p5Text(ctx, 'EXP', 180, 118, {
size: 11,
color: PAINT,
shadow: false
});
drawStatBar(ctx, 180, 126, 200, 8, expRate, PAINT);
// Séparateur
ctx.save();
ctx.fillStyle = COLOR1;
ctx.globalAlpha = 0.6;
ctx.fillRect(14, 174, w - 28, 2);
ctx.restore();
// Stats en grille
const stats = [
{ key: 'mhp', label: 'HP MAX', val: actor.mhp },
{ key: 'mmp', label: 'MP MAX', val: actor.mmp },
{ key: 'atk', label: 'ATK', val: actor.atk },
{ key: 'def', label: 'DEF', val: actor.def },
{ key: 'mat', label: 'M.ATK', val: actor.mat },
{ key: 'mdf', label: 'M.DEF', val: actor.mdf },
{ key: 'agi', label: 'VITESSE', val: actor.agi },
{ key: 'luk', label: 'CHANCE', val: actor.luk }
];
const colW = Math.floor(w / 2) - 20;
const rowH = 38;
const startY = 185;
stats.forEach((st, i) => {
const col = i % 2;
const row = Math.floor(i / 2);
const sx = 14 + col * (colW + 20);
const sy = startY + row * rowH;
drawSkewedRect(ctx, sx, sy + 2, colW, rowH - 6, 5, ACCENT, 0.06);
p5Text(ctx, st.label, sx + 8, sy + rowH / 2 - 6, {
size: 10,
color: COLOR1,
shadow: false
});
p5Text(ctx, String(st.val), sx + 8, sy + rowH / 2 + 9, {
size: 16,
color: ACCENT,
shadow: true
});
});
// HP / MP
const hpRatio = actor.mhp > 0 ? actor.hp / actor.mhp : 0;
const mpRatio = actor.mmp > 0 ? actor.mp / actor.mmp : 0;
const barY = h - 48;
p5Text(ctx, `HP ${actor.hp} / ${actor.mhp}`, 14, barY, {
size: 13,
color: hpRatio > 0.5 ? '#00DD55' : hpRatio > 0.25 ? '#FFAA00' : COLOR1
});
drawStatBar(ctx, 14, barY + 14, w - 28, 8, hpRatio,
hpRatio > 0.5 ? '#00DD55' : hpRatio > 0.25 ? '#FFAA00' : COLOR1
);
p5Text(ctx, `MP ${actor.mp} / ${actor.mmp}`, 14, barY + 26, {
size: 13,
color: '#5599FF'
});
drawStatBar(ctx, 14, barY + 40, w - 28, 8, mpRatio, '#5599FF');
};
// ============================================================
// WINDOW_MENU_COMMAND — menu principal stylisé
// ============================================================
class Window_UniqueMenuCommand extends Window_MenuCommand {
constructor(rect) {
super(rect);
this._splashes = [];
this._hoverAlphas = new Array(10).fill(0);
this._animFrame = 0;
this._lastIndex = -1;
this._selectedFlash = 0;
this.opacity = 0;
this.frameVisible = false;
this._generateItemSplashes();
}
_generateItemSplashes() {
this._splashes = [];
const w = this.width || 300;
const h = this.height || 400;
for (let i = 0; i < 8; i++) {
this._splashes.push({
x: w * 0.75 + Math.random() * w * 0.5,
y: 20 + Math.random() * h,
size: 12 + Math.random() * 30,
color: Math.random() > 0.6 ? COLOR1 : PAINT,
alpha: 0.05 + Math.random() * 0.09
});
}
}
itemHeight() { return 62; }
itemPadding() { return 16; }
maxCols() { return 1; }
update() {
super.update();
this._animFrame++;
if (!Array.isArray(this._hoverAlphas))
this._hoverAlphas = new Array(10).fill(0);
if (!Array.isArray(this._splashes))
this._splashes = [];
const idx = this.index();
for (let i = 0; i < this.maxItems(); i++) {
if (i === idx)
this._hoverAlphas[i] = Math.min(1, (this._hoverAlphas[i] || 0) + 0.08);
else
this._hoverAlphas[i] = Math.max(0, (this._hoverAlphas[i] || 0) - 0.05);
}
if (idx !== this._lastIndex) {
this._lastIndex = idx;
this._selectedFlash = 15;
this.refresh();
}
if (this._selectedFlash > 0) {
this._selectedFlash--;
this.refresh();
}
if (this._animFrame % 4 === 0)
this.refresh();
}
_refreshBack() {}
refresh() {
if (!this.contents) return;
if (!Array.isArray(this._splashes))
this._splashes = [];
if (!Array.isArray(this._hoverAlphas))
this._hoverAlphas = new Array(10).fill(0);
this.contents.clear();
const ctx = getCtx(this.contents);
if (ctx) {
drawBg(ctx, this.contentsWidth(), this.contentsHeight(), {
barSide: 'left',
barSize: 8,
splashes: this._splashes
});
}
super.refresh();
}
drawItem(index) {
const rect = this.itemLineRect(index);
const ctx = getCtx(this.contents);
if (!ctx) {
super.drawItem(index);
return;
}
const name = this.commandName(index);
const enabled = this.isCommandEnabled(index);
const isSelected = (index === this.index());
const hoverAlpha = (this._hoverAlphas && this._hoverAlphas[index]) || 0;
const skew = 12;
const pad = 4;
drawSkewedRect(ctx,
rect.x + BAR_WIDTH + pad,
rect.y + pad,
rect.width - BAR_WIDTH - pad * 2,
rect.height - pad * 2,
skew,
'#000000',
0.25
);
drawSkewedRect(ctx,
rect.x + BAR_WIDTH + pad + 2,
rect.y + pad,
rect.width - BAR_WIDTH - pad * 2 - 2,
rect.height - pad * 2,
skew,
ACCENT,
enabled ? (0.15 + hoverAlpha * 0.25) : 0.07
);
if (isSelected) {
const fb = this._selectedFlash > 0
? (this._selectedFlash / 15) * 0.3
: 0;
drawSkewedRect(ctx,
rect.x + BAR_WIDTH + pad + 2,
rect.y + pad,
rect.width - BAR_WIDTH - pad * 2 - 2,
rect.height - pad * 2,
skew,
COLOR1,
0.55 + fb
);
if (this._selectedFlash > 8) {
drawPaintSplash(ctx,
rect.x + rect.width - 30,
rect.y + rect.height / 2,
25 + (this._selectedFlash / 15) * 20,
PAINT,
0.6 + (this._selectedFlash / 15) * 0.3
);
}
ctx.save();
ctx.fillStyle = PAINT;
ctx.globalAlpha = 0.9 + Math.sin(this._animFrame * 0.15) * 0.1;
ctx.beginPath();
ctx.moveTo(rect.x + BAR_WIDTH + pad - 2, rect.y + rect.height / 2 - 8);
ctx.lineTo(rect.x + BAR_WIDTH + pad + 10, rect.y + rect.height / 2);
ctx.lineTo(rect.x + BAR_WIDTH + pad - 2, rect.y + rect.height / 2 + 8);
ctx.closePath();
ctx.fill();
ctx.restore();
}
const textX = rect.x + BAR_WIDTH + pad + skew + 12;
const textY = rect.y + rect.height / 2;
const fontSize = isSelected ? 22 : 19;
ctx.save();
ctx.font = `bold ${fontSize}px "Arial Black", Arial, sans-serif`;
ctx.textBaseline = 'middle';
ctx.fillStyle = '#000';
ctx.globalAlpha = 0.6;
ctx.fillText(name.toUpperCase(), textX + 2, textY + 2);
ctx.fillStyle = !enabled ? '#888' : ACCENT;
ctx.globalAlpha = !enabled ? 0.5 : isSelected ? 1 : 0.85;
ctx.fillText(name.toUpperCase(), textX, textY);
if (isSelected) {
const tw = ctx.measureText(name.toUpperCase()).width;
ctx.fillStyle = PAINT;
ctx.globalAlpha = 0.9;
ctx.fillRect(textX, textY + fontSize / 2 + 2, tw * 0.6, 2);
}
ctx.restore();
}
_updateCursor() {
this.setCursorRect(0, 0, 0, 0);
}
}
// ============================================================
// WINDOW_MENU_STATUS — affichage des membres dans le menu
// ============================================================
class Window_UniqueMenuStatus extends Window_MenuStatus {
constructor(rect) {
super(rect);
this.opacity = 0;
this.frameVisible = false;
}
refresh() {
if (!this.contents) return;
this.contents.clear();
const ctx = getCtx(this.contents);
if (ctx) {
drawBg(ctx, this.contentsWidth(), this.contentsHeight(), {
barSide: 'top',
barSize: 5,
speedLines: false
});
p5Text(ctx, 'PARTY', 12, 18, {
size: 13,
color: COLOR1
});
ctx.save();
ctx.fillStyle = PAINT;
ctx.globalAlpha = 0.6;
ctx.fillRect(12, 30, 50, 2);
ctx.restore();
}
super.refresh();
}
drawItem(index) {
const actor = $gameParty.members()[index];
if (!actor) return;
const rect = this.itemRect(index);
const ctx = getCtx(this.contents);
if (!ctx) {
super.drawItem(index);
return;
}
const pad = 6;
drawSkewedRect(ctx,
rect.x + pad,
rect.y + pad,
rect.width - pad * 2,
rect.height - pad * 2,
6,
ACCENT,
0.07
);
const hpRatio = actor.mhp > 0 ? actor.hp / actor.mhp : 0;
const mpRatio = actor.mmp > 0 ? actor.mp / actor.mmp : 0;
const hpColor =
hpRatio > 0.5 ? '#00DD55' :
hpRatio > 0.25 ? '#FFAA00' :
COLOR1;
const barX = rect.x + pad + 8;
const barMaxW = rect.width - pad * 2 - 75;
drawStatBar(ctx,
barX,
rect.y + rect.height - pad - 20,
barMaxW,
5,
hpRatio,
hpColor
);
drawStatBar(ctx,
barX,
rect.y + rect.height - pad - 10,
barMaxW,
5,
mpRatio,
'#5599FF'
);
p5Text(ctx,
actor.name().toUpperCase(),
rect.x + pad + 8,
rect.y + pad + 14,
{ size: 14 }
);
ctx.save();
ctx.font = '11px Arial';
ctx.fillStyle = hpColor;
ctx.globalAlpha = 1;
ctx.textBaseline = 'middle';
ctx.fillText(
`HP ${actor.hp}/${actor.mhp}`,
barX,
rect.y + rect.height - pad - 28
);
ctx.restore();
p5Text(ctx,
`LV.${actor.level}`,
rect.x + pad + 8,
rect.y + pad + 30,
{
size: 11,
color: PAINT,
shadow: false
}
);
this.drawFace(
actor.faceName(),
actor.faceIndex(),
rect.x + rect.width - 60 - pad,
rect.y + pad + 2,
54,
rect.height - pad * 2 - 16
);
}
}
// ============================================================
// GOLD WINDOW — version agrandie pour meilleure lisibilité
// ============================================================
Window_Gold.prototype.refresh = function () {
if (!this.contents) return;
this.contents.clear();
const ctx = getCtx(this.contents);
if (!ctx) {
Window_Base.prototype.refresh.call(this);
return;
}
const w = this.contentsWidth();
const h = this.contentsHeight();
drawBg(ctx, w, h, {
barSide: 'top',
barSize: 5,
barColor: PAINT,
speedLines: false,
splashes: []
});
p5Text(ctx, 'GOLD', 10, 14, {
size: 6,
color: PAINT,
shadow: false
});
ctx.save();
ctx.fillStyle = PAINT;
ctx.globalAlpha = 0.35;
ctx.fillRect(8, 24, w - 16, 1);
ctx.restore();
// *** MODIFIÉ POUR TOI : icône + texte plus grands ***
const iconX = 15;
const iconY = h / 2 + 6;
ctx.save();
const grad = ctx.createRadialGradient(iconX - 3, iconY - 3, 2, iconX, iconY, 20);
grad.addColorStop(0, '#FFE566');
grad.addColorStop(1, '#B8860B');
ctx.beginPath();
ctx.arc(iconX, iconY, 18, 0, Math.PI * 2);
ctx.fillStyle = grad;
ctx.fill();
ctx.strokeStyle = PAINT;
ctx.lineWidth = 2;
ctx.globalAlpha = 0.8;
ctx.stroke();
ctx.fillStyle = '#1A1A1A';
ctx.globalAlpha = 1;
ctx.font = 'bold 16px "Arial Black", Arial';
ctx.textAlign = 'center';
ctx.textBaseline = 'middle';
ctx.fillText('G', iconX, iconY + 1);
ctx.restore();
const value = $gameParty.gold();
const unit = TextManager.currencyUnit;
const valueStr = value.toLocaleString();
ctx.save();
ctx.font = 'bold 34px "Arial Black", Arial, sans-serif';
ctx.textBaseline = 'middle';
ctx.textAlign = 'left';
ctx.fillStyle = '#000';
ctx.globalAlpha = 0.7;
ctx.fillText(valueStr, 52, iconY + 2);
ctx.fillStyle = PAINT;
ctx.globalAlpha = 1;
ctx.fillText(valueStr, 50, iconY);
const vw = ctx.measureText(valueStr).width;
ctx.font = 'bold 14px Arial';
ctx.fillStyle = ACCENT;
ctx.globalAlpha = 0.8;
ctx.fillText(unit, 52 + vw + 8, iconY + 2);
ctx.restore();
};
// ============================================================
// SCÈNE MENU — remplacement complet par la version stylisée
// ============================================================
const _SceneMenu_create = Scene_Menu.prototype.create;
Scene_Menu.prototype.create = function () {
_SceneMenu_create.call(this);
// On remplace les fenêtres par nos versions stylisées
this._commandWindow.hide();
this._statusWindow.hide();
this._goldWindow.hide();
const cw = this.commandWindowRect();
const sw = this.statusWindowRect();
const gw = this.goldWindowRect();
this._uniqueCommandWindow = new Window_UniqueMenuCommand(cw);
this._uniqueStatusWindow = new Window_UniqueMenuStatus(sw);
this._uniqueGoldWindow = new Window_Gold(gw);
this.addWindow(this._uniqueCommandWindow);
this.addWindow(this._uniqueStatusWindow);
this.addWindow(this._uniqueGoldWindow);
this._uniqueCommandWindow.setHandler('item', this.commandItem.bind(this));
this._uniqueCommandWindow.setHandler('skill', this.commandSkill.bind(this));
this._uniqueCommandWindow.setHandler('equip', this.commandEquip.bind(this));
this._uniqueCommandWindow.setHandler('status', this.commandStatus.bind(this));
this._uniqueCommandWindow.setHandler('formation', this.commandFormation.bind(this));
this._uniqueCommandWindow.setHandler('options', this.commandOptions.bind(this));
this._uniqueCommandWindow.setHandler('save', this.commandSave.bind(this));
this._uniqueCommandWindow.setHandler('gameEnd', this.commandGameEnd.bind(this));
this._uniqueCommandWindow.setHandler('cancel', this.popScene.bind(this));
};
// ANIMATION D’OUVERTURE
Scene_Menu.prototype.start = function() {
Scene_Base.prototype.start.call(this);
// Position de départ (hors écran)
this._uniqueCommandWindow.x = -this._uniqueCommandWindow.width;
this._uniqueStatusWindow.x = Graphics.boxWidth;
this._uniqueGoldWindow.y = Graphics.boxHeight;
this._openingFrame = 0;
};
Scene_Menu.prototype.update = function() {
Scene_Base.prototype.update.call(this);
if (this._openingFrame < 20) {
this._openingFrame++;
// Commandes → glisse depuis la gauche
this._uniqueCommandWindow.x += (0 - this._uniqueCommandWindow.x) * 0.25;
// Statut → glisse depuis la droite
const targetStatusX = Math.floor(Graphics.boxWidth * 0.42);
this._uniqueStatusWindow.x += (targetStatusX - this._uniqueStatusWindow.x) * 0.25;
// Gold → glisse depuis le bas
const targetGoldY = Graphics.boxHeight - GOLD_H;
this._uniqueGoldWindow.y += (targetGoldY - this._uniqueGoldWindow.y) * 0.25;
}
};
// ============================================================
// RECTANGLES DES FENÊTRES
// ============================================================
Scene_Menu.prototype.commandWindowRect = function () {
const ww = Math.floor(Graphics.boxWidth * 0.42);
const wh = Graphics.boxHeight - GOLD_H - 20;
const wx = 0;
const wy = 0;
return new Rectangle(wx, wy, ww, wh);
};
Scene_Menu.prototype.statusWindowRect = function () {
const ww = Math.floor(Graphics.boxWidth * 0.58);
const wh = Graphics.boxHeight - GOLD_H - 20;
const wx = Math.floor(Graphics.boxWidth * 0.42);
const wy = 0;
return new Rectangle(wx, wy, ww, wh);
};
Scene_Menu.prototype.goldWindowRect = function () {
const ww = Graphics.boxWidth;
const wh = GOLD_H;
const wx = 12;
const wy = Graphics.boxHeight - GOLD_H;
return new Rectangle(wx, wy, ww, wh);
};
// ============================================================
// FIN DU PLUGIN
// ============================================================
// ============================================================
// HANDLERS DU MENU — OBLIGATOIRES POUR ÉVITER LE CRASH
// ============================================================
Scene_Menu.prototype.commandItem = function() {
SceneManager.push(Scene_Item);
};
Scene_Menu.prototype.commandSkill = function() {
SceneManager.push(Scene_Skill);
};
Scene_Menu.prototype.commandEquip = function() {
SceneManager.push(Scene_Equip);
};
Scene_Menu.prototype.commandStatus = function() {
SceneManager.push(Scene_Status);
};
Scene_Menu.prototype.commandFormation = function() {
SceneManager.push(Scene_Formation);
};
Scene_Menu.prototype.commandOptions = function() {
SceneManager.push(Scene_Options);
};
Scene_Menu.prototype.commandSave = function() {
SceneManager.push(Scene_Save);
};
Scene_Menu.prototype.commandGameEnd = function() {
SceneManager.push(Scene_GameEnd);
};
// ============================================================
// SCÈNE FORMATION — version simple type RPG Maker MV
// ============================================================
function Scene_Formation() {
this.initialize(...arguments);
}
Scene_Formation.prototype = Object.create(Scene_MenuBase.prototype);
Scene_Formation.prototype.constructor = Scene_Formation;
Scene_Formation.prototype.initialize = function() {
Scene_MenuBase.prototype.initialize.call(this);
this._pendingIndex = -1;
};
Scene_Formation.prototype.create = function() {
Scene_MenuBase.prototype.create.call(this);
this.createStatusWindow();
};
Scene_Formation.prototype.createStatusWindow = function() {
const rect = this.statusWindowRect();
this._statusWindow = new Window_MenuStatus(rect);
this._statusWindow.setHandler("ok", this.onStatusOk.bind(this));
this._statusWindow.setHandler("cancel", this.popScene.bind(this));
this.addWindow(this._statusWindow);
};
Scene_Formation.prototype.statusWindowRect = function() {
const ww = Graphics.boxWidth;
const wh = Graphics.boxHeight;
return new Rectangle(0, 0, ww, wh);
};
Scene_Formation.prototype.onStatusOk = function() {
const index = this._statusWindow.index();
if (this._pendingIndex < 0) {
this._pendingIndex = index;
this._statusWindow.activate();
} else {
$gameParty.swapOrder(this._pendingIndex, index);
this._pendingIndex = -1;
this._statusWindow.refresh();
this._statusWindow.activate();
}
};
})();
To embed this project on your website, copy the following code and paste it into your website's HTML: