- Papyrusスクリプトの記憶を記録に残すシリーズその11 -
前回の 自動脱衣・着衣機能をつけよう のスクリプトをアップデートします。
NPCおよびプレイヤーの自動脱衣・着衣スクリプト統合版(要SKSE)の修正です。
※2020/07/14 新サイトでアップデート記事を書きました。→ 自動脱衣スクリプト2020 | 今もSkyrim
目次
1. 変更点
今回のスクリプトはNPCもプレイヤーも自動脱衣・着衣するものです。UnEquipAll
というコードを使うかどうかで2つのバリエーションを用意しました。UnEquipAll
版はCTDに注意する必要がありますので後述してあります。
変更点は主として以下の2点です。トリガーボックスへのスクリプトの付け方等については前回を参照してください。
1-1. たいまつへの対応
たいまつは武器扱いではないため、前回のスクリプトでは対応できていませんでした。プレイヤーの装備情報を「Weapon」ではなく「Form」タイプのプロパティに保存することで、たいまつも着脱できるように対応しました。
NPCは暗い場所で自動的にたいまつを使うので対応不要ですが、記述の統一性を持たせるために一部変更しています。
1-2. 両手武器を外した際、前の片手武器が装備される仕様への対策
UnEquipAll
を使わない完全版でのみ必要な対策です。
両手武器を装備中、左手に巻物やたいまつを持ったりすると、右手にはその前に装備していた片手武器が自動的に装備されます。これはバニラの仕様で、スクリプトから両手武器を外しても同じことが起こります。
UnEquipAll
を使わない場合、この自動装備される片手武器も外す必要があり、対策しました。
2. UnEquipAll
版
まず簡単な、UnEquipAll
を使う方法から載せておきます。
前回も説明しましたが、脱衣する actPasser.UnEquipAll()
のところでCTDすることがありますが、それで良ければこちらの方が記述も短くて理解しやすいです。
CTDは、セーブデータロード直後、一度もセルロードを挟まずにNPC(フォロワー)がトリガーボックスに入った時に起こります。
使う場合は以下のスクリプトをトリガーボックスに付けて、armRing
および folArmor
の2つのプロパティだけ指定してください。
Scriptname EkaUndressScript05 extends ObjectReference { NPC、プレイヤー脱衣統合版(要SKSE)。トリガーボックスに適用。} ;下記2つのプロパティを指定--- Armor Property armRing Auto ; JewelryRingGold を指定 FormList Property folArmor Auto ; 作成した空の FormList を指定 ;------------------------------- Form Property fomWepL Auto Form Property fomWepR Auto Actor actPasser Form fomTemp Int i ;--------------------------------------------------入る時 Event OnTriggerEnter(ObjectReference akTriggerRef) actPasser = akTriggerRef as Actor If actPasser == None Return ElseIf actPasser == Game.GetPlayer() ; プレイヤー If folArmor.GetSize() > 0 folArmor.Revert() EndIf i = 0 While i < 31 ; 防具 fomTemp = actPasser.GetWornForm(Math.LeftShift(1, i)) If fomTemp != None folArmor.AddForm(fomTemp) fomTemp = None EndIf i += 1 EndWhile fomWepR = actPasser.GetEquippedObject(1) ; 右手武器 fomWepL = actPasser.GetEquippedObject(0) ; 左手武器 EndIf actPasser.UnEquipAll() actPasser = None EndEvent ;--------------------------------------------------出る時 Event OnTriggerLeave(ObjectReference akTriggerRef) actPasser = akTriggerRef as Actor If actPasser == None Return ElseIf actPasser != Game.GetPlayer() ; NPC着衣 actPasser.AddItem(armRing, 1, true) actPasser.EquipItem(armRing, false, true) actPasser.RemoveItem(armRing, 1, true) Else ; プレイヤー着衣 Int intNum = folArmor.GetSize() If intNum > 0 i = 0 While i < intNum && i < 31 fomTemp = folArmor.GetAt(i) If fomTemp != None && actPasser.GetItemCount(fomTemp) > 0 actPasser.EquipItemEx(fomTemp, 0, false, true) EndIf fomTemp = None i += 1 EndWhile folArmor.Revert() EndIf If fomWepR != None && actPasser.GetItemCount(fomWepR) > 0 actPasser.EquipItemEx(fomWepR, 1) EndIf fomWepR = None If fomWepL != None && actPasser.GetItemCount(fomWepL) > 0 actPasser.EquipItemEx(fomWepL, 2) EndIf fomWepL = None EndIf actPasser = None EndEvent
3. 完全版
本命です。UnEquipAll
版と異なるのは「入る時」の脱衣スクリプトの部分で、「出る時」はまったく同じ記述です。
以下のスクリプトをトリガーボックスに付けて、armRing
および folArmor
の2つのプロパティだけ指定してください。
Scriptname EkaUndressScript06 extends ObjectReference { NPC、プレイヤー脱衣統合版(要SKSE)。トリガーボックスに適用。UnEquipAll 未使用完全版。} ;下記2つのプロパティを指定--- Armor Property armRing Auto ; JewelryRingGold を指定 FormList Property folArmor Auto ; 作成した空の FormList を指定 ;------------------------------- Form Property fomWepL Auto Form Property fomWepR Auto Actor actPasser Form fomTemp Int i ;--------------------------------------------------入る時 Event OnTriggerEnter(ObjectReference akTriggerRef) i = 0 actPasser = akTriggerRef as Actor If actPasser == None Return ElseIf actPasser != Game.GetPlayer() ; NPC脱衣 While i < 31 actPasser.UnequipItemSlot(30 + i) i += 1 EndWhile fomTemp = actPasser.GetEquippedObject(1) ; 右手 If fomTemp != None actPasser.UnequipItemEx(fomTemp, 1) fomTemp = None Utility.Wait(0.01) EndIf fomTemp = actPasser.GetEquippedObject(0) ; 左手 If fomTemp != None actPasser.UnequipItemEx(fomTemp, 2) fomTemp = None EndIf Else ; プレイヤー脱衣 If folArmor.GetSize() > 0 folArmor.Revert() EndIf While i < 31 fomTemp = actPasser.GetWornForm(Math.LeftShift(1, i)) If fomTemp != None folArmor.AddForm(fomTemp) actPasser.UnequipItemSlot(30 + i) fomTemp = None EndIf i += 1 EndWhile Int intWepTypeR = actPasser.GetEquippedItemType(1) ; 右手武器タイプ If intWepTypeR != 0 fomWepR = actPasser.GetEquippedObject(1) ; 右手武器 If fomWepR != None actPasser.UnequipItemEx(fomWepR, 1) ; 両手武器の時、ここで直前の片手武器が装備される EndIf EndIf Int intWepTypeL = actPasser.GetEquippedItemType(0) ; 左手武器タイプ If intWepTypeR == 5 || intWepTypeR == 6 || intWepTypeR == 7 || intWepTypeR == 12 ; 両手装備の時 fomTemp = actPasser.GetEquippedObject(1) ; 両手装備前の右手装備を外す If fomTemp != None If actPasser.GetEquippedItemType(1) == 9 ; 魔法 actPasser.UnequipSpell(fomTemp as Spell, 1) Else actPasser.UnequipItemEx(fomTemp, 1) EndIf fomTemp = None Utility.Wait(0.01) EndIf fomTemp = actPasser.GetEquippedObject(0) ; 両手装備前の左手装備を外す If fomTemp != None If intWepTypeL == 9 ; 魔法 actPasser.UnequipSpell(fomTemp as Spell, 0) ElseIf intWepTypeL == 10 ; 盾が上手く外れないので指定 actPasser.UnequipItemSlot(39) Else actPasser.UnequipItemEx(fomTemp, 2) EndIf fomTemp = None EndIf ElseIf intWepTypeL != 0 && intWepTypeL != 9 && intWepTypeL != 10 ; 魔法は外さない,盾は外し済み fomWepL = actPasser.GetEquippedObject(0) ; 左手武器 If fomWepL != None actPasser.UnequipItemEx(fomWepL, 2) EndIf EndIf EndIf actPasser = None EndEvent ;--------------------------------------------------出る時 Event OnTriggerLeave(ObjectReference akTriggerRef) actPasser = akTriggerRef as Actor If actPasser == None Return ElseIf actPasser != Game.GetPlayer() ; NPC着衣 actPasser.AddItem(armRing, 1, true) actPasser.EquipItem(armRing, false, true) actPasser.RemoveItem(armRing, 1, true) Else ; プレイヤー着衣 Int intNum = folArmor.GetSize() If intNum > 0 i = 0 While i < intNum && i < 31 fomTemp = folArmor.GetAt(i) If fomTemp != None && actPasser.GetItemCount(fomTemp) > 0 actPasser.EquipItemEx(fomTemp, 0, false, true) EndIf fomTemp = None i += 1 EndWhile folArmor.Revert() EndIf If fomWepR != None && actPasser.GetItemCount(fomWepR) > 0 actPasser.EquipItemEx(fomWepR, 1) EndIf fomWepR = None If fomWepL != None && actPasser.GetItemCount(fomWepL) > 0 actPasser.EquipItemEx(fomWepL, 2) EndIf fomWepL = None EndIf actPasser = None EndEvent
ある程度はコメントとして説明を入れておきました。GetEquippedItemType
を使って武器のタイプを数字で取得し、条件分岐しています。
処理が重い武器だと両手武器を外した時にほんの一瞬だけ片手武器が表示されてしまいますが、これは防げませんでした。普段は両手武器をメインで使わないので、前回のときは気付きませんでしたよ。
---2018/07/05 追記---
前回の記事と同様、プレイヤー付呪品の装備について修正を行いました。
actPasser.EquipItem(fomTemp, false, true)
の部分を
actPasser.EquipItemEx(fomTemp, 0, false, true)
に書き換えたものです。
これにより、プレイヤーが付呪した装備品でも、装備の際に付呪効果が適用されるようになっています。
---追記以上---
補足:私はスクリプトを書くのは好きですが、専門家ではありません。内容は creationkit.com の情報と個人的な経験を基にして書いています。どうかご参考程度にご覧ください。
はじめまして 最近SkyrimSEをはじめた者です。
返信削除他の人が公開している家MODを使用していたのですが、着衣すると付呪の効果が反映されないので、CKの使い方を調べながらこちらのスクリプトを使用させていただきました。
コメントなどが詳しく書いていてくださるのでスクリプトがわからない自分でもどういうことをしているのか理解しやすかったです。
家のMODを改造して自分好みにしていこうと思っているのですが、オートソート、オートストレージをつけようと"General Stores - Auto Sorting Cloud Storage Resource"を入れてみたのですが、分類が大雑把で、もっと細かく仕分けできればとスクリプトを見たのですが、自分には何をやっているのかわからず。
本当にあつかましいのですが、もし時間がありオートストレージのMOD等も作れるようでしたら、
”General Stores - Auto Sorting Cloud Storage Resource for packrats”見たいなもので分類がもっと細かい物を考えていただけないでしょうか?
はじめまして!ようこそお越しくださいました。
削除付呪効果の件、少しでもヒントになったのなら嬉しいです。長いスクリプトを読んでいただいてありがとうございます。
オートストレージMODは面白そうですね。今までその系統のMODを使ったことがありませんが、スクリプトは書けそうな気がします。ご紹介いただいたMODのDescriptionを読んでみたところ、12種類のストレージに分類される感じでしょうか。
自由に配置できるクラウド型オートストレージMODを考想してみます。プロトタイプができるまでしばらくお待ちください!
こんばんは
返信削除こんな無茶なお願い聞いていただけるとは本当にありがとうございます。
プロトタイプできるのお待ちします。あまり無理せずに自分のペースでお願いします。
こんばんは
削除色々とバリエーションが思いついて逆に迷っていますが、とりあえずクラウド型を作ってみようと思っています。自由なペースでやりますので、期待しすぎず気長にお待ちを!