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