Jump to content

InstanceData Scripts - need a bit of enlightment


Recommended Posts

Hey guys,

 

Can anyone help me write a few lines of code?

 

I'm trying to get the weight of random pieces of armor or weapons that the player may have looted or modded. The Form Script function GetWeight() returns 0 weight, which makes sense since it's running on the base form.

 

There's this SKSE function in InstanceData script which should work for armors and weapons - "getWeight(Owner akOwner)" - but is not at all documented. I'm not sure what to pass as Owner here. Armor? Weapon? Form? None compile.

 

I tried this:

Function GetInstanceWeight(Form akObjectForm)

Armor ThisArmor = akObjectForm as Armor
float fArmorWeight = GetWeight(ThisArmor)
Return fArmorWeight

EndFunction

Of course, it does not compile - I get the error "too many arguments passed to function" as well as "type mismatched while assigning to a float". My understanding is that InstanceData function is supposed to return a float right?

 

If I remove the argument and try "ThisArmor.GetWeight()", it does compile - but it's only compiling the Form script function GetWeight() - not the InstanceData one.

 

Can anyone help me lift my confusion? Thanks a lot!

 

 

 

 

 

Link to comment
Share on other sites

Here is the Creation Kit Wiki page for F4SE GetWeight. And here is the SKSE GetWeight.

 

Essentially, it seems that your issue is that GetWeight doesn't take any arguments. And base weapons / armor definitely have weight, so I'm not sure why you're getting a return value of 0.0. It might be cause you're casting the Form to an Armor when you just need the original Form.

 

Edit: My mistake, I was confused about the issue. Disregard the above.

Edited by Reneer
Link to comment
Share on other sites

You need to have objectreference as Owner or at least slot on Actor where armor is equipped. For example

InstanceData:Owner thisInstance = Game.GetPlayer().GetInstanceOwner(6)

 

Now thisInstance is the armor on 6th slot that is underarmor body.

Then you can call any armor related instanceData function and pass this Instance.

For example:

Int bodyArmorDR = InstanceData.GetArmorRating(thisInstance)

 

Lets say you dont have that armor equipped. Then you need to have objectreference, that may be tricky with papyrus but lets say you have it, then do something like:

InstanceData:Owner thisInstance = new InstanceData:Owner

thisInstance.Owner = myArmorObjectReference

 

Then call needed function and pass thisInstance as in previous example.

Link to comment
Share on other sites

Hey thanks guys!

 

yeah I meant F4SE not SKSE, just old Skyrim habits, but what I'm trying to do is in Fallout 4. And yeah I've checked the CK wiki too.

 

But that's the thing, Shavkacagarikia, the wiki's examples do compile of course, but I cant' figure out how to call that GetWeight(Owner akOwner) function. If I try with an objectReference, I get the error "type mismatch on parameter 1: cannot pass an objectreference to an instance#owner" - and whatever else I try to pass as Owner, Papyrus rejects the parameter.

 

Can't remember all the attempts I made, and I'm pretty sure it's a matter of finding the proper syntax... but I'm at a loss of ideas on this one (not that I am a Papyrus wizard either, ok... ;))

 

If any of you guys could give ma a precise example, I'm sure that'd help :)

Link to comment
Share on other sites

Hmm... on second thoughts and after some more unsuccesful attempts, I think I need to be clearer...

 

What I'm trying to do is set a limit to the amount of weight you can put in a custom container - let's say 25.

 

OnActivate, I apply a filter, registerForMenuOpenClose("ContainerMenu"), then move to a state where I listen to OnItemAdded(...) and OnItemRemoved(...), in which events I use GetWeight() [the form function] to get the transferred items weight so I can stop transferrring them once my weight limit has been reached. Once the container menu is closed, I check the total weight with "GetInventoryWeight" and it works fine or components and potions. For armors and weapons it doesn't of course - I always get a 0 weight return. So basically, I'm trying to find a work around to get these items' weight nonetheless...

Link to comment
Share on other sites

I kinda already gave the answer. You need to create owner from the reference and pass it as parameter in needed function.

 

InstanceData:Owner thisInstance = new InstanceData:Owner

thisInstance.Owner = myArmorObjectReference

 

Then to get armor weight do:

Int armorRefWeight = InstanceData.GetWeight(thisInstance)

Link to comment
Share on other sites

Hey Shavkacagarikia,

 

Sorry if my English failed me - not native speaker here and absolutely no coding background other than what I learnt coding Skyrim or Fallout 4.

 

My mistake: I do not quite understand what "InstanceData:Owner thisInstance = new InstanceData:Owner" does exactly - I was trying to compile it this way: "InstanceData.Owner thisInstance = MyObjectReference.Owner as Owner" - skipping the "new" and replacing the ":" by "." What does the "new" stand for anyway?

 

Anyway, I quickly tried this since your last post:

float fContentTotalWeight

