見出し画像

RPGツクールプラグイン制作過程紹介 第9回

前回に引き続き、異なるスキルに対する反応を実装していきたいと思います。

プラグインパラメータの取得

前回はプラグインパラメータの定義とツクール上での設定までを行いましたが、まだこれだけでは動作しないのです。
動作させるには、プラグイン内での値の取得と対応する関数の設定を行う必要があります。

プラグインパラメータは、基本的には以下のいずれかの書式にて取得できます。

PluginManager.parameters("プラグイン名").パラメータ名
PluginManager.parameters("プラグイン名")["パラメータ名"]

PluginManager.parameters()は、パラメータの名前(@paramで指定した名前)をキーとしてパラメータの値(ユーザーが指定した値)を保持しているオブジェクトを返す関数です。
ですので通常のオブジェクトと同じ書式にて、@paramをキーにすることでパラメータの値にアクセスできます。上記の二つはどちらも同じです(厳密には識別子として無効な名前の場合上は使えないという違いがありますが、そもそも@paramには識別子として有効な名前をつけたほうが良いでしょう)。

早速以下のように取得してみます。

const skillReactionPatterns = PluginManager.parameters(PLUGIN_NAME).skillReactionPatterns;

前回作成したプラグインパラメータskillReactionPatternsと同名の定数に、このパラメータの値を代入しています。
なおPluginManager.parameters()の引数PLUGIN_NAMEとは以前プラグインコマンドを作成した際に定義した定数であり、このプラグインの名前の文字列("FieldAction")が入っています。これはプラグインパラメータでもそのまま使えます。

果たしてこれでこの定数にきちんと前回設定したプラグインパラメータの値が格納されるのでしょうか? 確認するために、console.log()を記述してみましょう。

const skillReactionPatterns = PluginManager.parameters(PLUGIN_NAME).skillReactionPatterns;
console.log(skillReactionPatterns);

実際にテストしてみると、Visual Studio Code(以下VSC)のDebug Consoleには以下のように出力されます(ツクールエディタ上からのテストプレイの場合F8キーにてコンソールを呼び出せます)。

スクリーンショット 2021-05-11 19.51.58

何やらバックスラッシュがたくさん入っていますね。これだけではよくわからないので、console.log()をさらに以下のようにしてみます。

console.log(skillReactionPatterns[0]);

skillReactionPatternsの後に[0]をつけてみました。これは配列の0番目の要素を取得するための書式ですね。
skillReactionPatternsは前回設定した通り、配列の値が格納されるパラメータです。ですのできちんと配列の値になっていれば、0番目の要素は前回設定した可燃物反応設定(識別子はcombustible)が格納されているはずなのです。
確認してみましょう。

スクリーンショット 2021-05-11 19.58.27

