- 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を考想してみます。プロトタイプができるまでしばらくお待ちください!
こんばんは
返信削除こんな無茶なお願い聞いていただけるとは本当にありがとうございます。
プロトタイプできるのお待ちします。あまり無理せずに自分のペースでお願いします。
こんばんは
削除色々とバリエーションが思いついて逆に迷っていますが、とりあえずクラウド型を作ってみようと思っています。自由なペースでやりますので、期待しすぎず気長にお待ちを!