Slight Problem with Pilfer

Post » Fri Jun 22, 2012 1:10 am

So, I just made a mod that auto-loots for you. Here's how it works:

The player has a cloak with an associated item 1 of an aimed concentration script spell.

This script spell only operates on dead people.

The script transfers all of their items to a chest in a duplicated CTest room.
Upon doing so it runs this script:

Scriptname PilferSort extends ObjectReference GlobalVariable Property PilferGlobal autoEvent OnItemAdded(Form akBaseItem, int aiItemCount, ObjectReference akItemReference, ObjectReference akSourceContainer)int skip = 0float Weight = akBaseItem.GetWeight()int Value = http://forums.bethsoft.com/topic/1381988-slight-problem-with-pilfer/akBaseItem.GetGoldValue()if (Weight==0.0 && Value> 0)  self.RemoveItem(akBaseItem, aiItemCount, true, Game.GetPlayer())  skip = 1	   endIffloat PilferVal = (Value/Weight)if (PilferVal >= (PilferGlobal.GetValue() as float) && skip==0)  self.RemoveItem(akBaseItem, aiItemCount, true, Game.GetPlayer())elseif (PilferVal < (PilferGlobal.GetValue() as float) && skip==0)  self.RemoveItem(akBaseItem, aiItemCount, true, akSourceContainer)endIfendEvent

Which works marvelously to sort the items into going either to the player or back to the enemy.

Here's the issue. I can't think of a way to "flag" the enemy as having been searched before, so while the items given to the player are correct, if you search the body afterwards and keep searching over and over, different items will be in their inventory as the items cycle between the chest and the body. Kind of a problem. I would use faction ranks, but unfortunately you can't manipulate the faction ranks of dead NPCs (for some stupid reason). Does anyone have an idea?
User avatar
Ellie English
 
Posts: 3457
Joined: Tue Jul 11, 2006 4:47 pm

Post » Thu Jun 21, 2012 10:15 pm

Actor values? Defunct ones like fame, infamy, brain conditions, etc.
User avatar
Shae Munro
 
Posts: 3443
Joined: Fri Feb 23, 2007 11:32 am

Post » Thu Jun 21, 2012 2:59 pm

Hmmm. I'll try it.
Worked marvelously. I thought you couldn't manipulate actor values once dead, but I guess you can. Thanks Rando.
User avatar
Jessica Stokes
 
Posts: 3315
Joined: Fri Jul 28, 2006 11:01 am

Post » Thu Jun 21, 2012 7:00 pm

Okay, so new problem for y'all.

Scriptname PilferSort extends ObjectReference GlobalVariable Property PilferGlobal autoKeyword Property VendorItemClothing autoKeyword Property VendorItemArmor autoEvent OnItemAdded(Form akBaseItem, int aiItemCount, ObjectReference akItemReference, ObjectReference akSourceContainer)int skip = 0float Weight = akBaseItem.GetWeight()int Value = http://forums.bethsoft.com/topic/1381988-slight-problem-with-pilfer/akBaseItem.GetGoldValue()if (Weight==0.0 && Value> 0)  self.RemoveItem(akBaseItem, aiItemCount, true, Game.GetPlayer())  skip = 1	   endIffloat PilferVal = (Value/Weight)if (PilferVal >= (PilferGlobal.GetValue() as float) && skip==0)  self.RemoveItem(akBaseItem, aiItemCount, true, Game.GetPlayer())elseif (PilferVal < (PilferGlobal.GetValue() as float) && skip==0)  self.RemoveItem(akBaseItem, aiItemCount, true, akSourceContainer)  if akBaseItem.HasKeyword(VendorItemArmor) || akBaseItem.HasKeyword(VendorItemClothing)   (akSourceContainer.GetBaseObject() as Actor).EquipItem(akBaseItem)  endIfendIfendEvent

This SHOULD as far as I can tell, put the armor that isn't worth the right amount of money back onto the corpse. But, not so much. Anyone know why? Maybe dead people can't equip things?
User avatar
naomi
 
Posts: 3400
Joined: Tue Jul 11, 2006 2:58 pm

Post » Thu Jun 21, 2012 1:13 pm

Please, please, please. Always include your source files with the mod not just the PEX compiled versions.

It's also been found that calling external functions like Game.GetPlayer() is almost 1000 times slower than using a local variable. Fortunately global variables seem to be relatively fast to access. Since this is going to be triggered by each item, efficiency is going to matter here, so to make your script faster try this:
Scriptname PilferSort extends ObjectReference GlobalVariable Property PilferGlobal autoActor thePlayer = NoneEvent OnItemAdded(Form akBaseItem, int aiItemCount, ObjectReference akItemReference, ObjectReference akSourceContainer)   if thePlayer == None  ; ideally this could have been set in OnInit() but init only happens once and people are already using your mod.      thePlayer = Game.GetPlayer()   endif   float Weight = akBaseItem.GetWeight()   if (Weight==0.0)      Weight = 0.000000001  ; fake a really tiny weight so the relative value is large   endif   int Value = http://forums.bethsoft.com/topic/1381988-slight-problem-with-pilfer/akBaseItem.GetGoldValue()   float PilferVal = (Value/Weight)   if (PilferVal>= (PilferGlobal.GetValue() as float))       self.RemoveItem(akBaseItem, aiItemCount, true, thePlayer)   else      self.RemoveItem(akBaseItem, aiItemCount, true, akSourceContainer)   endIfendEvent
And yes, from what I've seen the game doesn't try to re-equip items on dead NPCs the way Oblivion did.

We really need that RemoveAllItemsThatAreNotEquipped function.
User avatar
Carlitos Avila
 
Posts: 3438
Joined: Fri Sep 21, 2007 3:05 pm

Post » Thu Jun 21, 2012 8:48 pm

Here's my two cents:
Spoiler
ScriptName PilferSort extends ObjectReference Actor Property PlayerREF Auto ; Substantially faster than Game.GetPlayer()GlobalVariable Property PilferGlobal autoEvent OnItemAdded(Form akBaseItem, Int aiItemCount, ObjectReference akItemReference, ObjectReference akSourceContainer)	Bool bSkip = False ; Convert to bool	Float fWeight = akBaseItem.GetWeight() 	Int iValue = http://forums.bethsoft.com/topic/1381988-slight-problem-with-pilfer/akBaseItem.GetGoldValue()	If fWeight	ElseIf iValue ; Cheaper than Weight==0.0 && Value> 0 but does the same thing		RemoveItem(akBaseItem, aiItemCount, True, PlayerREF) ; Get rid of all Self instances. You do not need them.		bSkip = True	EndIf	Float fPilferVal = (iValue / fWeight)	If bSkip ; only needs to be checked once	ElseIf fPilferVal >= (PilferGlobal.GetValue() As Float		RemoveItem(akBaseItem, aiItemCount, True, PlayerREF)	Else ; If fPilferVal < (PilferGlobal.GetValue() As Float) <------------- Not needed		RemoveItem(akBaseItem, aiItemCount, True, akSourceContainer)	EndIf	If akBaseItem.HasKeyword(VendorItemArmor) || akBaseItem.HasKeyword(VendorItemClothing)		If (akSourceContainer As Actor) ; Only if akSourceContainer is an Actor			(akSourceContainer As Actor).EquipItem(akBaseItem)		EndIf	EndIfEndEvent
User avatar
Laura Shipley
 
Posts: 3564
Joined: Thu Oct 26, 2006 4:47 am


Return to V - Skyrim