Jump to content

Item Display and Storage - Script Help


thejadeshadow

Recommended Posts

Okay, so this is weird. (Tested this many times and checked that all my properties were set up correctly).

 

I have a SoulGem Activator set to a Black Star Static. And a MiscObject Activator set to a Paragon. And a Weapon Activator set to a Miraak Staff.

 

Click the Black Star Activator, removes it from my inventory, and enables the static, and stores it in the chest.

 

Click the Paragon Activator, won't remove it from my inventory, won't enable the static, doesn't store it in the chest.

 

Click the Miraak Staff Activator, won't remove it from my inventory, won't enable the static, doesn't store it in the chest.

 

 

 

 

Also.... I can't access the Master Container whether the DisableActivationByPlayer property is set to true or false.

Link to comment
Share on other sites

In the OnInit() event, at the very end of that event, put in a Debug.Notification("k: " + k) To see how many forms were put into the ItemToPlace array. If it's the number of properties you set, then the problem should be somewhere else. If it's less, then not all of the forms are being added to the array.

 

EDIT: Just noticed your second issue. cdcooley accidentally said it defaults to false, but it's actually set to default to true. So if you don't manually edit the property and make sure it's blank, it'll be true.

Edited by Xander9009
Link to comment
Share on other sites

I've tried both variations of the code below, as well as each true and false flag for both, but I can't access the chest no matter what.

bool Property DisableActivationByPlayer = true Auto
{Defaults to false, but if set to true the player will not be able to open the container by activating it.}
bool Property DisableActivationByPlayer = false Auto
{Defaults to false, but if set to true the player will not be able to open the container by activating it.}
Link to comment
Share on other sites

If anyone ever wondered about how long it takes to write a script and get things working this thread is a good example of how it works for me.

 

Here are updated scripts with a list for ingredients and also a slot for a form list (in case someone wants to store groups of items where there are too many to fit into an array). I've also added Debug.Trace lines so that if required properties aren't filled they will be reported in the Papyrus log file.

 

 

 

ScriptName ItemDisplay_MasterContainerScript extends ObjectReference
{Generic ItemDisplay script for a container object that stores items and is linked to activators which 
display matching static versions based on what is in the container.}

bool Property AllowOnlyDisplayableItems = false Auto
{Defaults to false, but if set to true container will return items that can not be displayed by one of its activators.}

bool Property DisableActivationByPlayer = false Auto
{Defaults to false, but if set to true the player will not be able to open the container by activating it.}

ItemDisplay_ActivatorScript[] Property DisplayActivator Auto
{The activators that are using this as their container.}

Actor Property PlayerRef Auto



;=====================================================================
; Functions that could be called by some other script to manipulate displays in other ways.
;=====================================================================

Function TakeItemsFromPlayer(bool forceGreedyMode = false)
{Signal all of the linked activators to take items from the player
(like clicking on all of the activators at once).
If forceGreedyMode is set to true all possible matching items will 
be stored even if the activators would normally just take one.}
	if DisplayActivator
		int i = DisplayActivator.Length
		while i > 0
			i -= 1
			DisplayActivator[i].TakeItemsFromPlayer(forceGreedyMode)
		endwhile
	endif
EndFunction


Function ReturnAllItemsToPlayer()
{Return all stored items to the player and disable all of the linked display items.}
	RemoveAllItems(PlayerRef, true, true)
	UpdateDisplay()
EndFunction


Function UpdateDisplay()
{Update all of the display items. Could also be called if some other 
script modifies the contents of the storage container.}
	if DisplayActivator
		int i = DisplayActivator.Length
		while i > 0
			i -= 1
			DisplayActivator[i].UpdateDisplay()
		endwhile
	endif
EndFunction



;=====================================================================
; Standard events that probably should not be accessed from other scripts.
;=====================================================================

