Jump to content

Item Sorters Revisited


Ez0n3

Recommended Posts

Hey,

 

I saw a post by Cipscis a while back (think here on the nexus, can't seem to find it again) which talked about a different way of sorting items and maintaining the weapons/armors current health. In a nutshell, you set items you don't want removed from the player to "temporary quest items" and then do a "Player.RemoveAllItems rDestinationContainer" and then set the "fake quest items" back to non-quest items.

 

The benefits being:

No timers

No item form lists

Works with all items (including custom items)

Change which items get sorted in-game

 

So I kind of picked up that ball and ran with it. The idea being, you place an item you want sorted into a container that the sorter "sees" (form list of containers). When the sort is run, it will "see" there is item X in container Y. It will then check if the player has more of item X. If they do, all item X will be put into container Y - retaining health if any.

 

What I ended up with works well with one exception. Items that originate in the containers will find their way back into them. IE: If container Y has item X in it from the start (GECK was used to add the items to the container), when I run the sort - item X will find its way back to container Y even though container Y no longer has that item.

 

In other words, you enter the cell for the first time. Container Y has 2 Whiskeys in it. Take the Whiskeys from the container (now in player inventory) and now container Y is empty. I run the sorter and the Whiskeys that were in container Y somehow find their way back into it (no longer in player inventory).

 

One way around it is to ensure that any containers that have the potential to be added to the sorter are empty from the get-go, but I think I may just be doing something wrong. I just don't see how it's possible those items could wind back up in their original container if a container isn't even set in the script.

 

Note:

When the sorter has something to do, the players items get unequipped. So I had to store previously equipped items to a temp list and then re-equip them afterwards - which was causing a crash because of the PipBoy. Thanks to another post I can't seem to re-find, it was pointed out to me that the PipBoy had to be re-equipped in MenuMode. So there's a little high-jinxery going on - but it works - except for the fore-mention container/item problem.

 

All of the form lists used start off empty and all of the globals are non-constant bools that start off 0.

 

The message "zzEzMSItemSorterCONTMESG" has:

0) Open

1) Add to List [shown if zzEzMSItemSorterIsInListGLOB == 0]

2) Remove from List [shown if zzEzMSItemSorterIsInListGLOB == 1]

3) Close

 

The message "zzEzMSItemSorterACTIMESG" has:

0) Sort Items

1) Enable Config Mode [shown if zzEzMSItemSorterConfigGLOB== 0]

2) Disable Config Mode [shown if zzEzMSItemSorterConfigGLOB== 1]

3) Exit

 

----

 

This is the script the containers that have the potential to be part of the sorter run (just adds or removes itself from a list via menu):

 

 

scn zzEzMSItemSorterCONTSCPT
; Requires NVSE

int bInit
int bInList
int bMsgBox
int iButton
float fTimer
ref rContainer

Begin onactivate
if (IsActionRef Player)
	if (zzEzMSItemSorterConfigGLOB)
		if (bInit == 0)
			set rContainer to GetSelf
			set bInit to 1
		endif
		
		if (bInList)
			set zzEzMSItemSorterIsInListGLOB to 1
		else
			set zzEzMSItemSorterIsInListGLOB to 0
		endif
		
		set bMsgBox to 1
		ShowMessage zzEzMSItemSorterCONTMESG
	else
		Activate
	endif
endif
End

Begin MenuMode
if (bMsgBox)
	set iButton to GetButtonPressed
	if (iButton > -1)
	
		if (iButton == 0) ; open the container
			Activate

		elseif (iButton == 1)
			ListAddReference zzEzMSItemSorterContainersFLST ; add myself to the sorter list
			set bInList to 1
			
		elseif (iButton == 2)
			ListRemoveForm zzEzMSItemSorterContainersFLST rContainer ; remove myself from the sorter list
			set bInList to 0
			
		endif

		SMS fxSearchAndMark
		SMS fxSpotterShader
		set fTimer to 0
		set bMsgBox to 0
	endif
endif
End

Begin GameMode
if (zzEzMSItemSorterConfigGLOB)
	if (fTimer > 0)
		set fTimer to (fTimer - GetSecondsPassed)
	else
		if (bInList)
			PMS fxSpotterShader
		else
			PMS fxSearchAndMark
		endif
		set fTimer to 3
	endif
else
	if (fTimer)
		SMS fxSearchAndMark
		SMS fxSpotterShader
		set fTimer to 0
	endif
endif
End

 

This is the script the sorter activator runs (the one having the issue):

 

scn zzEzMSItemSorterACTISCPT
; Requires NVSE

int bActive
int bInit
int iButton
int iIndexCont
int iIndexItem
int iMsgBox
int iStage
ref rContainer
ref rDestCont
ref rItem
ref rPipBoy

Begin onactivate
if (IsActionRef Player)
	if (iMsgBox || bActive) ; busy
	else
		set iMsgBox to 1
		ShowMessage zzEzMSItemSorterACTIMESG
	endif
endif
End

Begin MenuMode
if (iMsgBox)
	set iButton to GetButtonPressed
	if (iButton > -1)
	
		if (iMsgBox == 1)
			if (iButton == 0) ; sort
				set bActive to 1
				
			elseif (iButton == 1) ; config enable
				set zzEzMSItemSorterConfigGLOB to 1
				
			elseif (iButton == 2) ; config disable
				set zzEzMSItemSorterConfigGLOB to 0
				
			endif
			
		elseif (iMsgBox == 2) ; complete
			if (rPipBoy)
				Player.EquipItem rPipBoy 0 1
				set rPipBoy to 0
			endif
			ResetPipboyManager
		
		endif

		set iMsgBox to 0
	endif
endif
End

