Jump to content

Script having issues - Specific part running twice?


Deathfouton

Recommended Posts

Scriptname RealisticWeightsArrows extends ReferenceAlias

Keyword Property VendorItemArrowKeywordProperty Auto
MiscObject Property RWADummyArrow Auto
Faction Property PotentialFollowerFaction Auto
Int overflow = 0

Event OnItemAdded(Form akBaseItem, int aiItemCount, ObjectReference akItemReference, ObjectReference akSourceContainer)
	If akBaseItem.HasKeyword(VendorItemArrowKeywordProperty)
		Game.GetPlayer().AddItem(RWADummyArrow, aiItemCount, true)
	Endif
EndEvent

Event OnItemRemoved(Form akBaseItem, int aiItemCount, ObjectReference akItemReference, ObjectReference akDestContainer)
	If ((akDestContainer as actor) && akDestContainer != None) && (akDestContainer as Actor).GetFactionRank(PotentialFollowerFaction) >= -1 && akBaseItem.HasKeyword(VendorItemArrowKeywordProperty)
		If akDestContainer.GetItemCount(VendorItemArrowKeywordProperty) > 250
			Game.GetPlayer().AddItem(akBaseItem, 1, true)
			Debug.Notification("Follower ammo limit reached.")
		EndIf
	EndIf
	If akBaseItem.HasKeyword(VendorItemArrowKeywordProperty)
		Game.GetPlayer().RemoveItem(RWADummyArrow, aiItemCount, true, None)
	Endif
EndEvent

So I'm running this script, as a way to make a follower limit on arrows, along with adding a dummy arrow for weight. The dummy arrow stuff all works fine. The issue I'm having is that the first section of OnItemRemoved seems to be running twice. I've tested it many times through different forms, and I seem to be getting 2x the run on whatever I have inside that series of if statements. The current iteration was me narrowing down the issue. The weird part is that the second portion, where I add/remove dummy arrows, are not running multiple times. I can tell due to calculations on my characters weight being accurate. Am I missing something very obvious?

Link to comment
Share on other sites

Should have been more specific. By player or follower, I meant the actor who is triggering the events. A player alias would for this purpose be the player.

 

I was going to say 'quick and dirty' but I got carried away. This would be my approach to limiting the ammo on the follower. Keep in mind it only triggers when the player accesses the follower inventory and puts ammo into their inventory.

 

DO NOTE: Not tested for compilation for functionality

 

 

Actor Property PlayerRef Auto
Formlist Property ArrowList Auto ;can pre-fill in CK with base items or leave empty
FormLIst Property BoltList Auto ;can pre-fill in CK with base items or leave empty
Int Property ArrowLimit Auto
Int Property Boltlimit Auto

Event OnItemAdded(Form akBaseItem, int aiItemCount, ObjectReference akItemReference, ObjectReference akSourceContainer)
	If akBaseItem as Ammo
		If (akBaseItem as Ammo).IsBolt()
			If !(BoltList.HasForm(akBaseItem))
				BoltList.AddForm(akBaseItem)
			EndIf
		Else
			If !(ArrowList.HasForm(akBaseItem))
				ArrowList.AddForm(akBaseItem)
			EndIf
		EndIf
	EndIf
EndEvent


Event OnItemRemoved(Form akBaseItem, int aiItemCount, ObjectReference akItemReference, ObjectReference akDestContainer)
	If UI.IsMenuOpen("InventoryMenu") || UI.IsMenuOpen("GiftMenu") 
           ;using both inventory and gift menus as I am not sure which triggers for followers inventory
		If akBaseItem as Ammo 
                   ;is the item ammo, weeds out everything we do not want to deal with
			If akDestContainer 
                           ;is a valid container
				If akDestContainer as Actor  
                                   ; is an actor
					Actor DCA = akDestContainer as Actor
					If DCA.GetFactionRank(PotentialFollowerFaction) >= -1
						If (akBaseItem as Ammo).IsBolt()
							DealWithAmmo(akBaseItem,aiItemCount,akDestContainer,BoltList,BoltLimit)
						Else
							DealWithAmmo(akBaseItem,aiItemCount,akDestContainer,ArrowList,ArrowLimit)
						EndIf
					EndIf
				EndIf
			EndIf
		EndIf
	EndIf
EndEvent

Function DealWithAmmo(Form TheAmmo, Int Q, ObjectReference TheCont, FormList TheList, Int Limit)
	Int Current = TheCont.GetItemCount(TheList)
	If Current >= Limit
		Debug.Notification("Follower ammo limit exceeded.")
		Int Over = (Current - Limit)
		If Q >= Over
			TheCont.RemoveItem(TheAmmo,Over,true,PlayerRef)
			Debug.Notification(Over+" Ammo returned from "+Current)
			Current = Current - Over   ;remove if not drilling down to exact specified limit
			Over = Over - Over         ;remove if not drilling down to exact specified limit
		Else
			TheCont.RemoveItem(TheAmmo,Q,true,PlayerRef)
			Debug.Notification(Q+" Ammo returned from "+Current)
			Current = Current - Over   ;remove if not drilling down to exact specified limit
			Over = Over - Q            ;remove if not drilling down to exact specified limit
		EndIf

;remove below to not drill down to exact specified limit
		If Over != 0
			Int x = 0
			Int num = TheList.GetSize()
			While x < num
				Form Entry = TheList.GetAt(x)
				Int Q2 = TheCont.GetItemCount(Entry)
				If Q2 >= Over
					TheCont.RemoveItem(Entry,Over,true,PlayerRef)
					Debug.Notification(Over+" Ammo returned from "+Current)
					Over = Over - Over
				Else
					TheCont.RemoveItem(Entry,Q2,true,PlayerRef)
					Debug.Notification(Q2+" Ammo returned from "+Current)
					Over = Over - Q2
				EndIf
				x += 1
			EndWhile
		EndIf
;remove above to not drill down to exact specified limit

	EndIf
EndFunction

 

 

 

Basically what it does is as ammo is added to the player, formlists are built. The formlists do have to be created in the CK and filled into the properties, but they can be empty or pre-filled with base items. When ammo is given to a follower, a function is called which obtains the total number of ammo depending upon the type currently being transferred. If the total count exceeds the specified limit, it will remove either the excess from what was just transferred or remove all of what was transferred. If the amount is still greater than the limit, it cycles through the appropriate list and removes ammo until the specified limit is reached.

 

May need to use some states to help prevent overload if the player transfers a crap ton of different ammo in a row. Without actually testing first in a controlled environment, I couldn't begin to suggest how that should be done. That said, if you don't want to get super accurate and just want to return the last ammo added if the count is higher, then you can remove the portions designated by comments.

 

Also, in the OnItemRemoved event, some of the IF statements can be combined with &&. I separated them so that it would be easier to see what was going on.

 

Personally, I feel it is better to do this on a follower alias. So if it is possible to create an alias that points to a follower, put the script there. Of course, it would have to be modified to work from follower viewpoint instead of player viewpoint. And then you have the issue of compatibility with mod added followers, but you already have that to deal with as well since not all mod added followers use the same follower setup.

 

EDIT: Forgot to mention, it definitely requires SKSE.

Edited by IsharaMeradin
Link to comment
Share on other sites

  • Recently Browsing   0 members

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