4
Fork 0
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 

475 lines
16 KiB

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, 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