[JP]mod~

[JP]mod~

はじめに

[JP]イベントmod作成入門~基礎構文編の続きになります。

本ページでは、「イベントを呼び出すイベント」や「common\on_actions」等を用いたイベントの呼び出しを行い、イベントチェーン的な物の組み方を説明します。

(※: 本ゲームでのイベントチェーンは、正確には「状況レポート」に出てくるものを指しますが、

  本ページでは、単純に複数のイベントを順次発生させる方法の説明のみを行います)

基礎構文編

イベント呼出編 (本ページ)

以下、注意事項です。

イベント構文の読み方を知らない方は、先に基礎構文編をお読み下さい。

本ガイドも初心者向けです。中上級者には適しません。

その他の注意事項は、基礎構文編に準じます。

On_actions

まずは、on_actionsについて説明していきます。

on_actionsは、名の通り特定のアクションが起きた場合に、登録したイベントを発生させます。

ゲーム本体の "\stellaris\common\on_actions\00_on_actions.txt"を開くと、以下のようなテキストが表示されます。

# No scope, like on_game_start on_monthly_pulse = { events = { unrest.162 unrest.164 } } <中略> # Triggers event when ship enters a system # Scope = Ship # From = System # FromFrom = Country on_entering_system = { events = { country.2 country.6 } } <後略>

これらは、いずれも「特定の条件を満たした際にリストアップされているイベントを発生させる」効果を持ちます。

例えば、上の例の効果は、以下の通りです。

on_monthly_pulse: 「毎月1日にunrest.162とunrest.164と…を発生させる」

on_entering_system:「艦船が星系に侵入した際にcountry.2とcountry.6と…を発生させる」

on_actionsの追加on_actionsに新しいイベントを追加したい場合、追加したいイベントのみを記載したtxtファイルを作成し、これを "\<modファイル>\common\on_actions\" に放り込みます。

ファイル名の制限は特にありませんが、ファイル名がバニラ(ゲーム本体)や他のmodと被らないようにして下さい。被ると一方が他方に上書きされます。

特に、バニラファイルの上書きは、余計な互換性問題を招くので、よほどの理由がない限り止めましょう。

まぁ、「<mod名>_on_actions.txt」としておくのが無難です。

また、on_actions中では、あまり細かい条件は設定できません。細かい条件は、eventsファイル中のtriggerで設定します。

例えば、「パルサー星系に侵入した場合にイベントを起こす」としたい場合、以下の通りです。

# \common\on_actions\SEoG_on_actions.txt <前略> on_entering_system = { ## 艦船が星系に侵入した際に… events = { sample_event.111 } } <後略> # \events\SEoG_events_11.txt ship_event = { id = sample_event.111 <中略> is_triggered_only = yes trigger = { solar_system = { ## その船がいる星系が… is_star_class = sc_pulsar ## パルサー星系だと、イベント発生 } } }

ランダムイベント使用機会は限られるでしょうが、on_actionsのイベント発生確率を100%未満に設定する事も可能です。

方法は以下の通り、「events」の代わりに「random_events」を使用し、「<相対発生確率> = <イベントid>」の形で記述します。

# common\on_actions\<適当なファイル名>.txt on_space_battle_won = { ## 艦隊戦で、一方が勝利した場合、 events = { test_event.1 ## このイベントを必ず発生させる test_event.2 ## このイベントも必ず発生させる } random_events = { 100 = 0 ## 確率100/(100+20+10)で、イベントを発生させない 20 = test_event.3 ## 確率20/(100+20+10)で、このイベントを発生させる 10 = test_event.4 ## 確率10/(100+20+10)で、このイベントを発生させる } ## test_event.3とtest_event.4は、同時発生しない }

