Jump to content

[LE] How to generate an SKSE itemId hash without an actor?


Unappendixed

Recommended Posts

Hey all,

 

I'm working on a mod that involves a lot of equipping and unequipping items on the player actor, and of course I'm dealing with all of the pain that comes with dealing with Bethesda's weird ass inventory handling.

 

I finally tracked down the SKSE EquipItemById function, which sounds like a perfect solution, but after scouring the wiki and the psc files provided with SKSE, I'm struggling to find a way to actually get the necessary itemId int hash. It seems like the only built-in way to generate the hash is to use the GetEquippedItemId function, but it seems like I should be able to generate a hash from any ObjectReference, right? They contain information about the object's display name and enchantment status, which seems to be what the hash is based on.

 

Am I missing something, or is the only way to get that hash to take my object ref, equip it onto a dummy actor, retrieve the itemId hash with GetEquippedItemId, then delete the actor? And if there is no built-in way, does anyone know what math the function is doing so I could make my own function to do the same thing?

 

Hopefully that made sense. Thanks in advance for any replies.

Link to comment
Share on other sites

Instead you can use EquipItemEX which is the same function but it takes an actual form parameter rather than an int ID. To get the ID, you can also use the GetFormID() function.

Would that allow me to differentiate between, for example, a stock Iron Sword and a player enchanted or improved Iron Sword? That's the issue I'm really dealing with. Since GetFormID extends the Form script, I'm a tad dubious I won't just get the base object, and I don't see how I could provide a form parameter to EquipItemEx if the item is player made.

Link to comment
Share on other sites

Yes this is a problem with working in inventories or containers. When an item enters a container, it loses it's object reference unless it's a permanent reference. I think Bethesda did that to save memory. To make a reference permanent, you can just hold it as a script property, BUT it has to exist physically in the world, not in a container first. So it depends on the item sword you're trying to reference. If it's an item from your mod, you can use PlaceAtMe first and store the objectReference in a script property, then add the reference to the inventory and that does the trick, if it's a vanilla sword it might be harder to do.

Link to comment
Share on other sites

Yes this is a problem with working in inventories or containers. When an item enters a container, it loses it's object reference unless it's a permanent reference. I think Bethesda did that to save memory. To make a reference permanent, you can just hold it as a script property, BUT it has to exist physically in the world, not in a container first. So it depends on the item sword you're trying to reference. If it's an item from your mod, you can use PlaceAtMe first and store the objectReference in a script property, then add the reference to the inventory and that does the trick, if it's a vanilla sword it might be harder to do.

The gist of the mod is a sort of Iron Man "suit up" spell, which saves a custom player outfit and you can summon and instantly equip, then banish and return to your nerd robes or whatever. Given the scope, I basically can't rely on CK references at all, and it needs to keep track of enchantments and all that jazz.

 

Right now I have a partial solution where the script opens a container in a detached cell, and the player can drop the outfit they want into that container. Once the menu closes, the container drops each item one by one onto the floor of the cell and adds the generated ObjectRef to an array. The problem is that once that ObjectRef is added back to the player's inventory, I can't specify to equip that reference because it has no 3d. The GetEquippedItemId seems promising, but there's no way of guaranteeing that the player is ever wearing that exact instance of Iron Boots, since calling EquipItem will just equip whatever random reference matches the provided form.

 

I can sort of see a potential solution by taking those items out of the chest, equipping them to a dummy actor in the cell, and then calling GetEquippedItemId on the actor, but... man that's starting to sound really overcomplicated and prone to race conditions and stuff.

Link to comment
Share on other sites

You have entered an area of scripting that is severely under-documented

 

Now the statements below might seem equivalent. Veteran scripters often believe they are identical

 

Player.AddItem(Game.GetForm(WhateverSwordBaseID))

Player.AddItem(Player.PlaceAtMe(Game.GetForm(WhateverSwordBaseID))))

 

They are not the same. You have a sword in your inventory now sure... but thats where the similarity ends

 

Under the hood, the game treats things differently depending on how they came into the world. This is not common knowledge

 

To test this. Do a GetType() on each of the above. One will have no type aka 0. The other will be Type 61

 

One will be much more useful to you than the other. Guess which one

 

This matters. 61 will receive Objectreference Events and otherwise be something you can do things with. The other? Not so much

 

I am not an active author anymore so kinda fuzzy on the super effective ways to utilize SKSE to its potential, but I hope this helps steer you the right direction

Link to comment
Share on other sites

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...