ScriptName aaaKimachuuOutfit extends ActiveMagicEffect

Message Property MesLoad Auto ;ロードスロット選択メッセージ
Message Property MesLoadNPC Auto ;ロードスロット選択メッセージ
Message Property MesSave Auto ;セーブスロット選択メッセージ
Message Property MesSaveNPC Auto ;セーブスロット選択メッセージ
LeveledItem Property llOutfit01 Auto ;衣装用レベルドリスト
LeveledItem Property llOutfit02 Auto ;衣装用レベルドリスト
LeveledItem Property llOutfit03 Auto ;衣装用レベルドリスト
LeveledItem Property llOutfit04 Auto ;衣装用レベルドリスト
LeveledItem Property llOutfit05 Auto ;衣装用レベルドリスト
LeveledItem Property llOutfit06 Auto ;衣装用レベルドリスト
LeveledItem Property llOutfit07 Auto ;衣装用レベルドリスト
LeveledItem Property llOutfit08 Auto ;衣装用レベルドリスト
LeveledItem Property llOutfit09 Auto ;衣装用レベルドリスト
Outfit Property npcOutfit01 Auto ;衣装
Outfit Property npcOutfit02 Auto ;衣装
Outfit Property npcOutfit03 Auto ;衣装
Outfit Property npcOutfit04 Auto ;衣装
Outfit Property npcOutfit05 Auto ;衣装
Outfit Property npcOutfit06 Auto ;衣装
Outfit Property npcOutfit07 Auto ;衣装
Outfit Property npcOutfit08 Auto ;衣装
Outfit Property npcOutfit09 Auto ;衣装
Outfit Property npcOutfitEmpty Auto ;空の衣装

String sPath1 = "../KimachuuOutfit/KimachuuOutfit" ;ファイルパス前半
String sPath2 = ".json" ;ファイルパス後半

Event OnEffectStart(Actor akTarget, Actor akCaster) ;レッサーパワーで現在の服装をセーブしたりロードしたりするMODだよ
	Actor TargetRef = Game.GetCurrentCrosshairRef() as Actor ;NPCがクロスヘアにいるかどうか判別する

	if TargetRef && akTarget.IsSneaking() ;クロスヘアにNPCがいて自分がスニーク状態だった場合
		Int iIndex = MesSaveNPC.Show() ;セーブスロット選択メニュー
		If iIndex <= 8 ;キャンセル以外ならセーブ処理開始
			outfitSaveNPC(TargetRef, iIndex) ;選択した番号がそのままファイル名となる
		Else
			Debug.Notification("Cancel.") ;キャンセル通知
		EndIf
	Elseif TargetRef ;クロスヘアにNPCがいる場合
		Int iIndex = MesLoadNPC.Show() ;ロードスロット選択メニュー
		If iIndex <= 8 ;キャンセル以外ならロード処理開始
			outfitLoadNPC(TargetRef, iIndex) ;選択した番号がそのままファイル名となる
		Else
			Debug.Notification("Cancel.") ;キャンセル通知
		EndIf
	ElseIf akTarget.IsSneaking() ;スニーク中かどうかを判断し、スニーク中なら服装をセーブ
		Int iIndex = MesSave.Show() ;セーブスロット選択メニュー
		If iIndex <= 8 ;キャンセル以外ならセーブ処理開始
			outfitSave(akTarget, iIndex) ;選択した番号がそのままファイル名となる
		Else
			Debug.Notification("Cancel.") ;キャンセル通知
		EndIf
	Else ;スニーク中で無ければ服装をロード
		Int iIndex = MesLoad.Show() ;ロードスロット選択メニュー
		If iIndex <= 8 ;キャンセル以外ならロード処理開始
			outfitLoad(akTarget, iIndex) ;選択した番号がそのままファイル名となる
		Else
			Debug.Notification("Cancel.") ;キャンセル通知
		EndIf
	EndIf
endEvent

