Thinking Skeever

Skyrim/The Witcher 3 Modについてのあれこれ。FoModの作り方、Mod導入時のトラブル事例などのニッチな話を書いていきます。a.k.a. BowmoreLover@nexusmods

FOModの作り方(チュートリアル05)

今回は少し複雑なインストール条件にチャレンジしてみましょうか。
プレイヤー向けの家を追加するModを例にFOModを作ってみます。

  • 部屋の見た目が3種類あり、それぞれ別のespがあるものとします。
  • さらにDLC HearthFiresの有無でespが2種類あり、全体で6種類のespがあるものとします。

Modファイル FOModTutor05.zip の構成

FOModTutor05\
    00 Core Files - HF\
        meshes\
            Core-hf-mesh.txt
        textures\
            Core-hf-texture.txt
    00 Core Files - Vanilla\
        meshes\
            Core-Vanilla-mesh.txt
        textures\
            Core-Vanilla-texture.txt
    10 Type1 - HF
        Type1-HF-esp.txt
    10 Type1 - Vanilla
        Type1-Vanilla-esp.txt
    10 Type2 - HF
        Type2--HF-esp.txt
    10 Type2 - Vanilla
        Type2-Vanilla-esp.txt
    10 Type3 - HF
        Type3-HF-esp.txt
    10 Type3 - Vanilla
        Type3-Vanilla-esp.txt
    FOMod\
        info.xml
        ModuleConfig.xml
        Images\
            Intro.jpg
            Type1.jpg
            Type2.jpg
            Type3.jpg

ページ構成の検討

今まで学んできた方法で実現可能か考えてみます。
DLCの有無と部屋のタイプの組み合わせで6種類のespをコピーし分ける必要があるので、次のページが必要そうです。

  • はじめにページ
  • DLC有無の選択ページ
  • DLC無のときの部屋のタイプ選択ページ(DLC無を選んだときに表示)
  • DLC有のときの部屋のタイプ選択ページ(DLC有を選んだときに表示)
  • 最終確認ページ

この程度なんとか実現できそうですが、似たようなページを2つ用意するのは少々無駄な気がします。
また、もしDLC有無以外に条件が増えた場合、全ての条件を網羅するためにページを増やしていかねばならず、さらに無駄が増えそうです。
ページが増えると、(コピペでいいとはいえ)英語版を作成するための翻訳箇所も増え面倒そうです。

今回は新しいタグ<conditionalFileInstalls>を使って楽をしてみます。

info.xmlの作成

<?xml version="1.0" encoding="UTF-16"?>
<fomod>
    <Name>FOMod Tutorial 05</Name>
    <Author>ThinkingSkeever</Author>
    <Version>0.0</Version>
    <Website>http://thinkingskeever.hatenablog.com/</Website>
    <Description>
    <p>This is FOMod Tutorial.</p>
    </Description>
</fomod>

ModuleConfig.xmlの作成

<?xml version="1.0" encoding="UTF-16"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="http://qconsulting.ca/fo3/ModConfig5.0.xsd">
    <moduleName>FOMod Tutorial 05</moduleName>
    <installSteps order="Explicit">

        <!-- *** はじめにページ *** -->

        <installStep name="">
            <optionalFileGroups order="Explicit">
                <group name="ようこそ!" type="SelectExactlyOne">
                    <plugins order="Explicit">
                        <plugin name="ようこそ">
                            <description>
                                ダウンロードしてくれてありがとう。&#xD;
