urami-demo/www/js/plugins/MPP_MapLight.js
2026-04-24 20:01:10 -05:00

110 lines
4 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.

/*:
* @plugindesc MV専用指定したマップのみ暗くし、灯りを表示するプラグイン
* @author 木星ペンギン(改変:魚雷城)
*
* @param Light Colors
* @desc 灯りの色をRGB形式で設定例: ["255,255,255", "255,128,64"]
* @default ["255,255,255"]
*
* @param Darkness Opacity
* @desc マップの暗さ0〜255。数値が大きいほど暗い。
* @default 160
*
* @param Target Maps
* @desc 暗くする対象マップIDをカンマ区切りで指定例: 1,3,5
* @default 1
*
* @help
* プラグインコマンド:
* SetCharLight [キャラID] [半径] [色番号] [明滅幅]
* キャラに灯りを表示します。
* キャラID -1: プレイヤー, 0以上: イベントID
*/
(function() {
const parameters = PluginManager.parameters('MPP_MapLight');
const lightColors = JSON.parse(parameters['Light Colors'] || '["255,255,255"]');
const darknessOpacity = Number(parameters['Darkness Opacity'] || 160);
const targetMapIds = (parameters['Target Maps'] || '1').split(',').map(id => Number(id.trim()));
const _lightData = {};
// プラグインコマンド処理
const _Game_Interpreter_pluginCommand = Game_Interpreter.prototype.pluginCommand;
Game_Interpreter.prototype.pluginCommand = function(command, args) {
_Game_Interpreter_pluginCommand.call(this, command, args);
if (command === 'SetCharLight') {
const charId = Number(args[0]);
const radius = Number(args[1]);
const colorId = Number(args[2]);
const flick = Number(args[3]);
_lightData[charId] = {
radius: radius,
color: lightColors[colorId - 1] || "255,255,255",
flick: flick
};
}
};
// ライトレイヤー追加
const _Spriteset_Map_createUpperLayer = Spriteset_Map.prototype.createUpperLayer;
Spriteset_Map.prototype.createUpperLayer = function() {
_Spriteset_Map_createUpperLayer.call(this);
this.createLightLayer();
};
Spriteset_Map.prototype.createLightLayer = function() {
this._lightBitmap = new Bitmap(Graphics.width, Graphics.height);
this._lightSprite = new Sprite(this._lightBitmap);
this._lightSprite.blendMode = PIXI.BLEND_MODES.MULTIPLY;
this.addChild(this._lightSprite);
};
const _Spriteset_Map_update = Spriteset_Map.prototype.update;
Spriteset_Map.prototype.update = function() {
_Spriteset_Map_update.call(this);
this.updateLightLayer();
};
Spriteset_Map.prototype.updateLightLayer = function() {
const bitmap = this._lightBitmap;
bitmap.clear();
// 対象外マップなら return暗くしない
if (!targetMapIds.includes($gameMap.mapId())) return;
// 暗く塗る
bitmap.fillAll(`rgba(0, 0, 0, ${darknessOpacity / 255})`);
// 灯りを描画
for (const key in _lightData) {
const data = _lightData[key];
let chara = null;
if (Number(key) === -1) {
chara = $gamePlayer;
} else {
chara = $gameMap.event(Number(key));
}
if (chara) {
const x = chara.screenX();
const y = chara.screenY();
const r = data.radius * 48;
const color = data.color.split(',').map(Number);
const ctx = bitmap.context;
const gradient = ctx.createRadialGradient(x, y, 0, x, y, r);
gradient.addColorStop(0, `rgba(${color[0]},${color[1]},${color[2]},1.0)`);
gradient.addColorStop(1, `rgba(${color[0]},${color[1]},${color[2]},0.0)`);
ctx.save();
ctx.globalCompositeOperation = 'destination-out';
ctx.fillStyle = gradient;
ctx.beginPath();
ctx.arc(x, y, r, 0, Math.PI * 2, false);
ctx.fill();
ctx.restore();
bitmap._setDirty();
}
}
};
})();