Getting an ObjectReference for an equipped item

Post » Wed Jun 20, 2012 3:38 am

I'm trying to make a durability mod and I've spent literally hours in the CK and with Papyrus trying to get the ObjectReference of an equipped object.

I feel like I must have missed something really basic and simple - as everything I have tried so far just returns BaseObjects or None.

I even tried dropping the item then using FindClosestReferenceOfType - but that is just too slow for use during combat...

So, does anyone have any magic tricks for getting the ObjectReference of an equipped item on an actor?


Thanks!
User avatar
Natalie J Webster
 
Posts: 3488
Joined: Tue Jul 25, 2006 1:35 pm

Post » Wed Jun 20, 2012 9:02 am

Unfortunately, I think that once an item is entered into the player's inventory, Papyrus has no access to it's ObjectReference.
This was the same in Oblivion.
And we needed a very advanced version of OBSE to access the properties (e.g. durability, charge, etc...) of inventory objects.
SKSE (or a CK update from Bethesda) is required for this.

EDIT:
Here's an idea,
  • detect when a new item is added to the player's inventory
  • save that item in an array
  • save that item's durability in an array
  • detect when the player equips that item
  • when you need to remove from that item's durability, remove from the durability array
  • when that durability is 0, preven the player from equipping that item
  • when the player gets another item of the same type, simply add 100 more to that item's durability
  • when the player loses that item, subtract 100 from that item's durability
User avatar
Jason White
 
Posts: 3531
Joined: Fri Jul 27, 2007 12:54 pm

Post » Wed Jun 20, 2012 10:21 am

Damn I was hoping I didn't need to resort to 3rd party plugins :( - although most people will soon be using SKSE because of SkyUI!

Your array idea, is something I've been thinking about too, although not quite in the same way. Your way does seem quite cunning, but that really would abstract the process a bit to far for my liking as it couldn't differentiate between variants of objects (i.e. player-enchanted etc)

Also, the main purpose of the mod I have in mind is to have weapons break during combat, requiring weapon changes 'under fire' - so I'd need to force unequip when it hits zero ... actually that is quite possible and I can set the 'disable equip' flag on the UnEquip .... hmmm ... ideas

Thanks kuertee!
User avatar
YO MAma
 
Posts: 3321
Joined: Thu Dec 21, 2006 8:24 am

Post » Tue Jun 19, 2012 8:55 pm

If you simply attach a script to the weapon (the object, not the reference), this script extends objectreferences, you have access to every properties of the objectreference and you can call and use every objectecreference function and events, even if the object is in the inventory. To have the reference, just use "self" in this script.
User avatar
Josh Sabatini
 
Posts: 3445
Joined: Wed Nov 14, 2007 9:47 pm

Post » Tue Jun 19, 2012 11:13 pm

Your array idea, is something I've been thinking about too, although not quite in the same way. Your way does seem quite cunning, but that really would abstract the process a bit to far for my liking as it couldn't differentiate between variants of objects (i.e. player-enchanted etc)...Also, the main purpose of the mod I have in mind is to have weapons break during combat, requiring weapon changes 'under fire' - so I'd need to force unequip when it hits zero ... actually that is quite possible and I can set the 'disable equip' flag on the UnEquip .... hmmm ... ideas...Thanks kuertee!
OBSE added quite a lot to what was available in Oblivion's Construction Set.
Mods that didn't have OBSE simply couldn't stack up against those that did.
I'm hoping SKSE would provide the same level of modability. Though, I can guess that it's very few releases wouldn't be as advanced as OBSE of today.
E.g. with OBSE we could alter tha magnitude of a 3rd Magic Effect attached to a spell. That wasn't possible in Oblivion's CS.
That one function saved me from creating multiple spells of incremental magnitudes like how I'm doing now for my Battle fatigue and injuries, Encumbering loot armour and weapons and Eat and sleep mods.

Anyway, I agree re: the method above beeing a little abstract from actually having each item have their own durability value. But when in the game, the player would get the same impression as with a mod that does. I suppose, you can create it so that it can be easily extended for when SKSE is out. E.g. structure your code so that Function calls are like methods attached to the item.

Spoiler
E.g.:
Event OnEquipItem (Form item)	    If getItemDurability (equippedItem) <= 0	    ;when an update allows for actual checking of durability this can easily be changed to:	    ;If item.getDurability () <= 0	    ;or something like that				OnItemBreak (equippedItem)		EndIfEndEventFunction getItemDurability (Form item)	    ;return tha durabilty value from your array hereEndFunction;writing it with this even gets it ready in case a new version of the CK (or a version of SKSE) allows us an OnItemBreak () Event.;If it does become avaiable, you won't even need to check the item's equipping with OnEquipItem () above, because it's already broken.Function OnItemBreak (Form item)		;do what you wish when an Item breaksEndFunction
Writing it with Events () and "action" Functions () kind-of gets it ready for when you need to extend it or when you need to support another plug-in.

