Jump to content

[Papyrus] Help me finish container weight script


Recommended Posts

I have been working on a script to add weight caps to containers. Thanks to the help of other modders, I got a basic script set up.

 

I was wondering if someone can take a look at it and help me finish:

 

 

 

 

Scriptname zzzContainerWeightCap extends Actor

Float Property fMax
Float fItem
Float fCurrent
Int iCount
Bool bFull
Keyword Property VendorItemArrow Auto

Event OnItemRemoved(Form akBaseItem, int aiItemCount, ObjectReference akItemReference, ObjectReference akDestContainer)
    If UI.IsMenuOpen("ContainerMenu") == 1
; Set the containers max weight
        If (akDestContainer.GetBaseObject().GetWorldModelPath() == "Clutter\Containers\Satchel.nif" )
            fMax = 10.0
        ElseIf (akDestContainer.GetBaseObject().GetWorldModelPath() == "Clutter\Containers\MiscSackSmall.nif" OR "Clutter\Containers\MiscSack02Small.nif" OR "Clutter\Containers\MiscSack02SmallFlat.nif" OR "Clutter\Common\StrongBox01.nif"    )
            fMax = 25.0
        ElseIf (akDestContainer.GetBaseObject().GetWorldModelPath() == "Clutter\WoodFires\SpitPotClosedLoose01.nif" OR "Clutter\WoodFires\SpitPotClosed01.nif" OR "Clutter\WoodFires\SpitPotClosed01.nif" )        
            fMax = 30.0
        ElseIf (akDestContainer.GetBaseObject().GetWorldModelPath() == "Architecture\WhiteRun\WRClutter\WRBurialUrn01.nif" OR "Clutter\Sack01.NIF" OR "Clutter\SBurialUrn01.nif" OR "Clutter\Containers\MiscPouch.nif" OR "Clutter\Ruins\RuinsCanopicJar01.nif" OR "Clutter\Ruins\RuinsCanopicJar02.nif" )        
            fMax = 50.0
        ElseIf (akDestContainer.GetBaseObject().GetWorldModelPath() == "Clutter\Containers\MiscSackLarge.nif" OR "Clutter\Containers\MiscSackLargeFlat01.nif" OR "Clutter\Containers\MiscSackLargeFlat02.nif" OR "Clutter\Containers\MiscSackLargeFlat03.nif" OR "Clutter\Containers\MiscSack02Large.nif" OR "Clutter\Containers\MiscSack02LargeFlat.nif" OR "Effects\FXSpiderWebKitSkeeverDinner.nif" OR "Effects\FXSpiderWebKitDinner.nif" )        
            fMax = 75.0
        ElseIf (akDestContainer.GetBaseObject().GetWorldModelPath() == "Clutter\Common\EndTable01.nif" OR "Clutter\Ruins\RuinsLargeUrnWithStand01.nif" OR "Clutter\Upperclass\UpperEndTable01.nif" OR "Furniture\Noble\NobleNightTable01.nif" OR "Furniture\OrcFurniture\OrcEndTable01.nif" OR "_BYOH\Furniture\BYOHUpperEndTable02.nif" )
            fMax = 100.0
        ElseIf (akDestContainer.GetBaseObject().GetWorldModelPath() == "Architecture\WhiteRun\WRClutter\WRCoffin01.nif" OR "Architecture\Riften\Clutter\RTCoffin01.nif" OR "Clutter\Barrel01.NIF" OR "Clutter\Common\Cupboard01.nif" OR "Clutter\Common\Dresser01.nif" OR "Clutter\Common\Wardrobe01.nif" OR "Clutter\Common\CommonCoffin01.nif" OR "Clutter\Containers\SafeandLock01.nif" OR "Clutter\Dwemer\DweDresser01.nif" OR "Clutter\Sovngarde\SovBarrel01.nif" OR "Clutter\Upperclass\UpperCupboard.nif" OR "Clutter\Upperclass\UpperDresser01.nif" OR "Clutter\Upperclass\UpperWardrobe01.nif" OR "Clutter\Windhelm\WHcoffin01.nif" OR "Dungeons\Dwemer\Clutter\MrkCryptCoffin01container.nif" OR "Dungeons\Dwemer\Clutter\MrkCryptCoffin02container.nif" OR "Furniture\OrcFurniture\OrcDresser01.nif" OR "Dungeons\Dwemer\Clutter\MrkCryptCoffin01container.nif" OR "Dungeons\Dwemer\Clutter\MrkCryptCoffin02container.nif" OR "Furniture\OrcFurniture\OrcDresser01.nif" OR "Furniture\Noble\NobleChestDrawers01.nif" OR "Furniture\Noble\NobleChestDrawers02.nif" OR "Furniture\Noble\NobleWardrobe01.nif" OR "Furniture\Noble\SCoffin.nif" OR "Furniture\Noble\SCoffinPoor.nif" OR "DLC02\Dungeons\Apocrypha\Animated\ApoUrn\ApoUrn01.nif" OR "DLC02\Clutter\DLC2DarkElfUrn01.nif" )
            fMax = 125.0
        ElseIf (akDestContainer.GetBaseObject().GetWorldModelPath() == "Clutter\Dwemer\DweContainter02.nif" OR "DLC02\Dungeons\Apocrypha\Animated\ApoUrn\ApoUrn02.nif" )
            fMax = 150.0
        ElseIf (akDestContainer.GetBaseObject().GetWorldModelPath() == "Clutter\Ruins\Ruins_SmallChest.nif" OR "DLC02\Architecture\Riekling\DLC2RieklingTent01.nif" )
            fMax = 175.0
        ElseIf (akDestContainer.GetBaseObject().GetWorldModelPath() == "Clutter\Containers\Chest01\Chest01.nif" OR "Clutter\Falmer\FalmerContainer.nif" OR "Clutter\Upperclass\UpperChest01.nif" OR "DLC01\Clutter\DLC01SnowElfChest.nif" OR "DLC01\SoulCairn\sc_chest.nif" OR "DLC01\SoulCairn\sc_chest02.nif" )
            fMax = 200.0
        ElseIf (akDestContainer.GetBaseObject().GetWorldModelPath() == "Clutter\Dwemer\DweChest01.nif"    OR "Clutter\Dwemer\DweContainer01.nif" OR "Clutter\Falmer\FalmerContainer02.nif" OR "Clutter\Ruins\Ruins_LargeChest.nif" OR "Furniture\Noble\NobleChest01.nif" )    
            fMax = 225.0
        Else
            fMax = 150.0
        EndIf
        fItem = akBaseItem.GetWeight()
        if ( akBaseItem.HasKeyword(VendorItemArrow) == 1 )
            fItem = 0.1
        EndIf
        iCount = Math.Floor((fMax-fCurrent)/fItem)
        fCurrent += fItem*aiItemCount
        If(aiItemCount > iCount)
            akDestContainer.RemoveItem(akBaseItem, (aiItemCount - iCount), true, GetReference())
            bFull = True
        EndIf
        ;Debug.Notification(fCurrent as Int + "/" + fMax as Int + " (Add)")    
    EndIf
