285 lines
No EOL
11 KiB
JavaScript
285 lines
No EOL
11 KiB
JavaScript
//=============================================================================
|
||
// SimpleVoiceEx.js (based on SimpleVoice.js v2.0.5)
|
||
// ----------------------------------------------------------------------------
|
||
// (C)2017‑2025 Triacontane (Modded by ChatGPT on 2025‑04‑26)
|
||
// Released under the MIT License.
|
||
// http://opensource.org/licenses/mit-license.php
|
||
// ----------------------------------------------------------------------------
|
||
// Version
|
||
// 2.1.0 2025/04/26 専用音量を適用するチャンネルを複数指定できるよう機能拡張
|
||
// ----------------------------------------------------------------------------
|
||
// [GitHub] : https://github.com/triacontane/
|
||
//=============================================================================
|
||
|
||
/*:
|
||
* @plugindesc 簡易ボイス+チャンネル別音量拡張
|
||
* @target MZ
|
||
* @url https://github.com/triacontane/RPGMakerMV/tree/mz_master/SimpleVoice.js
|
||
* @base PluginCommonBase
|
||
* @author トリアコンタン
|
||
*
|
||
* @param optionName
|
||
* @text 共通ボイス音量名称
|
||
* @type string
|
||
* @desc オプションで共通ボイス音量を表示する際の名称
|
||
* @default ボイス 音量
|
||
*
|
||
* @param optionValue
|
||
* @text オプション初期値
|
||
* @type number
|
||
* @desc 共通ボイス音量の初期値
|
||
* @default 100
|
||
*
|
||
* @param exclusiveChannels
|
||
* @text 別枠音量チャンネル一覧
|
||
* @type string
|
||
* @desc カンマ区切りで指定したチャンネルは専用ボイス音量を使用します (例: 1,2,3)。空欄で機能OFF。
|
||
* @default
|
||
*
|
||
* @param exclusiveOptionName
|
||
* @text 別枠ボイス音量名称
|
||
* @type string
|
||
* @desc オプションで専用ボイス音量を表示する際の名称
|
||
* @default ボイス 音量 Ex
|
||
*
|
||
* @command PLAY_VOICE
|
||
* @text ボイスの演奏
|
||
* @desc ボイスを演奏します。
|
||
*
|
||
* @arg name
|
||
* @text ファイル名称
|
||
* @desc ボイスファイルの名称
|
||
* @default
|
||
* @type file
|
||
* @dir audio/se
|
||
*
|
||
* @arg volume
|
||
* @text 音量
|
||
* @desc ボイスファイルの音量
|
||
* @default 90
|
||
* @min 0
|
||
* @max 100
|
||
* @type number
|
||
*
|
||
* @arg pitch
|
||
* @text ピッチ
|
||
* @desc ボイスファイルのピッチ
|
||
* @default 100
|
||
* @type number
|
||
*
|
||
* @arg pan
|
||
* @text 左右バランス
|
||
* @desc ボイスファイルの左右バランス
|
||
* @default 0
|
||
* @min -100
|
||
* @max 100
|
||
* @type number
|
||
*
|
||
* @arg channel
|
||
* @text チャンネル番号
|
||
* @desc チャンネル番号。同番号のボイスは重ならず一つだけ再生されます。
|
||
* @default 0
|
||
* @type number
|
||
*
|
||
* @arg loop
|
||
* @text ループ再生
|
||
* @desc ボイスをループ再生するか
|
||
* @default false
|
||
* @type boolean
|
||
*
|
||
* @command STOP_VOICE
|
||
* @text ボイスの停止
|
||
* @desc 演奏中のボイスを停止します。
|
||
*
|
||
* @arg name
|
||
* @text ファイル名称
|
||
* @desc 停止するボイスファイルの名称
|
||
* @default
|
||
* @type file
|
||
* @dir audio/se
|
||
*
|
||
* @arg channel
|
||
* @text チャンネル番号
|
||
* @desc 停止するチャンネル番号
|
||
* @default 0
|
||
* @type number
|
||
*
|
||
* @help SimpleVoiceEx.js
|
||
*
|
||
* 簡易ボイス再生プラグインを拡張し、指定した複数チャンネルのみ
|
||
* “専用ボイス音量” スライダーで音量調整できるようにします。
|
||
*
|
||
* ◆セットアップ手順
|
||
* 1. プラグインパラメータ [exclusiveChannels] にカンマ区切りで
|
||
* 専用音量を適用したいチャンネル番号を入力してください。
|
||
* (例)1,3,5
|
||
* 2. オプション画面に「共通ボイス音量」と「専用ボイス音量 Ex」の
|
||
* 2つのスライダーが追加されます。
|
||
* 3. PLAY_VOICE コマンドでチャンネルを指定して再生すると、
|
||
* exclusiveChannels に含まれるチャンネルは専用音量で、
|
||
* それ以外は共通音量で再生されます。
|
||
*
|
||
* Base plugin『PluginCommonBase.js』が必要です。
|
||
*/
|
||
|
||
(() => {
|
||
'use strict';
|
||
|
||
const script = document.currentScript;
|
||
const param = PluginManagerEx.createParameter(script);
|
||
|
||
//-------------------------------------------------------------------------
|
||
// パラメータ解析
|
||
//-------------------------------------------------------------------------
|
||
/** 共通ボイス音量の名称 */
|
||
const commonOptionName = String(param.optionName || 'ボイス 音量');
|
||
/** 専用ボイス音量の対象チャンネル配列 */
|
||
const exclusiveChannels = (param.exclusiveChannels || '')
|
||
.split(',')
|
||
.map(s => Number(s.trim()))
|
||
.filter(n => !Number.isNaN(n) && n > 0);
|
||
/** 専用ボイス音量項目を使うか */
|
||
const useExclusive = exclusiveChannels.length > 0;
|
||
/** 専用ボイス音量の名称 */
|
||
const exOptionName = String(param.exclusiveOptionName || 'ボイス 音量 Ex');
|
||
/** 共通音量初期値 */
|
||
const defaultCommonVolume = Number(param.optionValue || 100);
|
||
/** 専用音量初期値(共通と同じ値を採用) */
|
||
const defaultExclusiveVolume = defaultCommonVolume;
|
||
|
||
//-------------------------------------------------------------------------
|
||
// プラグインコマンド
|
||
//-------------------------------------------------------------------------
|
||
PluginManagerEx.registerCommand(script, 'PLAY_VOICE', args => {
|
||
AudioManager.playVoice(args, args.loop, args.channel);
|
||
});
|
||
|
||
PluginManagerEx.registerCommand(script, 'STOP_VOICE', args => {
|
||
if (args.name) {
|
||
AudioManager.stopVoice(args.name, null);
|
||
} else if (args.channel) {
|
||
AudioManager.stopVoice(null, args.channel);
|
||
} else {
|
||
AudioManager.stopVoice(null, null);
|
||
}
|
||
});
|
||
|
||
//=============================================================================
|
||
// ConfigManager : 共通・専用ボイス音量を保存/読込
|
||
//=============================================================================
|
||
Object.defineProperty(ConfigManager, 'voiceVolume', {
|
||
get() { return AudioManager._voiceVolume; },
|
||
set(v) { AudioManager._voiceVolume = v; }
|
||
});
|
||
|
||
Object.defineProperty(ConfigManager, 'exclusiveVoiceVolume', {
|
||
get() { return AudioManager._exclusiveVoiceVolume; },
|
||
set(v) { AudioManager._exclusiveVoiceVolume = v; }
|
||
});
|
||
|
||
const _SVEx_CM_makeData = ConfigManager.makeData;
|
||
ConfigManager.makeData = function() {
|
||
const data = _SVEx_CM_makeData.apply(this, arguments);
|
||
data.voiceVolume = this.voiceVolume;
|
||
if (useExclusive) data.exclusiveVoiceVolume = this.exclusiveVoiceVolume;
|
||
return data;
|
||
};
|
||
|
||
const _SVEx_CM_load = ConfigManager.load;
|
||
ConfigManager.load = function() {
|
||
this.voiceVolume = defaultCommonVolume;
|
||
if (useExclusive) this.exclusiveVoiceVolume = defaultExclusiveVolume;
|
||
_SVEx_CM_load.apply(this, arguments);
|
||
};
|
||
|
||
const _SVEx_CM_applyData = ConfigManager.applyData;
|
||
ConfigManager.applyData = function(config) {
|
||
_SVEx_CM_applyData.apply(this, arguments);
|
||
if (config.hasOwnProperty('voiceVolume')) {
|
||
this.voiceVolume = this.readVolume(config, 'voiceVolume');
|
||
}
|
||
if (useExclusive && config.hasOwnProperty('exclusiveVoiceVolume')) {
|
||
this.exclusiveVoiceVolume = this.readVolume(config, 'exclusiveVoiceVolume');
|
||
}
|
||
};
|
||
|
||
//=============================================================================
|
||
// Window_Options : ボリューム項目追加
|
||
//=============================================================================
|
||
const _SVEx_WO_addVolumeOptions = Window_Options.prototype.addVolumeOptions;
|
||
Window_Options.prototype.addVolumeOptions = function() {
|
||
_SVEx_WO_addVolumeOptions.apply(this, arguments);
|
||
this.addCommand(commonOptionName, 'voiceVolume');
|
||
if (useExclusive) this.addCommand(exOptionName, 'exclusiveVoiceVolume');
|
||
};
|
||
|
||
const _SVEx_SO_maxCommands = Scene_Options.prototype.maxCommands;
|
||
Scene_Options.prototype.maxCommands = function() {
|
||
return _SVEx_SO_maxCommands.apply(this, arguments) + 1 + (useExclusive ? 1 : 0);
|
||
};
|
||
|
||
//=============================================================================
|
||
// AudioManager : ボイス演奏拡張
|
||
//=============================================================================
|
||
AudioManager._voiceBuffers = [];
|
||
AudioManager._voiceVolume = defaultCommonVolume;
|
||
AudioManager._exclusiveVoiceVolume = defaultExclusiveVolume;
|
||
|
||
AudioManager.updateVoiceParameters = function(buffer, voice) {
|
||
const ch = Number(voice.channel || 0);
|
||
const vol = (useExclusive && exclusiveChannels.includes(ch))
|
||
? this._exclusiveVoiceVolume
|
||
: this._voiceVolume;
|
||
this.updateBufferParameters(buffer, vol, voice);
|
||
};
|
||
|
||
AudioManager.playVoice = function(voice, loop, channel) {
|
||
const voicePath = PluginManagerEx.convertEscapeCharacters(voice.name);
|
||
if (voicePath) {
|
||
const path = ('se/' + voicePath).split('/');
|
||
const name = path.pop();
|
||
const folder = path.join('/') + '/';
|
||
this.stopVoice(voice.name, channel);
|
||
const buffer = this.createBuffer(folder, name);
|
||
voice.channel = channel; // ensure the channel number stays on voice object
|
||
this.updateVoiceParameters(buffer, voice);
|
||
buffer.play(loop, 0);
|
||
buffer.path = voicePath;
|
||
buffer.channel = channel;
|
||
this._voiceBuffers.push(buffer);
|
||
}
|
||
};
|
||
|
||
AudioManager.stopVoice = function(name, channel) {
|
||
const voicePath = name ? PluginManagerEx.convertEscapeCharacters(name) : null;
|
||
this._voiceBuffers.forEach(buffer => {
|
||
if (!name && !channel || buffer.path === voicePath || buffer.channel === channel) {
|
||
buffer.stop();
|
||
}
|
||
});
|
||
this.filterPlayingVoice();
|
||
};
|
||
|
||
AudioManager.filterPlayingVoice = function() {
|
||
this._voiceBuffers = this._voiceBuffers.filter(buffer => {
|
||
const playing = buffer.isPlaying() || !buffer.isReady();
|
||
if (!playing) buffer.stop();
|
||
return playing;
|
||
});
|
||
};
|
||
|
||
const _SVEx_AM_stopAll = AudioManager.stopAll;
|
||
AudioManager.stopAll = function() {
|
||
_SVEx_AM_stopAll.apply(this, arguments);
|
||
this.stopVoice();
|
||
};
|
||
|
||
//=============================================================================
|
||
// Scene_Base : シーンフェード時にボイスも停止
|
||
//=============================================================================
|
||
const _SVEx_SB_fadeOutAll = Scene_Base.prototype.fadeOutAll;
|
||
Scene_Base.prototype.fadeOutAll = function() {
|
||
_SVEx_SB_fadeOutAll.apply(this, arguments);
|
||
AudioManager.stopVoice();
|
||
};
|
||
})(); |