Scripting Tutorial: Modify Weapon On Equip

From the Oblivion ConstructionSet Wiki
Jump to navigation Jump to search
Tools used in this tutorial

Required


Intro[edit | edit source]

This article covers modifying a weapon when equipped. After searching many websites including this one I decided to write an article on what I learned about onEquip and OBSE 18. onEquip has its own challenges for what it can run and OBSE works great when applied properly. Lets get to it.

The scope of what I was trying to accomplish was: equip a weapon, have the weapon modify itself and become enchanted conditionally, and to not need a user action to make this happen other than equip.

Because I am a novice Oblivion scripter I went for the first solution. Run everything from the onEquip function attached to the object's script. Wrong! I spent a lot of time trying various things only to get strange results or simply it didn't work. At one point I found I could create a cloneform of the base form of an object, but when enchanting inside the onEquip function it would enchant base forms and clone forms alike. Not what I wanted to say the least. So once I realized the folly was putting everything in the onEquip call it was time to look outside the event.

The next step I took was trying to get onEquip to "Cast" an enchantment that did exactly what I wanted. However, like before I ran into it just won't work from onEquip syndrome. The next thing I tried was adding an object to the players inventory (a ring) that had the spell. This created a whole bunch of issues and still didn't work. I even tried calling EquipItem2 but that crashed Oblivion. What to do...

Finally I figured it out. Don't try to do much of anything inside onEquip! Don't daisy chain calls, spells, etc. Set a flag and let another script service the flag/event. What would be able to do that? A quest script can. So, here is some basic code to show you what I mean.


Part 1: OnEquip Method[edit | edit source]

OnEquip method for object script sets event flag in quest.

begin OnEquip Player
 Set WOLEvents.EvEquipWOL to 1 ; Set event flag
end

Part 2: Event Flag[edit | edit source]

Event flag detected in quest.

if (EvEquipWOL) ; Detecting event flag
 PrintC "Cloning weapon"
 set Weapon to Player.GetEquippedObject 16 ; Get the equipped weapon base type.
 Call WOLCloneWeapon Weapon ; OBSE 18 Function call. Reduces code in scripts.
 set EvEquipWOL to 0 ; Event flag reset
endif

Part 3: OBSE 18 Function call[edit | edit source]

This is our OBSE 18 "Function" call to do the dirty work. The handy part of this function is that I use the exact same function in a spell designed to do the same thing. Only change the important code once. Code reuse. I know, sick and wrong.

begin Function { Weapon }

 set test to IsClonedForm Weapon
 if ( test )
  PrintC "Already cloned: %i", Weapon
 else
  set TWeapon to CloneForm Weapon
  SetEnchantment WOLWeaponStrike TWeapon

  set ClonedWeapon to TWeapon

  Player.RemoveItemNS Weapon 1
  Player.AddItemNS ClonedWeapon 1
  Player.EquipItemNS ClonedWeapon
		
  PrintC "New clone: %i, Old: %i" ClonedWeapon Weapon
  set Weapon to ClonedWeapon
 endif

 SetFunctionValue Weapon

 sv_Destruct ctext
end

Sweet isn't it?! OBSE 18 is certainly making this a lot easier with the new features.

Conclusion[edit | edit source]

I sure hope this article saves someone some headache. OBSE is a great tool to do some neat things with Oblivion, but sometimes understanding exactly how to do something helps tremendously. I know it took me quite a while to understand some of the intricacies. The one that really threw me was this:

TWeapon.SetEnchantment WOLWeaponStrike 

OR

SetEnchantment WOLWeaponStrike TWeapon

The first one "sort of" works in the onEquip function. It doesn't do what it is supposed to, but it sort of works. But the first one would not work at all in the code I laid out above. The second one is the proper way to do it for an objectID and works well. For what I was doing the second one is what I should have been using. Unfortunately it took a few hours to understand one was a 'refID' and the other was a 'objectID'. Anyway, that is how we learn...