Scripting Tutorial: Custom Bound Items

From the Oblivion ConstructionSet Wiki
Revision as of 15:54, 21 December 2023 by 173.17.114.221 (talk)
Jump to navigation Jump to search

This tutorial assumes you are familiar enough with the construction set to at least make gear by copying items and can create/edit scripts.


Tools used in this tutorial

Required


S

The Task

Recently I was working on an object that would summon other pieces of armor/weapons to the selected actor when worn. Basically, it would be a bound armor/weapon enchantment that could be put on equipment. A few interesting challenges came up however, so I thought I'd put my findings here for people who would like to do similar things in the future. This might include spells that make you "change form" by equipping certain gear, or a certain set of armor or weapons that must be used together.

First Attempt

My first inkling was to just try putting the 'bound weapon' enchantment on a piece of equipment. This does not work, and even if it had, would prevent custom gear from being summoned as the bound item code is a built-in magic effect. However, we can recreate it just as well with scripting.

Script Goals

So let’s first list the requirements of what we're trying to do.

  • Create a 'magical' piece of equipment, for this tutorial lets say a ring, which binds a weapon, shield, and helmet to an actor.
  • All the gear must be used together, so the actor cannot use a different helmet with this weapon or shield, or even just take off parts of the equipment.
  • All summoned equipment is removed from the actor's inventory when the ring is removed (just like when a bound weapon or armor is removed).
  • The gear cannot be sold.

What NOT to do

When I first attempted this I made scripts that did lots of redundant checks and tests for scenarios that might screw up the scripts, and that was a mistake. When dealing with code that modifies the inventory of an actor, and especially what they are wearing, too many scripts trying to do the same thing on something can confuse Oblivion.

I was also setting references more often than I needed to, which resulted in cases where I actually lost a reference and caused bugs in my scripts. The real trick in this scenario is to make your code as small as possible and cover the widest general case.

Making the Gear

Ready Ring

So let’s just go through the requirements to make what we need. To begin, make the magical gear. Start with the ring that summons the other equipment. In the construction set, choose a ring (I selected the Jade Sapphire Ring), and copy it with ID "bindTestRing" and name "Ready Ring" or something cleverer. Don't bother making the ring a quest item or anything like that. Just a regular, playable ring. We'll make the script for it in a moment. This item can be a valuable item if you want; it IS a magic ring after all.

Summoned Blade

Now we do the actual summoned gear. Choose a 1-handed weapon (I took an Ebony Long sword) and copy it. I gave it ID “bindTestSword” and name "Summoned Blade". Also, make sure to give it a monetary value of 0.

Summoned Shield

Do the same for a shield. I choose the Ebony Shield and copied it as “Summoned Shield” with ID “bindTestShield”.

Summoned Helmet

Repeat this process one more time for the helmet. I went with the Ebony Helmet and copied it as “Summoned Helmet” with ID “bindTestHelmet”. Don't forget to set the monetary values of these items to 0!

So now we have four pieces of equipment:

  • Ready Ring - Summons the equipment. ID: bindTestRing
  • Summoned Blade - Blade bound to the player by the ring. ID: bindTestSword
  • Summoned Shield - Shield bound to player by the ring. ID: bindTestShield
  • Summoned Helmet - Helmet bound to player by the ring. ID: bindTestHelmet

Bound Item Scripting

Make it PASSIVE

Now we just need to make the scripts that will simulate the bound item effect. When I first attempted this, I made the summoned items unable to be removed by the player. What I discovered was that in an un-patched copy of oblivion, this would cause a crash when going to jail. Also, if the user tried wearing multiple different items that would summon gear, the game would quickly get confused on what they were allowed and not allowed to wear.

The most stable strategy to use in this case is to make the gear as passive as possible; which is to say, if any of the summoned gear is removed, ALL of the gear is removed. We'll accomplish this with two scripts.

Summoned Item Script

The first script goes on all the summoned items (sword, shield, and helmet):


ScriptName bindTestSummonedScript

; Tutorial Summoned Item Script.
; This is for any item summoned by the "Ready Ring"
; Handles two things: Removing item when the player unequips it,
; and unequipping the ready ring when that happens

;UserRef is the actor that has the summoned gear
ref UserRef

Begin OnUnequip
	;If the user is wearing the summoning object(the ring), remove it.
	if(UserRef.GetEquipped bindTestRing == 1)
		UserRef.UnequipItem bindTestRing 0
	endif

	; And remove this 'summoned' object
	Disable
	RemoveMe
End