ターゲットスコープさて、最初の例のコメントアウト(#)された部分に「Scope = Ship」・「From = System」・「FromFrom = Country」等の記載があるかと思います。

これらは、ターゲットスコープと言って、「誰を対象にしたイベントか」を指します。

非常に重要ですが、同時に非常にややこしくもあり、ここでは割愛します(そのうち、別ページで作ろうかと思います)。

とりあえず、ここでは「Scope (this)」についてのみ触れていきます。

これは、「何をイベント対象にするか」を示していて、

「on_entering_system」の場合は「scope = ship」ですので、艦船がイベント対象になります。

(表記揺れがあり、「this = ship」等となっている項目もありますが、同じような意味です。ちなみに、thisの方が厳密な表現です。)

したがって、ここに入れられるイベントは「ship_event」のみです。他のイベント(planet_event等)を入れても動作しません。

同様に、scope = country なら country_event、scope = pops なら pop_event 等となります。

また、no scope については、単なる「event」が対応します。

# common\on_actions\<適当なファイル名>.txt on_monthly_pulse = { ## scope: なし events = { test_event.1 test_event.2 } } on_entering_system = { ## scope: this = ship events = { test_event.3 test_event.4 } } ############## ### 良い例 ### ############## # events\<適当なファイル名>.txt event = { id = test_event.1 title = test_event.1.name <中略> } ship_event = { id = test_event.3 title = test_event.3.name <中略> } ############## ### 悪い例 ### ############## # events\<適当なファイル名>.txt country_event = { ## scope 不一致 id = test_event.2 title = test_event.2.name <中略> } planet_event = { ## scope 不一致 id = test_event.4 title = test_event.4.name <中略> }

まとめ & on_actionsの例

まとめとしては、以下の通りです。

on_actionsでは、特定の動作等を行ったタイミングで、任意のイベントを発生させる。

on_actionsで大雑把な条件を指定し、詳細条件はeventファイル中のtriggerで指定する。

「action名 = { events = { イベントリスト } } 」の形。「events」の入れ忘れに注意。

random_eventsを使うと、「条件を満たした場合に一定確率で発生」もできる。 scope (誰をターゲットにしたイベントか)に注意

バニラの "00_on_actions.txt" 中に、コメントアウトで書いてある。

「scope = ***」と「this = ***」の2つは、実質的に同じ意味

ついでにon_actionsの例を載せておきます。

全体からすれば、ほんの一握りですので、網羅的な一覧は、バニラ(ゲーム本体)の "\common\on_actions" 中のtxtファイルを見て下さい。

また、表中のfromシリーズについては、とりあえず無視で問題ありません。

ターゲットスコープを理解してから、再び見に来ると良いかもしれません。

関数名 発生条件 this(scope) from fromfrom fromfromfrom on_monthly_pulse 毎月1日 なし - - - on_yearly_pulse 毎年1月1日 なし - - - on_game_start 新規ゲーム開始時 なし - - - on_space_battle_won 艦隊戦で勝利した 勝利した帝国 相手帝国 勝利した艦隊 相手の艦隊 on_space_battle_lost 艦隊戦で敗北した 敗北した帝国 相手帝国 敗北した艦隊 相手の艦隊 on_building_mining_station 採掘ステーションの建設完了 建設船 ステーションができた惑星(恒星・衛星) - - on_building_research_station 研究ステーションの建設完了 建設船 ステーションができた惑星(恒星・衛星) - - on_terraforming_begun テラフォーミング開始 対象惑星 実施帝国 - - on_terraforming_complete テラフォーミング完了 対象惑星 実施帝国 - -

フラグ制御

ない

イベントを制御するにあたって、最重要級の関数の1つがフラグ制御です。

ゲームの内部処理においては、年がら年中出てくる代物なので、知っている人も多いかと思いますので、そういう人は最後の表にざっと目を通す程度で十分かと思います。

フラグは、「内部動作の管理上、重要な出来事が発生したか否か」を記録しておくための物です。いつ・どこでフラグを設定し・除去し・有無を確認するかは、全てソースコード上で指定します。

例えば、「過去にタイタンを建造した事がある国限定のイベントを起こしたい」と思った場合、

タイタン建造時に「タイタン建造フラグ」を建造国に設定する (フラグを建てる)

イベントのtrigger内に、「タイタン建造フラグ」を持つ国のみと条件付けするという形で、指定できます。

「現在タイタンを保有する国」であれば、フラグではなく保有艦船の全数検査 (any_owned_ship = { is_ship_size = titan })でも可能です。しかし、現在の状態(保有している)では無く、過去の状態(建造した事がある)を参照したい場合、基本的にフラグが必須です。

本ゲームのフラグに対する関数は、set (フラグを立てる)、remove (フラグを取り除く)、has (フラグの有無を確認)の3種類があります。また、何を対象にするか(帝国か、船か等)で関数名が変わり、下表の組み合わせになります。

例えば、帝国フラグ(国旗ではありませんよ)を建てたい場合、「set_country_flag = test_flag_A」などという形で指定します。

フラグ名は、アルファベット・数字・アンダースコア(_)なら、なんでも構いません。例によってスペ-ス・全角文字は、ダメです。

以下、一覧表です。別に、全部を覚える必要はありません。必要な時に見返して下さい。

ターゲット フラグ設定 フラグ除去 フラグ確認 備考 ゲーム全体 set_global_flag remove_global_flag has_global_flag セーブファイルそのものがターゲット 帝国 set_country_flag remove_country_flag has_country_flag 中立機構や、危機勢力等も含む 帝国の関係 set_relation_flag remove_relation_flag has_relation_flag

reverse_has_relation_flag 構文が他と異なる。脚注*1参照 星系 set_star_flag remove_star_flag has_star_flag 恒星ではので注意 恒星・惑星等 set_planet_flag remove_planet_flag has_planet_flag 「単一の天体」は、基本全て「planet」 メガストラクチャー set_megastructure_flag remove_megastructure_flag has_megastructure_flag - 艦隊 set_fleet_flag remove_fleet_flag has_fleet_flag 軍艦専用。「1個艦隊」に対するフラグ、1隻では。 艦船 set_ship_flag remove_ship_flag has_ship_flag 1隻の軍艦・民間船が対象 補助オブジェクト set_ambient_object_flag remove_ambient_object_flag has_ambient_object_flag 「亜光速探査機」イベの探査機等 派閥 set_pop_faction_flag remove_pop_faction_flag has_pop_faction_flag - リーダー set_leader_flag remove_leader_flag has_leader_flag 国家元首を含む 種族 set_species_flag remove_species_flag has_species_flag - POP set_pop_flag remove_pop_flag has_pop_flag - *1: relation_flag のみ構文が異なり、「set_relation_flag = { who = <相手国> flag = <フラグ名> }」となる。remove・hasも同様。

「reverse_has_relation_flag」は、reverseとある通り、「相手国が自国へ set_relation_flag しているか」を見る。

フラグが無いことを確認したい場合、「not = { has_****_flag = <フラグ名> }」とする。

応用: 「set_timed_****_flag = { flag = <フラグ名> days = <日数> }」とすると、期間限定フラグを建てられる。フラグは、基本的に対応するオブジェクトにしか設定できません。例えば、planetに対して、fleet_flagを設定することはできません。きちんとターゲットスコープ(イベントの対象オブジェクト)を移す必要があります。

例外として、global_flagのみ、ターゲットスコープにかかわらず、使用できます。当然ですが、他のオブジェクトと共用になるため、万能フラグではありません。例えば、「レヴァイサンを倒した艦隊フラグ」は、global_flagではなく fleet_flagで設定する必要があります。もし、global_flagで設定すると、「過去に誰かがレヴァイサンを倒した事があるフラグ」として機能するでしょう。

基礎構文編の復習

さて、次項で、実践的なイベント呼び出し法を説明していきますので、その前に軽く基礎構文編のおさらいです。

イベントは、下表に示した7種類に分類されています。

コード対象 event ゲーム全体 (特定コードからの呼び出し専用)

country_event ゲーム全体 (大部分はこちら)

帝国(empire)

planet_event 惑星・恒星・その他天体 fleet_event 艦隊 (軍艦のみ、1隻ではなく1個艦隊) ship_event 個別の軍艦・民間船・軌道ステーション pop_faction_event 派閥 pop_event POP

イベントフォルダ内に、親要素(いかなる「{ }」にも括られていない場所)として配置すると、「これはイベントです」と定義するコードになります。

一方で、他のイベントの immediate 等々の「効果を記述する部分」に子要素として入れると、「このイベントを呼び出す」という効果になります。

後者の場合、

immediate = { country_event = { id = test_event.1 day = 20 random = 10 } } のように指定することで、発生タイミングを遅らせることができます。

「event」内の「trigger」は、イベント発生条件を定めます。

trigger内の条件が満たされない限り、イベントの呼び出しを受けても、実際にはイベントは発生しません。

また、「is_triggered_only = yes」が無い場合、triggerが満たされると、呼び出しを受けずとも自発的に発動します。

その場合、mean_time_to_happenで発生時期をランダムにできます。

工事中: 実践的なイベント呼出1: On Actions・イベント呼出・分岐


[JP]mod~ image 92
[JP]mod~ image 93だけ

前座本項と次項では、実践的なイベント呼び出し法として、2つのイベント例を元に、イベント同士のつなげ方を説明していきます。

なお、イベント呼び出しに特化しているため、実際の効果の作りは雑ですので、ご了承下さい。

また、右に示したような、フローチャートも併記しておきます。

必要に応じ、流れを把握するのにお使い下さい。

(画像クリックで拡大できます。)

イベント概要右のフローチャートに示した通り、本イベントは、月初めの時点で財政赤字の場合に融資提案を受けるイベントです。融資を受ける(借金する)決断をした場合、エネルギー100を得られますが、1年後に利子付きで返済をすることになります。返済できないと、艦船を没収されるオマケ付きです。

ソースコード組み、という観点からは、

毎月の融資提案をon_actionで呼び出し、

適切なイベント呼び出しと条件設定の下で、各帝国に融資提案を表示させ、

各帝国の選択に応じたイベント分岐(片方はイベント終了)を実施し、

借金返済時の国の財政状態で、返済イベントを切り替える。といった流れになります。

貸出イベントの呼出さて、まずは貸出イベントを呼び出します。「毎月」が条件なので、on_monthly_pulseを使います。

## \common\on_actions\SEoG_on_actions.txt on_monthly_pulse = { events = { sample_event.120 } }

on_monthly_pulse は、ターゲットスコープを持たないので、そのままでは「帝国」をイベント対象に設定できません。

そこで、まずは帝国をイベント対象に設定するためのクッションイベントを用意します。

## \events\SEoG_events_12.txt event = { id = sample_event.120 hide_window = yes is_triggererd_only = yes immediate = { every_country = { limit = { is_country_type = default } country_event = { id = sample_event.121 } } } } このイベントに限り、復習も兼ねて全行の説明をしていきます。

コード 説明 event = { ターゲットスコープが無いため、単なる「event」です。 hide_window = yes イベントを呼び出すためのイベントなので、ウィンドウ表示は不要です。内部処理として、ひっそりと行われます。 is_triggererd_only = yes on_monthly_pulseで呼び出す前提のため、呼び出された時発生するようにします。 immediate = { ここから、実際の効果の記述です。 every_country = { 「event」は、ターゲットを取らないため、誰を対象にするイベントかを、指定する必要があります。

今回は、全ての国を対象にするため、「every_country」です。ただじ、次行の「limit」内の条件を満たす国に限定しています。 limit = { is_country_type = default } この条件ですが、頻繁に出てきます。意味は、「種別がdefaultの国に限る」です。「default」は、「没落でも中立機構でもプレスリン等々でもない、普通の帝国」の意味です。 country_event = { id = sample_event.121 } 融資イベントを呼び出します。daysが無いため、直ちに呼び出し行います。 補足 「{」や「}」の数が合っているか注意しましょう。「カッコの閉じ忘れで動作不良」は、定番のバグです。 オマケ: is_country_type 国家の種別は、default (通常帝国)、fallen_empire (没落帝国・未覚醒)、awakened_fallen_empire (覚醒帝国)が代表的です。

一覧は、ゲーム本体の "\Stellaris\common\country_types\" に入っています。

さて、上の説明を見れば(あるいは見なくとも)分かるかと思いますが、財政赤字については全く触れていません。その部分の条件付けは、本ガイドでは、呼び出しを受ける sample_event.121 の trigger 内で行います(every_countryのlimit内で指定することも可能です)。

貸出イベント続いて、貸出イベントについて、作成していきます。

本イベントは、プレイヤーに借金するか否かを問うイベントなので、window表示が必要になります。

そのため、まず最初にid・title・desc・pictureを入れます。

テキスト系は例によって、キー & ymlファイル方式です。ymlファイルの記載は省略します。

また、国家(帝国)を対象としたイベントのため、種別はcountry_eventです。

country_event = { id = sample_event.121 title = sample_event.121.name ## タイトル「は・じ・めて・の」 desc = sample_event.121.desc picture = GFX_evt_city_ruins ## ↓sample_event.121.descの趣旨 ## 「1年後に2割増で返済するなら、エネルギー100貸すけどどうする?」

続いて、発生条件(フローチャート一番左の菱形3つ)を定めます。

本ゲームでは、特に指定しない場合、複数条件の列挙はandあつかい(全条件を満たした場合のみイベント発動)になります。

ですので、フローチャートの条件3つを列挙するのシンプルなコードです。

trigger = { energy <= 0 has_monthly_income = { resource = energy value < 0 } not = { has_country_flag = seog_has_loan } ## 借金中か否かは、フラグで判断。 } 上から、「エネルギー備蓄が0以下」・「指定資源(エネルギー)の月収が0未満」・「seog_has_loanフラグを持っていない」の意味です。

seog_has_loanフラグは、借金をするタイミングで「set_country_flag」で建て、借金返済と同時に「remove_country_flag」で取り払うことで、借金中か否かを判別させる仕組みにします。

フローチャートを辿ると、次は借金をするか否かをプレイヤーに問う段階になります。

選択肢提示より前に行うべき処理がないため、いつもの「immedinate」は無しです。

選択肢は、optionで提示するため、

option = { name = sample_event.121a.name ## 借りる custom_tooltip = sample_event.121a.tooltip } option = { name = sample_event.121b.name ## 借りない。 custom_tooltip = sample_event.121b.tooltip } となります。例によって、ymlファイルで、それっぽい文を入れる必要があります。

さて、借金しない場合、特に何もしないため、2つ目の選択肢については、これ以上手を入れる必要はありません。

しかし、借金をする場合、「エネルギー100を得る」・「借金中フラグを建てる」・「返済イベントを呼び出す」の3つの処理が必要になります。

したがって、option中に、それらの処理を加え、以下の形になります。

option = { name = sample_event.121a.name ## 借りる custom_tooltip = sample_event.121a.tooltip add_energy = 100 hidden_effect = { set_country_flag = seog_has_loan country_event = { id = sample_event.122 days = 360 } ## 返済成功 country_event = { id = sample_event.123 days = 360 } ## 返済失敗 } } option = { name = sample_event.121b.name ## 借りない。 custom_tooltip = sample_event.121b.tooltip } 「エネルギー100を得る」については、ツールチップに表示する方が良いでしょう。なので、option直下に記載します。

内部処理たる、フラグ管理やイベント呼び出しは非表示が妥当です。よって、「hidden_effect」の中に入れます。

返済イベント呼び出しについては、貸出時点では、借金が返済できるか否かが不明ですので、とりあえず返済成功・失敗の両方を呼び出しておきます。返済は1年後なので、「days = 360」を忘れないで下さい。

融資イベントで行う事は、これで全てなので、上記のコードをくっつけ、足りないカッコを補うと、以下の通り出来上がりです。

## \events\SEoG_events_12.txt country_event = { id = sample_event.121 title = sample_event.121.name ## タイトル「は・じ・めて・の」 desc = sample_event.121.desc picture = GFX_evt_city_ruins is_triggered_only = yes trigger = { energy <= 0 has_monthly_income = { resource = energy value < 0 } not = { has_country_flag = seog_has_loan } } ## immediate無し。選択肢提示前に行うべき処理がないため。 option = { name = sample_event.121a.name ## 借りる custom_tooltip = sample_event.121a.tooltip add_energy = 100 hidden_effect = { set_country_flag = seog_has_loan country_event = { id = sample_event.122 days = 360 } country_event = { id = sample_event.123 days = 360 } } } option = { name = sample_event.121b.name ## 借りない。 custom_tooltip = sample_event.121b.tooltip } }

工事中: 実践的なイベント呼出1: On Actions・イベント呼出・分岐 (続き)

Tips

字数制限に引っかかったので、セクションを分けました(苦笑)。気を取り直して続きです。

借金返済イベントさて、借金返済イベントの方は、淡々と処理を実行するだけなのでシンプルです。

## \events\SEoG_events_12.txt ## 借金返済成功イベント country_event = { id = sample_event.122 title = sample_event.122.name ## タイトル「返済期限」。 desc = sample_event.122.desc ## 説明文、趣旨: 「エネルギー120を返済する」。 picture = GFX_evt_city_ruins is_triggered_only = yes trigger = { energy >= 120 } option = { name = sample_event.122a.name ## タイトル「さっさと返済しよう」 custom_tooltip = sample_event.122a.tooltip add_energy = -120 hidden_effect = { remove_country_flag = seog_has_loan } } } ## \events\SEoG_events_12.txt ## 借金返済失敗イベント country_event = { id = sample_event.123 title = sample_event.123.name ## タイトル「返済期限」 desc = sample_event.123.desc ## 説明文、趣旨: 「エネルギー不足で、船2隻を売った」 picture = GFX_evt_alien_segregation is_triggered_only = yes trigger = { energy < 120 } immediate = { random_owned_ship = { delete_ship = this } ## 保有艦船を1隻消し去る。 random_owned_ship = { delete_ship = this } ## 2隻消すので、2回書く。 remove_country_flag = seog_has_loan } option = { name = sample_event.123a.name ## 「残念だ」 custom_tooltip = sample_event.123a.tooltip } }

最大の注意事項は、先程の融資イベントで成功・失敗の双方を呼び出したため、triggerで「エネルギ-備蓄120以上なら返済成功、120未満なら返済失敗」となるよう条件制御を行う事です。

これを忘れると、両方のイベントが発生してしまうので、ご注意下さい。

また、借金返済後は、再度借金できるように、「remove_country_flag = seog_has_loan」で借金フラグを消しています。

もし、「借金はゲーム中で1回限り」としたいなら、これらの行を削除すればOKです。

「返済失敗時は、再借金できない」としたいなら、失敗イベントのみ、同フラグ除去を無くすと実現できます。

: デバッグ 上記の返済失敗イベントは、イベントの繋げ方説明用なので、実用する場合は複数の問題を含んでいます。 発展的な内容ですが、バグ避けの面倒さが良く分かる部分ですので、興味があれば見てみて下さい。 返済成功イベ: add_energy = -120

上記の例では、optionsの中に入れましたが、実は不適切です。

というのも、「エネルギ-備蓄120以上を確認 → イベントウィンドウを表示 → 返済を選択 → 支払い」の順で処理される訳ですが、返済を選択する前に他の操作をしたり、時間を進めたりができてしまいます。

したがって、プレイヤーが「ウィンドウ表示 → エネルギ-を(タイル障害物除去等で)使いきる → 返済を選択」とすると、「借金を踏み倒しつつ、処理上は返済完了として進める」ができてしまいます。

それを防止するためには、add_energy を (optionではなく)immediate 内に入れる必要があります。

その場合、ツールチップ上にはエネルギ-120を払った旨が表示されなくなるため、文章を調整したりcustom_tooltip に手動で入れたりする必要があります。

返済失敗イベ: random_owned_ship

「保有艦船からランダムで1隻」の意味ですが、軍艦・民間船・軌道ステーションの全てが対象になりえます。

「差し押さえ対象が採掘ステーションでも、建設船でも、コルベでも、タイタンでも1隻は1隻だから良い」と考えるなら問題無しです。

しかし、「軌道ステーションを艦船と呼ぶのに違和感」とか「コルベもタイタンも同じあつかいはオカシイ」とか思うのであれば、もう少し丁寧な条件設定が必要になります。

非常に稀なケースでしょうが、艦船を0~1隻しか保有していない場合、random_owned_ship の対象が無くなります。

その場合、対象不在で「delete_ship = this」が実行できず、処理がスキップされます。

エラー等は出ませんが、「船で払ったふりして借金踏み倒し」状態になります。

したがって、本来なら「艦船ですら払えずにデフォルト(債務不履行)」イベントが必要になります。

返済失敗イベ: delete_ship

random_owned_ship で選ばれた艦船に、リーダーが搭乗していた場合、delete_ship で船を消す際に死にます。

さすがに変なので、実際には、それを回避するコードも挟む必要があります。

本項の解説は以上です。

Stellaris modに限らず、どのプログラムにも言えることですが、構文と関数を覚えたら、バカ正直に条件や操作・効果を記載していくのが基本です。

プログラムは、空気も行間も読んでくれません。右も左も分からない新入社員に教育する時以上に、ハッキリクッキリ指示を出しましょう。

Source: https://steamcommunity.com/sharedfiles/filedetails/?id=1360672749					

More Stellaris guilds