moon-red-goddess-cornelia/js/plugins/InstantEvent.js
2025-03-31 13:21:45 -05:00

1000 lines
No EOL
32 KiB
JavaScript
Raw Permalink Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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.

// InstantEvent.js Ver.1.1.0
// MIT License (C) 2024 あわやまたな
// http://opensource.org/licenses/mit-license.php
/*:
* @target MZ
* @base PluginCommonBase
* @orderAfter PluginCommonBase
* @plugindesc It makes it easy to mass-produce elaborate events.
* Introduces the concepts of so-called arguments and immediate functions.
* @author あわやまたな (Awaya_Matana)
* @url https://awaya3ji.seesaa.net/article/503552403.html
* @help Ver.1.1.0
* [Introduction]
* Considering the purpose of the plugin, for convenience we will refer to the "Event ID" as the "Target ID".
* This is because the event ID uses unique control characters so that it can be used for various numbers.
* An "argument" is an independent variable that cannot be interfered with from the outside.
* This is useful when you want to change the processing depending on the input value.
*
* [Plugin Commands]
* The target ID is basically a number used to specify "This Event",
* but it can also be used as a different number by using the following scripts and control characters.
*
* [Scripts]
* this._eventId //Get the current target ID
* this._args[n] //Get the argument (n is an integer greater than or equal to 0)
* this._pictureId //Get the current replacement picture ID
*
* [Control characters (for plugin commands only)]
* \eventId //Get the current target ID
* \args[n] //Get the argument (n is an integer greater than or equal to 0)
* \pictureId //Get the current replacement picture ID
*
* [Control characters (for "Show Text" only)]
* \Vpp[n] //Add 1 to variable #n (Variable++)
* \Vmm[n] //Subtract 1 from variable #n (Variable--)
* \Son[n] //Switch #n ON (Switch ON)
* \Soff[n] //Switch #n OFF (Switch OFF)
*
* \WfV[n,m] //Wait until variable #n is equal to or greater than m (Wait for Variable)
* \WfS[n] //Wait until switch n is ON (Wait for Switch)
* \WfS[n,false] //Wait until switch n is OFF
*
* [Specifications]
* Instant parallel events will be deleted once their content has been achieved.
*
* Creating a new instant parallel event with a duplicate identifier will not delete the old one.
*
* If there are multiple instant parallel events with duplicate identifiers,
* "Delete Instant Parallel Events" and "Wait for Completion" will be performed on all of them.
*
* If the identifier is not specified or is blank, the blank itself becomes the identifier.
* Therefore, you can "Remove Instant Parallel Events" and "Wait for Completion" while leaving the identifier blank.
*
* Even if this._pictureId is 0, \pictureId will be set to 1.
* This is to ensure smooth test play.
*
* @param controlCharactersEnabled
* @text Enable Control Characters
* @desc Use control characters to manipulate variables and switches.
* @type boolean
* @default true
*
* @param timing
* @text Timing
* @desc Improvised parallel processing on the map occurs after the player's processing.
* @type boolean
* @default false
* @on After the player
* @off Default
*
* @param playerToEvent
* @text Treat the player as an event
* @desc When the target ID is -1, you will be able to handle the player using "This Event" or this.character(0).
* @type boolean
* @default true
*
* @command setupInstantEvent
* @text Instant Event
* @desc The commands in the "Skip" directly below will be extracted and executed in order.
*
* @arg targetId
* @text Target ID
* @desc Specify the ID of the operation target.
* For multiple entries, use ",", "-", or "to".
* @default \eventId
*
* @arg options
* @text Options
* @type struct<options>
* @desc Configure additional settings.
*
* @command setupInstantCommonEvent
* @text Instant Common Event
* @desc This will run the common event content with various functions added.
*
* @arg targetId
* @text Target ID
* @desc Specify the ID of the operation target.
* For multiple entries, use ",", "-", or "to".
* @default \eventId
*
* @arg commonEventId
* @text Common Event ID
* @desc Select a common event.
* @default 1
* @type common_event
*
* @arg options
* @text Options
* @type struct<options>
* @desc Configure additional settings.
*
* @command setupInstantParallelEvent
* @text Instant Parallel Event
* @desc Creates a disposable parallel process from the common event.
*
* @arg targetId
* @text Target ID
* @desc Specify the ID of the operation target.
* For multiple entries, use ",", "-", or "to".
* @default \eventId
*
* @arg options
* @text Options
* @type struct<parallelOptions>
* @desc Configure additional settings.
*
* @command setupInstantParallelCommonEvent
* @text Instant Parallel Common Event
* @desc Creates a disposable parallel process from the common event.
*
* @arg targetId
* @text Target ID
* @desc Specify the ID of the operation target.
* For multiple entries, use ",", "-", or "to".
* @default \eventId
*
* @arg commonEventId
* @text Common Event ID
* @desc Select a common event.
* @default 1
* @type common_event
*
* @arg options
* @text Options
* @type struct<parallelOptions>
* @desc Configure additional settings.
*
* @command removeParallelInstantEvent
* @text Remove Parallel Instant Event
* @desc Removes an instant parallel event.
*
* @arg id
* @text Identifier
* @desc The name to manage the event.
* %1:Target ID %2:Map ID
* @default EV:%1
*
* @arg targetId
* @text Target ID
* @desc Specify the number to be entered in %1.
* For multiple entries, use ",", "-", or "to".
* @default \eventId
*
* @command removeAllParallelInstantEvents
* @text Remove All Parallel Instant Events
* @desc Removes all instant parallel events.
*
* @command waitForCompletion
* @text Wait for Completion
* @desc Waits for the specified instant parallel event to complete.
*
* @arg id
* @text Identifier
* @desc The name to manage the event.
* %1:Target ID %2:Map ID
* @default EV:%1
*
* @command replacePictureId
* @text Replace Picture ID
* @desc Replaces the default picture event command numbers all at once.
*
* @arg pictureId
* @text Picture ID
* @desc Reset to 0.
* @default \eventId
*
*/
/*~struct~options:
*
* @param args
* @text Arguments
* @desc The value that will be placed in \args[n] and this._args[n] of the called event.
* @type string[]
*
* @param times
* @text Number of Times
* @desc The number of executions.
* @default 1
*
*/
/*~struct~parallelOptions:
*
* @param id
* @text Identifier
* @desc The name to manage the event.
* %1:Target ID %2:Map ID
* @default EV:%1
*
* @param args
* @text Arguments
* @desc The value that will be placed in \args[n] and this._args[n] of the called event.
* @type string[]
*
* @param times
* @text Number of Times
* @desc The number of executions.
* @default 1
*
* @param delay
* @text Delay
* @desc Specify the number of frames. The execution timing will be gradually delayed depending on the number of targets and executions.
* @default 0
*
* @param autoRemove
* @text Auto Remove
* @desc Removes this event when moving between maps (useless in battle).
* @default false
* @type boolean
*
*/
/*:ja
* @target MZ
* @base PluginCommonBase
* @orderAfter PluginCommonBase
* @plugindesc 凝ったイベントを容易に量産可能にします。
* いわゆる引数や即時関数の概念を導入。
* @author あわやまたな (Awaya_Matana)
* @url https://awaya3ji.seesaa.net/article/503552403.html
* @help
* [はじめに]
* プラグインの用途を考慮し、「イベントID」の事を便宜上「対象ID」と呼ぶことにします。
* イベントIDを独自の制御文字で様々な数値に流用できるようにしている為です。
* 「引数」は、外部から干渉できない独立した変数です。
* 入力値に応じて処理を変えたい場合に役立ちます。
*
* [プラグインコマンド]
* 対象IDは基本的に「このイベント」を指定する為の数値ですが、
* 以下のスクリプトや制御文字を活用する事で別の数値として流用することも可能です。
*
* [スクリプト]
* this._eventId  //現在の対象IDを取得
* this._args[n]  //引数を取得nは0以上の整数
* this._pictureId //現在置換中のピクチャIDを取得
*
* [制御文字(プラグインコマンド専用)]
* \eventId  //現在の対象IDを取得
* \args[n]  //引数を取得nは0以上の整数
* \pictureId //現在置換中のピクチャIDを取得
*
* [制御文字(文章の表示専用)]
* \Vpp[n]   //変数nを1加算Variable++
* \Vmm[n]   //変数nを1減算Variable--
* \Son[n]   //スイッチnをONSwitch ON
* \Soff[n]  //スイッチnをOFFSwitch OFF
*
* \WfV[n,m]  //変数nがm以上になるまでウェイトWait for Variable
* \WfS[n]   //スイッチnがONになるまでウェイトWait for Switch
* \WfS[n,false]  //スイッチnがOFFになるまでウェイト
*
* [仕様]
* 一度実行内容を達成した即席並列イベントは削除されます。
*
* 識別子の重複した即席並列イベントを新たに生成しても古い方は削除されません。
*
* 重複した識別子の即席並列イベントが複数存在する場合、その全てに対して
*「即席並列イベントの削除」「完了までウェイト」が行われます。
*
* 識別子が未指定、もしくは空欄である場合、空欄そのものが識別子となります。
* なので識別子が空欄のまま「即席並列イベントの削除」「完了までウェイト」が行えます。
*
* this._pictureIdが0でも\pictureIdは1が入ります。
* テストプレイを円滑に行う為です。
*
* [更新履歴]
* 2024/06/05Ver.1.0.0 公開。
* 2024/06/13Ver.1.1.0 挙動の修正。
*
* @param controlCharactersEnabled
* @text 制御文字有効化
* @desc 変数やスイッチを操作する制御文字を使います。
* @type boolean
* @default true
*
* @param timing
* @text タイミング
* @desc マップでの即席並列処理をプレイヤーの処理より後に実行する。
* 標準は並列処理の後、プレイヤーの処理の前。
* @type boolean
* @default false
* @on プレイヤーより後
* @off 標準
*
* @param playerToEvent
* @text プレイヤーをイベント化
* @desc 対象IDが-1の時に「このイベント」やthis.character(0)などでプレイヤーを扱えるようにします。
* @type boolean
* @default true
*
* @command setupInstantEvent
* @text 即席イベントの設定
* @desc 真下にある「スキップ」内の実行内容を切り出し、様々な機能を追加した状態で順番に実行します。
*
* @arg targetId
* @text 対象ID
* @desc 操作対象のIDを指定します。IDの数だけ実行内容を生成。
* 範囲・複数指定はコンマやハイフン、to(例1-3,12,15,18to20)
* @default \eventId
*
* @arg options
* @text オプション
* @type struct<options>
* @desc 追加設定を行います。
*
* @command setupInstantCommonEvent
* @text 即席コモンイベントの設定
* @desc コモンイベントの実行内容に様々な機能を追加した状態で順番に実行します。
*
* @arg targetId
* @text 対象ID
* @desc 操作対象のIDを指定します。IDの数だけ実行内容を生成。
* 範囲・複数指定はコンマやハイフン、to(例1-3,12,15,18to20)
* @default \eventId
*
* @arg commonEventId
* @text コモンイベントID
* @desc コモンイベントを選択します。
* @default 1
* @type common_event
*
* @arg options
* @text オプション
* @type struct<options>
* @desc 追加設定を行います。
*
* @command setupInstantParallelEvent
* @text 即席並列イベントの設定
* @desc 真下にある「スキップ」内から実行内容を切り出し、1度だけ実行される使い捨ての並列処理を生成します。
*
* @arg targetId
* @text 対象ID
* @desc 操作対象のIDを指定します。IDの数だけ実行内容を生成。
* 範囲・複数指定はコンマやハイフン、to(例1-3,12,15,18to20)
* @default \eventId
*
* @arg options
* @text オプション
* @type struct<parallelOptions>
* @desc 追加設定を行います。
*
* @command setupInstantParallelCommonEvent
* @text 即席並列コモンイベントの設定
* @desc 実行内容に様々な機能を追加した状態のコモンイベントから、1度だけ実行される使い捨ての並列処理を生成します。
*
* @arg targetId
* @text 対象ID
* @desc 操作対象のIDを指定します。IDの数だけ実行内容を生成。
* 範囲・複数指定はコンマやハイフン、to(例1-3,12,15,18to20)
* @default \eventId
*
* @arg commonEventId
* @text コモンイベントID
* @desc コモンイベントを選択します。
* @default 1
* @type common_event
*
* @arg options
* @text オプション
* @type struct<parallelOptions>
* @desc 追加設定を行います。
*
* @command removeParallelInstantEvent
* @text 即席並列イベントの削除
* @desc 即席並列イベントを削除します。
*
* @arg id
* @text 識別子
* @desc 特定の文字列を入れると以下に置き換わります。
* %1対象ID %2マップID
* @default EV:%1
*
* @arg targetId
* @text 対象ID
* @desc %1に入る数字を指定します。
* 範囲・複数指定はコンマやハイフン、to(例1-3,12,15,18to20)
* @default \eventId
*
* @command removeAllParallelInstantEvents
* @text 全ての即席並列イベントの削除
* @desc 即席並列イベントを全て削除します。
*
* @command waitForCompletion
* @text 完了までウェイト
* @desc 指定した即席並列イベントが完了するまで待ちます。
*
* @arg id
* @text 識別子
* @desc 特定の文字列を入れると以下に置き換わります。
* %1このイベントのイベントID %2マップID
* @default EV:%1
*
* @command replacePictureId
* @text ピクチャIDの置換
* @desc 標準のピクチャ系イベントコマンドの番号を一括で置き換えます。
* @arg pictureId
* @text ピクチャID
* @desc 0で元に戻す。
* @default \eventId
*
*/
/*~struct~options:ja
*
* @param args
* @text 引数
* @desc 呼び出し先のイベントの\args[n]、this._args[n]に入る値。
* @type string[]
*
* @param times
* @text 実行回数
* @desc 実行回数です。
* @default 1
*
*/
/*~struct~parallelOptions:ja
*
* @param id
* @text 識別子
* @desc 特定の文字列を入れると以下に置き換わります。
* %1対象ID %2マップID
* @default EV:%1
*
* @param args
* @text 引数
* @desc 呼び出し先のイベントの\args[n]、this._args[n]に入る値。
* @type string[]
*
* @param times
* @text 実行回数
* @desc 実行回数です。
* @default 1
*
* @param delay
* @text 遅延
* @desc フレーム数を指定。対象数および実行回数に応じて実行タイミングを徐々に遅らせます。
* @default 0
*
* @param autoRemove
* @text 自動削除
* @desc マップ移動時にこのイベントを削除します(戦闘では無意味)。
* @default false
* @type boolean
*
*/
(() => {
'use strict';
const pluginName = document.currentScript.src.match(/^.*\/(.*).js$/)[1];
const parameter = PluginManager.parameters(pluginName);
const controlCharactersEnabled = parameter.controlCharactersEnabled === "true";
const timing = parameter.timing === "true";
const playerToEvent = parameter.playerToEvent === "true";
//-----------------------------------------------------------------------------
// PluginManagerEx
PluginManagerEx.registerCommand(document.currentScript, "setupInstantEvent", function(args) {
const list = InstantEventManager.extractList(self, this._index, this._list);
if (list) {
this.setupInstantCommon(list, InstantEventManager.extractEventIds(self, args.targetId), args.options);
}
});
PluginManagerEx.registerCommand(document.currentScript, "setupInstantCommonEvent", function(args) {
const event = $dataCommonEvents[args.commonEventId];
if (event) {
this.setupInstantCommon(event.list, InstantEventManager.extractEventIds(self, args.targetId), args.options);
}
});
PluginManagerEx.registerCommand(document.currentScript, "setupInstantParallelEvent", function(args) {
const list = InstantEventManager.extractList(self, this._index, this._list);
if (list) {
this.setupInstantParallel(list, InstantEventManager.extractEventIds(self, args.targetId), args.options);
}
});
PluginManagerEx.registerCommand(document.currentScript, "setupInstantParallelCommonEvent", function(args) {
const event = $dataCommonEvents[args.commonEventId];
if (event) {
this.setupInstantParallel(event.list, InstantEventManager.extractEventIds(self, args.targetId), args.options);
}
});
PluginManagerEx.registerCommand(document.currentScript, "removeParallelInstantEvent", function(args) {
this.removeInstantParallel(args.id, InstantEventManager.extractEventIds(self, args.targetId));
});
PluginManagerEx.registerCommand(document.currentScript, "removeAllParallelInstantEvents", function(args) {
this.removeAllInstantParallels();
});
PluginManagerEx.registerCommand(document.currentScript, "waitForCompletion", function(args) {
this.waitForInstantParallels(args.id);
});
const _PluginManagerEx_convertEscapeCharactersEx = PluginManagerEx.convertEscapeCharactersEx;
PluginManagerEx.convertEscapeCharactersEx = function(text, data = null) {
text = _PluginManagerEx_convertEscapeCharactersEx.call(this, text, data);
text = text.replace(/\x1bEVENTID/gi, InstantEventManager._eventId);
text = text.replace(/\x1bARGS\[(\d+)]/gi, (_, p1) => InstantEventManager._args[parseInt(p1)]);
text = text.replace(/\x1bPICTUREID/gi, InstantEventManager._pictureId || 1);
return text;
};
PluginManagerEx.registerCommand(document.currentScript, "replacePictureId", function(args) {
this._pictureId = args.pictureId || 0;
});
//-----------------------------------------------------------------------------
// PluginManager
//完了までウェイトの監視用
PluginManager.registerCommand(pluginName, "updateWaitMode", function(args) {
const owner = this.instantParallelOwner();
const instantEvents = InstantEventManager.instantEvents(owner);
const isRunning = instantEvents.some(interpreter => interpreter._instantId === args.id && interpreter.isRunning());
if (isRunning) {
this.wait(1);
} else {
this.command113();
}
});
//複数回実行用
PluginManager.registerCommand(pluginName, "setupChild", function(args) {
const event = this._instantCommonEvent;
if (event) {
this.setupInstantChild(event.list, args.targetId, event.args);
}
});
//制御文字で呼び出す値をセット
const _PluginManager_callCommand = PluginManager.callCommand;
PluginManager.callCommand = function(self, pluginName, commandName, args) {
InstantEventManager._eventId = self._eventId;
InstantEventManager._pictureId = self._pictureId || 0;
InstantEventManager._args = self._args || [];
_PluginManager_callCommand.apply(this, arguments);
};
//-----------------------------------------------------------------------------
// Game_Interpreter
if (playerToEvent) {
const _Game_Interpreter_character = Game_Interpreter.prototype.character;
Game_Interpreter.prototype.character = function(param) {
return _Game_Interpreter_character.call(this, param === 0 ? this._eventId : param);
};
}
const _Game_Interpreter_clear = Game_Interpreter.prototype.clear;
Game_Interpreter.prototype.clear = function() {
_Game_Interpreter_clear.call(this);
this._pictureId = 0;
};
Game_Interpreter.prototype.setupInstant = function(list, eventId, args, id, autoRemove) {
this.setup(list, eventId);
this._instantId = String(id || "");
this._args = args || [];
this._autoRemove = autoRemove || false;
};
Game_Interpreter.prototype.setupInstantChild = function(list, eventId, args) {
this.setupChild(list, eventId);
this._childInterpreter.setupInstant(list, eventId, args);
};
Game_Interpreter.prototype.setupInstantParallel = function(baseList, targets, options = {}) {
const times = options.times || 1;
targets = InstantEventManager.allTargets(self, targets, times);
const baseDelay = options.delay || 0;
const owner = this.instantParallelOwner();
for (let i = 0; i < targets.length; i++) {
let list = baseList;
const targetId = targets[i] || 0;
const delay = baseDelay * i;
if (delay) {
list = list.clone();
list.unshift({"code":230,"indent":list[0].indent,"parameters":[delay]});
}
InstantEventManager.setupInterpreter(owner, list, targetId, options.args, String(options.id ?? "").format(targetId, this._mapId), options.autoRemove);
}
}
//深度やデータ数を増やさないようにコマンドを生成。
Game_Interpreter.prototype.setupInstantCommon = function(list, targets, options = {}) {
const times = options.times || 1;
const args = options.args || null;
targets = InstantEventManager.allTargets(self, targets, times);
//一回だけならそのまま実行
if (targets.length === 1){
this.setupInstantChild(list, targets[0], args);
return;
}
//複数回なら新たに専用リストを生成。
const newList = InstantEventManager.repeatList(self, targets);
this.setupChild(newList, this._eventId);
this._childInterpreter._instantCommonEvent = {"list": list, "args": args };
};
Game_Interpreter.prototype.removeInstantParallel = function(id, targets) {
const owner = this.instantParallelOwner();
id = String(id ?? "");
for (let i = 0; i < targets.length; i++) {
const targetId = targets[i] || 0;
InstantEventManager.removeEvent(owner, id.format(targetId, this._mapId));
}
};
Game_Interpreter.prototype.removeAllInstantParallels = function() {
const owner = this.instantParallelOwner();
InstantEventManager.removeAllEvents(owner);
};
//即席並列の実行主体を選択。
Game_Interpreter.prototype.instantParallelOwner = function() {
return $gameParty.inBattle() ? BattleManager : $gameMap;
};
Game_Interpreter.prototype.waitForInstantParallels = function(id) {
id = String(id ?? "");
this.setupChild(InstantEventManager.waitList(self, id.format(this._eventId, this._mapId)));
};
// Show Picture Move Picture Rotate Picture Tint Picture Erase Picture
for (const XXX of [231, 232, 233, 234, 235]) {
const commandXXX = "command" + XXX;
const _Game_Interpreter_commandXXX = Game_Interpreter.prototype[commandXXX];
Game_Interpreter.prototype[commandXXX] = function(params) {
const defaultId = params[0];
params[0] = this._pictureId || defaultId;
const r = _Game_Interpreter_commandXXX.call(this, params);
params[0] = defaultId;
return r;
};
}
//即席並列ならリフレッシュを要求
const _Game_Interpreter_terminate = Game_Interpreter.prototype.terminate;
Game_Interpreter.prototype.terminate = function() {
_Game_Interpreter_terminate.call(this);
if (this._isInstantParallel) {
const owner = this.instantParallelOwner();
InstantEventManager.requestRefresh(owner);
}
};
//-----------------------------------------------------------------------------
// Game_System
//制作者が本プラグインを導入する前のデータを読み込んだとき
const _Game_System_onAfterLoad = Game_System.prototype.onAfterLoad;
Game_System.prototype.onAfterLoad = function() {
_Game_System_onAfterLoad.call(this);
if (!InstantEventManager.instantEvents($gameMap)) {
InstantEventManager.initEvents($gameMap);
}
};
//-----------------------------------------------------------------------------
// Game_Map
const _Game_Map_initialize = Game_Map.prototype.initialize;
Game_Map.prototype.initialize = function() {
_Game_Map_initialize.call(this);
InstantEventManager.initEvents(this);
};
//マップ切り替え時に自動消去(&オートセーブ対策)
const _Game_Map_setupEvents = Game_Map.prototype.setupEvents;
Game_Map.prototype.setupEvents = function() {
_Game_Map_setupEvents.call(this);
InstantEventManager.executeAutoRemove(this);
};
//即席並列の更新
if (!timing) {
const _Game_Map_updateEvents = Game_Map.prototype.updateEvents;
Game_Map.prototype.updateEvents = function() {
_Game_Map_updateEvents.call(this);
InstantEventManager.updateEvents(this);
};
}
//-----------------------------------------------------------------------------
// Game_Player
if (timing) {
const _Game_Player_update = Game_Player.prototype.update;
Game_Player.prototype.update = function(sceneActive) {
_Game_Player_update.call(this, sceneActive);
InstantEventManager.updateEvents($gameMap);
};
}
//-----------------------------------------------------------------------------
// Scene_Map
//シーン終了時にリフレッシュ(メニューからのセーブ対策)
const _Scene_Map_terminate = Scene_Map.prototype.terminate;
Scene_Map.prototype.terminate = function() {
_Scene_Map_terminate.call(this);
InstantEventManager.refreshEvents($gameMap);
};
//-----------------------------------------------------------------------------
// Scene_Battle
//シーン終了時に全削除
const _Scene_Battle_terminate = Scene_Battle.prototype.terminate;
Scene_Battle.prototype.terminate = function() {
_Scene_Battle_terminate.call(this);
InstantEventManager.removeAllEvents(BattleManager);
};
//-----------------------------------------------------------------------------
// BattleManager
const _BattleManager_update = BattleManager.update;
BattleManager.update = function(timeActive) {
_BattleManager_update.call(this, timeActive);
InstantEventManager.updateEvents(this);
};
const _BattleManager_initMembers = BattleManager.initMembers;
BattleManager.initMembers = function() {
_BattleManager_initMembers.call(this);
InstantEventManager.initEvents(this);
};
//-----------------------------------------------------------------------------
// InstantEventManager
//初期化用のinitEventsと更新用のupdateEventsを任意のシーンに取り入れることでマップと戦闘以外でも即席並列イベントが利用可能になる。
//removeAllEventsは全て削除したい時に。executeAutoRemoveはお好みで。
class InstantEventManager {
static _eventId = 0;
static _pictureId = 0;
static _args = [];
static initEvents(self) {
self._instantEvents = [];
}
static instantEvents(self) {
return self._instantEvents;
}
static setupInterpreter(self, list, eventId, args, id) {
const interpreter = new Game_Interpreter();
interpreter.setupInstant(list, eventId, args, id);
self._instantEvents.push(interpreter);
interpreter._isInstantParallel = true;
this.requestRefresh(self);
}
static requestRefresh(self) {
self._needsInstantEventsRefresh = true;
};
static refreshEvents(self) {
self._instantEvents = self._instantEvents.filter(interpreter => interpreter.isRunning());
self._needsInstantEventsRefresh = false;
}
static refreshIfNeeded(self) {
if (self._needsInstantEventsRefresh) {
this.refreshEvents(self);
}
}
static updateEvents(self) {
for (const interpreter of self._instantEvents) {
interpreter.update();
}
this.refreshIfNeeded(self);
}
static removeEvent(self, id) {
id = String(id);
self._instantEvents.forEach(interpreter => interpreter._instantId === id && interpreter.terminate());
}
static removeAllEvents(self) {
self._instantEvents = [];
}
static executeAutoRemove(self) {
this.refreshEvents(self);
self._instantEvents = self._instantEvents.filter(interpreter => !interpreter._autoRemove);
}
static extractEventIds(self, str) {
const eventIds = [];
String(str).split(",").forEach(id => {
if (!isNaN(id)) {
eventIds.push(Number(id) + 0);
return;
}
const range = id.replace(/to/gi,"-").split("-").map(Number);
//マイナス対策
if (range.length === 4) {
range.shift();
range[0] = -range[0] + 0;
range[1] = -range.pop() + 0;
} else if (range.length === 3) {
if (range[1]) {
range.shift();
range[0] = -range[0] + 0;
} else if (range[2]){
range[1] = -range.pop() + 0;
}
}
//マイナス対策ここまで
if (isNaN(range[1])) {
range[1] = range[0];
}
if (range[0] > range[1]) {
for (let i = range[0]; i >= range[1]; i--) {
eventIds.push(i)
}
} else {
for (let i = range[0]; i <= range[1]; i++) {
eventIds.push(i);
}
}
});
return eventIds;
}
static extractList(self, index, list) {
const scanEnd = list.length - 1;
let skipStart = -1;
let skipEnd = -1;
let indent = 0;
for (let i = index + 1; i <= scanEnd; i++) {
const command = list[i];
if (command.code === 109) {
skipStart = i;
indent = command.indent;
break;
}
}
if (skipStart === -1) {
return null;
}
for (let i = skipStart + 1; i <= scanEnd; i++) {
const command = list[i];
if (command.code === 409 && command.indent === indent) {
skipEnd = i;
break;
}
}
if (skipEnd === -1) {
return null;
}
const startIndex = skipStart + 1;
const endIndex = skipEnd;
return list.slice(startIndex, endIndex);
}
static waitList(self, id) {
return [{"code":112,"indent":0,"parameters":[]},
{"code":357,"indent":1,"parameters":[pluginName,"updateWaitMode","",{"id":id}]},
{"code":0,"indent":1,"parameters":[]},
{"code":413,"indent":0,"parameters":[]},
{"code":0,"indent":0,"parameters":[]}];
}
//複数実行用の実行内容を生成
static repeatList(self, targets) {
const newList = [];
for (let i = 0; i < targets.length; i++) {
const targetId = targets[i] || 0;
newList.push({"code":357,"indent":0,"parameters":[pluginName,"setupChild","",{"targetId": targetId}]});
}
newList.push({"code":0,"indent":0,"parameters":[]});
return newList;
}
static allTargets(self, targets, times) {
if (times === 1) {
return targets;
}
let allTargets = [];
for (const targetId of targets) {
for (let i = 0; i < times; i++) {
targets = allTargets.push(targetId);
}
}
return allTargets;
}
}
window.InstantEventManager = InstantEventManager;
//以下「文章の表示」用制御文字
if (!controlCharactersEnabled) {
return;
}
//-----------------------------------------------------------------------------
// Window_Message
const _Window_Message_initMembers = Window_Message.prototype.initMembers;
Window_Message.prototype.initMembers = function() {
_Window_Message_initMembers.call(this);
this._waitForSwVa = null;
};
const _Window_Message_processEscapeCharacter = Window_Message.prototype.processEscapeCharacter;
Window_Message.prototype.processEscapeCharacter = function(code, textState) {
switch (code) {
case "VPP":
var variableId = this.obtainEscapeParam(textState);
$gameVariables.setValue(variableId, $gameVariables.value(variableId) +1);
break;
case "VMM":
var variableId = this.obtainEscapeParam(textState);
$gameVariables.setValue(variableId, $gameVariables.value(variableId) -1);
break;
case "SON":
var switchId = this.obtainEscapeParam(textState);
$gameSwitches.setValue(switchId, true);
break;
case "SOFF":
var switchId = this.obtainEscapeParam(textState);
$gameSwitches.setValue(switchId, false);
break;
case "WFV":
var params = obtainEscapeParam(textState).split(",");
params.unshift(1);
params[1] = Number(params[1]);
params[2] = Number(params[2] || 1);
this._waitForSwVa = params;
break;
case "WFS":
var params = obtainEscapeParam(textState).split(",");
params.unshift(0);
params[1] = Number(params[1]);
params[2] = params[2] === "true";
this._waitForSwVa = params;
break;
default:
_Window_Message_processEscapeCharacter.apply(this, arguments);
break;
}
};
//文字列のパラメータを取得
function obtainEscapeParam(textState) {
const regExp = /^\[(.+?)\]/;
const arr = regExp.exec(textState.text.slice(textState.index));
if (arr) {
textState.index += arr[0].length;
return arr[1]
} else {
return "";
}
};
const _Window_Message_updateWait = Window_Message.prototype.updateWait;
Window_Message.prototype.updateWait = function() {
const updateWait = _Window_Message_updateWait.call(this);
return updateWait || this.updateSwVa();
};
Window_Message.prototype.updateSwVa = function() {
const params = this._waitForSwVa;
if (params) {
switch (params[0]) {
case 0:
const switchId = params[1];
const boolean = params[2];
if ($gameSwitches.value(swicthId) === boolean) {
this._waitForSwVa = null;
return false;
}
return true;
case 1:
const variableId = params[1];
const value = params[2];
if ($gameVariables.value(variableId) >= value) {
this._waitForSwVa = null;
return false;
}
return true;
}
}
return false;
};
const _Window_Message_isWaiting = Window_Message.prototype.isWaiting;
Window_Message.prototype.isWaiting = function() {
return _Window_Message_isWaiting.call(this) || this._waitForSwVa;
};
})();