EndEvent
Event OnItemAdded(Form akBaseItem, int aiItemCount, ObjectReference akItemReference, ObjectReference akSourceContainer)
    If UI.IsMenuOpen("ContainerMenu") == 1
; Set the containers max weight
        If (akSourceContainer.GetBaseObject().GetWorldModelPath() == "Clutter\Containers\Satchel.nif" )
            fMax = 10.0
        ElseIf (akSourceContainer.GetBaseObject().GetWorldModelPath() == "Clutter\Containers\MiscSackSmall.nif" OR "Clutter\Containers\MiscSack02Small.nif" OR "Clutter\Containers\MiscSack02SmallFlat.nif" OR "Clutter\Common\StrongBox01.nif"    )
            fMax = 25.0
        ElseIf (akSourceContainer.GetBaseObject().GetWorldModelPath() == "Clutter\WoodFires\SpitPotClosedLoose01.nif" OR "Clutter\WoodFires\SpitPotClosed01.nif" OR "Clutter\WoodFires\SpitPotClosed01.nif" )        
            fMax = 30.0
        ElseIf (akSourceContainer.GetBaseObject().GetWorldModelPath() == "Architecture\WhiteRun\WRClutter\WRBurialUrn01.nif" OR "Clutter\Sack01.NIF" OR "Clutter\SBurialUrn01.nif" OR "Clutter\Containers\MiscPouch.nif" OR "Clutter\Ruins\RuinsCanopicJar01.nif" OR "Clutter\Ruins\RuinsCanopicJar02.nif" )        
            fMax = 50.0
        ElseIf (akSourceContainer.GetBaseObject().GetWorldModelPath() == "Clutter\Containers\MiscSackLarge.nif" OR "Clutter\Containers\MiscSackLargeFlat01.nif" OR "Clutter\Containers\MiscSackLargeFlat02.nif" OR "Clutter\Containers\MiscSackLargeFlat03.nif" OR "Clutter\Containers\MiscSack02Large.nif" OR "Clutter\Containers\MiscSack02LargeFlat.nif" OR "Effects\FXSpiderWebKitSkeeverDinner.nif" OR "Effects\FXSpiderWebKitDinner.nif" )        
            fMax = 75.0
        ElseIf (akSourceContainer.GetBaseObject().GetWorldModelPath() == "Clutter\Common\EndTable01.nif" OR "Clutter\Ruins\RuinsLargeUrnWithStand01.nif" OR "Clutter\Upperclass\UpperEndTable01.nif" OR "Furniture\Noble\NobleNightTable01.nif" OR "Furniture\OrcFurniture\OrcEndTable01.nif" OR "_BYOH\Furniture\BYOHUpperEndTable02.nif" )
            fMax = 100.0
        ElseIf (akSourceContainer.GetBaseObject().GetWorldModelPath() == "Architecture\WhiteRun\WRClutter\WRCoffin01.nif" OR "Architecture\Riften\Clutter\RTCoffin01.nif" OR "Clutter\Barrel01.NIF" OR "Clutter\Common\Cupboard01.nif" OR "Clutter\Common\Dresser01.nif" OR "Clutter\Common\Wardrobe01.nif" OR "Clutter\Common\CommonCoffin01.nif" OR "Clutter\Containers\SafeandLock01.nif" OR "Clutter\Dwemer\DweDresser01.nif" OR "Clutter\Sovngarde\SovBarrel01.nif" OR "Clutter\Upperclass\UpperCupboard.nif" OR "Clutter\Upperclass\UpperDresser01.nif" OR "Clutter\Upperclass\UpperWardrobe01.nif" OR "Clutter\Windhelm\WHcoffin01.nif" OR "Dungeons\Dwemer\Clutter\MrkCryptCoffin01container.nif" OR "Dungeons\Dwemer\Clutter\MrkCryptCoffin02container.nif" OR "Furniture\OrcFurniture\OrcDresser01.nif" OR "Dungeons\Dwemer\Clutter\MrkCryptCoffin01container.nif" OR "Dungeons\Dwemer\Clutter\MrkCryptCoffin02container.nif" OR "Furniture\OrcFurniture\OrcDresser01.nif" OR "Furniture\Noble\NobleChestDrawers01.nif" OR "Furniture\Noble\NobleChestDrawers02.nif" OR "Furniture\Noble\NobleWardrobe01.nif" OR "Furniture\Noble\SCoffin.nif" OR "Furniture\Noble\SCoffinPoor.nif" OR "DLC02\Dungeons\Apocrypha\Animated\ApoUrn\ApoUrn01.nif" OR "DLC02\Clutter\DLC2DarkElfUrn01.nif" )
            fMax = 125.0
        ElseIf (akSourceContainer.GetBaseObject().GetWorldModelPath() == "Clutter\Dwemer\DweContainter02.nif" OR "DLC02\Dungeons\Apocrypha\Animated\ApoUrn\ApoUrn02.nif" )
            fMax = 150.0
        ElseIf (akSourceContainer.GetBaseObject().GetWorldModelPath() == "Clutter\Ruins\Ruins_SmallChest.nif" OR "DLC02\Architecture\Riekling\DLC2RieklingTent01.nif" )
            fMax = 175.0
        ElseIf (akSourceContainer.GetBaseObject().GetWorldModelPath() == "Clutter\Containers\Chest01\Chest01.nif" OR "Clutter\Falmer\FalmerContainer.nif" OR "Clutter\Upperclass\UpperChest01.nif" OR "DLC01\Clutter\DLC01SnowElfChest.nif" OR "DLC01\SoulCairn\sc_chest.nif" OR "DLC01\SoulCairn\sc_chest02.nif" )
            fMax = 200.0
        ElseIf (akSourceContainer.GetBaseObject().GetWorldModelPath() == "Clutter\Dwemer\DweChest01.nif"    OR "Clutter\Dwemer\DweContainer01.nif" OR "Clutter\Falmer\FalmerContainer02.nif" OR "Clutter\Ruins\Ruins_LargeChest.nif" OR "Furniture\Noble\NobleChest01.nif" )    
            fMax = 225.0
        Else
            fMax = 150.0
        EndIf
        fItem = akBaseItem.GetWeight()
        if ( akBaseItem.HasKeyword(VendorItemArrow) == 1 )
            fItem = 0.1
        EndIf
        fCurrent -= fItem*aiItemCount
        ;Debug.Notification(fCurrent as Int + "/" + fMax as Int + " (Remove)")
        If(bFull)
            Debug.Notification("This container is full. (Current weight: " + fCurrent as Int + " of " + fMax as Int + ")")
            bFull = False
        EndIf
    EndIf