Event OnActivate(ObjectReference akActionRef)
{If the player accesses the container directly the displays still need to get updated.}
	if akActionRef == PlayerRef && !DisableActivationByPlayer
		Activate(akActionRef, true)
		while !Utility.IsInMenuMode()
			Utility.WaitMenuMode(0.1)	; wait for container to open
		endwhile
		Utility.Wait(0.01) ; and then close again
		UpdateDisplay() ; now update
	endif
EndEvent


Event OnItemAdded(Form akBaseItem, int aiItemCount, ObjectReference akItemReference, ObjectReference akSourceContainer)
{Ensure nothing is stored in this container that can not be displayed by one of the activators (if configured).}
	if AllowOnlyDisplayableItems && akSourceContainer
		bool mustGiveBack = true
		if DisplayActivator
			int i = DisplayActivator.Length
			while i > 0 && mustGiveBack
				i -= 1
				if DisplayActivator[i].CanDisplay(akBaseItem)
					mustGiveBack = false
				endif
			endwhile
		endif
		if mustGiveBack
			RemoveItem(akBaseItem, aiItemCount, true, akSourceContainer)
		endif
	endif
EndEvent

Event OnInit()
	BlockActivation()
	if !DisplayActivator
		Debug.Trace(self + " missing required DisplayActivator")
	endif
EndEvent

Event OnLoad()
	BlockActivation()
EndEvent

ScriptName ItemDisplay_ActivatorScript extends ObjectReference
{Generic ItemDisplay script for an activator object that stores an item (or one of a set 
of leveled items) in a master container and displays a matching static version in the world.}

ObjectReference Property ItemToDisplay Auto
{The display item to be enabled or disabled. If not filled, the reference linked in the CK will be used instead.}

Armor[] Property ItemToPlace_Armor Auto
{An item (or group of leveled items) that can be stored in the container and displayed.}

Ammo[] Property ItemToPlace_Ammo Auto
{An item (or group of leveled items) that can be stored in the container and displayed.}

Book[] Property ItemToPlace_Book Auto
{An item (or group of leveled items) that can be stored in the container and displayed.}

Ingredient[] Property ItemToPlace_Ingredient Auto
{An item (or group of leveled items) that can be stored in the container and displayed.}

MiscObject[] Property ItemToPlace_MiscObject Auto
{An item (or group of leveled items) that can be stored in the container and displayed.}

Potion[] Property ItemToPlace_Potion Auto
{An item (or group of leveled items) that can be stored in the container and displayed.}

SoulGem[] Property ItemToPlace_SoulGem Auto
{An item (or group of leveled items) that can be stored in the container and displayed.}

Weapon[] Property ItemToPlace_Weapon Auto
{An item (or group of leveled items) that can be stored in the container and displayed.}

FormList Property ItemToPlace_WithFormList Auto
{A group of items that should be stored or retrieved. Use if you have a group too large 
to fit in one of the other arrays. Items in the list will always be removed regardless 
of the TransferAllMatchingItems property.}

ObjectReference Property MasterContainer Auto
{The container (possibly shared with other activators) that will hold the real items.}

Actor Property PlayerRef Auto

bool Property TransferAllMatchingItems = false Auto
{Should activating transfer all possible items instead of just one?}


Form[] Property ItemToPlace Auto Hidden
{Items are copied here from the more specificly typed versions of the script.}



;=====================================================================
; Functions that can be called from the MasterContainer and other scripts.
;=====================================================================

Function TakeItemsFromPlayer(bool forceGreedyMode = false)
{Try to take a matching item (or all matching items) from the player then update the display.
The forceGreedyMode setting will cause a transfer of all matching items even if the activator
would normally only transfer one.}
	TransferItems(PlayerRef, MasterContainer, TransferAllMatchingItems || forceGreedyMode)
	UpdateDisplay()
EndFunction


Function ReturnAllItemsToPlayer()
{Return all matching items to the player and update the display.}
	TransferItems(MasterContainer, PlayerRef, true)
	UpdateDisplay()
EndFunction