If you simply attach a script to the weapon (the object, not the reference), this script extends objectreferences, you have access to every properties of the objectreference and you can call and use every objectecreference function and events, even if the object is in the inventory. To have the reference, just use "self" in this script.
Issue is that you really don't want to attach a SCRIPT to every object in the game.
The viable solution, along the thread, you are proposing is to force an ObjectReference to an Alias with a script.
However, once it leaves that alias, the Script also leaves that Object.
And, I think, another problem is that you still need an ObjectReference - which is not available from a container (e.g. a Player's inventory).
User avatar
Damned_Queen
 
Posts: 3425
Joined: Fri Apr 20, 2007 5:18 pm

Post » Wed Jun 20, 2012 2:12 am

I don't know if this will be the solution for you.... it didn't work out for me but I was trying to get objectreferences of weapons to apply effect shaders to them. Actually, I could apply effect shaders but they didn't work the way I wanted to (hardly visible, at the tip of the weapon only). Since I couldn't get it the next step I stopped. I thought of this idea when I had to figure out whether or not to re-add a certain item in the player inventory (which are not objectreferences) or how to re-associate an item with a referencealias which only works with object references. This may open the door for you. I dunno.

Here's my alias reference fixup function, declerations at the top of the script:

 ReferenceAlias Property JournalAlias autoBook Property mm_BeluaVampireJournal auto


Some code in my fixup function:

 ; Fixup the journal alias if that needs to be done if JournalAlias.GetReference() == None  Trace("Fixing Journal Alias: " + JournalAlias)  ObjectReference Journal = Player.PlaceAtMe(mm_BeluaVampireJournal)  JournalAlias.ForceRefTo(Journal)  Player.RemoveItem(mm_BeluaVampireJournal,10)  Player.AddItem(JournalAlias.GetReference()) Else  Trace("JournalAlias NOT None: " + JournalAlias.GetReference()) EndIf

As you can see here I'm checking to see if an alias in my quest is already filled. If it's not I need to fill it with an object. To get the objectreference for an object that isn't actually of ObjectReference type, you can call PlaceAtme with any formtype. PlaceAtMe, however, returns an ObjectReference ID of the object you placed regardless of the formtype. Then I removed any existing items of that type from the player, and re-added the journal to the player using the aliases GetReference() function.

My code for getting at the weapons object reference was similar but I didn't take it too far because the effectshaders just didn't work right on the object (and even in the debug log it said it wouldn't play although .... something.... was going on). I deleted that code so this is from memory:
 Weapon lefthandWeaponWeapon righthandWeaponObjectReference LeftHandWeaponObjectObjectReference RightHandWeaponObjectEvent OnEffectStart(Actor target, Actor caster)   LeftHandWeapon = target.GetEquippedWeapon(abLeftHand = true)   RightHandWeapon = target.GetEquippedWeapon(abLeftHand = false)   if LeftHandWeapon != None	  LeftHandWeaponObject = target.PlaceAtMe(LeftHandWeapon)   EndIf   if LeftHandWeapon != None	  LeftHandWeaponObject = target.PlaceAtMe(LeftHandWeapon)   EndIf   ;... do more work...EndEvent

So the problem with THIS code is you end up with a duplicate item sitting at the targets feet. I was then able to apply a shader, again it didn't work as expected or I would have taken it a step farther. I did try re-equipping the item but the call failed when using the objectreference. There might be a way around that using the same method I used in my journal sample above, and that's to assign the object to a reference alias and then get the reference back out.

I don't know if any of this will help you.... but it might give you some ideas to make some progress without attaching a script to every blessed object.

Finally if you want to know when someone hit another actor create a cloak spell with like a 20 foot radius. Have the cloak spell apply a dummy effect with a script. In the script you can use the OnHit event to get access to who it was, and what form object they used to attack with:



Event OnHit(ObjectReference akAggressor, Form akSource, Projectile akProjectile, bool abPowerAttack, bool abSneakAttack, \
bool abBashAttack, bool abHitBlocked)

Parameters
  • akAggressor: The http://www.creationkit.com/ObjectReference_Script_(Papyrus) that attacked this reference.
  • akSource: The http://www.creationkit.com/Weapon_Script, http://www.creationkit.com/Spell_Script, http://www.creationkit.com/Explosion_Script, http://www.creationkit.com/Ingredient_Script, http://www.creationkit.com/Potion_Script, or http://www.creationkit.com/Enchantment_Script that hit this reference.
  • akProjectile: The http://www.creationkit.com/Projectile_Script_(Papyrus) that hit this reference.
  • abPowerAttack: Was the hit caused by a power attack?
  • abSneakAttack: Was the hit caused by a sneak attack?
  • abBashAttack: Was the hit caused by a bash attack?
  • abHitBlocked: Was the hit blocked?
Good luck!!!

- MM
User avatar
Nana Samboy
 
Posts: 3424
Joined: Thu Sep 14, 2006 4:29 pm

Post » Tue Jun 19, 2012 10:38 pm

Thanks guys, will take a look at those ideas...

I had tried dropping the item and then getting its Ref ... but that is too slow - duplicating is a cunning idea, but all these tickle the issue of enhanced or enchanted items still appearing as the base formID....
User avatar
zoe
 
Posts: 3298
Joined: Sun Nov 12, 2006 1:09 pm


Return to V - Skyrim