Auto State Waiting
	Event OnActivate(ObjectReference akActionRef)
		Self.AddInventoryEventFilter(none)
		RegisterForMenuOpenCloseEvent("ContainerMenu")
		fContentTotalWeight = Self.GetInventoryWeight()
		Debug.Notification("OnActivate total weight is " + fContentTotalWeight)
		GoToState("Transfer")
	EndEvent
EndState

State Transfer
	Event OnItemAdded(Form akItemForm, Int aiCount, ObjectReference akItemReference, ObjectReference akSourceContainer)
		string sItemName = akItemReference.getDisplayName()
		InstanceData:Owner ThisItemOwner = new InstanceData:Owner
		ThisItemOwner.Owner = akItemReference
		float armorRefWeight = InstanceData.GetWeight(ThisItemOwner)
		Debug.Notification(sItemName + " new item weighs " + armorRefWeight + " units")
	EndEvent
	Event OnMenuOpenCloseEvent(string asMenuName, bool abOpening)
		If asMenuName == "ContainerMenu" && !abOpening
			fContentTotalWeight = Self.GetInventoryWeight()
			Debug.Notification("ContainerClosed new weight is " + fContentTotalWeight)
		EndIf
		UnregisterForMenuOpenCloseEvent("ContainerMenu")
		RemoveAllInventoryEventFilters()
		GoToState("Waiting")
	EndEvent
EndState

Now this compiles - but testing it makes the game crash on the Event "OnItemAdded" - I removed the GetDisplayName() function to be sure, replaced it with a debug which runs okay, then again it crashes so my guess is it's crashing when I'm calling "InstanceData:Owner ThisItemOwner = new InstanceDataOwner" and the following lines. Never had the game crash on me from a script before and I have been testing a lot of custom scripts before

 

Now, I'm running all this from a container, I still have to test it on a dropped Item, but in earlier versions when I was using the form function "getWeight()" on same container I had absolutely no issue whether I was calling forms or objectReferences other than the fact that only MiscItems or Potions would return their proper weight. Any idea what causes this crash?

 

And a millions thanks again for your help!

Link to comment
Share on other sites

Well, found a stupid workaround to fulfill my purpose...

 

Considering that modded armors and weapons don't come by the hundreds and that items only get added to a container one by one until there's more than 5 of them, I rewrote my Transfer state like this, using the GetInventoryWeight() function which returns very reliable Int's:

State Transfer
	Event OnItemAdded(Form akItemForm, Int aiCount, ObjectReference akItemReference, ObjectReference akSourceContainer)
		Form AddedItemForm = akItemForm
		float fUpdatedWeight = Self.GetInventoryWeight()
		float fItemsWeight = fUpdatedWeight - fContentTotalWeight
		Debug.Notification("Added Item's weight is " + fItemsWeight)
		If fUpdatedWeight >= 25.00
			(Self as ObjectReference).RemoveItem(AddedItemForm, 1, false, Game.GetPlayer())
		EndIf
	EndEvent
	Event OnMenuOpenCloseEvent(string asMenuName, bool abOpening)
		If asMenuName == "ContainerMenu" && !abOpening
			fContentTotalWeight = Self.GetInventoryWeight()
			Debug.Notification("ContainerClosed new weight is " + fContentTotalWeight)
		EndIf
		UnregisterForMenuOpenCloseEvent("ContainerMenu")
		RemoveAllInventoryEventFilters()
		GoToState("Waiting")
	EndEvent
EndState

This works and gives me the proper weight for whatever type of objects I transfer to my container. I still have to add more code to take aiCount in consideration and make sure that the item that's returned to the PC in case of overweight is exactly the same modded weapon or armor than the one which was initially transferred and that it doesn't loose its enchantment like it could happen in Skyrim, but that's a start.

 

Oh, and in my many tests, I noticed a funny thing too: if you transfer say 56 references of same item, OnItemAdded will run once for the first 40 items, and then run again for the 16 other ones.

 

And I had to pass the container as "(Self as ObjectReference)" because "self" alone wouldn't do anything.

 

Still, I'd like to understand InstanceData scripts and be able to use these functions if I can get my limited "non-coder" brain to grasp the concept... ;)

Link to comment
Share on other sites

You probably get crash because onitemadded's akitemreference parameter is mostly none if added object isnt persistent or added from ground. As I said its tricky to have reference of item thats been added in inventory.
Link to comment
Share on other sites

Yeah, maybe in that example - not sure though 'cause in my many tests when I was trying to get it to work with the form function GetWeight(), I used akItemReference in the same event and same circumstances before. If it's non persistent now, it should have been non persistent then too, and I never crashed before from script errors, at worst it just doesn't work. Never seen a "none" return crash my game.

 

Thanks a lot for your help anyway, I'll use my workaround for now and get back to trying and understand instanceData later ;). Cheers Shavkacagarikia!

Link to comment
Share on other sites

  • Recently Browsing   0 members

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