Deathfouton Posted January 29, 2017 Share Posted January 29, 2017 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 More sharing options...
IsharaMeradin Posted January 29, 2017 Share Posted January 29, 2017 Which actor is this script on? Is it the player or the follower?Are you opposed to using SKSE functions? Link to comment Share on other sites More sharing options...
Deathfouton Posted January 30, 2017 Author Share Posted January 30, 2017 Sorry for the late response, Im not opposed to SKSE, and the script is on a quest instead of the player, with the reference alias's fill type being set to specific reference: cell (any) for PlayerRef("Player"). Link to comment Share on other sites More sharing options...
IsharaMeradin Posted January 30, 2017 Share Posted January 30, 2017 (edited) 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 January 30, 2017 by IsharaMeradin Link to comment Share on other sites More sharing options...
Recommended Posts