476 lines
16 KiB
Plaintext
476 lines
16 KiB
Plaintext
Scriptname _00E_Theriantrophist_AlchemyControl extends ReferenceAlias
|
|
|
|
;=====================================================================================
|
|
; PROPERTIES
|
|
;=====================================================================================
|
|
|
|
Keyword Property _00E_Theriantrophist_DarkBloodEffect Auto
|
|
Keyword Property _00E_Theriantrophist_Effect Auto
|
|
Keyword Property _00E_Theriantrophist_ChymikumLife Auto
|
|
{the perk that allows the player to drink theriantrophist potions}
|
|
Actor Property PlayerREF Auto
|
|
Perk Property _00E_Class_Theriantrophist_P01_WerewolfBlood Auto
|
|
Message Property _00E_Theriantrophist_ReallyWantToBrewPotion Auto
|
|
Message Property _00E_FS_Theriantrophist_PotionFortified Auto
|
|
MagicEffect Property _00E_Theriantrophist_NoEffect Auto
|
|
|
|
Perk Property _00E_Class_Theriantrophist_P03_GreyAlchemist_01 Auto
|
|
Perk Property _00E_Class_Theriantrophist_P03_GreyAlchemist_02 Auto
|
|
Perk Property _00E_Class_Theriantrophist_P03_GreyAlchemist_03 Auto
|
|
|
|
MagicEffect Property _00E_Theriantrophist_AlchChymikum_FireClaws Auto
|
|
MagicEffect Property _00E_Theriantrophist_AlchChymikum_Armor Auto
|
|
MagicEffect Property _00E_Theriantrophist_AlchChymikum_Damage Auto
|
|
MagicEffect Property _00E_Theriantrophist_AlchChymikum_FrostClaws Auto
|
|
MagicEffect Property _00E_Theriantrophist_AlchChymikum_Health Auto
|
|
MagicEffect Property _00E_Theriantrophist_AlchChymikum_ShockClaws Auto
|
|
MagicEffect Property _00E_Theriantrophist_AlchChymikum_Speed Auto
|
|
MagicEffect Property _00E_Theriantrophist_AlchChymikum_Stamina Auto
|
|
|
|
MagicEffect Property _00E_AlchReduceArcaneFever Auto
|
|
MagicEffect Property _00E_AlchRestoreMagicka Auto
|
|
MagicEffect Property _00E_AlchRestoreStamina Auto
|
|
MagicEffect Property AlchFortifyHealth Auto
|
|
MagicEffect Property AlchFortifyHealRate Auto
|
|
MagicEffect Property AlchFortifyMagicka Auto
|
|
MagicEffect Property AlchFortifyMagickaRate Auto
|
|
MagicEffect Property AlchFortifyStamina Auto
|
|
MagicEffect Property AlchFortifyStaminaRate Auto
|
|
MagicEffect Property AlchInvisibillity Auto
|
|
MagicEffect Property AlchWaterbreathing Auto
|
|
MagicEffect Property AlchResistFire Auto
|
|
MagicEffect Property AlchResistFrost Auto
|
|
MagicEffect Property AlchResistMagic Auto
|
|
MagicEffect Property AlchResistShock Auto
|
|
MagicEffect Property AlchFortifyAlchemy Auto
|
|
MagicEffect Property AlchFortifyAlteration Auto
|
|
MagicEffect Property AlchFortifyBarter Auto
|
|
MagicEffect Property AlchFortifyBlock Auto
|
|
MagicEffect Property AlchFortifyCarryWeight Auto
|
|
MagicEffect Property AlchFortifyConjuration Auto
|
|
MagicEffect Property AlchFortifyDestruction Auto
|
|
MagicEffect Property AlchFortifyEnchanting Auto
|
|
MagicEffect Property AlchFortifyHeavyArmor Auto
|
|
MagicEffect Property AlchFortifyIllusion Auto
|
|
MagicEffect Property AlchFortifyLightArmor Auto
|
|
MagicEffect Property AlchFortifyLockpicking Auto
|
|
MagicEffect Property AlchFortifyMarksman Auto
|
|
MagicEffect Property AlchFortifyOneHanded Auto
|
|
MagicEffect Property AlchFortifyPersuasion Auto
|
|
MagicEffect Property AlchFortifyPickpocket Auto
|
|
MagicEffect Property AlchFortifySmithing Auto
|
|
MagicEffect Property AlchFortifySneak Auto
|
|
MagicEffect Property AlchFortifyTwoHanded Auto
|
|
MagicEffect Property AlchRestoreMagicka Auto
|
|
MagicEffect Property AlchRestoreStamina Auto
|
|
|
|
FormList Property _00E_EmptyFormlist Auto
|
|
|
|
ObjectReference Property _00E_SecureChest_HostChestREF Auto
|
|
|
|
Int Property GreyAlchemist2PotionDurationLimitInSeconds = 180 Autoreadonly Hidden
|
|
{The potion duration of all werewolf potions is limited to this amount if the player has the first and second perk grey alchemist}
|
|
Int Property GreyAlchemist1PotionDurationLimitInSeconds = 120 Autoreadonly Hidden
|
|
{The potion duration of all werewolf potions is limited to this amount if the player has the first perk grey alchemist}
|
|
Int Property NoAlchemistPotionDurationLimitInSeconds = 90 Autoreadonly Hidden
|
|
{The potion duration of all werewolf potions is limited to this amount if the player has not the perk grey alchemist}
|
|
|
|
_00E_FS_NQ11_Functions Property FS_NQ11 Auto
|
|
|
|
bool bDoneDarkBlood = false
|
|
bool bDoneChymikum = false
|
|
|
|
Int curScriptVersion = 0
|
|
Int Property LATEST_SCRIPT_VERSION = 5 AutoReadOnly
|
|
|
|
Potion[] aCreatedPotions
|
|
string[] aPotionNames
|
|
string[] aPotionModels
|
|
|
|
;=====================================================================================
|
|
; FUNCTIONS
|
|
;=====================================================================================
|
|
|
|
function _addNamedPotion(Potion aPotion, string sName, string sModel)
|
|
|
|
if ! aPotion || sName == ""
|
|
return
|
|
endif
|
|
|
|
aPotion.SetName(sName)
|
|
if sModel != ""
|
|
aPotion.SetWorldModelPath(sModel)
|
|
endif
|
|
|
|
if aCreatedPotions.length == 0
|
|
aCreatedPotions = new Potion[128]
|
|
aPotionNames = new string[128]
|
|
aPotionModels = new string[128]
|
|
endif
|
|
|
|
int i = aCreatedPotions.Find(aPotion)
|
|
|
|
if i >= 0
|
|
aPotionNames[i] = sName
|
|
aPotionModels[i] = sModel
|
|
else
|
|
i = aCreatedPotions.Find(none)
|
|
if i >= 0
|
|
aCreatedPotions[i] = aPotion
|
|
aPotionNames[i] = sName
|
|
aPotionModels[i] = sModel
|
|
else
|
|
; No more slots left, let's forget what we do not have in our inventory
|
|
int n = 0
|
|
while n < 128
|
|
if PlayerREF.GetItemCount(aCreatedPotions[n]) == 0
|
|
aCreatedPotions[n] = aPotion
|
|
aPotionNames[n] = sName
|
|
aPotionModels[n] = sModel
|
|
return
|
|
endif
|
|
n += 1
|
|
endwhile
|
|
endif
|
|
endif
|
|
|
|
endfunction
|
|
|
|
function _removeNamedPotion(Potion aPotion)
|
|
if aPotion
|
|
int i = aCreatedPotions.Find(aPotion)
|
|
if i > -1
|
|
aCreatedPotions[i] = None
|
|
aPotionNames[i] = ""
|
|
aPotionModels[i] = ""
|
|
endif
|
|
endif
|
|
endfunction
|
|
|
|
Function _UpdatePotion(Potion item, Int count)
|
|
|
|
Int i
|
|
MagicEffect[] potionEffects = item.GetMagicEffects()
|
|
Int nPotionEffects = potionEffects.Length
|
|
Bool bIsTheriantrophistPotion = item.HasKeyword(_00E_Theriantrophist_Effect)
|
|
MagicEffect firstTheriantrophistEffect = None
|
|
|
|
If bIsTheriantrophistPotion && EnderalFunctions.IsDLLLoaded() ; FRESHLY BREWN THERIANTROPHIST POTION
|
|
|
|
PlayerREF.removeItem(item, count, abSilent = true)
|
|
|
|
Bool bRemoveTheriantrophistEffects = False
|
|
If !PlayerREF.hasPerk(_00E_Class_Theriantrophist_P01_WerewolfBlood)
|
|
If _00E_Theriantrophist_ReallyWantToBrewPotion.Show() != 1
|
|
bRemoveTheriantrophistEffects = True
|
|
EndIf
|
|
EndIf
|
|
|
|
MagicEffect[] newEffects = new MagicEffect[10]
|
|
Float[] newMagnitudes = new Float[10]
|
|
Int[] newAreas = new Int[10]
|
|
Int[] newDurations = new Int[10]
|
|
Int nNewEffects = 0
|
|
|
|
If bRemoveTheriantrophistEffects
|
|
i = 0
|
|
While i < nPotionEffects && nNewEffects < newEffects.Length
|
|
If potionEffects[i].HasKeyword(_00E_Theriantrophist_Effect) == False
|
|
newEffects[nNewEffects] = potionEffects[i]
|
|
newMagnitudes[nNewEffects] = item.getNthEffectMagnitude(i)
|
|
newAreas[nNewEffects] = item.getNthEffectArea(i)
|
|
newDurations[nNewEffects] = item.getNthEffectDuration(i)
|
|
nNewEffects += 1
|
|
EndIf
|
|
i += 1
|
|
EndWhile
|
|
|
|
If nNewEffects == 0
|
|
newEffects[nNewEffects] = _00E_Theriantrophist_NoEffect
|
|
nNewEffects += 1
|
|
EndIf
|
|
Else
|
|
Int maxDuration = NoAlchemistPotionDurationLimitInSeconds
|
|
Int durationBonus = PlayerREF.GetActorValue("Variable02") as Int
|
|
|
|
If PlayerREF.hasPerk(_00E_Class_Theriantrophist_P03_GreyAlchemist_03)
|
|
maxDuration = -1 ; no duration mali are required
|
|
ElseIf PlayerREF.hasPerk(_00E_Class_Theriantrophist_P03_GreyAlchemist_02)
|
|
maxDuration = GreyAlchemist2PotionDurationLimitInSeconds
|
|
ElseIf PlayerREF.hasPerk(_00E_Class_Theriantrophist_P03_GreyAlchemist_01)
|
|
maxDuration = GreyAlchemist1PotionDurationLimitInSeconds
|
|
Endif
|
|
|
|
i = 0
|
|
While i < nPotionEffects && nNewEffects < newEffects.Length
|
|
newEffects[nNewEffects] = potionEffects[i]
|
|
newMagnitudes[nNewEffects] = item.getNthEffectMagnitude(i)
|
|
newAreas[nNewEffects] = item.getNthEffectArea(i)
|
|
newDurations[nNewEffects] = item.getNthEffectDuration(i)
|
|
|
|
If newEffects[nNewEffects].HasKeyword(_00E_Theriantrophist_Effect)
|
|
If firstTheriantrophistEffect == None
|
|
firstTheriantrophistEffect = newEffects[nNewEffects]
|
|
EndIf
|
|
If maxDuration >= 0 && newDurations[nNewEffects] > maxDuration
|
|
newDurations[nNewEffects] = maxDuration
|
|
EndIf
|
|
If durationBonus > 0
|
|
newDurations[nNewEffects] = newDurations[nNewEffects] + durationBonus
|
|
EndIf
|
|
EndIf
|
|
|
|
nNewEffects += 1
|
|
i += 1
|
|
EndWhile
|
|
|
|
If durationBonus > 0
|
|
_00E_FS_Theriantrophist_PotionFortified.Show(durationBonus)
|
|
EndIf
|
|
EndIf
|
|
|
|
Potion newPotion = EnderalFunctions.CreatePotion(newEffects, newMagnitudes, newAreas, newDurations, nNewEffects)
|
|
|
|
if aCreatedPotions.Find(newPotion) == -1
|
|
string newName = _RenamePotion(newPotion, newEffects, nNewEffects, bRemoveTheriantrophistEffects)
|
|
string newModel = _SetPotionModel(newPotion, firstTheriantrophistEffect, newEffects[0])
|
|
_addNamedPotion(newPotion, newName, newModel)
|
|
endif
|
|
|
|
GoToState("") ; skip OnItemAdded
|
|
PlayerREF.addItem(newPotion, count, abSilent = true)
|
|
GoToState("InCrafting")
|
|
|
|
If bRemoveTheriantrophistEffects == False
|
|
_UpdateNQ11(newPotion)
|
|
EndIf
|
|
|
|
return
|
|
|
|
EndIf
|
|
|
|
if aCreatedPotions.Find(item) == -1
|
|
string newNameC = _RenamePotion(item, potionEffects, nPotionEffects, True)
|
|
string newModelC = _SetPotionModel(item, None, potionEffects[0])
|
|
_addNamedPotion(item, newNameC, newModelC)
|
|
endif
|
|
|
|
if bIsTheriantrophistPotion
|
|
_UpdateNQ11(item)
|
|
endif
|
|
|
|
EndFunction
|
|
|
|
String Function _RenamePotion(Potion p, MagicEffect[] potionEffects, Int nPotionEffects, Bool bCommonPotion)
|
|
String name = ""
|
|
|
|
If bCommonPotion
|
|
If p.isPoison()
|
|
name = Game.GetGameSettingString("sCreatedPoisonNamePrefix")
|
|
Else
|
|
name = Game.GetGameSettingString("sCreatedPotionNamePrefix")
|
|
Endif
|
|
EndIf
|
|
|
|
Int nEffectsAdded = 0
|
|
Int i = 0
|
|
While i < nPotionEffects && nEffectsAdded < 2
|
|
If nEffectsAdded > 0
|
|
name += ", "
|
|
EndIf
|
|
name += potionEffects[i].getName()
|
|
nEffectsAdded += 1
|
|
i += 1
|
|
EndWhile
|
|
|
|
return name
|
|
EndFunction
|
|
|
|
String Function _SetPotionModel(Potion p, MagicEffect firstTheriantrophistEffect, MagicEffect firstEffect)
|
|
string modelName
|
|
string modelPath = ""
|
|
|
|
If firstTheriantrophistEffect
|
|
If firstTheriantrophistEffect == _00E_Theriantrophist_AlchChymikum_FireClaws
|
|
modelName = "ChymikumFire"
|
|
ElseIf firstTheriantrophistEffect == _00E_Theriantrophist_AlchChymikum_Armor
|
|
modelName = "ChymikumArmor"
|
|
ElseIf firstTheriantrophistEffect == _00E_Theriantrophist_AlchChymikum_Damage
|
|
modelName = "ChymikumDamage"
|
|
ElseIf firstTheriantrophistEffect == _00E_Theriantrophist_AlchChymikum_FrostClaws
|
|
modelName = "ChymikumFrost"
|
|
ElseIf firstTheriantrophistEffect == _00E_Theriantrophist_AlchChymikum_Health
|
|
modelName = "ChymikumLife"
|
|
ElseIf firstTheriantrophistEffect == _00E_Theriantrophist_AlchChymikum_ShockClaws
|
|
modelName = "ChymikumShock"
|
|
ElseIf firstTheriantrophistEffect == _00E_Theriantrophist_AlchChymikum_Speed
|
|
modelName = "ChymikumSpeed"
|
|
ElseIf firstTheriantrophistEffect == _00E_Theriantrophist_AlchChymikum_Stamina
|
|
modelName = "ChymikumStamina"
|
|
Else
|
|
modelName = "DarkBloodPotion"
|
|
Endif
|
|
|
|
modelPath = "meshes\\enderal\\forgottenstories\\theriantrophist\\" + modelName + ".nif"
|
|
|
|
ElseIf firstEffect && p.isPoison() == False
|
|
|
|
If firstEffect == _00E_AlchReduceArcaneFever
|
|
modelPath = "Meshes\\Clutter\\Quest\\MS12WhitePhialRepaired.nif"
|
|
ElseIf firstEffect == _00E_AlchRestoreMagicka || firstEffect == AlchRestoreMagicka
|
|
modelPath = "Meshes\\Clutter\\Potions\\PotionMagickaLesser.nif"
|
|
ElseIf firstEffect == _00E_AlchRestoreStamina || firstEffect == AlchRestoreStamina
|
|
modelPath = "Meshes\\Clutter\\Potions\\PotionStaminaLesser.nif"
|
|
ElseIf firstEffect == AlchFortifyHealth
|
|
modelPath = "Meshes\\Clutter\\Potions\\PotionFortifyHealthLesser.nif"
|
|
ElseIf firstEffect == AlchFortifyHealRate
|
|
modelPath = "Meshes\\Clutter\\Potions\\PotionFortifyHealRateLesser.nif"
|
|
ElseIf firstEffect == AlchFortifyMagicka
|
|
modelPath = "Meshes\\Clutter\\Potions\\PotionMagickaExtra.nif"
|
|
ElseIf firstEffect == AlchFortifyMagickaRate
|
|
modelPath = "Meshes\\Clutter\\Potions\\PotionFortifyMagiRateLesser.nif"
|
|
ElseIf firstEffect == AlchFortifyStamina
|
|
modelPath = "Meshes\\Clutter\\Potions\\PotionFortifyStaminaLesser.nif"
|
|
ElseIf firstEffect == AlchFortifyStaminaRate
|
|
modelPath = "Meshes\\Clutter\\Potions\\PotionFortifyStamRateLesser.nif"
|
|
ElseIf firstEffect == AlchInvisibillity || firstEffect == AlchWaterbreathing
|
|
modelPath = "Meshes\\Clutter\\Potions\\PotionInvisibiltyLesser.nif"
|
|
ElseIf firstEffect == AlchResistFire
|
|
modelPath = "Meshes\\Clutter\\Potions\\PotionResistFire50.nif"
|
|
ElseIf firstEffect == AlchResistFrost
|
|
modelPath = "Meshes\\Clutter\\Potions\\PotionResistFrost50.nif"
|
|
ElseIf firstEffect == AlchResistMagic
|
|
modelPath = "Meshes\\Clutter\\Potions\\PotionResistMagicka50.nif"
|
|
ElseIf firstEffect == AlchResistShock
|
|
modelPath = "Meshes\\Clutter\\Potions\\PotionResistShock50.nif"
|
|
ElseIf firstEffect == AlchFortifyAlchemy || firstEffect == AlchFortifyAlteration || firstEffect == AlchFortifyBarter || firstEffect == AlchFortifyBlock
|
|
modelPath = "Meshes\\Clutter\\Potions\\PotionFortifySkill01.nif"
|
|
ElseIf firstEffect == AlchFortifyCarryWeight || firstEffect == AlchFortifyConjuration || firstEffect == AlchFortifyDestruction || firstEffect == AlchFortifyEnchanting
|
|
modelPath = "Meshes\\Clutter\\Potions\\PotionFortifySkill01.nif"
|
|
ElseIf firstEffect == AlchFortifyHeavyArmor || firstEffect == AlchFortifyIllusion || firstEffect == AlchFortifyLightArmor || firstEffect == AlchFortifyLockpicking
|
|
modelPath = "Meshes\\Clutter\\Potions\\PotionFortifySkill01.nif"
|
|
ElseIf firstEffect == AlchFortifyMarksman || firstEffect == AlchFortifyOneHanded || firstEffect == AlchFortifyPersuasion || firstEffect == AlchFortifyPickpocket
|
|
modelPath = "Meshes\\Clutter\\Potions\\PotionFortifySkill01.nif"
|
|
ElseIf firstEffect == AlchFortifySmithing || firstEffect == AlchFortifySneak || firstEffect == AlchFortifyTwoHanded
|
|
modelPath = "Meshes\\Clutter\\Potions\\PotionFortifySkill01.nif"
|
|
EndIf
|
|
|
|
EndIf
|
|
|
|
return modelPath
|
|
EndFunction
|
|
|
|
Function _UpdateNQ11(Potion newPotion)
|
|
If (bDoneChymikum && bDoneDarkBlood) || FS_NQ11.IsRunning() == False
|
|
Return
|
|
EndIf
|
|
|
|
Bool bUpdateNQ11 = False
|
|
|
|
If newPotion.HasKeyword(_00E_Theriantrophist_ChymikumLife) && FS_NQ11.GetCurrentStageID() >= 10 && !bDoneChymikum
|
|
bDoneChymikum = True
|
|
bUpdateNQ11 = True
|
|
EndIf
|
|
If newPotion.HasKeyword(_00E_Theriantrophist_DarkBloodEffect) && FS_NQ11.GetCurrentStageID() >= 10 && !bDoneDarkBlood
|
|
bDoneDarkBlood = True
|
|
bUpdateNQ11 = True
|
|
EndIf
|
|
|
|
If bUpdateNQ11 && FS_NQ11.GetCurrentStageID() < 17
|
|
FS_NQ11.ShowTutorial(2)
|
|
|
|
If bDoneChymikum && bDoneDarkBlood
|
|
_SetNewStageNQ11(17)
|
|
ElseIf bDoneChymikum
|
|
_SetNewStageNQ11(15)
|
|
ElseIf bDoneDarkBlood
|
|
_SetNewStageNQ11(16)
|
|
EndIf
|
|
EndIf
|
|
EndFunction
|
|
|
|
Function _SetNewStageNQ11(Int newStage)
|
|
If newStage > FS_NQ11.GetCurrentStageID()
|
|
FS_NQ11.SetCurrentStageID(newStage)
|
|
EndIf
|
|
EndFunction
|
|
|
|
Function _InitAchemyControl()
|
|
|
|
GoToState("")
|
|
|
|
; Version update
|
|
If curScriptVersion < LATEST_SCRIPT_VERSION
|
|
Int oldScriptVersion = curScriptVersion
|
|
curScriptVersion = LATEST_SCRIPT_VERSION
|
|
|
|
If oldScriptVersion < 5
|
|
RemoveAllInventoryEventFilters()
|
|
UnregisterForAllMenus()
|
|
UnregisterForUpdate()
|
|
_00E_Theriantrophist_Update_12.Run(self)
|
|
EndIf
|
|
EndIf
|
|
|
|
; Re-register menu listener to stay resilient to co-save deletion or corruption
|
|
RegisterForMenu("Crafting Menu")
|
|
|
|
EndFunction
|
|
|
|
|
|
;=====================================================================================
|
|
; EVENTS
|
|
;=====================================================================================
|
|
|
|
Event OnMenuOpen(String MenuName)
|
|
GoToState("InCrafting")
|
|
EndEvent
|
|
|
|
Event OnMenuClose(String MenuName)
|
|
GoToState("")
|
|
EndEvent
|
|
|
|
State InCrafting
|
|
Event OnItemAdded(Form baseItem, int count, ObjectReference itemRef, ObjectReference source)
|
|
if ! UI.IsMenuOpen("Crafting Menu")
|
|
GoToState("")
|
|
return
|
|
endif
|
|
Potion item = baseItem as Potion
|
|
If item
|
|
; Ignore not-custom potions (with FormID not starting with 0xFF) or already registered potions
|
|
If (Math.LogicalAnd(item.GetFormID(), 0xFF000000) == 0xFF000000) && aCreatedPotions.Find(item) == -1
|
|
_UpdatePotion(item, count)
|
|
EndIf
|
|
EndIf
|
|
EndEvent
|
|
EndState
|
|
|
|
Event OnInit()
|
|
curScriptVersion = LATEST_SCRIPT_VERSION
|
|
_InitAchemyControl()
|
|
EndEvent
|
|
|
|
Event OnPlayerLoadGame()
|
|
_InitAchemyControl()
|
|
|
|
if aCreatedPotions.length == 0
|
|
return
|
|
endif
|
|
|
|
int i = 0
|
|
while i < 128
|
|
if aCreatedPotions[i]
|
|
if PlayerREF.GetItemCount(aCreatedPotions[i]) == 0 && _00E_SecureChest_HostChestREF.GetItemCount(aCreatedPotions[i]) == 0
|
|
_removeNamedPotion(aCreatedPotions[i])
|
|
else
|
|
aCreatedPotions[i].SetName(aPotionNames[i])
|
|
if aPotionModels[i] != ""
|
|
aCreatedPotions[i].SetWorldModelPath(aPotionModels[i])
|
|
endif
|
|
endif
|
|
endif
|
|
i += 1
|
|
endwhile
|
|
EndEvent
|