これはFOModのチュートリアルです。&#xD;
次のページでインストールオプションが選べます。
                            </description>
                            <image path="FOMod\Images\Intro.jpg"/>
                            <files>
                            </files>
                            <typeDescriptor>
                                <type name="Required"/>
                            </typeDescriptor>
                        </plugin>
                    </plugins>
                </group>
            </optionalFileGroups>
        </installStep>

        <!-- *** DLC有無の選択ページ *** -->

        <installStep name="">
            <optionalFileGroups order="Explicit">
                <group name="DLCの有無" type="SelectExactlyOne">
                    <plugins order="Explicit">
                        <plugin name="Vanilla">
                            <description>
                                DLCなし
                            </description>
                            <image path=""/>
                            <files>
                            </files>
                            <conditionFlags>
                                <flag name="VanillaFlag">On</flag>
                            </conditionFlags>
                            <typeDescriptor>
                                <type name="Optional"/>
                            </typeDescriptor>
                        </plugin>
                        <plugin name="HearthFires">
                            <description>
                                DLC HearthFires
                            </description>
                            <image path=""/>
                            <files>
                            </files>
                            <conditionFlags>
                                <flag name="HFFlag">On</flag>
                            </conditionFlags>
                            <typeDescriptor>
                                <type name="Optional"/>
                            </typeDescriptor>
                        </plugin>
                    </plugins>
                </group>
            </optionalFileGroups>
        </installStep>

        <!-- *** 部屋のタイプ選択ページ *** -->

        <installStep name="">
            <optionalFileGroups order="Explicit">
                <group name="部屋のタイプ" type="SelectExactlyOne">
                    <plugins order="Explicit">
                        <plugin name="タイプ1">
                            <description>
                            </description>
                            <image path="FOMod\Images\Type1.jpg"/>
                            <files>
                            </files>
                            <conditionFlags>
                                <flag name="TypeFlag">1</flag>
                            </conditionFlags>
                            <typeDescriptor>
                                <type name="Optional"/>
                            </typeDescriptor>
                        </plugin>
                        <plugin name="タイプ2">
                            <description>
                            </description>
                            <image path="FOMod\Images\Type2.jpg"/>
                            <files>
                            </files>
                            <conditionFlags>
                                <flag name="TypeFlag">2</flag>
                            </conditionFlags>
                            <typeDescriptor>
                                <type name="Optional"/>
                            </typeDescriptor>
                        </plugin>
                        <plugin name="タイプ3">
                            <description>
                            </description>
                            <image path="FOMod\Images\Type3.jpg"/>
                            <files>
                            </files>
                            <conditionFlags>
                                <flag name="TypeFlag">3</flag>
                            </conditionFlags>
                            <typeDescriptor>
                                <type name="Optional"/>
                            </typeDescriptor>
                        </plugin>
                    </plugins>
                </group>
            </optionalFileGroups>
        </installStep>

        <!-- *** 最終確認ページ *** -->

        <installStep name="">
            <optionalFileGroups order="Explicit">
                <group name="インストールの開始" type="SelectExactlyOne">
                    <plugins order="Explicit">
                        <plugin name="インストールの開始">
                            <description>
                                インストールオプションの選択が完了しました。&#xD;