Function outfitSave(Actor aObj1, Int iNum) ;服装のセーブ処理
	Int i = 0 ;繰り返し処理用の数値
	Weapon wObjR = None ;右手の武器
	Spell spObjR = None ;右手の魔法
	Weapon wObjL = None ;左手の武器
	Spell spObjL = None ;左手の魔法
	String sObjsID ;取得したEditorIDを格納する場所

	Form[] fArmor = Utility.CreateFormArray(32, None) ;32個の配列を作成、アーマー格納用
	fArmor = po3_sksefunctions.AddAllEquippedItemsToArray(aObj1) ;po3 Papyrus Extenderの機能で装備中のアーマーを配列に格納する
	Int iArmorC = fArmor.length ;装備中のアーマーがどれくらいの容量かを確認

	if iArmorC == 0 ;容量が0、つまり何も装備していなければ処理中断
		Debug.MessageBox("Nothing equipped.") ;処理中断通知
		return ;処理中断
	endIf

	JsonUtil.ClearAll(sPath1 + iNum + sPath2) ;PapyrusUtil SEの機能でファイル内容を空にする

	While i < iArmorC ;全てのアーマーを処理し終わるまで繰り返す
		String sArmorID = ""
		Armor aArmor = None

		aArmor = fArmor[i] as armor ;先程の配列に格納されたi番目のアーマーをチェック
		sArmorID = po3_sksefunctions.GetFormEditorID(aArmor) ;po3 Papyrus Extenderの機能でアーマーのEditorIDを取得する
		If sArmorID ;i番目にアーマーを装備している
			JsonUtil.SetStringValue(sPath1 + iNum + sPath2, "armor" + i, sArmorID) ;PapyrusUtil SEの機能で、jsonファイルにアーマーのEditorIDを書き込む
		Else ;i番目にアーマーを装備していない
			JsonUtil.SetStringValue(sPath1 + iNum + sPath2, "armor" + i, "");PapyrusUtil SEの機能で、jsonファイルの該当部分を消去する
		EndIf
		i += 1 ;次のアーマーの処理に移行させる為、変数を加算
	EndWhile

	Int iREquip = aObj1.GetEquippedItemType(1) ;右手の装備を取得
	If iREquip >= 1 && iREquip <= 8 ;右手に武器を持っている
		wObjR = aObj1.GetEquippedWeapon() ;右手の武器を取得
	ElseIf iREquip == 9 ;右手に魔法を持っている
		spObjR = aObj1.GetEquippedSpell(1) ;右手の魔法を取得
	ElseIf iREquip == 12 ;右手にクロスボウを持っている
		wObjR = aObj1.GetEquippedWeapon() ;右手のクロスボウを取得
	EndIf

	If wObjR != None ;右手に武器が存在する
		String sObjwID = po3_sksefunctions.GetFormEditorID(wObjR) ;po3 Papyrus Extenderの機能で、武器のEditorIDを取得する
		JsonUtil.SetStringValue(sPath1 + iNum + sPath2, "rhandwep", sObjwID) ;PapyrusUtil SEの機能で、jsonファイルに武器を書き込む
		JsonUtil.SetStringValue(sPath1 + iNum + sPath2, "rhandsp", "") ;PapyrusUtil SEの機能で、jsonファイルの魔法を空白にする
	ElseIf spObjR != None ;右手に魔法が存在する
		sObjsID = po3_sksefunctions.GetFormEditorID(spObjR) ;po3 Papyrus Extenderの機能で、魔法のEditorIDを取得する
		JsonUtil.SetStringValue(sPath1 + iNum + sPath2, "rhandwep", "") ;PapyrusUtil SEの機能で、jsonファイルの武器を空白にする
		JsonUtil.SetStringValue(sPath1 + iNum + sPath2, "rhandsp", sObjsID) ;PapyrusUtil SEの機能で、jsonファイルに魔法を書き込む
	Else ;右手に何も存在しない
		JsonUtil.SetStringValue(sPath1 + iNum + sPath2, "rhandwep", "") ;PapyrusUtil SEの機能で、jsonファイルの武器を空白にする
		JsonUtil.SetStringValue(sPath1 + iNum + sPath2, "rhandsp", "") ;PapyrusUtil SEの機能で、jsonファイルの魔法を空白にする
	EndIf

	Int iLEquip = aObj1.GetEquippedItemType(0) ;左手の装備を取得
	If iLEquip >= 1 && iLEquip <= 8 ;左手に武器を持っている
		wObjL = aObj1.GetEquippedWeapon(True) ;左手の武器を取得
	ElseIf iLEquip == 9 ;左手に魔法を持っている
		spObjL = aObj1.GetEquippedSpell(0) ;左手の魔法を取得
	EndIf

	If wObjL != None ;左手に武器が存在する
		String sObjwID = po3_sksefunctions.GetFormEditorID(wObjL) ;po3 Papyrus Extenderの機能で、武器のEditorIDを取得する
		JsonUtil.SetStringValue(sPath1 + iNum + sPath2, "lhandwep", sObjwID) ;PapyrusUtil SEの機能で、jsonファイルに武器を書き込む
		JsonUtil.SetStringValue(sPath1 + iNum + sPath2, "lhandsp", "") ;PapyrusUtil SEの機能で、jsonファイルの魔法を空白にする
	ElseIf spObjL != None ;左手に魔法が存在する
		sObjsID = po3_sksefunctions.GetFormEditorID(spObjL) ;po3 Papyrus Extenderの機能で、魔法のEditorIDを取得する
		JsonUtil.SetStringValue(sPath1 + iNum + sPath2, "lhandwep", "") ;PapyrusUtil SEの機能で、jsonファイルの武器を空白にする
		JsonUtil.SetStringValue(sPath1 + iNum + sPath2, "lhandsp", sObjsID) ;PapyrusUtil SEの機能で、jsonファイルに魔法を書き込む
	Else ;左手に何も存在しない
		JsonUtil.SetStringValue(sPath1 + iNum + sPath2, "lhandwep", "") ;PapyrusUtil SEの機能で、jsonファイルの武器を空白にする
		JsonUtil.SetStringValue(sPath1 + iNum + sPath2, "lhandsp", "") ;PapyrusUtil SEの機能で、jsonファイルの魔法を空白にする
	EndIf

	Debug.MessageBox("Done.") ;処理完了メッセージ
	JsonUtil.Save(sPath1 + iNum + sPath2) ;PapyrusUtil SEの機能でjsonファイルに書き込む
