111 lines
5.2 KiB
JavaScript
111 lines
5.2 KiB
JavaScript
/*:
|
||
* @target MZ
|
||
* @plugindesc [v1.0.0] ゲージを一括グレースケール化。メニュー用(Sprite_Gauge)もバトル用(Window_Base.drawGauge)も白黒でグラデ。戦闘でもカラーに戻りません。
|
||
* @author
|
||
*
|
||
* @help
|
||
* =============================================================================
|
||
* ■ 概要
|
||
* =============================================================================
|
||
* - ツクールMZでは、メニュー画面のゲージ表示に Sprite_Gauge を使うことが多く、
|
||
* バトルステータスのゲージに Window_Base.drawGauge を用いるパターンがあり、
|
||
* 片方だけを上書きしていると「メニューは白黒だけどバトルはカラー」の問題が起こります。
|
||
* - このプラグインは両方( drawGaugeRect と drawGauge )を上書きし、
|
||
* color1/color2 をモノクロにしたうえで輝度差を強制的に大きめに保ち、
|
||
* 白黒グラデーションが消えないようにします。
|
||
* - 結果として、メニュー画面でもバトルステータスでもゲージはモノクロ化され、
|
||
* グラデーションもはっきり見えるようになります。
|
||
*
|
||
* ■ 使い方
|
||
* 1) このファイルを「IM_GrayscaleGaugeUnifiedPatch.js」でjs/pluginsフォルダに置き、
|
||
* プラグイン管理でONにします。
|
||
* 2) それだけで、メニュー画面・バトル画面を含めたすべてのゲージがグレースケール表示
|
||
* (color1/color2を白黒化)されるようになります。
|
||
* 3) 他プラグインで drawGaugeRect または drawGauge を再上書きしている場合、
|
||
* ロード順によって競合する可能性があります。最下部に置くなど調整してください。
|
||
*
|
||
* ■ バージョン
|
||
* v1.0.0 (2025/xx/xx):
|
||
* - 初版。Sprite_Gauge と Window_Base.drawGauge の両方を白黒化&差分強制処理。
|
||
*
|
||
*/
|
||
|
||
(() => {
|
||
"use strict";
|
||
|
||
//--------------------------------------------------------------------------
|
||
// A) ヘルパー: color1, color2 をモノクロ化し、輝度差を強制してグラデを残す
|
||
//--------------------------------------------------------------------------
|
||
function calcLuminance(hexColor) {
|
||
const hex = hexColor.replace(/^#/, "");
|
||
if (hex.length<6) return 128; // fallback
|
||
const r = parseInt(hex.slice(0,2),16);
|
||
const g = parseInt(hex.slice(2,4),16);
|
||
const b = parseInt(hex.slice(4,6),16);
|
||
return Math.round(0.299*r + 0.587*g + 0.114*b);
|
||
}
|
||
|
||
function lumToHex(L) {
|
||
const v = Math.max(0, Math.min(255, L));
|
||
const s = v.toString(16).padStart(2,"0");
|
||
return `#${s}${s}${s}`;
|
||
}
|
||
|
||
// 2色をモノクロ化してから、差が minDiff未満なら押し広げる
|
||
function grayscaleWithMinDiff(c1, c2, minDiff=80) {
|
||
let L1 = calcLuminance(c1);
|
||
let L2 = calcLuminance(c2);
|
||
|
||
const diff = Math.abs(L2 - L1);
|
||
if (diff<minDiff) {
|
||
const needed = minDiff - diff;
|
||
const push = Math.floor(needed/2);
|
||
if (L1< L2) {
|
||
L1 = Math.max(0, L1 - push);
|
||
L2 = Math.min(255, L2 + push);
|
||
} else if (L1> L2) {
|
||
L1 = Math.min(255, L1 + push);
|
||
L2 = Math.max(0, L2 - push);
|
||
} else {
|
||
// L1==L2
|
||
let up = L1 + minDiff;
|
||
if (up>255) up=255;
|
||
L2= up;
|
||
}
|
||
}
|
||
return [lumToHex(L1), lumToHex(L2)];
|
||
}
|
||
|
||
//--------------------------------------------------------------------------
|
||
// B) Window_Base.drawGauge の上書き => バトル画面などがcolorで戻るのを防ぐ
|
||
//--------------------------------------------------------------------------
|
||
const _Window_Base_drawGauge = Window_Base.prototype.drawGauge;
|
||
Window_Base.prototype.drawGauge = function(x, y, width, rate, color1, color2) {
|
||
// minDiff=80などで白黒化
|
||
const [g1, g2] = grayscaleWithMinDiff(color1, color2, 80);
|
||
_Window_Base_drawGauge.call(this, x, y, width, rate, g1, g2);
|
||
};
|
||
|
||
//--------------------------------------------------------------------------
|
||
// C) Sprite_Gauge.drawGaugeRect の上書き => メニュー画面などに対応
|
||
//--------------------------------------------------------------------------
|
||
if (typeof Sprite_Gauge !== "undefined") {
|
||
const _Sprite_Gauge_drawGaugeRect = Sprite_Gauge.prototype.drawGaugeRect;
|
||
Sprite_Gauge.prototype.drawGaugeRect = function(x, y, w, h) {
|
||
// gaugeBackColorは元の色(背景) => そのままでOK or グレースケールしてもOK
|
||
// color1, color2
|
||
const c1 = this.gaugeColor1();
|
||
const c2 = this.gaugeColor2();
|
||
|
||
const [g1, g2] = grayscaleWithMinDiff(c1, c2, 80);
|
||
|
||
// fillRect(背景色) は元のまま
|
||
const fillW = Math.floor(w * this.gaugeRate());
|
||
this.bitmap.fillRect(x, y, w, h, this.gaugeBackColor());
|
||
|
||
// gradientFillRect => g1, g2
|
||
this.bitmap.gradientFillRect(x, y, fillW, h, g1, g2, false);
|
||
};
|
||
}
|
||
|
||
})();
|