EndEvent

 

 

 

Basically I will attach this script to a player alias in a quest.

 

Could anyone help me correct this script/help me finish it?

 

Thanks in advance

 

Kind regards

 

Andre

Link to comment
Share on other sites

1. If applying the script to a reference alias it should extend ReferenceAlias as opposed to extending Actor

2. You are keeping a running variable fCurrent to track the current weight of the container and yet you want this to work with multiple containers. That value will get so out of whack if even just two containers are used.

 

Try using the following function to obtain the current weight instead:

Float Function GetContainerWeight(ObjectReference TheCont)
	Int NumItems = TheCont.GetNumItems()
	Int i = 0
	Float CurrentWeight = 0.0
	While ( i < NumItems )
		If ( TheCont.GetNthForm(i) )
			CurrentWeight = CurrentWeight + ( TheCont.GetNthForm(i).GetWeight() * TheCont.GetItemCount(TheCont.GetNthForm(i)) )
			i += 1
		EndIf
	EndWhile
;	CurrentWeight = TheCont.GetTotalItemWeight()
	Return CurrentWeight
EndFunction

Could take some time with containers with lots of items but runs rather quick on normal quantities. If the weight is over, subtract/remove however many of the currently added item you need to in order to reduce the weight.

Link to comment
Share on other sites