EndFunction

Function outfitLoad(Actor aObj1, Int iNum) ;服装のロード処理
	Int i = 0 ;繰り返し処理用の数値
	Int iFCount = 0 ;読み込みに失敗したアーマーの数

	aObj1.SetAlpha(0.0) ;プレイヤーが裸になると困るので、一時的に透明にセット
	Utility.Wait(0.1) ;事故防止の為の待機時間
	aObj1.UnequipAll() ;プレイヤーを脱がす
	While i < 32 ;全てのアーマーを読み込むまで繰り返す
		String sObjID = JsonUtil.GetStringValue(sPath1 + iNum + sPath2, "armor" + i) ;PapyrusUtil SEの機能でアーマーのEditorID文字列を格納
		Form aArmorID = po3_sksefunctions.GetFormFromEditorID(sObjID) ;po3 Papyrus Extenderの機能でアーマーのEditorIDを取得
		If sObjID && !aArmorID ;アーマーの名前は存在するが、EditorIDが存在しなかった場合
			iFCount += 1 ;読み込み失敗数を加算
		ElseIf aArmorID && (aObj1.GetItemCount(aArmorID) == 0) ;該当アーマーが存在し、該当アーマーを未所持
			aObj1.AddItem(aArmorID, 1, True) ;該当アーマーを入手
			aObj1.EquipItem(aArmorID, False, True) ;該当アーマーを装備
		ElseIf aArmorID && (aObj1.GetItemCount(aArmorID) >= 1) ;該当アーマーが存在し、該当アーマーを所持
			aObj1.EquipItem(aArmorID, False, True) ;該当アーマーを装備
		Endif
		i += 1 ;次のアーマーの処理に移行させる為、変数を加算
	EndWhile

	Utility.Wait(0.1)
	
	aObj1.SetAlpha(1.0) ;プレイヤーの透明度を元に戻す

	String sObjRwep = None ;右手の武器の名前
	String sObjRsp = None ;右手の魔法の名前
	Form fObjRwep = None ;右手の武器
	Spell spObjR = None ;右手の魔法

	sObjRwep = JsonUtil.GetStringValue(sPath1 + iNum + sPath2, "rhandwep") ;PapyrusUtil SEの機能で、右手の武器の名前を取得
	sObjRsp = JsonUtil.GetStringValue(sPath1 + iNum + sPath2, "rhandsp") ;PapyrusUtil SEの機能で、右手の魔法の名前を取得
	fObjRwep = po3_sksefunctions.GetFormFromEditorID(sObjRwep) ;po3 Papyrus Extenderの機能で、右手の武器の名前からEditorIDを取得
	spObjR = po3_sksefunctions.GetFormFromEditorID(sObjRsp) As Spell ;po3 Papyrus Extenderの機能で、右手の魔法の名前からEditorIDを取得

	If fObjRwep != None && (aObj1.GetItemCount(fObjRwep) == 0) ;右手の武器が存在するが、所持していない
		aObj1.AddItem(fObjRwep, 1, True) ;該当武器を所持品に追加
		aObj1.EquipItemEx(fObjRwep) ;該当武器を右手に装備
	ElseIf fObjRwep != None && (aObj1.GetItemCount(fObjRwep) >= 1) ;右手の武器が存在し、所持している
		aObj1.EquipItemEx(fObjRwep) ;該当武器を右手に装備
	ElseIf spObjR != None ;右手に魔法が存在する
		aObj1.AddSpell(spObjR) ;該当魔法を習得
		aObj1.EquipSpell(spObjR, 1) ;該当魔法を右手に装備
	EndIf

	String sObjLwep = None ;左手の武器の名前
	String sObjLsp = None ;左手の魔法の名前
	Form fObjLwep = None ;左手の武器
	Spell spObjL = None ;左手の魔法

	sObjLwep = JsonUtil.GetStringValue(sPath1 + iNum + sPath2, "lhandwep") ;PapyrusUtil SEの機能で、左手の武器の名前を取得
	sObjLsp = JsonUtil.GetStringValue(sPath1 + iNum + sPath2, "lhandsp") ;PapyrusUtil SEの機能で、左手の魔法の名前を取得
	fObjLwep = po3_sksefunctions.GetFormFromEditorID(sObjLwep) ;po3 Papyrus Extenderの機能で、左手の武器の名前からEditorIDを取得
	spObjL = po3_sksefunctions.GetFormFromEditorID(sObjLsp) As Spell ;po3 Papyrus Extenderの機能で、左手の魔法の名前からEditorIDを取得

	If fObjLwep != None && (aObj1.GetItemCount(fObjLwep) == 0) ;左手の武器が存在するが、所持していない
		aObj1.AddItem(fObjLwep, 1, True) ;該当武器を所持品に追加
		aObj1.EquipItemEx(fObjLwep, 2) ;該当武器を左手に装備
	ElseIf fObjLwep != None && (aObj1.GetItemCount(fObjLwep) >= 1) ;左手の武器が存在し、所持している
		aObj1.EquipItemEx(fObjLwep, 2) ;該当武器を左手に装備
	ElseIf spObjL != None ;左手に魔法が存在する
		aObj1.AddSpell(spObjL) ;該当魔法を習得
		aObj1.EquipSpell(spObjL, 0) ;該当魔法を左手に装備
	EndIf

	If iFCount >= 1 ;読み込み失敗アーマーが1つ以上
		Debug.MessageBox("Done. Failed loads:" + iFCount) ;処理完了メッセージ、読み込みに失敗したアーマーの数を表示する
	Else
		Debug.MessageBox("Done.") ;処理完了メッセージ
	EndIf
