User:Candlemaster/Unenchanter
Unenchanter[edit | edit source]
These scripts require OBSE
The goal of the script is to take any enchanted item inside the container, remove enchantments from enchanted items, and create an "invert sigil stone" containing the effects that you just took off the item. Originally my idea was to allow the player to retrieve sigil stones that they've already used by separating them from the enchanted item, but this is far more versatile (and possible). This would allow players to transfer enchantments from one item to another, or to save an item's enchantment for later. No longer do you have to wait to get the highest level item possible before using that transcendant sigil stone, you could simply extract it's effects later.
Intentional omissions:
- Any ammunition (ie, arrows)
- Any staff (as it's impossible to get an unenchanted staff anyway)
- Any item containing a Script Effect enchantment (This is to avoid conflicts with the item's script)
First Attempt[edit | edit source]
scn HVHGTUnenchanterScript long NumEffects long CurrentEffect short DoOnce ref Myself ref cInvObj ref NewStone Begin OnActivate Activate Set DoOnce to 1 End Begin GameMode if HVHGTOBSE.HasOBSE == 0 ;Basically checks for the presence of OBSE return else if DoOnce == 0 return endif set Myself to GetSelf array_var Items ForEach Items <- Myself.GetItems let cInvObj := Items["Value"] if eval ( GetEnchantment cInvObj == 0 || GetObjectType cInvObj == 34 ) ;Only work on enchanted non-arrows PrintToConsole "Skipped an inappropriate item" Continue ;This ran fine when I placed a non-enchanted ring into the container endif if eval ( GetObjectType cInvObj == 33 ) ;Special consideration for weapons if eval ( GetWeaponType == 4 ) ;Don't do anything to a staff PrintToConsole "Skipped an inappropriate item" Continue ;I experienced a CTD when placing an enchanted staff into the container endif let NumEffects := GetMagicItemEffectCount cInvObj let CurrentEffect := 0 if NumEffects > 0 Label if eval ( IsNthEffectItemScripted cInvObj CurrentEffect ) PrintToConsole "Skipped a scripted item" Continue endif set CurrentEffect to ( CurrentEffect + 1 ) if ( CurrentEffect < NumEffects ) GoTo ;The loop ends here, but only if you have no more effects to go through. endif PrintToConsole "Found an appropriate item" let NewStone := CloneForm HVHGTInvertSigilStoneBase RemoveNthEffectItem newStone 0 CopyAllEffectItems cInvObj NewStone Myself.AddItem NewStone 1 RemoveEnchantment cInvObj PrintToConsole "An item has been Unenchanted" endif else let NumEffects := GetMagicItemEffectCount cInvObj let CurrentEffect :=0 if NumEffects > 0 Label if eval ( IsNthEffectItemScripted cInvObj CurrentEffect ) PrintToConsole "Skipped a scripted item" Continue endif set CurrentEffect to ( CurrentEffect + 1 ) if ( CurrentEffect < NumEffects ) GoTo ;The loop ends here, but only if you have no more effects to go through. endif PrintToConsole "Found an appropriate item" let NewStone := CloneForm HVHGTInvertSigilStoneBase RemoveNthEffectItem newStone 0 CopyAllEffectItems cInvObj NewStone Myself.AddItem NewStone 1 RemoveEnchantment cInvObj PrintToConsole "An item has been Unenchanted" endif endif Loop set DoOnce to 0 endif End
When tested, I placed a plain, unenchanted brass ring into the container. I got the console printout for "Found an inappropriate item", and all was well. However, when I placed an enchanted staff into the container (which should have triggered the same result as the unenchanted ring), I got a crash to desktop.
Second Attempt[edit | edit source]
scn HVHGTUnenchanterScript long NumEffects short DoOnce ref Myself ref cInvObj ref TempEnch ref NewStone Begin onactivate Activate Set DoOnce to 1 End Begin GameMode if HVHGTOBSE.HasOBSE == 0 ;Basically checks for the presence of OBSE return else if DoOnce == 0 return endif let Myself := GetSelf array_var Items ForEach Items <- Myself.GetItems let cInvObj := Items["Value"] if eval ( GetEnchantment cInvObj == 0 || IsAmmo cInvObj || IsBook cInvObj ) ;Only work on enchanted non-arrows PrintToConsole "Skipped an innapropriate item" Continue endif if eval ( IsWeapon cInvObj ) ;Special consideration for weapons if eval ( GetWeaponType cInvObj == 4 ) ;Don't do anything to a staff PrintToConsole "Skipped an innapropriate item" Continue endif let TempEnch := GetEnchantment cInvObj let NumEffects := GetMagicItemEffectCount TempEnch if NumEffects > 0 if eval ( MagicItemHasEffect SEFF TempEnch ) PrintToConsole "Skipped a scripted item" Continue endif PrintToConsole "Found an appropriate item" let NewStone := CloneForm HVHGTInvertSigilStoneBase CopyAllEffectItems TempEnch NewStone RemoveNthEffectItem newStone 0 Myself.AddItem NewStone 1 RemoveEnchantment cInvObj PrintToConsole "An item has been Unenchanted" Continue endif else let TempEnch := GetEnchantment cInvObj let NumEffects := GetMagicItemEffectCount TempEnch if NumEffects > 0 if eval ( MagicItemHasEffect SEFF TempEnch ) PrintToConsole "Skipped a scripted item" Continue endif PrintToConsole "Found an appropriate item" let NewStone := CloneForm HVHGTInvertSigilStoneBase CopyAllEffectItems TempEnch NewStone RemoveNthEffectItem newStone 0 Myself.AddItem NewStone 1 RemoveEnchantment cInvObj PrintToConsole "An item has been Unenchanted" Continue endif endif Loop set DoOnce to 0 endif End
This is my latest version of the script. In general it is the same, except I've placed Continues throughout the loop to help with processing times. I've replaced and fixed a couple of key things, most importantly are the removal of the loop-within-a-loop, replacing it with MagicItemHasEffect SEFF, but more importantly I moved RemoveNthEffectItem NewStone 0 to after CopyAllEffectItems. I believe that this is what was causing the CTD's, as HVHGTInvertSigilStoneBase has only one effect on it, RemoveNthEffectItem was rendering it effectless. Also, I've added checks to make sure it wont unenchant scrolls.
When testing, the script ran as desired. Items placed into the container were stripped of their enchantment, and a sigil stone containing a copy of the item's enchantment was added. The only bug is that the created sigil stone doesn't retain the enchantment's charge, but instead sets it to the number of uses set in the base invert sigil stone. I'm not sure if it's possible to set this value in script, to retain charge information.