Begin OnAdd
	; Get the whoever is holding this item at this time only.
	set UserRef to GetContainer
	; If they're not wearing the summoning object, remove this!
	if(UserRef.GetEquipped bindTestRing == 0)
		UserRef.UnequipItem bindTestRing 0
		Disable
		RemoveMe
	endif
End

So basically the script makes sure this item has the matching summoner object when it gets put into something’s inventory and cleans itself up when unequipped. A few things of note: The container reference is only set when the summoned item is added to an inventory. This is the only time it needs to happen. Setting it in other locations will lead to weird bugs when it is removed from an actor’s inventory (i.e. dropping the item). The check for the summoner object in the OnAdd block fixes the weird scenario when you go to prison while wearing this gear. The disable and remove being used one after the other makes the script handle making the summoned object go away when it is either dropped or just unequipped.

Summoner Item Script

This is the script that goes on the object that calls the other items forth (the ring):


ScriptName bindTestSummonerScript

; Tutorial Item Summoner Script
; This is for the magical object (Ready Ring) which will
; summon a sword, shield, and helmet onto the player
; If the ring is removed, these items are unequipped(and then remove themselves)

;UserRef is the actor that has the summoned gear
ref UserRef

; When the ring is unequipped for any reason(sell/drop/normal),
; we force removal of all 'summoned' items
; These items in turn remove themselves, thus completing the
; bound weapon/armor effect
Begin OnUnequip

	; Just go through, if a bound item is equipped, remove it
	
	; Sword
	if(UserRef.GetEquipped bindTestSword == 1)
		UserRef.UnequipItem bindTestSword 0
	endif

	; Shield
	if(UserRef.GetEquipped bindTestShield == 1)
		UserRef.UnequipItem bindTestShield 0
	endif

	; Helmet
	if(UserRef.GetEquipped bindTestHelmet == 1)
		UserRef.UnequipItem bindTestHelmet 0
	endif

End

Begin OnAdd
	; Get whomever is holding this object
	set UserRef to GetContainer
End

; When someone equips the ring, we activate the 'bound weapon/armor' enchantments
Begin OnEquip

	; If the player does not have the item, add it and force equip it.
	; This prevents us from getting 2 copies of an item if we've
	; somehow overwhelmed oblivion into not removing one

	; First do the sword
	if(UserRef.GetItemCount bindTestSword <= 0)
		UserRef.AddItem bindTestSword, 1
	endif
	UserRef.EquipItem bindTestSword 0

	; Then Shield
	if(UserRef.GetItemCount bindTestShield <= 0)
		UserRef.AddItem bindTestShield, 1		
	endif
	UserRef.EquipItem bindTestShield 0

	; And Helmet
	if(UserRef.GetItemCount bindTestHelmet <= 0)
		UserRef.AddItem bindTestHelmet, 1		
	endif
	UserRef.EquipItem bindTestHelmet 0

End

So for this script, when the ring is added, we add the other summoned items (unless the player somehow already has a copy of them). They are then equipped. When this item is unequipped, all the other summoned items are unequipped (which then remove themselves from the player altogether). This is why the summoned items only need to check for and remove the ready ring.


We’re just about ready. Make sure the bindTestSummonedScript is on the sword, shield and helmet, and the bindTestSummonerScript is on the ring. Now just throw the ring in the game somewhere (I usually just drop them in the market district by Edgar’s) and try it out! A scripted summon-item enchantment for gear. It has been stable in all my tests; I have been unable to separate the gear or get copies of the summoned items. Try for yourself: Equipping and unequipping, dropping, selling, going to jail, etc. It will even work with other objects that summon gear on the player!


Further Cleanup

One last glitchy situation remains: Enchanting! The enchantment or sigil stone enchantments will royally screw up any of the summoning or summoned gear. To get around this, we'll just make the gear unable to be enchanted(since summoned gear should be magical anyways).

To do this, make an enchantment for equipment with a scripted effect that does not actually run a script. You can change the name of the scripted effect to "Bound Equipment on Self" or something similar. Do the same for an enchantment on a weapon. Then go and put these enchantments on each of the summoner/summoned gear. Now the player will be unable to further enchant/break our bound item equipment!

Possible Modifications

There are some simple modifications one could do if you wanted slightly different bound item ‘rules’. If you want the gear to be summoned but then mixed and matched, just remove the “summoner item” removal portion of the first script. That is more similar to how 'classic' bound items work.

Another possible modification would be to make the ring not remove the summoned items. That way the ring could be equipped for a set of bound gear and then removed and replaced with something else.

And that's it, hope this has been helpful!