Function UpdateDisplay()
{Refresh the display item to match the master container contents.}
	if ItemToDisplay
		bool shouldHide = true
		if ItemToPlace
			int i = ItemToPlace.Length
			while i > 0 && shouldHide
				i -= 1
				if  MasterContainer.GetItemCount(ItemToPlace[i]) > 0
					shouldHide = false
				endif
			endwhile
		endif
		if ItemToPlace_WithFormList && MasterContainer.GetItemCount(ItemToPlace_WithFormList) > 0
			shouldHide = false
		endif
		if shouldHide
			ItemToDisplay.Disable()
		else
			ItemToDisplay.Enable()
		endif
	endif
EndFunction


bool Function CanDisplay(Form akBaseItem)
	if ItemToPlace && ItemToPlace.Find(akBaseItem) >= 0
		return true
	elseif ItemToPlace_WithFormList && ItemToPlace_WithFormList.HasForm(akBaseItem)
		return true
	else
		return false
	endif
EndFunction




;=====================================================================
; Internal functions and events not meant to be called from other scripts.
;=====================================================================

Event OnActivate(ObjectReference akActionRef)
{Exchange item between player and MasterContainer and always sync display.}
	if akActionRef == PlayerRef
		if !TransferItems(MasterContainer, PlayerRef, TransferAllMatchingItems)
			TransferItems(PlayerRef, MasterContainer, TransferAllMatchingItems)
		endif
		UpdateDisplay()
	endif
EndEvent


bool Function TransferItems(ObjectReference source, ObjectReference destination, bool greedy)
{Utility function to do the transfer of just the first match or all matches (if greedy). 
Returns false when no items are moved.}
	bool searching = true
	if MasterContainer
		int count
		if ItemToPlace
			int i = ItemToPlace.Length
			while i > 0 && (searching || greedy)
				i -= 1
				count = source.GetItemCount(ItemToPlace[i])
				if count > 0
					if !greedy
						count = 1
					endif
					source.RemoveItem(ItemToPlace[i], count, true, destination)
					searching = false
				endif
			endwhile
		endif
		if ItemToPlace_WithFormList && (searching || greedy)
			count = source.GetItemCount(ItemToPlace_WithFormList)
			if count > 0
				source.RemoveItem(ItemToPlace_WithFormList, count, true, destination)
				searching = false
			endif
		endif
	endif
	return !searching
EndFunction


Event OnInit()
{Copy the contents of the more specific lists into the ItemToPlace list. 
With the possibility of more than one type of item being collected together.}
	if !ItemToDisplay ; if property not set, try to get display item from a linked ref
		ItemToDisplay = GetLinkedRef()
	endif
	if !ItemToDisplay
		Debug.Trace(self + " missing (optional) ItemToDisplay")
	endif
	if !MasterContainer
		Debug.Trace(self + " missing required MasterContainer")
	endif

	int size = ItemToPlace_Armor.Length + ItemToPlace_Ammo.Length + ItemToPlace_Book.Length + ItemToPlace_Ingredient.Length 
	size += ItemToPlace_MiscObject.Length + ItemToPlace_Potion.Length + ItemToPlace_SoulGem.Length + ItemToPlace_Weapon.Length
	if size < 1 || size > 128
		if !ItemToPlace_WithFormList
			Debug.Trace(self + " missing required ItemToPlace list")
		endif
		return	; can not continue with that many items!
	endif
	ItemToPlace = NewFormArray(size)
	int k = 0
	if ItemToPlace_Weapon
		int i = ItemToPlace_Weapon.Length
		while i > 0
			i -= 1
			ItemToPlace[k] = ItemToPlace_Weapon[i]
			k += 1
		endwhile
	endif
	if ItemToPlace_SoulGem
		int i = ItemToPlace_SoulGem.Length
		while i > 0
			i -= 1
			ItemToPlace[k] = ItemToPlace_SoulGem[i]
			k += 1
		endwhile
	endif
	if ItemToPlace_Potion
		int i = ItemToPlace_Potion.Length
		while i > 0
			i -= 1
			ItemToPlace[k] = ItemToPlace_Potion[i]
			k += 1
		endwhile
	endif
	if ItemToPlace_MiscObject
		int i = ItemToPlace_MiscObject.Length
		while i > 0
			i -= 1
			ItemToPlace[k] = ItemToPlace_MiscObject[i]
			k += 1
		endwhile
	endif
	if ItemToPlace_Book
		int i = ItemToPlace_Book.Length
		while i > 0
			i -= 1
			ItemToPlace[k] = ItemToPlace_Book[i]
			k += 1
		endwhile
	endif
	if ItemToPlace_Ingredient
		int i = ItemToPlace_Ingredient.Length
		while i > 0
			i -= 1
			ItemToPlace[k] = ItemToPlace_Ingredient[i]
			k += 1
		endwhile
	endif
	if ItemToPlace_Ammo
		int i = ItemToPlace_Ammo.Length
		while i > 0
			i -= 1
			ItemToPlace[k] = ItemToPlace_Ammo[i]
			k += 1
		endwhile
	endif
	if ItemToPlace_Armor
		int i = ItemToPlace_Armor.Length
		while i > 0
			i -= 1
			ItemToPlace[k] = ItemToPlace_Armor[i]
			k += 1
		endwhile
	endif
	if ItemToPlace.Find(None) >= 0
		Debug.Trace(self + " ItemToPlace: " + ItemToPlace)
	endif
