コンテナのアイテムを変換してばらまく

Modを作ろう

次のようなModを作ってみます。 コンテナをアクティベートしたら中に入っているアイテムがばらまかれる お金は小銭入れに変換してばらまく 小銭入れを拾ったらお金に戻る 目次 アクティベートを検知するコンテナのアイテムをばら […]

次のようなModを作ってみます。

  • コンテナをアクティベートしたら中に入っているアイテムがばらまかれる
  • お金は小銭入れに変換してばらまく
  • 小銭入れを拾ったらお金に戻る

アクティベートを検知する

アクティベートはPerkで捕捉できます。Perkを作ってプレイヤーに持たせておきます。

コンテナのアイテムをばらまく

コンテナのアイテム一覧をGetCointainerFormsで取得して、ループで処理します。

Non-Playableフラグのアイテムは無視します。

お金は別処理とします。

  • DropObjectでコンテナからフィールドにアイテムを放出する
  • MoveToで初期位置に誘導する(省略可)
  • ApplyHavokImpulseで飛ばす
  • 効果音を鳴らす

DropObject関数は、コンテナの中から外に出す処理をします。コンテナからアイテムを取り除く処理と、フィールドにアイテムを生成する処理を同時に行います。ただし、はじめからDisableに出来ないのと、初期位置も指定できません。

そこで、MoveTo関数で目的の位置に移動します。MoveToは3Dがロードされている必要がないので、待つ必要はなく最速で実行します。コンテナの高さを取得して、高さの少しだけ上がいいでしょう。複数のアイテムを同じ位置に持ってくると、アイテム同士がぶつかり合ってうまく飛ばないので、角度をかえていくといいでしょう。

MoveToはテレポートではなくて超高速に移動しているようなので、勢いが付く場合があります。ですが、基本的には飛ばないので、ApplyHavokImpulse関数で上に向かって飛ばします。ApplyHavokImpulseは3Dがロードされている必要があります。厳密に待ってもいいのですが、面倒なのでUtility.Wait(0.1)で0.1秒待てばほぼ大丈夫です。

お金を小銭入れに変換する

まず、小銭入れを作っておきます。バニラの小銭入れはFloraという、採集できる植物のレコードです。データ的には花やキノコと同じ扱いなのです。これだとうまくいかないので、MiscObjectで作ります。メッシュとサウンドはオリジナルのFlora版をそのまま使います。

以下のスクリプトを紐づけておきます。

MiscObject版の小銭入れ (papyrus)

Scriptname emObjectCoinPurseScript Extends ObjectReference

Int GoldCount = 0 ; 小銭入れの中に入っている金額


Event OnContainerChanged(ObjectReference akNewContainer, ObjectReference akOldContainer)
    debug.trace(Self + " " + akNewContainer + " " + akOldContainer)

    Actor kPlayerRef = Game.GetPlayer()
    MiscObject kGold = Game.GetForm(0xF) as MiscObject

    if akNewContainer
        ; いずれかのコンテナに入れられた
        if akNewContainer as Actor == kPlayerRef
            ; プレイヤーが入手したのなら、小銭入れの中に入っているゴールドを取り出す
            if GoldCount
                kPlayerRef.AddItem(kGold, GoldCount)
            endif

            ; 小銭入れは回収(削除)する
            kPlayerRef.RemoveItem(Self.GetBaseObject(), abSilent = true)
        else
            ; プレイヤー以外のコンテナに入れられたのなら、コンテナ内のゴールドを数える
            Int iCount = akNewContainer.GetItemCount(kGold)

            ; ゴールドが見つかったら回収(削除)して小銭入れの中に入れる
            if iCount
                akNewContainer.RemoveItem(kGold, iCount, abSilent = true)
                GoldCount += iCount
            endif
        endif
    else
        ; コンテナから外に出された(Cellに置かれた)
    endif
EndEvent

金額を保持するために、一度コンテナに入れるのがポイントです。

コンテナのアイテム一覧にMiscObjectのGold001が見つかったら、コンテナの中に小銭入れを入れます。

あとは、前述のアイテムをばらまく処理と同じです。お金をばらまくのではなく、お金は無視して小銭入れをばらまきます。

動作を確認する

お金の入っているコンテナ(Actorでも可)をアクティベートします。なければお金を入れてからアクティベートです。

小銭入れが出てきたら、コンソールを開いて小銭入れを選択して、sv(Show Varsの略)を実行するとスクリプトの情報が表示されるので便利です。

77ゴールド持たせてみた例です。きちんとスクリプトのプロパティに金額が保存されているのがわかります。

タイトルとURLをコピーしました