455 lines
17 KiB
JavaScript
455 lines
17 KiB
JavaScript
//=============================================================================
|
||
// ParallelBgs.js
|
||
// ----------------------------------------------------------------------------
|
||
// (C)2016 Triacontane
|
||
// This software is released under the MIT License.
|
||
// http://opensource.org/licenses/mit-license.php
|
||
// ----------------------------------------------------------------------------
|
||
// Version
|
||
// 1.1.0 2022/07/16 BGSの自動演奏が設定されているマップに移動したとき、もとのBGSを全停止できる機能を追加
|
||
// 1.0.4 2021/03/06 BGMのフェードアウトのイベントコマンドでは現在のラインのBGSのみフェードアウトするよう修正
|
||
// 1.0.3 2020/02/02 ヘルプのプラグインコマンド「PB_BGSライン変更」が間違っていたので「PB_BGS_ライン変更」に修正(コード修正なし)
|
||
// 1.0.2 2017/01/05 BGSの演奏状態によっては、セーブ&ロードした際に一部のBGSが演奏されなくなる現象の修正(byくらむぼん氏)
|
||
// 1.0.1 2016/11/16 BGSをプレーしていない状態でセーブ&ロードするとエラーになる現象の修正
|
||
// 1.0.0 2016/11/12 初版
|
||
// ----------------------------------------------------------------------------
|
||
// [Blog] : https://triacontane.blogspot.jp/
|
||
// [Twitter]: https://twitter.com/triacontane/
|
||
// [GitHub] : https://github.com/triacontane/
|
||
//=============================================================================
|
||
|
||
/*:
|
||
* @plugindesc BGS並行演奏プラグイン
|
||
* @author トリアコンタン
|
||
*
|
||
* @param stopAllAutoPlay
|
||
* @text 自動演奏により停止
|
||
* @desc BGSの自動演奏が設定されたマップに移動したとき、全ラインのBGSの演奏を停止します。
|
||
* @default false
|
||
* @type boolean
|
||
*
|
||
* @help 複数のBGSを並行して演奏できます。プラグインコマンドからBGSの演奏ラインを
|
||
* 変更すると元のBGSを演奏したまま、新しくBGSを演奏することができます。
|
||
* 並行演奏しているBGSはそれぞれ個別に、音量やピッチ、左右バランスを調節できます。
|
||
* 演奏ラインのデフォルトは[1]です。
|
||
*
|
||
* ラインの数に制限はありませんが、あまりに大量のBGSを
|
||
* 同時に演奏しようとすると動作に影響がでる恐れがあります。
|
||
*
|
||
* なお、マップで指定するオート演奏のBGSはラインが[1]で固定になります。
|
||
*
|
||
* 追加機能として、BGS演奏中にSEを演奏すると自動でBGSを一時フェードアウトする
|
||
* プラグインコマンドを提供します。SEがより明瞭に聴き取れるようになります。
|
||
* フェードアウト時間やSEの演奏タイミングを設定することもできます。
|
||
*
|
||
* プラグインコマンド詳細
|
||
* イベントコマンド「プラグインコマンド」から実行。
|
||
* (パラメータの間は半角スペースで区切る)
|
||
*
|
||
* PB_BGS_ライン変更 2 # BGSの演奏ラインを[2]に変更します。
|
||
* PB_BGS_CHANGE_LINE 2 # 同上
|
||
* PB_BGS_全停止 # 全ての演奏中のBGSを停止します。
|
||
* PB_BGS_ALL_STOP # 同上
|
||
* PB_BGS_SE演奏時フェードアウト 1 # SE演奏時にBGSを自動フェードアウトします
|
||
* PB_BGS_FADEOUT_FOR_SE 1 # 同上(※1)
|
||
* PB_BGS_フェードアウト時間 3 # 自動フェードアウトに掛かる時間を指定します。
|
||
* PB_BGS_FADEOUT_TIME 3 # 同上
|
||
*
|
||
* ※1 フェードアウト方法を指定できます。
|
||
* 0 : フェードアウトせずに通常通りSEを演奏します。
|
||
* 1 : SE演奏と同時にフェードアウトを開始します。
|
||
* 2 : フェードアウトが完了してからSE演奏します。
|
||
*
|
||
* 2の設定はSEの演奏を実行してから、実際に演奏されるまで時間が掛かります。
|
||
* 使いどころにご注意ください。
|
||
*
|
||
* 利用規約:
|
||
* 作者に無断で改変、再配布が可能で、利用形態(商用、18禁利用等)
|
||
* についても制限はありません。
|
||
* このプラグインはもうあなたのものです。
|
||
*/
|
||
|
||
(function() {
|
||
'use strict';
|
||
var metaTagPrefix = 'PB_';
|
||
|
||
var getCommandName = function(command) {
|
||
return (command || '').toUpperCase();
|
||
};
|
||
|
||
var getArgNumber = function(arg, min, max) {
|
||
if (arguments.length < 2) min = -Infinity;
|
||
if (arguments.length < 3) max = Infinity;
|
||
return (parseInt(convertEscapeCharacters(arg), 10) || 0).clamp(min, max);
|
||
};
|
||
|
||
var convertEscapeCharacters = function(text) {
|
||
if (text == null) text = '';
|
||
var windowLayer = SceneManager._scene._windowLayer;
|
||
return windowLayer ? windowLayer.children[0].convertEscapeCharacters(text) : text;
|
||
};
|
||
|
||
/**
|
||
* Create plugin parameter. param[paramName] ex. param.commandPrefix
|
||
* @param pluginName plugin name(EncounterSwitchConditions)
|
||
* @returns {Object} Created parameter
|
||
*/
|
||
var createPluginParameter = function(pluginName) {
|
||
var paramReplacer = function(key, value) {
|
||
if (value === 'null') {
|
||
return value;
|
||
}
|
||
if (value[0] === '"' && value[value.length - 1] === '"') {
|
||
return value;
|
||
}
|
||
try {
|
||
return JSON.parse(value);
|
||
} catch (e) {
|
||
return value;
|
||
}
|
||
};
|
||
var parameter = JSON.parse(JSON.stringify(PluginManager.parameters(pluginName), paramReplacer));
|
||
PluginManager.setParameters(pluginName, parameter);
|
||
return parameter;
|
||
};
|
||
|
||
var param = createPluginParameter('ParallelBgs');
|
||
|
||
//=============================================================================
|
||
// Game_Interpreter
|
||
// プラグインコマンドを追加定義します。
|
||
//=============================================================================
|
||
var _Game_Interpreter_pluginCommand = Game_Interpreter.prototype.pluginCommand;
|
||
Game_Interpreter.prototype.pluginCommand = function(command, args) {
|
||
_Game_Interpreter_pluginCommand.apply(this, arguments);
|
||
if (!command.match(new RegExp('^' + metaTagPrefix))) return;
|
||
this.pluginCommandParallelBgs(command.replace(metaTagPrefix, ''), args);
|
||
};
|
||
|
||
Game_Interpreter.prototype.pluginCommandParallelBgs = function(command, args) {
|
||
switch (getCommandName(command)) {
|
||
case 'BGS_CHANGE_LINE' :
|
||
case 'BGS_ライン変更' :
|
||
$gameSystem.setBgsLine(getArgNumber(args[0], 1));
|
||
break;
|
||
case 'BGS_ALL_STOP' :
|
||
case 'BGS_全停止' :
|
||
AudioManager.stopAllBgs();
|
||
break;
|
||
case 'BGS_FADEOUT_FOR_SE' :
|
||
case 'BGS_SE演奏時フェードアウト' :
|
||
$gameSystem.setBgsFadeForSe(getArgNumber(args[0], 0));
|
||
break;
|
||
case 'BGS_FADEOUT_TIME' :
|
||
case 'BGS_フェードアウト時間' :
|
||
$gameSystem.setBgsFadeTime(getArgNumber(args[0], 1));
|
||
break;
|
||
}
|
||
};
|
||
|
||
var _Game_Interpreter_command246 = Game_Interpreter.prototype.command246;
|
||
Game_Interpreter.prototype.command246 = function(params) {
|
||
AudioManager._bgsFadeOutByLine = true;
|
||
var result = _Game_Interpreter_command246.apply(this, arguments);
|
||
AudioManager._bgsFadeOutByLine = false;
|
||
return result;
|
||
};
|
||
|
||
//=============================================================================
|
||
// Game_System
|
||
// BGS演奏ラインを変更します。
|
||
//=============================================================================
|
||
var _Game_System_initialize = Game_System.prototype.initialize;
|
||
Game_System.prototype.initialize = function() {
|
||
_Game_System_initialize.apply(this, arguments);
|
||
this.initBgsMember();
|
||
};
|
||
|
||
Game_System.prototype.initBgsMember = function() {
|
||
this.setBgsLine(this.getBgsLine());
|
||
this.setBgsFadeForSe(this.getBgsFadeForSe());
|
||
this.setBgsFadeTime(this.getBgsFadeTime());
|
||
};
|
||
|
||
Game_System.prototype.getBgsLine = function() {
|
||
return this._bgsLine || 1;
|
||
};
|
||
|
||
Game_System.prototype.setBgsLine = function(value) {
|
||
this._bgsLine = value;
|
||
AudioManager.setBgsLineIndex(value);
|
||
};
|
||
|
||
Game_System.prototype.getBgsFadeForSe = function() {
|
||
return this._bgsFadeForPlayingSe || 0;
|
||
};
|
||
|
||
Game_System.prototype.setBgsFadeForSe = function(value) {
|
||
this._bgsFadeForPlayingSe = value;
|
||
AudioManager.setBgsFadeForSe(value);
|
||
};
|
||
|
||
Game_System.prototype.getBgsFadeTime = function() {
|
||
return this._bgsFadeTime || 1;
|
||
};
|
||
|
||
Game_System.prototype.setBgsFadeTime = function(value) {
|
||
this._bgsFadeTime = value;
|
||
AudioManager.setBgsFadeTime(value);
|
||
};
|
||
|
||
var _Game_System_onAfterLoad = Game_System.prototype.onAfterLoad;
|
||
Game_System.prototype.onAfterLoad = function() {
|
||
_Game_System_onAfterLoad.apply(this, arguments);
|
||
this.initBgsMember();
|
||
};
|
||
|
||
var _Game_Map_autoplay = Game_Map.prototype.autoplay;
|
||
Game_Map.prototype.autoplay = function() {
|
||
if ($dataMap.autoplayBgs && param.stopAllAutoPlay) {
|
||
AudioManager.stopAllBgs();
|
||
}
|
||
AudioManager.multiLineDisable = true;
|
||
_Game_Map_autoplay.apply(this, arguments);
|
||
AudioManager.multiLineDisable = false;
|
||
};
|
||
|
||
//=============================================================================
|
||
// AudioManager
|
||
// 複数のBGS演奏ラインを管理します。
|
||
//=============================================================================
|
||
AudioManager.multiLineDisable = false;
|
||
AudioManager._bgsLineIndex = 1;
|
||
AudioManager._bgsFadeForSe = 0;
|
||
AudioManager._bgsFadeTime = 1;
|
||
AudioManager._allBgsBuffer = [];
|
||
AudioManager._currentAllBgs = [];
|
||
AudioManager._delaySeStack = [];
|
||
AudioManager._allStop = false;
|
||
AudioManager._stopAllBgs = true;
|
||
AudioManager._bgsFading = false;
|
||
AudioManager._bgsFadeCounter = 0;
|
||
|
||
var _AudioManager_bgsVolume = Object.getOwnPropertyDescriptor(AudioManager, 'bgsVolume');
|
||
Object.defineProperty(AudioManager, 'bgsVolume', {
|
||
get: function() {
|
||
return _AudioManager_bgsVolume.get.call(this);
|
||
},
|
||
set: function(value) {
|
||
_AudioManager_bgsVolume.set.call(this, value);
|
||
var nowBgs = this._currentBgs;
|
||
this.iterateAllBgs(function() {
|
||
if (nowBgs !== this._currentBgs) this.updateBgsParameters(this._currentBgs);
|
||
}.bind(this));
|
||
},
|
||
configurable: true
|
||
});
|
||
|
||
Object.defineProperty(AudioManager, '_bgsBuffer', {
|
||
get: function() {
|
||
return this._allBgsBuffer[this.getBgsLineIndex()];
|
||
},
|
||
set: function(value) {
|
||
this._allBgsBuffer[this.getBgsLineIndex()] = value;
|
||
}
|
||
});
|
||
|
||
Object.defineProperty(AudioManager, '_currentBgs', {
|
||
get: function() {
|
||
return this._currentAllBgs[this.getBgsLineIndex()];
|
||
},
|
||
set: function(value) {
|
||
this._currentAllBgs[this.getBgsLineIndex()] = value;
|
||
}
|
||
});
|
||
|
||
AudioManager.getBgsLineIndex = function() {
|
||
return this.multiLineDisable ? 1 : this._bgsLineIndex;
|
||
};
|
||
|
||
AudioManager.setBgsLineIndex = function(index) {
|
||
this._bgsLineIndex = index;
|
||
};
|
||
|
||
AudioManager.setBgsFadeForSe = function(value) {
|
||
this._bgsFadeForSe = value;
|
||
};
|
||
|
||
AudioManager.setBgsFadeTime = function(value) {
|
||
this._bgsFadeTime = value;
|
||
};
|
||
|
||
var _AudioManager_playBgs = AudioManager.playBgs;
|
||
AudioManager.playBgs = function(bgs, pos) {
|
||
if (!bgs) return;
|
||
this._stopAllBgs = false;
|
||
if (Array.isArray(bgs)) {
|
||
this.playAllBgs(bgs);
|
||
} else {
|
||
_AudioManager_playBgs.apply(this, arguments);
|
||
}
|
||
this._stopAllBgs = true;
|
||
};
|
||
|
||
AudioManager.playAllBgs = function(bgsArray) {
|
||
this.stopAllBgs();
|
||
var prevIndex = this._bgsLineIndex;
|
||
this._bgsLineIndex = 1;
|
||
bgsArray.forEach(function(bgs, index) {
|
||
this._bgsLineIndex = index;
|
||
this.playBgs(bgs, null);
|
||
}, this);
|
||
this._bgsLineIndex = prevIndex;
|
||
};
|
||
|
||
var _AudioManager_replayBgs = AudioManager.replayBgs;
|
||
AudioManager.replayBgs = function(bgs) {
|
||
if (!bgs) return;
|
||
if (Array.isArray(bgs)) {
|
||
this.replayAllBgs(bgs);
|
||
} else {
|
||
_AudioManager_replayBgs.apply(this, arguments);
|
||
}
|
||
};
|
||
|
||
AudioManager.replayAllBgs = function(bgsArray) {
|
||
this.stopAllBgs();
|
||
var prevIndex = this._bgsLineIndex;
|
||
this._bgsLineIndex = 1;
|
||
bgsArray.forEach(function(bgs, index) {
|
||
this._bgsLineIndex = index;
|
||
this.replayBgs(bgs);
|
||
}, this);
|
||
this._bgsLineIndex = prevIndex;
|
||
};
|
||
|
||
var _AudioManager_saveBgs = AudioManager.saveBgs;
|
||
AudioManager.saveBgs = function() {
|
||
var bgsArray = [];
|
||
this.iterateAllBgs(function() {
|
||
bgsArray[this._bgsLineIndex] = _AudioManager_saveBgs.apply(this, arguments);
|
||
}.bind(this));
|
||
return bgsArray.length > 1 ? bgsArray : bgsArray[0];
|
||
};
|
||
|
||
var _AudioManager_stopBgs = AudioManager.stopBgs;
|
||
AudioManager.stopBgs = function() {
|
||
if (!this._stopAllBgs) {
|
||
_AudioManager_stopBgs.apply(this, arguments);
|
||
} else {
|
||
this.stopAllBgs();
|
||
}
|
||
};
|
||
|
||
AudioManager.stopAllBgs = function() {
|
||
this.iterateAllBgs(function() {
|
||
_AudioManager_stopBgs.apply(this, arguments);
|
||
}.bind(this));
|
||
};
|
||
|
||
var _AudioManager_fadeOutBgs = AudioManager.fadeOutBgs;
|
||
AudioManager.fadeOutBgs = function(time) {
|
||
if (this._bgsFadeOutByLine) {
|
||
_AudioManager_fadeOutBgs.call(this, time);
|
||
} else {
|
||
this.iterateAllBgs(function() {
|
||
_AudioManager_fadeOutBgs.call(this, time);
|
||
}.bind(this));
|
||
}
|
||
};
|
||
|
||
const _AudioManager_fadeInBgs = AudioManager.fadeInBgs;
|
||
AudioManager.fadeInBgs = function(time) {
|
||
this.iterateAllBgs(function() {
|
||
_AudioManager_fadeInBgs.call(this, time);
|
||
}.bind(this));
|
||
};
|
||
|
||
AudioManager.iterateAllBgs = function(callBack) {
|
||
var prevIndex = this._bgsLineIndex;
|
||
Object.keys(this._allBgsBuffer).forEach(function(index) {
|
||
this._bgsLineIndex = index;
|
||
callBack(this._bgsBuffer);
|
||
}, this);
|
||
this._bgsLineIndex = prevIndex;
|
||
};
|
||
|
||
var _AudioManager_playSe = AudioManager.playSe;
|
||
AudioManager.playSe = function(se) {
|
||
if (this.isNeedFadeOut()) {
|
||
this.fadeOutBgsForSe();
|
||
}
|
||
if (this._bgsFadeForSe === 2 && this._currentBgs && this._bgsFadeCounter > 0) {
|
||
this._delaySeStack.push(se);
|
||
} else {
|
||
_AudioManager_playSe.apply(this, arguments);
|
||
}
|
||
};
|
||
|
||
AudioManager.updateBgsFade = function() {
|
||
if (this.isNeedFadeIn()) {
|
||
this.fadeInBgsForSe();
|
||
}
|
||
if (this._bgsFadeCounter > 0) {
|
||
this._bgsFadeCounter--;
|
||
if (this._bgsFadeCounter === 0) {
|
||
this.playDelayedSe();
|
||
}
|
||
}
|
||
};
|
||
|
||
AudioManager.fadeOutBgsForSe = function() {
|
||
var currentAllBgs = this._currentAllBgs.clone();
|
||
this.fadeOutBgs(this._bgsFadeTime);
|
||
this._currentAllBgs = currentAllBgs;
|
||
this._bgsFading = true;
|
||
this._bgsFadeCounter = this._bgsFadeTime * 60;
|
||
};
|
||
|
||
AudioManager.isNeedFadeOut = function() {
|
||
return !this._bgsFading && this._bgsFadeForSe !== 0;
|
||
};
|
||
|
||
AudioManager.fadeInBgsForSe = function() {
|
||
this.fadeInBgs(this._bgsFadeTime);
|
||
this._bgsFading = false;
|
||
this._bgsFadeCounter = 0;
|
||
};
|
||
|
||
AudioManager.isNeedFadeIn = function() {
|
||
return this._bgsFading && !this.isPlayingAnySe() && this._bgsFadeCounter === 0;
|
||
};
|
||
|
||
AudioManager.playDelayedSe = function() {
|
||
while (this._delaySeStack.length > 0) {
|
||
_AudioManager_playSe.call(this, this._delaySeStack.pop());
|
||
}
|
||
};
|
||
|
||
AudioManager.isPlayingAnySe = function() {
|
||
return this._seBuffers.some(function(audio) {
|
||
return audio.isExist();
|
||
});
|
||
};
|
||
|
||
//=============================================================================
|
||
// WebAudio
|
||
// 演奏が要求済みかどうかを返します。
|
||
//=============================================================================
|
||
WebAudio.prototype.isExist = function() {
|
||
return this._autoPlay;
|
||
};
|
||
|
||
//=============================================================================
|
||
// SceneManager
|
||
// AudioManagerの更新処理を呼び出します。
|
||
//=============================================================================
|
||
var _SceneManager_updateScene = SceneManager.updateScene;
|
||
SceneManager.updateScene = function() {
|
||
_SceneManager_updateScene.apply(this, arguments);
|
||
if (this._scene) {
|
||
AudioManager.updateBgsFade();
|
||
}
|
||
};
|
||
})();
|
||
|