Scriptname _FS_Phasmalist_ControlQuest extends Quest ; the main phasmalist quest that aggregates references to the aliases who do the main work and provides a global interface for some utility functions _00E_Phasmalist_ApparationAlias Property apparationAlias Auto ; Old version of the apparition alias _00E_Phasmalist_NewApparitionAlias Property NewApparitionAlias Auto _00E_Phasmalist_DespectralizeCont Property despectralizeContainerAlias Auto _00E_Phasmalist_ApparationInventory Property spectralizeContainer Auto _00E_Phasmalist_PlayerAliasScript Property PlayerAlias Auto Quest Property FS_NQ08 Auto Perk Property _00E_Class_Phasmalist_P02_CraftTier1 Auto Shout Property _00E_Phasmalist_A3_MoveApparationToPlayerShout Auto WordofPower Property _00E_A3_Phasmalist_MoveApparationToPlayer1 Auto MiscObject Property _00E_UpdateInventoryItem auto MiscObject Property _00E_Phasmalist_Invis_EnchantmentRequirement Auto GlobalVariable Property _00E_AchievementsEnabled Auto GlobalVariable Property _00E_PhasmalistAchievementUnlocked Auto GlobalVariable Property _00E_Phasmalist_TankMode Auto Message Property _00E_Phasmalist_NoApparitionCurrentlySummoned Auto Perk Property _00E_Class_Phasmalist_P05_C_Violence_01 Auto Actor Property PlayerREF Auto Bool bCreatedFirstTrinket = false Int iScriptVersion = 0 Int Property CURRENT_SCRIPT_VERSION = 2 AutoReadOnly ;===================================================================================== ; GLOBAL FUNCTIONS ;===================================================================================== ; use only if necessary, if possible add _FS_Phasmalist_ControlQuest as a property! _FS_Phasmalist_ControlQuest Function getControlQuest() Global Return Game.GetFormFromFile(0x0101ec71, "Enderal - Forgotten Stories.esm") as _FS_Phasmalist_ControlQuest EndFunction Function UnsummonApparitionIfExists() Global getControlQuest().UnsummonApparition() EndFunction Function MoveApparitionToPlayer() Global getControlQuest().TeleportApparitionToPlayer() EndFunction ;===================================================================================== ; HELPER EVENTS & FUNCTIONS ;===================================================================================== Event OnInit() iScriptVersion = CURRENT_SCRIPT_VERSION EndEvent ; called on loadgame by _00E_Phasmalist_LoadGameFailsave, attached to an alias of quest abilities Function LoadGameFailsave() Bool bDoApparitionOnLoadGame = True ; Version update If iScriptVersion < CURRENT_SCRIPT_VERSION If iScriptVersion < 1 apparationAlias.UnregisterForAllKeys() EquippedTrinket = apparationAlias.getEquippedTrinket() iTeleportApparitionKeyCode = apparationAlias.iCallApparitionKeyCode PlayerAlias.ForceRefTo(PlayerREF) If apparationAlias.GetRef() != None apparationAlias.unsummon(True) If IsBadApparitionLocation(PlayerREF.GetCurrentLocation()) == False SummonApparition(PlayerREF, False, True) EndIf EndIf apparationAlias.onTrinketEquipped(None) _00E_Phasmalist_TankMode.SetValue(0) RegisterTeleportKey() ((self as Quest) as _FS_Phasmalist_AffinityControlQuest).OnGameLoad() ; Obsolete, not needed anymore, so shut it down bDoApparitionOnLoadGame = False Else If iScriptVersion < 2 && PlayerREF.HasPerk(_00E_Class_Phasmalist_P05_C_Violence_01) && IsApparitionSpawned() SummonApparition(PlayerREF, False, True) bDoApparitionOnLoadGame = False EndIf EndIf iScriptVersion = CURRENT_SCRIPT_VERSION EndIf If bDoApparitionOnLoadGame NewApparitionAlias.OnLoadGame() EndIf If FS_NQ08.getStage() == 7 RegisterForModEvent("Phasmalist_Learn_Soulsmith1", "OnUnlockSoulsmithNovice") EndIf EndFunction ; Event called by _00E_Phasmalist_Soul Function OnPlayerSoulCollected() If FS_NQ08.getStage() == 5 || FS_NQ08.getStage() == 1 If PlayerREF.hasPerk(_00E_Class_Phasmalist_P02_CraftTier1) FS_NQ08.setStage(10) Else FS_NQ08.setStage(7) RegisterForModEvent("Phasmalist_Learn_Soulsmith1", "OnUnlockSoulsmithNovice") EndIf EndIf EndFunction ; Event called by _00E_Phasmalist_Workbench Function OnPlayerItemSpectralized() If FS_NQ08.getStage() == 15 FS_NQ08.setStage(20) EndIf EndFunction ; Event called by _00E_Phasmalist_TrinketSC Function OnPlayerTrinketCreated() If bCreatedFirstTrinket == False bCreatedFirstTrinket = True If !PlayerREF.HasSpell(_00E_Phasmalist_A3_MoveApparationToPlayerShout) PlayerREF.AddShout(_00E_Phasmalist_A3_MoveApparationToPlayerShout) Game.unlockWord(_00E_A3_Phasmalist_MoveApparationToPlayer1) EndIf If FS_NQ08.getStage() == 10 FS_NQ08.setStage(15) EndIf If _00E_AchievementsEnabled.GetValueInt() == 1 && _00E_PhasmalistAchievementUnlocked.GetValueInt() == 0 _00E_PhasmalistAchievementUnlocked.SetValueInt(1) Steam.UnlockAchievement("END_APPARITION_01") EndIf EndIf RemoveEnchantmentItem() AddEnchantmentItem() EndFunction Event OnUnlockSoulsmithNovice(string eventName, string strArg, float numArg, Form sender) If FS_NQ08.getStage() == 7 FS_NQ08.setStage(10) UnRegisterForModEvent("Phasmalist_Learn_Soulsmith1") EndIf EndEvent Function ForceInventoryContainerLoad(ObjectReference cont) cont.additem(_00E_UpdateInventoryItem) cont.removeitem(_00E_UpdateInventoryItem) EndFunction Function AddEnchantmentItem() PlayerREF.AddItem(_00E_Phasmalist_Invis_EnchantmentRequirement, PlayerREF.GetAV("Enchanting") as int, True) EndFunction Function RemoveEnchantmentItem(Int _iDefault = 0) If _iDefault > 0 PlayerREF.RemoveItem(_00E_Phasmalist_Invis_EnchantmentRequirement, _iDefault, true) Else PlayerREF.RemoveItem(_00E_Phasmalist_Invis_EnchantmentRequirement, PlayerREF.GetItemCount(_00E_Phasmalist_Invis_EnchantmentRequirement), true) EndIf EndFunction ;===================================================================================== ; EQUIPPED TRINKET ;===================================================================================== _00E_Phasmalist_TrinketSC EquippedTrinket Function OnTrinketEquipped(_00E_Phasmalist_TrinketSC trinket) EquippedTrinket = Trinket EndFunction Function OnTrinketUnequipped(_00E_Phasmalist_TrinketSC trinket) If trinket == EquippedTrinket EquippedTrinket = None EndIf UnsummonApparition() EndFunction _00E_Phasmalist_TrinketSC Function GetEquippedTrinket() Return EquippedTrinket EndFunction Bool Function IsTrinketEquipped() Return (EquippedTrinket != None) EndFunction ;===================================================================================== ; APPARITION CONTROL ;===================================================================================== Keyword Property _00E_Phasmalist_NoSummonLocation Auto Keyword Property _00E_Phasmalist_NoSummonLocationTown Auto Perk Property _00E_Class_Phasmalist_P08_B_PhasmalicVeil Auto Int CurrentSummonState = 0 Int Property SUMMON_STATE_IDLE = 0 AutoReadOnly Int Property SUMMON_STATE_SUMMONING = 1 AutoReadOnly Int Property SUMMON_STATE_UNSUMMONING = 2 AutoReadOnly Int Property SUMMON_STATE_BUSY = 3 AutoReadOnly Bool Function IsBadApparitionLocation(Location loc) If loc If loc.HasKeyword(_00E_Phasmalist_NoSummonLocation) Return True ElseIf loc.HasKeyword(_00E_Phasmalist_NoSummonLocationTown) && PlayerREF.HasPerk(_00E_Class_Phasmalist_P08_B_PhasmalicVeil) == False Return True EndIf EndIf Return False EndFunction Actor Function GetApparitionRef() Return NewApparitionAlias.GetActorRef() EndFunction Actor Function GetApparitionFailsafeRef() If CurrentSummonState == SUMMON_STATE_UNSUMMONING Return None EndIf Return NewApparitionAlias.AliasFailsafeRef EndFunction Bool Function IsApparitionSpawned() If NewApparitionAlias.GetActorRef() Return (CurrentSummonState != SUMMON_STATE_UNSUMMONING) ; It exists and is not being unsummoned Else Return (CurrentSummonState == SUMMON_STATE_SUMMONING) ; It's not there yet but spawning EndIf EndFunction Bool Function IsApparitionChangingSummonStatus() Return (CurrentSummonState == SUMMON_STATE_SUMMONING || CurrentSummonState == SUMMON_STATE_UNSUMMONING) EndFunction Function SummonApparition(ObjectReference placeAtRef, Bool bPhasmalismTankMode = False, Bool bSilent = False) If _TryLockSummonState(SUMMON_STATE_SUMMONING) == False Return EndIf UnregisterTeleportKey() If bPhasmalismTankMode && bSilent == False bSilent = True NewApparitionAlias.PlaySummonExplosion(placeAtRef) EndIf ; Unsummon previous apparition If NewApparitionAlias.GetRef() != None NewApparitionAlias.Unsummon(bSilent) EndIf ; Create new apparition _00E_Phasmalist_TrinketSC trinket = GetEquippedTrinket() If trinket Actor summonedRef = placeAtRef.placeAtMe(trinket.connectedApparation, abInitiallyDisabled = True) as Actor If summonedRef NewApparitionAlias.ForceRefTo(summonedRef) NewApparitionAlias.Summon(trinket, placeAtRef, bPhasmalismTankMode, bSilent) EndIf EndIf RegisterTeleportKey() _UnlockSummonState() EndFunction Function UnsummonApparition(Bool bSilent = False) If _TryLockSummonState(SUMMON_STATE_UNSUMMONING) UnregisterTeleportKey() If NewApparitionAlias.GetRef() != None NewApparitionAlias.Unsummon(bSilent) EndIf RegisterTeleportKey() _UnlockSummonState() EndIf EndFunction Function TeleportApparitionToPlayer(Bool bTeleportInFront = False, Bool bSilent = False) If _TryLockSummonState(SUMMON_STATE_BUSY) NewApparitionAlias.TeleportToPlayer(bTeleportInFront, bSilent) _UnlockSummonState() EndIf EndFunction Function SetApparitionCombatStyle(CombatStyle newCombatStyle) If _TryLockSummonState(SUMMON_STATE_BUSY) NewApparitionAlias.SetCombatStyle(newCombatStyle) _UnlockSummonState() EndIf EndFunction Function ShowApparitionStats() If _TryLockSummonState(SUMMON_STATE_BUSY) NewApparitionAlias.ShowStatsMenu() _UnlockSummonState() EndIf EndFunction Function ShowApparitionEquipment() If _TryLockSummonState(SUMMON_STATE_BUSY) NewApparitionAlias.ShowEquipment() _UnlockSummonState() EndIf EndFunction Function TransformApparitionToWerewolf(Actor akSpellTarget) If _TryLockSummonState(SUMMON_STATE_BUSY) NewApparitionAlias.TransformToWerewolf(akSpellTarget) _UnlockSummonState() EndIf EndFunction Function TransformApparitionFromWerewolf(Actor akSpellTarget) If _TryLockSummonState(SUMMON_STATE_BUSY) NewApparitionAlias.TransformFromWerewolf(akSpellTarget, False, False) _UnlockSummonState() EndIf EndFunction Bool Function _TryLockSummonState(Int newSummonState) While CurrentSummonState != SUMMON_STATE_IDLE If newSummonState == SUMMON_STATE_BUSY || newSummonState == SUMMON_STATE_UNSUMMONING ; There's no point to do newSummonState if the apparition is being unsummoned If CurrentSummonState == SUMMON_STATE_UNSUMMONING Return False EndIf EndIf Utility.WaitMenuMode(0.1) EndWhile CurrentSummonState = newSummonState Return True EndFunction Function _UnlockSummonState() CurrentSummonState = SUMMON_STATE_IDLE EndFunction ;===================================================================================== ; CALL APPARITION KEY ;===================================================================================== Int Property iTeleportApparitionKeyCode = 34 Auto Hidden Location Property _00E_Dreamworld_Location Auto Function ChangeTeleportKey(int iKeyCode) UnregisterTeleportKey() iTeleportApparitionKeyCode = iKeyCode RegisterTeleportKey() EndFunction Function RegisterTeleportKey() If iTeleportApparitionKeyCode != 0 RegisterForKey(iTeleportApparitionKeyCode) EndIf EndFunction Function UnregisterTeleportKey() If iTeleportApparitionKeyCode != 0 UnregisterForKey(iTeleportApparitionKeyCode) EndIf EndFunction Event OnKeyDown(int iKeyCode) If iKeyCode == iTeleportApparitionKeyCode UnregisterTeleportKey() If Utility.IsInMenuMode() == False && UI.IsTextInputEnabled() == False && Game.IsFightingControlsEnabled() && UI.IsMenuOpen("Dialogue Menu") == False && PlayerREF.GetCurrentLocation() != _00E_Dreamworld_Location If IsApparitionSpawned() == False || _00E_Phasmalist_TankMode.GetValue() != 0 _00E_Phasmalist_NoApparitionCurrentlySummoned.Show() Else TeleportApparitionToPlayer(True) EndIf EndIf RegisterTeleportKey() EndIf EndEvent