Begin GameMode
if (bActive)
	
	; get currently equipped items
	if (iStage == 0)
		set iIndexCont to ListGetCount zzEzMSItemSorterContainersFLST
		if (iIndexCont) 
			set iIndexCont to (iIndexCont - 1)
		else ; quit if there are no containers
			ShowMessage zzEzMSItemSorterNoneMESG
			set bActive to 0
			Return
		endif

		DisablePlayerControls 1 1 1 1 0 1 1
		
		set rPipBoy to 0
		set iIndexItem to 19 ; slots
		
		Label 10
			if (iIndexItem > -1)
				set rItem to Player.GetEquippedObject iIndexItem
				if (iIndexItem == 6) ; skip the pipboy
					set rPipBoy to rItem
				elseif (rItem)
					ListAddForm zzEzMSItemSorterEquippedFLST rItem
				endif
				set iIndexItem to (iIndexItem - 1)
				Goto 10
			endif

		set iStage to 1

	; start the sort
	elseif (iStage == 1)
		set iIndexItem to (Player.GetNumItems - 1)
		set rContainer to ListGetNthForm zzEzMSItemSorterContainersFLST iIndexCont
		set rDestCont to 0
		
		Label 20
		
			; check containers one at a time
			if (iIndexItem > -1)
				set rItem to Player.GetInventoryObject iIndexItem
				if (IsQuestItem rItem) ; skip real quest items
				else
					if (rContainer.GetItemCount rItem)
						if (rDestCont == 0)
							set rDestCont to rContainer ; the only way a destination container gets set is if it passes these checks
						endif
					else
						ListAddForm zzEzMSItemSorterQuestItemsFLST rItem
						SetQuestItem 1 rItem
					endif
				endif
				
				if (iIndexItem)
					set iIndexItem to (iIndexItem - 1)
					Goto 20
				endif
			endif

		; if GetItemCount fails, this should be empty
		if (rDestCont)
			Player.RemoveAllItems rDestCont 1
		endif
		
		; set fake quest items back to non-quest items
		Label 30
			if (ListGetCount zzEzMSItemSorterQuestItemsFLST)
				set rItem to ListGetNthForm zzEzMSItemSorterQuestItemsFLST 0
				SetQuestItem 0 rItem
				ListRemoveNthForm zzEzMSItemSorterQuestItemsFLST 0
				Goto 30
			endif
		
		set iIndexCont to (iIndexCont - 1)
		if (iIndexCont > -1)
			Return ; next container
		else
			if (ListGetCount zzEzMSItemSorterEquippedFLST)
				set iStage to 2 ; re-equip
			else
				set iStage to 3 ; done
			endif
		endif
			
	; re-equip previously equipped items
	elseif (iStage == 2)
		set iIndexItem to 19 ; slots

		Label 40
			if (iIndexItem > -1)
				set rItem to ListGetNthForm zzEzMSItemSorterEquippedFLST iIndexItem
				if (rItem)
					Player.EquipItem rItem 0 1 ; equipping pipboy here will crash
				endif
				ListRemoveNthForm zzEzMSItemSorterEquippedFLST iIndexItem
				set iIndexItem to (iIndexItem - 1)
				Goto 40
			endif

		set iStage to 3

	; complete
	elseif (iStage == 3)
		EnablePlayerControls
		set bActive to 0
		set iIndexCont to 0
		set iIndexItem to 0
		set iStage to 0
		set rContainer to 0
		set rDestCont to 0
		set rItem to 0

		set iMsgBox to 2
		ShowMessage zzEzMSItemSorterDoneMESG ; sort complete
	endif

endif
End

 

On a side note, if I use "ListAddReference zzEzItemSorterContainersFLST" - how can I check if a reference is in the list? I can seem to get "IsInList" or "ListGetFormIndex" to detect added references :(

 

Edit:

I think I've narrowed it down to "GetItemCount" not working right, or NVSE not working right with GetItemCount (replicate):

set iIndexItem to (Player.GetNumItems - 1)
set rContainer to zzRefrigeratorCONTREF

Label 10
if (iIndexItem > -1)
	set rItem to Player.GetInventoryObject iIndexItem
	set iCount to 0
	
	; this is returning "1" even though there are "0" of them for items that spawned in this container
	set iCount to rContainer.GetItemCount rItem

	printc "Container: %n Item: %n Qty: %x", rContainer rItem iCount

	set iCount to 0
	set iIndexItem to (iIndexItem - 1)
	Goto 10
endif

"rContainer.GetItemCount rItem" will return 1 even though there may have been more than 1 of those items at spawn. If 3 Whiskeys spawned in the container and then were removed, it will return "1" if it's checking for "Whiskey". Even if the 3 whiskeys that spawn and were taken by player and then were dropped on the floor, if I add a Whiskey to the player using the console - it will return "1".

 

Thanks

Edited by Ez0n3
Link to comment
Share on other sites

GetItemCount seems to return "1" if the item is a "Level Item", I don't get it :wallbash:

 

Say I put 3 "RadAway" and 3 "FoodLiquor100" into a container. Then I take all of the items from that container (they are now in my inventory). GetItemCount will return "1" for any item from the Level List "FoodLiquor100".

 

An "NVAtomicCocktail" is almost guaranteed to spawn using FoodLiquor100. So lets say, there are 3 RadAways (non-level list) and 3 NVAtomicCocktails (1 from each level list, or 3 from 1 list, etc) - so there would be this on spawn:

 

Container:

Atomic Cocktail (3)

RadAway (3)

 

I take them all (now on player) and run GetItemCount for those two items, I will get:

 

NVAtomicCocktail 1

RadAway 0

 

I open the container, and it's still empty and I still have all of them on the player.

 

My head hurts... :wallbash: :wallbash:

Edited by Ez0n3
Link to comment
Share on other sites

  • Recently Browsing   0 members

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