インストールを開始します。
                            </description>
                            <image path=""/>
                            <files>
                            </files>
                            <typeDescriptor>
                                <type name="Required"/>
                            </typeDescriptor>
                        </plugin>
                    </plugins>
                </group>
            </optionalFileGroups>
        </installStep>

    </installSteps>

    <!-- *** ファイルのコピー *** -->

    <conditionalFileInstalls>
        <patterns>

            <!-- *** コアファイル *** -->

            <pattern>
                <dependencies operator="And">
                    <flagDependency flag="VanillaFlag" value="On"/>
                </dependencies>
                <files>
                    <folder source="00 Core Files - Vanilla" destination="" priority="0"/>
                </files>
            </pattern>

            <pattern>
                <dependencies operator="And">
                    <flagDependency flag="HFFlag" value="On"/>
                </dependencies>
                <files>
                    <folder source="00 Core Files - HF" destination="" priority="0"/>
                </files>
            </pattern>

            <!-- *** ESPファイル Type1 *** -->

            <pattern>
                <dependencies operator="And">
                    <flagDependency flag="TypeFlag" value="1"/>
                    <flagDependency flag="VanillaFlag" value="On"/>
                </dependencies>
                <files>
                    <folder source="10 Type1 - Vanilla" destination="" priority="0"/>
                </files>
            </pattern>

            <pattern>
                <dependencies operator="And">
                    <flagDependency flag="TypeFlag" value="1"/>
                    <flagDependency flag="HFFlag" value="On"/>
                </dependencies>
                <files>
                    <folder source="10 Type1 - HF" destination="" priority="0"/>
                </files>
            </pattern>

            <!-- *** ESPファイル Type2 *** -->

            <pattern>
                <dependencies operator="And">
                    <flagDependency flag="TypeFlag" value="2"/>
                    <flagDependency flag="VanillaFlag" value="On"/>
                </dependencies>
                <files>
                    <folder source="10 Type2 - Vanilla" destination="" priority="0"/>
                </files>
            </pattern>

            <pattern>
                <dependencies operator="And">
                    <flagDependency flag="TypeFlag" value="2"/>
                    <flagDependency flag="HFFlag" value="On"/>
                </dependencies>
                <files>
                    <folder source="10 Type2 - HF" destination="" priority="0"/>
                </files>
            </pattern>

            <!-- *** ESPファイル Type3 *** -->

            <pattern>
                <dependencies operator="And">
                    <flagDependency flag="TypeFlag" value="3"/>
                    <flagDependency flag="VanillaFlag" value="On"/>
                </dependencies>
                <files>
                    <folder source="10 Type3 - Vanilla" destination="" priority="0"/>
                </files>
            </pattern>

            <pattern>
                <dependencies operator="And">
                    <flagDependency flag="TypeFlag" value="3"/>
                    <flagDependency flag="HFFlag" value="On"/>
                </dependencies>
                <files>
                    <folder source="10 Type3 - HF" destination="" priority="0"/>
                </files>
            </pattern>

        </patterns>

    </conditionalFileInstalls>

</config>

インストール方法

  • FOModTutor05フォルダごとZIPファイルなどに圧縮してMod管理ツールでインストールします。

動作確認のポイント

  • DLCの有無と部屋のタイプの組み合わせで、インストールされるダミーファイルが変化することを確認します。

f:id:thinkingskeever:20150429221521j:plain
f:id:thinkingskeever:20150429221525j:plain

解説

  • 検討段階では5ページになるはずだったところ、4ページで収まっていることに注目してください。
  • <installSteps>内では<folder>によるファイルコピーをせず、<conditionFlags>によるフラグの設定のみを行っています。
    • "VanillaFlag":Vanillaを選んだときに"On"を設定
    • "HFFlag":HearthFiresを選んだときに"On"を設定
    • "TypeFlag":選んだ部屋のタイプに応じて"1"、"2"、"3"のいずれかを設定
  • xml後半の<conditionalFileInstalls>で、前半で設定されたフラグの組み合わせにしたがってファイルをコピーしています。
    • <pattern>内には、コピー条件を示す<dependencies>と、コピーするファイルを示す<files>をセットで記述しています。
    • operator="And"は、<flagDependency>で指定された条件すべてを満たしたときにファイルをコピーすることを示しています。この例では使っていませんがoperator="Or"に変更すると、どれか1つでも条件が満たされればコピーされます。

どうでしょうか。前半のページ表示部分ではフラグを設定することに専念し、コピー処理を後半にまとめて書けるので、処理が整理しやすくないですか?
この例は比較的簡単な条件でしたが、前提Modや競合Modとの組み合わせで互換パッチの選択がとても複雑なModでも柔軟に対応できそうですね。

最後に

ざっと駆け足で説明してきましたがいかがでしたか。
私の見た限り現存するModの9割方はこれまで学んだ機能だけででFOModを作成できています。
FOModにはまだまだ隠された機能がありますが、それについては追々(気が向いたら)書いていこうと思います。

以上です。

Copyright (C) 2015,2017 ThinkingSkeever, All Rights Reserved.
ブログの記事内に記載されているメーカー名、製品名称等は、日本及びその他の国における各企業の商標または登録商標です。
リンクはご自由に。記事の転載はご遠慮ください。記事を引用する場合はトラックバックするか元のURLを明記してください。