EndEvent


Form[] Function NewFormArray(int size)
{Create a new form array with the right length.}
	if size == 1
		return new Form[1]
	elseif size == 2
		return new Form[2]
	elseif size == 3
		return new Form[3]
	elseif size == 4
		return new Form[4]
	elseif size == 5
		return new Form[5]
	elseif size == 6
		return new Form[6]
	elseif size == 7
		return new Form[7]
	elseif size == 8
		return new Form[8]
	elseif size == 9
		return new Form[9]
	elseif size == 10
		return new Form[10]
	elseif size == 11
		return new Form[11]
	elseif size == 12
		return new Form[12]
	elseif size == 13
		return new Form[13]
	elseif size == 14
		return new Form[14]
	elseif size == 15
		return new Form[15]
	elseif size == 16
		return new Form[16]
	elseif size == 17
		return new Form[17]
	elseif size == 18
		return new Form[18]
	elseif size == 19
		return new Form[19]
	elseif size == 20
		return new Form[20]
	elseif size == 21
		return new Form[21]
	elseif size == 22
		return new Form[22]
	elseif size == 23
		return new Form[23]
	elseif size == 24
		return new Form[24]
	elseif size == 25
		return new Form[25]
	elseif size == 26
		return new Form[26]
	elseif size == 27
		return new Form[27]
	elseif size == 28
		return new Form[28]
	elseif size == 29
		return new Form[29]
	elseif size == 30
		return new Form[30]
	elseif size == 31
		return new Form[31]
	elseif size == 32
		return new Form[32]
	elseif size == 33
		return new Form[33]
	elseif size == 34
		return new Form[34]
	elseif size == 35
		return new Form[35]
	elseif size == 36
		return new Form[36]
	elseif size == 37
		return new Form[37]
	elseif size == 38
		return new Form[38]
	elseif size == 39
		return new Form[39]
	elseif size == 40
		return new Form[40]
	elseif size == 41
		return new Form[41]
	elseif size == 42
		return new Form[42]
	elseif size == 43
		return new Form[43]
	elseif size == 44
		return new Form[44]
	elseif size == 45
		return new Form[45]
	elseif size == 46
		return new Form[46]
	elseif size == 47
		return new Form[47]
	elseif size == 48
		return new Form[48]
	elseif size == 49
		return new Form[49]
	elseif size == 50
		return new Form[50]
	elseif size == 51
		return new Form[51]
	elseif size == 52
		return new Form[52]
	elseif size == 53
		return new Form[53]
	elseif size == 54
		return new Form[54]
	elseif size == 55
		return new Form[55]
	elseif size == 56
		return new Form[56]
	elseif size == 57
		return new Form[57]
	elseif size == 58
		return new Form[58]
	elseif size == 59
		return new Form[59]
	elseif size == 60
		return new Form[60]
	elseif size == 61
		return new Form[61]
	elseif size == 62
		return new Form[62]
	elseif size == 63
		return new Form[63]
	elseif size == 64
		return new Form[64]
	elseif size == 65
		return new Form[65]
	elseif size == 66
		return new Form[66]
	elseif size == 67
		return new Form[67]
	elseif size == 68
		return new Form[68]
	elseif size == 69
		return new Form[69]
	elseif size == 70
		return new Form[70]
	elseif size == 71
		return new Form[71]
	elseif size == 72
		return new Form[32]
	elseif size == 73
		return new Form[73]
	elseif size == 74
		return new Form[74]
	elseif size == 75
		return new Form[75]
	elseif size == 76
		return new Form[76]
	elseif size == 77
		return new Form[77]
	elseif size == 78
		return new Form[78]
	elseif size == 79
		return new Form[79]
	elseif size == 80
		return new Form[80]
	elseif size == 81
		return new Form[81]
	elseif size == 82
		return new Form[82]
	elseif size == 83
		return new Form[83]
	elseif size == 84
		return new Form[84]
	elseif size == 85
		return new Form[85]
	elseif size == 86
		return new Form[86]
	elseif size == 87
		return new Form[87]
	elseif size == 88
		return new Form[88]
	elseif size == 89
		return new Form[89]
	elseif size == 90
		return new Form[90]
	elseif size == 91
		return new Form[91]
	elseif size == 92
		return new Form[92]
	elseif size == 93
		return new Form[93]
	elseif size == 94
		return new Form[94]
	elseif size == 95
		return new Form[95]
	elseif size == 96
		return new Form[96]
	elseif size == 97
		return new Form[97]
	elseif size == 98
		return new Form[98]
	elseif size == 99
		return new Form[99]
	elseif size == 100
		return new Form[100]
	elseif size == 101
		return new Form[101]
	elseif size == 102
		return new Form[102]
	elseif size == 103
		return new Form[103]
	elseif size == 104
		return new Form[104]
	elseif size == 105
		return new Form[105]
	elseif size == 106
		return new Form[106]
	elseif size == 107
		return new Form[107]
	elseif size == 108
		return new Form[108]
	elseif size == 109
		return new Form[109]
	elseif size == 110
		return new Form[110]
	elseif size == 111
		return new Form[111]
	elseif size == 112
		return new Form[112]
	elseif size == 113
		return new Form[113]
	elseif size == 114
		return new Form[114]
	elseif size == 115
		return new Form[115]
	elseif size == 116
		return new Form[116]
	elseif size == 117
		return new Form[117]
	elseif size == 118
		return new Form[118]
	elseif size == 119
		return new Form[119]
	elseif size == 120
		return new Form[120]
	elseif size == 121
		return new Form[121]
	elseif size == 122
		return new Form[122]
	elseif size == 123
		return new Form[123]
	elseif size == 124
		return new Form[124]
	elseif size == 125
		return new Form[125]
	elseif size == 126
		return new Form[126]
	elseif size == 127
		return new Form[127]
	else
		return new Form[128]
	endif
EndFunction

 

Link to comment
Share on other sites

  • 1 month later...

Follow up! (sorry for the long delay, holidays and all.....busy life!).

 

AMAZING! I love this script so much. It's effective, easy to apply and customize and is exactly what I wanted.

 

Thank you a thousand times to everyone who helped! The new script will be up on the Elysium Estate nexus starting with version 4.1 and higher if y'all want to see it in action. (not currently in the 4.0 version).

 

:laugh:

Link to comment
Share on other sites

  • Recently Browsing   0 members

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