おや……? ずいぶん出力が短いですね。[が一つだけ出力されてしまいました。
これはなんなのかというと、先ほど出力されたものの1文字目なのです。
というのも、実はプラグインパラメータで取得される値は全て文字列なのです。文字列に対して[n]を実行するとn番目の文字が返ってくるので、先頭の文字である[が出力された、ということなのです。
パラメータの@typeには数字入力(number)やオンオフの二択(boolean)、配列([])、オブジェクト(struct)など値に様々な型を設定することができます。ですがこれらはエディタ上での入力にのみ影響し、実際の値はあくまでも文字列なのです。値を配列やオブジェクトなどの実際の型にするには、JSON.parse関数にて型変換する必要があります。
JSON.parseとは、文字列を通常の書式(リテラル)と見なして(例えば[ ]を配列、{ }をオブジェクトとして)解釈するJavaScript標準の関数です。

skillReactionPatterns定数のコードを以下のように変形してみます。

const skillReactionPatterns = JSON.parse(PluginManager.parameters(PLUGIN_NAME).skillReactionPatterns);

再びconsole.logを以下に戻します。

console.log(skillReactionPatterns);

[0]を外しました。テストプレイで出力してみます。

スクリーンショット 2021-05-12 17.00.56

少しわかりにくいのですが、VSCでは配列の値には(1)と頭につくので(数字は要素数)、この値はきちんと配列になっています。
ただしその中身をよく見ると、オブジェクトに""がついています。JSON.parseは1段階までしか変換してくれないので、中身は別途変換する必要があるのです。
そこで以下のようにしてみます。

const skillReactionPatterns = JSON.parse(PluginManager.parameters(PLUGIN_NAME).skillReactionPatterns)
       .map(str => JSON.parse(str));

JSON.parseを実行した結果の配列でmap関数を実行し、その結果をskillReactionPatternsに代入しています。なお長くなりすぎたのでmap以下を改行していますが、そのまま続けて書く場合と動作は変わりません。
mapとは配列のメソッドであり、配列の要素を一つずつ=>の左側で指定した変数(ここではstr)に代入し、=>の右側を評価した結果に置き換えた新たな配列を返します。平たく言うと、配列の要素を変換する関数です。つまりこの場合、配列の各要素に対してJSON.parseを実行し、要素を文字列からオブジェクトに変換した配列を新たに作ってskillReactionPatternsに代入しているのです。再度コンソール出力を実行してみましょう。

スクリーンショット 2021-05-11 22.52.53

配列の中身がオブジェクトになりました。
ただしオブジェクトのそれぞれの値は文字列になってしまっており、適切な型ではありません。
そこでさらに、型変換するために以下の処理を追加します。

for (let i=0; i<skillReactionPatterns.length; i++) {
    const str = skillReactionPatterns[i].patterns;
    const ary = JSON.parse(str).map(s => JSON.parse(s));
    for (let j=0; j<ary.length; j++) {
        for (const key of Object.keys(ary[j])) {
            const value = ary[j][key];
            if (!["A","B","C","D"].includes(value)) {
                ary[j][key] = JSON.parse(value);
            }
        }
    }
    skillReactionPatterns[i].patterns = ary;
}

こちらはかなり複雑ですね。
解説しだすとあまりにも長くなってしまうので、ここでは各種の値を適切な型に変換している処理なんだな、程度にご理解いただければ問題ありません。
腕に覚えのある方はぜひコードの意味を解読してみてください。ポイントとしてはセルフスイッチ記号のADは文字列のままにしたい値なので、それらはJSON.parseの対象外にしている、というところです(ただの文字列をJSON.parseするとエラーになってしまうため)。

最後に、以下の処理を加えます。

const SKILL_REACTION_PATTERNS = {};
for (const obj of skillReactionPatterns) {
    SKILL_REACTION_PATTERNS[obj.identifier] = obj.patterns;
}

これはプラグインパラメータ取得用定数をさらに扱いやすくするために、skillReactionPatternsをオブジェクトに変換するための処理です。
まずSKILL_REACTION_PATTERNSという新しいオブジェクトを作り、そこにskillReactionPatternsの各要素のidentifierがキーで、patternsを値として代入しています。
なぜこのような処理をしているのかと言うと、skillReactionPatternsSKILL_REACTION_PATTERNSから識別子"combustible"の値を取得するコードを比較すればわかります。

// 配列(skillReactionPatterns)の場合
const object = skillReactionPatterns.find(obj => obj.identifier === "combustible");
const patterns = object ? object.patterns : [];
// オブジェクト(SKILL_REACTION_PATTERNS)の場合
const patterns = SKILL_REACTION_PATTERNS["combustible"] || [];

どちらもpatternsに代入される値は同じです。下の方がより簡潔な記述で値を取得できているのがお分かりいただけるかと思います。

これでプラグインパラメータの値を全て適切な型の値としてSKILL_REACTION_PATTERNS定数に格納することができました。
再度コンソールにて確認してみましょう。

スクリーンショット 2021-05-12 20.16.02

きちんと配列は配列に、オブジェクトはオブジェクトに、数値は数値に、文字列は文字列に変換されてますね!
続いてはそれを実際に関数内で取得してみます。

関数の設定

まず、以前作成したGame_EventskillSwitchId関数を覚えておいででしょうか。

Game_Event.prototype.skillSwitchId = function() {
    return this.event().meta.skillSwitchId;
};

これはイベントのメタタグ(<skillSwitchId:スイッチ番号>)にて設定したスイッチ番号を取得するための関数でしたね。
今後、イベントには単独のスイッチ番号ではなく上記で設定した構造体の識別子を入力するようにします。
それに伴い、この関数名及びメタタグの名前も変更しましょう。さしずめ、skillReactionIdとでもしましょうか(IDというと数字のような印象を受けますが、ここではidentifier、識別子の略語として使用しています)。

まず、現在の関数はコピーした上でコメントアウトないし削除しておきます。

スクリーンショット 2021-05-12 20.23.16

そしてコピーした関数を以下のように書き換えます。

Game_Event.prototype.skillReactionId = function() {
    return this.event().meta.skillReactionId || "";
};

関数名とイベントのメタタグの名前をskillReactionIdに書き換えました。
そしてユーザーがメタタグに入力した識別子を返すようにしています。
なおイベントにメタタグが設定されていない場合、この式の結果はnullになります。予期せぬエラー防止のために、nullになった場合は""(空の文字列)を返すようにしています。
論理演算子OR||)は左辺を評価した結果が真であれば左辺の値を返し、右辺は何もしません。反対に、左辺が偽になった場合は右辺を評価してその値を返します。
この性質を利用して、nullundefinedになってほしくない値に代わりの値を設定するためによく用いられます。if文を使用しても同じ結果を得られますが、こちらは1行で記述できるためコードが非常にスリムになるという効果があります。

これでイベント側の関数は設定できました。実際にイベントに設定してみましょう。

スクリーンショット 2021-05-12 20.31.16

スクリーンショット 2021-05-12 20.31.43

イベントのメモに<skillReactionId:combustible>と入力しました。
また、2ページ目の条件をこれまでのゲームスイッチからセルフスイッチ(A)に変更しました。
これにより、このイベントは変数番号を変更する必要なく丸ごとコピーすることができるようになりました。マップ上の全てのたきぎをこのイベントのコピーに置き換えています。
また、ロウソクイベントにも<skillReactionId:combustible>を設定しています。

続いてこの識別子を使用した実際のスイッチ処理を組んでいきましょう。
まず、Game_PlayertoggleSwitchesByFacingSkillTargetsをコピーして元の関数はコメントアウトないし削除します。

スクリーンショット 2021-05-12 20.43.37

そして以下のように書き換えます。

Game_Player.prototype.toggleSwitchesByFacingSkillTargets = function() {
    const events = this.facingSkillTargets();
    for (const event of events) {
        const patterns = SKILL_REACTION_PATTERNS[event.skillReactionId()];
        if (patterns) {
            // 暫定措置として変数1番にコモンイベントIDを事前に代入しておく
            const commonEventId = $gameVariables.value(1);
            const struct = patterns.find(obj => obj.commonEventId === commonEventId);
            if (struct) {
                const selfSwitchCondition = struct.selfSwitchCondition;
                const mapId = $gameMap.mapId();
                const eventId = event.eventId();
                let ok = false;
                if (!selfSwitchCondition) {
                    ok = ["A","B","C","D"].every(ch => !$gameSelfSwitches.value([mapId, eventId, ch]));
                } else {
                    ok = $gameSelfSwitches.value([mapId, eventId, selfSwitchCondition]);
                }
                if (ok) $gameSelfSwitches.setValue([mapId, eventId, struct.selfSwitchCh], struct.selfSwitchValue);
            }
        }
    }
};

for (const event of events) { }の中身が完全に変更されました。
上から見ていきましょう。

const patterns = SKILL_REACTION_PATTERNS[event.skillReactionId()];
if (patterns) {
    // 省略
}

SKILL_REACTION_PATTERNSとは上記にて用意したプラグインパラメータの値を保持するオブジェクトですね。
SKILL_REACTION_PATTERNS定数にイベントのskillReactionId関数で取得した識別子をキーとしてアクセスすることにより、この識別子に対応する構造体格納配列を取得し、定数patternsに代入しています。
SKILL_REACTION_PATTERNS定数にイベントの識別子が存在しなかった場合patternsにはundefinedが代入され、具体的な値を得ることはできません。これはつまりイベントにskillReactionIdが設定されていないか、設定されている識別子がプラグインパラメータのいずれの識別子とも一致しない(設定し忘れもしくはスペルミスが原因)ということでしょうが、このようなケースにも備えておく必要があります。
その場合(patternsundefinedの場合)は何もせずに処理を終わらせるため、以降の処理をif (patterns) {}のブロック内に置いているのです。

// 暫定措置として変数1番にコモンイベントIDを事前に代入しておく
const commonEventId = $gameVariables.value(1);

プラグインパラメータにはコモンイベント番号を設定していました。あるスキルを使用した際、そのスキルに設定されているコモンイベントの番号に応じてイベントのスイッチ反応が変わる、という仕組みにするためでしたね。
実はコモンイベント番号はある理由により、取得するのが非常に難しいのです。その理由がなんなのかは次回以降にご紹介しますが、今回は暫定措置として変数1番にコモンイベント番号を事前に手動で代入することにします。
コモンイベント側は、以下のように設定しておきます。

スクリーンショット 2021-05-12 22.42.25

スクリーンショット 2021-05-12 22.42.51

コモンイベント2番の場合2を、3番の場合3を変数1番に代入しています。そのままですね……。
次回以降、この手順は省略可能にする予定です。

const struct = patterns.find(obj => obj.commonEventId === commonEventId);
if (struct) {
    // 省略
}

これは、上記で取得したpatterns配列のfind関数を実行しています。
find関数は上記でご紹介したmap関数と同様に=>の左側で指定した変数(ここではobj)に配列の要素が代入され、=>の右側の式を評価します。その結果最初に真になった要素を返します。
つまりプラグインパラメータで指定したコモンイベント番号と、上述の変数1番に代入したコモンイベント番号が一致した構造体を定数structに代入する、という処理です。
find関数を実行した結果一つも真にならなかった場合、nullを返します。その場合そこで終了させるため、以降の処理はif (struct)のブロック内に記述しています。上記のif (patterns)と同じですね。

const selfSwitchCondition = struct.selfSwitchCondition;
const mapId = $gameMap.mapId();
const eventId = event.eventId();

これらは以降の処理にて使用する定数を事前に用意することを目的とした処理です。

まず、selfSwitchCondition定数には上記で取得した構造体structselfSwitchConditionプロパティの値を代入しています。これは、ユーザーがプラグインパラメータにて指定した値です。この処理が有効になるためのセルフスイッチの条件を表します。

mapId定数には現在のマップのIDを代入しています。これは$gameMap.mapId()で取得できます。

eventId定数には現在対象となっているイベントのIDを代入しています。

let ok = false;
if (!selfSwitchCondition) {
    ok = ["A","B","C","D"].every(ch => !$gameSelfSwitches.value([mapId, eventId, ch]));
} else {
    ok = $gameSelfSwitches.value([mapId, eventId, selfSwitchCondition]);
}

これはやや複雑な処理をしています。

まずlet ok = falseというのは、実際にスイッチの値変更を行うかどうかを記録するための変数です。以降の処理で再代入するために、constではなくletを使用しています。

if (!selfSwitchCondition)というのは、上述のセルフスイッチ条件がなしの場合、という意味です。前回このプラグインパラメータはプルダウンにてなしという値を選択可能にしましたが、実際の値はnullになります。nullの場合上の処理が、そうでない場合(ADの場合)下の処理が実行されます。

上の処理では、 ["A","B","C","D"]という配列のevery関数を実行しています。
まず、セルフスイッチ条件がなしというのは、セルフスイッチABCDのいずれもオフである、という条件を表します。
every関数は配列のメソッドであり、配列の全ての要素が条件を満たした場合trueを、一つでも条件を満たさなかった場合falseを返します。
使い方は上述のmapfindとよく似ていて、配列の要素を代入した変数を使用して式を評価し、全てが真であるかを判定します。
ここでは"A","B","C","D"という文字列をch変数に代入しています。chはその後ろの[mapId, eventId, ch]という配列の中で使用されているのですが、これはなんなのでしょうか?
ツクールのセルフスイッチは、Game_SelfSwitchesというクラスで管理されています。そのインスタンスは$gameSelfSwitchesで参照されます。あるイベントのあるセルフスイッチの値(オンオフか)は、$gameSelfSwitches.value(キー)で取得できます。
キーは必ず[マップID, イベントID, セルフスイッチ記号]の配列である必要があります。そのため[mapId, eventId, ch]という配列を作り、$gameSelfSwitches.value()に代入しているのです。ここではセルフスイッチがオフであるかどうかを判定したいので、!をつけて真偽反転しています。

下の処理はその反対です。selfSwitchCondition定数で指定されているセルフスイッチがオンであるかどうかを判定するため、[mapId, eventId, selfSwitchCondition]というキーとなる配列を作って$gameSelfSwitches.value()に代入しています。

また、上も下も最終的に式の結果をok変数に代入しています。

if (ok) $gameSelfSwitches.setValue([mapId, eventId, struct.selfSwitchCh], struct.selfSwitchValue);

これは上記のokが真である場合にのみ実行される処理です。つまりセルフスイッチ条件を満たした場合にのみ実行される、ということですね。

Game_SelfSwitchessetValue関数は、キーを第一引数に、変化後のスイッチの値を第二引数として呼び出します。
キーは上記と同じフォーマットなのですが、ここではセルフスイッチ記号にstruct.selfSwitchChを指定しています。構造体に設定されているセルフスイッチ記号パラメータですね。つまりユーザーが指定した記号のセルフスイッチをオンまたはオフにせよ、ということです。
オンなのかオフなのかは、同じくユーザーが指定した変化後スイッチパラメータであるstruct.selfSwitchValueを代入することで指定しています。

これでようやくこの関数が読み解けました。
それではテストしてみましょう!

きちんと《ファイアⅠ》の場合点火し、《ウォーターⅠ》の場合消火されていますね!
また、火がついていない場合(セルフスイッチAがオフの場合)《ウォーターⅠ》を使っても何も起きません。これは、構造体のセルフスイッチ条件Aオフと設定したためで、正常に動作しています!

まとめ

今回はプラグインパラメータの値を型変換し、またそれを関数内で利用する仕組みを作りました。お疲れ様でした。

構造体が複雑であるために最後の関数も複雑になってしまいましたが、多くの場合プラグインパラメータもそれを利用する関数ももっとシンプルに作ることができます。紹介の順番の関係でいきなり複雑な例になってしまったのが心残りではあります。

次回は今回の宿題として、なぜ変数1番にコモンイベント番号を代入する必要があるのか、またそれを省略するにはどうすればいいのか、を見ていきたいと思います。

それではまた次回お会いしましょう!

今回までの最終コード

GitHub

//=============================================================================
// RPG Maker MZ - 
//=============================================================================

/*:
* @target MZ
* @plugindesc 
* @author 
*
* @help 
*
* @param skillReactionPatterns
* @text Skill Reaction Patterns
* @desc Contains skill reaction patterns as many as necessary.
* @type struct<switchPatternList>[]
* 
* @command toggleSwitchesByFacingSkillTargets
* @text Turn Switches on by Events Faced by Player
* @desc Turns on switches whose IDs correspond to <skillReactionId: > note of events faced by the player.
*
* @command requestAnimationAtFacingSkillTargets
* @text Show Animation at Facing Events
* @desc Show a specified animation at events faced by the player.
* 
* @arg animationId
* @text Animation ID
* @desc ID of the animation to be shown.
* @type animation
* 
*/

/*~struct~switchPatternList:
*
* @param identifier
* @text Identifier
* @desc The identifier for skill reaction patterns.
* @type string
* 
* @param patterns
* @text Skill Reaction Pattern List
* @desc The list for skill reaction patterns.
* @type struct<switchPattern>[]
* 
*/

/*~struct~switchPattern:
*
* @param commonEventId
* @text Common Event ID
* @desc The common event ID which affects the event.
* @type common_event
* 
* @param selfSwitchCh
* @text Self Switch Character
* @desc The self switch character which will change.
* @default A
* @type select
* @option A
* @option B
* @option C
* @option D
* 
* @param selfSwitchValue
* @text Self Switch Value
* @desc The changed Value of the self switch.
* @type boolean
* @default true
* 
* @param selfSwitchCondition
* @text Self Switch Condition
* @desc The self switch character which needs to be on for enabling this reaction.
* @default none
* @type select
* @option none
* @value null
* @option A
* @option B
* @option C
* @option D
* 
*/

/*:ja
* @target MZ
* @plugindesc 
* @author 
*
* @help 
*
* @param skillReactionPatterns
* @text スキル反応パターン
* @desc スキルに対する反応パターンを、反応の種類だけ定義します。
* @type struct<switchPatternList>[]
* 
* @command toggleSwitchesByFacingSkillTargets
* @text 直前イベントスイッチオン
* @desc プレイヤーの目の前のイベントのメタタグに設定されているスイッチをオンにします。
*
* @command requestAnimationAtFacingSkillTargets
* @text 直前イベントアニメーション表示
* @desc プレイヤーの目の前のイベントに指定したIDのアニメーションを表示します。
* 
* @arg animationId
* @text 表示アニメーション番号
* @desc 表示するアニメーションの番号です。
* @type animation
* 
* 
*/

/*~struct~switchPatternList:ja
*
* @param identifier
* @text 識別子
* @desc スキル反応パターンの識別子です。
* @type string
* 
* @param patterns
* @text スキル反応パターンリスト
* @desc スキル反応パターンのリストです。
* @type struct<switchPattern>[]
* 
*/

/*~struct~switchPattern:ja
*
* @param commonEventId
* @text コモンイベントID
* @desc イベントに作用するコモンイベントのIDです。
* @type common_event
* 
* @param selfSwitchCh
* @text セルフスイッチ記号
* @desc 変化するセルフスイッチの記号です。
* @default A
* @type select
* @option A
* @option B
* @option C
* @option D
* 
* @param selfSwitchValue
* @text 変化後スイッチ
* @desc 反応後に変化するセルフスイッチの値です。
* @type boolean
* @default true
* 
* @param selfSwitchCondition
* @text セルフスイッチ条件
* @desc この反応を有効にするためにオンになっている必要があるセルフスイッチの記号です。
* @default なし
* @type select
* @option なし
* @value null
* @option A
* @option B
* @option C
* @option D
* 
*/

(() => {
   'use strict';


   const PLUGIN_NAME = "FieldAction";


   const skillReactionPatterns = JSON.parse(PluginManager.parameters(PLUGIN_NAME).skillReactionPatterns)
       .map(str => JSON.parse(str));
   for (let i=0; i<skillReactionPatterns.length; i++) {
       const str = skillReactionPatterns[i].patterns;
       const ary = JSON.parse(str).map(s => JSON.parse(s));
       for (let j=0; j<ary.length; j++) {
           for (const key of Object.keys(ary[j])) {
               const value = ary[j][key];
               if (!["A","B","C","D"].includes(value)) {
                   ary[j][key] = JSON.parse(value);
               }
           }
       }
       skillReactionPatterns[i].patterns = ary;
   }
   const SKILL_REACTION_PATTERNS = {};
   for (const obj of skillReactionPatterns) {
       SKILL_REACTION_PATTERNS[obj.identifier] = obj.patterns;
   }
   
   PluginManager.registerCommand(PLUGIN_NAME, "toggleSwitchesByFacingSkillTargets", args => {
       $gamePlayer.toggleSwitchesByFacingSkillTargets();
   });
   
   PluginManager.registerCommand(PLUGIN_NAME, "requestAnimationAtFacingSkillTargets", args => {
       const targets = $gamePlayer.facingSkillTargets();
       const animationId = Number(args.animationId);
       $gameTemp.requestAnimation(targets, animationId);
   });


   Game_Player.prototype.facingSkillTargets = function() {
       const direction = this.direction();
       const x1 = this.x;
       const y1 = this.y;
       const x2 = $gameMap.roundXWithDirection(x1, direction);
       const y2 = $gameMap.roundYWithDirection(y1, direction);
       const events = $gameMap.eventsXy(x2, y2);
       return events;
   };
  
   Game_Player.prototype.isFacingSkillTargets = function() {
       const events = this.facingSkillTargets();
       return events.length > 0;
   };
  
   Game_Player.prototype.toggleSwitchesByFacingSkillTargets = function() {
       const events = this.facingSkillTargets();
       for (const event of events) {
           const patterns = SKILL_REACTION_PATTERNS[event.skillReactionId()];
           if (patterns) {
               // 暫定措置として変数1番にコモンイベントIDを事前に代入しておく
               const commonEventId = $gameVariables.value(1);
               const struct = patterns.find(obj => obj.commonEventId === commonEventId);
               if (struct) {
                   const selfSwitchCondition = struct.selfSwitchCondition;
                   const mapId = $gameMap.mapId();
                   const eventId = event.eventId();
                   let ok = false;
                   if (!selfSwitchCondition) {
                       ok = ["A","B","C","D"].every(ch => !$gameSelfSwitches.value([mapId, eventId, ch]));
                   } else {
                       ok = $gameSelfSwitches.value([mapId, eventId, selfSwitchCondition]);
                   }
                   if (ok) $gameSelfSwitches.setValue([mapId, eventId, struct.selfSwitchCh], struct.selfSwitchValue);
               }
           }
       }
   };
   
   
   Game_Event.prototype.skillReactionId = function() {
       return this.event().meta.skillReactionId || "";
   };

})();

この記事が気に入ったらサポートをしてみませんか?