enderalse/source/scripts/_fs_phasmalist_controlquest.psc

389 lines
12 KiB
Plaintext

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)
Game.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