EndFunction

Function outfitLoadNPC(Actor aObj1, Int iNum) ;服装のロード処理
	Int i = 0 ;繰り返し処理用の数値
	Int iFCount = 0 ;読み込みに失敗したアーマーの数

	aObj1.SetAlpha(0.0) ;NPCが裸になると困るので、一時的に透明にセット
	Utility.Wait(0.1) ;事故防止の為の待機時間

	aObj1.SetOutfit(npcOutfitEmpty) ;NPCに空の服を着せる

	Utility.Wait(0.1)

	if iNum == 0
		llOutfit01.Revert() ;レベルドリストの初期化
	Elseif iNum == 1
		llOutfit02.Revert() ;レベルドリストの初期化
	Elseif iNum == 2
		llOutfit03.Revert() ;レベルドリストの初期化
	Elseif iNum == 3
		llOutfit04.Revert() ;レベルドリストの初期化
	Elseif iNum == 4
		llOutfit05.Revert() ;レベルドリストの初期化
	Elseif iNum == 5
		llOutfit06.Revert() ;レベルドリストの初期化
	Elseif iNum == 6
		llOutfit07.Revert() ;レベルドリストの初期化
	Elseif iNum == 7
		llOutfit08.Revert() ;レベルドリストの初期化
	Elseif iNum == 8
		llOutfit09.Revert() ;レベルドリストの初期化
	EndIf

	Utility.Wait(0.1)

	While i < 32 ;全てのアーマーを読み込むまで繰り返す
		String sObjID = JsonUtil.GetStringValue(sPath1 + iNum + sPath2, "armor" + i) ;PapyrusUtil SEの機能でアーマーのEditorID文字列を格納
		Form aArmorID = po3_sksefunctions.GetFormFromEditorID(sObjID) ;po3 Papyrus Extenderの機能でアーマーのEditorIDを取得
		If sObjID && !aArmorID ;アーマーの名前は存在するが、EditorIDが存在しなかった場合
			iFCount += 1 ;読み込み失敗数を加算
		ElseIf aArmorID && iNum == 0 ;アーマーのEditorIDが存在する場合
			llOutfit01.AddForm(aArmorID, 1, 1) ;該当アーマーをレベルドリストに入れる
		ElseIf aArmorID && iNum == 1 ;アーマーのEditorIDが存在する場合
			llOutfit02.AddForm(aArmorID, 1, 1) ;該当アーマーをレベルドリストに入れる
		ElseIf aArmorID && iNum == 2 ;アーマーのEditorIDが存在する場合
			llOutfit03.AddForm(aArmorID, 1, 1) ;該当アーマーをレベルドリストに入れる
		ElseIf aArmorID && iNum == 3 ;アーマーのEditorIDが存在する場合
			llOutfit04.AddForm(aArmorID, 1, 1) ;該当アーマーをレベルドリストに入れる
		ElseIf aArmorID && iNum == 4 ;アーマーのEditorIDが存在する場合
			llOutfit05.AddForm(aArmorID, 1, 1) ;該当アーマーをレベルドリストに入れる
		ElseIf aArmorID && iNum == 5 ;アーマーのEditorIDが存在する場合
			llOutfit06.AddForm(aArmorID, 1, 1) ;該当アーマーをレベルドリストに入れる
		ElseIf aArmorID && iNum == 6 ;アーマーのEditorIDが存在する場合
			llOutfit07.AddForm(aArmorID, 1, 1) ;該当アーマーをレベルドリストに入れる
		ElseIf aArmorID && iNum == 7 ;アーマーのEditorIDが存在する場合
			llOutfit08.AddForm(aArmorID, 1, 1) ;該当アーマーをレベルドリストに入れる
		ElseIf aArmorID && iNum == 8 ;アーマーのEditorIDが存在する場合
			llOutfit09.AddForm(aArmorID, 1, 1) ;該当アーマーをレベルドリストに入れる
		Endif
		i += 1 ;次のアーマーの処理に移行させる為、変数を加算
	EndWhile

	Utility.Wait(0.1)

	if iNum == 0
		aObj1.SetOutfit(npcOutfit01) ;NPCに服を着せる
	Elseif iNum == 1
		aObj1.SetOutfit(npcOutfit02) ;NPCに服を着せる
	Elseif iNum == 2
		aObj1.SetOutfit(npcOutfit03) ;NPCに服を着せる
	Elseif iNum == 3
		aObj1.SetOutfit(npcOutfit04) ;NPCに服を着せる
	Elseif iNum == 4
		aObj1.SetOutfit(npcOutfit05) ;NPCに服を着せる
	Elseif iNum == 5
		aObj1.SetOutfit(npcOutfit06) ;NPCに服を着せる
	Elseif iNum == 6
		aObj1.SetOutfit(npcOutfit07) ;NPCに服を着せる
	Elseif iNum == 7
		aObj1.SetOutfit(npcOutfit08) ;NPCに服を着せる
	Elseif iNum == 8
		aObj1.SetOutfit(npcOutfit09) ;NPCに服を着せる
	EndIf

	Utility.Wait(0.1)

	aObj1.SetAlpha(1.0) ;NPCの透明度を元に戻す

	If iFCount >= 1 ;読み込み失敗アーマーが1つ以上
		Debug.MessageBox("Done. Failed loads:" + iFCount) ;処理完了メッセージ、読み込みに失敗したアーマーの数を表示する
	Else
		Debug.MessageBox("Done.") ;処理完了メッセージ
	EndIf
