Tough OBSE script problem

Post » Tue May 18, 2010 4:52 am

Basically, what I'm trying to do is create a scripted container that checks it's inventory for enchanted items. If it finds an enchanted item, it creates an "invert sigil stone" containing the item's enchantment, then removes the enchantment from the item. By design, it's meant to skip ammo, staves, and anything with a Script Effect enchantment. When I add an unenchanted ring to the container, it skips the ring properly. However, when I added an enchanted staff (which it should have skipped) I get a crash-to-desktop.

Here's my script:
scn HVHGTUnenchanterScriptlong NumEffectslong CurrentEffectshort DoOnceref Myselfref cInvObjref NewStoneBegin OnActivate	Activate	Set DoOnce to 1EndBegin GameMode	if HVHGTOBSE.HasOBSE == 0		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 innapropriate 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 innapropriate 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	endifEnd


Thanks in advance. I'm completely, 100% stumped on this.
User avatar
Code Affinity
 
Posts: 3325
Joined: Wed Jun 13, 2007 11:11 am

Post » Tue May 18, 2010 4:41 am

I haven't yet looked into it too deeply, but the first thing I see is your "GetWeaponType" call is missing its parameter.
So if this is copy&paste of your actual script and not just a typo of you writing it down for us here, this line will attempt to determine the weapon type of the container whenever the item it found is a weapon of sorts. I'm not sure but I think this one can cause a CTD already.
User avatar
Robert DeLarosa
 
Posts: 3415
Joined: Tue Sep 04, 2007 3:43 pm

Post » Tue May 18, 2010 1:36 pm

Huh, you're right. I don't know if that's the only problem or not, but that definitely is a problem. I'm amazed that I missed that...

Alright, I just tested it out, changing that line to "if eval ( GetWeaponType cInvObj == 4 )". I still got a CTD when I added an enchanted item to the container. As far as I can see, if "if eval ( GetEnchantment cInvObj == 0 || GetObjectType cInvObj == 34 )" returns false (allowing the loop to continue), I get a crash.

Might there be a problem with trying to put a Label-GoTo loop inside of a ForEach loop? (With a "continue" after the Label, even)

Edit: Just to confirm, I can now put a staff into the container without crashing. I can put arrows and unenchanted apparel into the container, but I haven't tested enchanted arrows.

Is there a way to check for the presence of a Script Effect on a certain magic item without scanning through each individual effect? Or if I could check for the presence of a specified magic effect (SEFF, aka Script Effect) without scanning through each effect?
User avatar
Rude_Bitch_420
 
Posts: 3429
Joined: Wed Aug 08, 2007 2:26 pm

Post » Tue May 18, 2010 1:55 am

I've made a massive breakthrough. I think the CTD was being caused by "RemoveNthEffectItem newStone 0" being run before "CopyAllEffectItems cInvObj NewStone", which was removing the only effect item on NewStone (I put a dummy dispel enchantment on it). In any case, here's my new script. And, get this: it works! I place an item in the container, I close the container, I open it again and I see the old item, completely free of enchantment, along with an invert sigil stone containing the old item's enchantment.

Here's my script:
scn HVHGTUnenchanterScriptlong NumEffectslong CurrentEffectshort DoOnceref Myselfref cInvObjref TempEnchref NewStoneBegin OnActivate	Activate	Set DoOnce to 1EndBegin GameMode	if HVHGTOBSE.HasOBSE == 0		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 ) ;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				let CurrentEffect := 0				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"				endif			else				let TempEnch := GetEnchantment cInvObj				let NumEffects := GetMagicItemEffectCount TempEnch				let CurrentEffect := 0				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"				endif			endif		Loop		set DoOnce to 0	endifEnd
There is one problem. When I use it to extract the enchantment of a weapon, it doesn't save the weapon's charge. I unenchanted Nevershatter, which normally has 46 uses, and re-enchanted it with the same sigil stone. The new item has 35 uses, which is what the base Invert Sigil Stone is set to. I can find the number of uses of the old enchantment by obtaining the charge and cost, but is there a function to set the uses on a sigil stone? I did a search through OBSE's documentation, and there are no "Sigil Stone"-specific functions, in fact barely any sigil stone information at all.
User avatar
Kara Payne
 
Posts: 3415
Joined: Thu Oct 26, 2006 12:47 am


Return to IV - Oblivion