No worries, I'm fine about using SKSE.

In that case you'll want to use the GetTotalItemWeight() function on the container. It can give you the combined weight of everything currently in the container with a single call. It works perfectly in the current version of SKSE. (It had a bug when it was first introduced which is probably why IsharaMeradin had it commented out in that sample code but commented out and was using the loop instead.)

 

The only problem will be that you will also need to get an item count of all of the arrows since you're trying to assign weight to those. But it will still be much faster than iterating through every item.

 

So I think this is what you need. I've made sure it compiles but haven't actually tested it.

 

 

ScriptName zzzContainerWeightCap extends ReferenceAlias

Keyword Property VendorItemArrow Auto
{Need to track arrows to count them as having weight.}

Event OnItemRemoved(Form akBaseItem, int aiItemCount, ObjectReference akItemReference, ObjectReference akDestContainer)
{Check container weight when item transferred from player to a container.}
	If akDestContainer && !(akDestContainer as Actor) && UI.IsMenuOpen("ContainerMenu") ; container but not follower or merchant container
		float maxWeight
		string modelPath = akDestContainer.GetBaseObject().GetWorldModelPath()
		If modelPath == "Clutter\\Containers\\Satchel.nif"
			maxWeight = 10.0
		ElseIf modelPath == "Clutter\\Containers\\MiscSackSmall.nif" || modelPath == "Clutter\\Containers\\MiscSack02Small.nif" || modelPath == "Clutter\\Containers\\MiscSack02SmallFlat.nif" || modelPath == "Clutter\\Common\\StrongBox01.nif"
			maxWeight = 25.0
		ElseIf modelPath == "Clutter\\WoodFires\\SpitPotClosedLoose01.nif" || modelPath == "Clutter\\WoodFires\\SpitPotClosed01.nif" || modelPath == "Clutter\\WoodFires\\SpitPotClosed01.nif"
			maxWeight = 30.0
		ElseIf modelPath == "Architecture\\WhiteRun\\WRClutter\\WRBurialUrn01.nif" || modelPath == "Clutter\\Sack01.NIF" || modelPath == "Clutter\\SBurialUrn01.nif" || modelPath == "Clutter\\Containers\\MiscPouch.nif" || modelPath == "Clutter\\Ruins\\RuinsCanopicJar01.nif" || modelPath == "Clutter\\Ruins\\RuinsCanopicJar02.nif"
			maxWeight = 50.0
		ElseIf modelPath == "Clutter\\Containers\\MiscSackLarge.nif" || modelPath == "Clutter\\Containers\\MiscSackLargeFlat01.nif" || modelPath == "Clutter\\Containers\\MiscSackLargeFlat02.nif" || modelPath == "Clutter\\Containers\\MiscSackLargeFlat03.nif" || modelPath == "Clutter\\Containers\\MiscSack02Large.nif" || modelPath == "Clutter\\Containers\\MiscSack02LargeFlat.nif" || modelPath == "Effects\\FXSpiderWebKitSkeeverDinner.nif" || modelPath == "Effects\\FXSpiderWebKitDinner.nif"
			maxWeight = 75.0
		ElseIf modelPath == "Clutter\\Common\\EndTable01.nif" || modelPath == "Clutter\\Ruins\\RuinsLargeUrnWithStand01.nif" || modelPath == "Clutter\\Upperclass\\UpperEndTable01.nif" || modelPath == "Furniture\\Noble\\NobleNightTable01.nif" || modelPath == "Furniture\\OrcFurniture\\OrcEndTable01.nif" || modelPath == "_BYOH\\Furniture\\BYOHUpperEndTable02.nif"
			maxWeight = 100.0
		ElseIf modelPath =="Architecture\\WhiteRun\\WRClutter\\WRCoffin01.nif" || modelPath == "Architecture\\Riften\\Clutter\\RTCoffin01.nif" || modelPath == "Clutter\\Barrel01.NIF" || modelPath == "Clutter\\Common\\Cupboard01.nif" || modelPath == "Clutter\\Common\\Dresser01.nif" || modelPath == "Clutter\\Common\\Wardrobe01.nif" || modelPath == "Clutter\\Common\\CommonCoffin01.nif" || modelPath == "Clutter\\Containers\\SafeandLock01.nif" || modelPath == "Clutter\\Dwemer\\DweDresser01.nif" || modelPath == "Clutter\\Sovngarde\\SovBarrel01.nif" || modelPath == "Clutter\\Upperclass\\UpperCupboard.nif" || modelPath == "Clutter\\Upperclass\\UpperDresser01.nif" || modelPath == "Clutter\\Upperclass\\UpperWardrobe01.nif" || modelPath == "Clutter\\Windhelm\\WHcoffin01.nif" || modelPath == "Dungeons\\Dwemer\\Clutter\\MrkCryptCoffin01container.nif" || modelPath == "Dungeons\\Dwemer\\Clutter\\MrkCryptCoffin02container.nif" || modelPath == "Furniture\\OrcFurniture\\OrcDresser01.nif" || modelPath == "Dungeons\\Dwemer\\Clutter\\MrkCryptCoffin01container.nif" || modelPath == "Dungeons\\Dwemer\\Clutter\\MrkCryptCoffin02container.nif" || modelPath == "Furniture\\OrcFurniture\\OrcDresser01.nif" || modelPath == "Furniture\\Noble\\NobleChestDrawers01.nif" || modelPath == "Furniture\\Noble\\NobleChestDrawers02.nif" || modelPath == "Furniture\\Noble\\NobleWardrobe01.nif" || modelPath == "Furniture\\Noble\\SCoffin.nif" || modelPath == "Furniture\\Noble\\SCoffinPoor.nif" || modelPath == "DLC02\\Dungeons\\Apocrypha\\Animated\\ApoUrn\\ApoUrn01.nif" || modelPath == "DLC02\\Clutter\\DLC2DarkElfUrn01.nif"
			maxWeight = 125.0
		ElseIf modelPath == "Clutter\\Dwemer\\DweContainter02.nif" || modelPath == "DLC02\\Dungeons\\Apocrypha\\Animated\\ApoUrn\\ApoUrn02.nif"
			maxWeight = 150.0
		ElseIf modelPath == "Clutter\\Ruins\\Ruins_SmallChest.nif" || modelPath == "DLC02\\Architecture\\Riekling\\DLC2RieklingTent01.nif"
			maxWeight = 175.0
		ElseIf modelPath == "Clutter\\Containers\\Chest01\\Chest01.nif" || modelPath == "Clutter\\Falmer\\FalmerContainer.nif" || modelPath == "Clutter\\Upperclass\\UpperChest01.nif" || modelPath == "DLC01\\Clutter\\DLC01SnowElfChest.nif" || modelPath == "DLC01\\SoulCairn\\sc_chest.nif" || modelPath == "DLC01\\SoulCairn\\sc_chest02.nif"
			maxWeight = 200.0
		ElseIf modelPath == "Clutter\\Dwemer\\DweChest01.nif" || modelPath == "Clutter\\Dwemer\\DweContainer01.nif" || modelPath == "Clutter\\Falmer\\FalmerContainer02.nif" || modelPath == "Clutter\\Ruins\\Ruins_LargeChest.nif" || modelPath == "Furniture\\Noble\\NobleChest01.nif"
			maxWeight = 225.0
		Else
			maxWeight = 150.0
		EndIf
		float currentWeight = akDestContainer.GetTotalItemWeight() + 0.1 * akDestContainer.GetItemCount(VendorItemArrow)
		float itemWeight = akBaseItem.GetWeight()
		If itemWeight == 0.0 && akBaseItem.HasKeyword(VendorItemArrow)
			itemWeight = 0.1
		EndIf
		If currentWeight >= maxWeight
			If itemWeight > 0.0
				int itemReturnCount = Math.Floor((currentWeight - maxWeight)/itemWeight)
				If itemReturnCount > aiItemCount
					itemReturnCount = aiItemCount
				EndIf
				if itemReturnCount > 0
					akDestContainer.RemoveItem(akBaseItem, itemReturnCount, true, GetReference())
				EndIf
			EndIf
			currentWeight = akDestContainer.GetTotalItemWeight() + 0.1 * akDestContainer.GetItemCount(VendorItemArrow)
			Debug.Notification("This container is full. (Current weight: " + (currentWeight as int) + " of " + (maxWeight as int) + ")")
		EndIf
	EndIf
EndEvent

 

 

Link to comment
Share on other sites

  • Recently Browsing   0 members

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