EndFunction

Function outfitSaveNPC(Actor aObj1, Int iNum) ;服装のセーブ処理
	Int i = 0 ;繰り返し処理用の数値
	String sObjsID ;取得したEditorIDを格納する場所

	Form[] fArmor = Utility.CreateFormArray(32, None) ;32個の配列を作成、アーマー格納用
	fArmor = po3_sksefunctions.AddAllEquippedItemsToArray(aObj1) ;po3 Papyrus Extenderの機能で装備中のアーマーを配列に格納する
	Int iArmorC = fArmor.length ;装備中のアーマーがどれくらいの容量かを確認

	if iArmorC == 0 ;容量が0、つまり何も装備していなければ処理中断
		Debug.MessageBox("Nothing equipped.") ;処理中断通知
		return ;処理中断
	endIf
	
	JsonUtil.ClearAll(sPath1 + iNum + sPath2) ;PapyrusUtil SEの機能でファイル内容を空にする

	While i < iArmorC ;全てのアーマーを処理し終わるまで繰り返す
		String sArmorID = ""
		Armor aArmor = None

		aArmor = fArmor[i] as armor ;先程の配列に格納されたi番目のアーマーをチェック
		sArmorID = po3_sksefunctions.GetFormEditorID(aArmor) ;po3 Papyrus Extenderの機能でアーマーのEditorIDを取得する
		If sArmorID ;i番目にアーマーを装備している
			JsonUtil.SetStringValue(sPath1 + iNum + sPath2, "armor" + i, sArmorID) ;PapyrusUtil SEの機能で、jsonファイルにアーマーのEditorIDを書き込む
		Else ;i番目にアーマーを装備していない
			JsonUtil.SetStringValue(sPath1 + iNum + sPath2, "armor" + i, "");PapyrusUtil SEの機能で、jsonファイルの該当部分を消去する
		EndIf
		i += 1 ;次のアーマーの処理に移行させる為、変数を加算
	EndWhile

	Debug.MessageBox("Done.") ;処理完了メッセージ
	JsonUtil.Save(sPath1 + iNum + sPath2) ;PapyrusUtil SEの機能でjsonファイルに書き込む
EndFunction