cumbrianlad Posted March 15, 2020 Share Posted March 15, 2020 Darn... even the thread title's got out of hand. So in a nutshell, I have a little alcove with 21 static versions of unique items (The claws, paragons etc on the 2 shelves in the screenshot). In front of the display will be an activator with an 'ActivateLinkedChestDummyScript' on it, linked to a chest in the void. My idea was to have this alcove as a storage chest for every unique item that the player collects and wants to keep, not just the items you can see in the screenshot. Initially I was just going to have it as the shot from the time the player gets the home, but then thought it would be nice if each static was enabled when the player added the playable (Misc Item, Weapon or armour piece) version to the chest. I can do this for single item displays with a simple script using OnItemAdded and OnItemRemoved events, just by creating a property for the Misc Item and static, checking if the item added matches the static version and enabling/disabling it to suit. To do it this way for 21 objects seems ridiculous. I'd have 42 lines of script before actually doing anything, just for the properties! Then both of my events would have around 60 lines if I did it with 'If', 'ElseIf' and 'Else' statements. Close to 200 lines to be executed every time the player adds something to the chest. Is it possible to do this using, say a pair of FormLists, one for the playables, one for the statics? The script would have to check that the item added/removed was in the 'MiscItem' formlist and if it was, enable/disable the corresponding static from the second formlist. That way the script quickly says to itself "Is this item one I should do something about?... No?, do nothing, Yes? sort out that static from the other list." The sorting script would be on the chest, of course. I end up with 2 formlist properties and a dozen or so lines for each event. The problem lies in my self-confessed ineptitude with papyrus! I haven't a clue. If there's no easy way to do this that's kind on the game engine, I'll just have the items all displayed from the start. They do look pretty. Link to comment Share on other sites More sharing options...
IsharaMeradin Posted March 15, 2020 Share Posted March 15, 2020 You have X number of displays each needing to be activated when a specific item is added to a dedicated chest. Utilize index matching form lists Script(s) goes on container, not tested for compilation or function (tho it should work) Method One: Handle objects one at a time as added FormList Property DisplayList Auto FormList Property ItemList Auto Event OnItemAdded(Form akBaseItem, int aiItemCount, ObjectReference akItemReference, ObjectReference akSourceContainer) If ItemList.HasForm(akBaseItem) ; does list have the added item int index = ItemList.Find(akBaseItem) ; obtain index of item ObjectReference DisplayObj = DisplayList.GetAt(index) as ObjectReference ; get matching display at the index If DisplayObj.IsDisabled() DisplayObj.Enable() ; enable the display EndIf Else ;item not a displayable object - send it back (Self as ObjectReference).RemoveItem(akBaseItem,aiItemcount,false,akSourceContainer) EndIf EndEvent Event OnItemRemoved(Form akBaseItem, int aiItemCount, ObjectReference akItemReference, ObjectReference akDestContainer) If ItemList.HasForm(akBaseItem) int index = ItemList.Find(akBaseItem) ObjectReference DisplayObj = DisplayList.GetAt(index) as ObjectReference If DisplayObj.IsEnabled() DisplayObj.Disable() ; disable the display EndIf EndIf EndEvent Method Two: Handle objects sequentially in one go after container is closed (requires SKSE) FormList Property DisplayList Auto FormList Property ItemList Auto Event OnInit() RegisterForMenu("ContainerMenu") EndEvent Event OnItemAdded(Form akBaseItem, int aiItemCount, ObjectReference akItemReference, ObjectReference akSourceContainer) If !(ItemList.HasForm(akBaseItem)) ; does list NOT have the added item (Self as ObjectReference).RemoveItem(akBaseItem,aiItemcount,false,akSourceContainer) EndIf Event Event OnMenuClose(String MenuName) If MenuName == "ContainerMenu" Int index = ItemList.GetSize() Debug.Notification("Updating displays please be patient") While index >= 0 index -= 1 Form Entry = ItemList.GetAt(index) ObjectReference DisplayObj = DisplayList.GetAt(index) as ObjectReference ; get matching display at the index If (Self as ObjectReference).GetItemCount(Entry) >= 1 ; container has the object If DisplayObj.IsDisabled() DisplayObj.Enable() ; enable the display EndIf Else ; container does not have the object If DisplayObj.IsEnabled() DisplayObj.Disable() ; disable the display EndIf EndWhile Debug.Notification("Finished updating displays") EndIf EndEvent Link to comment Share on other sites More sharing options...
cumbrianlad Posted March 15, 2020 Author Share Posted March 15, 2020 IsharaMeredin, you are a star. I've already got your name on my 'Credits' List, so I can't add you twice!* What I will do is add a little note to the description at the top of the script giving individual credit there. Since you've not only saved me from impending insanity, but also scrubbed around 180 lines off the script, I could write a poem there, extolling your virtues, if you'd like!*2 I'd use the version without SKSE, although its a nice idea. My script gets even more compact since I don't need to return an item not in the display to the player. I just do nothing in the 'Else' statement. I'm doing it this way since I made a conscious decision not to restrict what players could store in any of my containers. If they want to store cabbages in there, they can! I'm assuming that all I need to do with both formlists is to ensure that the paired items are added to the list in the same order, so that if the Misc Item 'PortalGemBlue' is number 6 in the 'ItemList' FormList, 'MBRVportalGemBluestat' is also sixth in the 'DisplayList' FormList. * although, how did that song go? Ishara, Ishara, so good they named him twice? I think that's how it goes, but my memory's not what it used to be.*2 seems like a perfectly legitimate use of papyrus lines to me! Link to comment Share on other sites More sharing options...
IsharaMeradin Posted March 15, 2020 Share Posted March 15, 2020 I'd use the version without SKSE, although its a nice idea. My script gets even more compact since I don't need to return an item not in the display to the player. I just do nothing in the 'Else' statement. I'm doing it this way since I made a conscious decision not to restrict what players could store in any of my containers. If they want to store cabbages in there, they can! I'm assuming that all I need to do with both formlists is to ensure that the paired items are added to the list in the same order, so that if the Misc Item 'PortalGemBlue' is number 6 in the 'ItemList' FormList, 'MBRVportalGemBluestat' is also sixth in the 'DisplayList' FormList. Just keep in mind that if the player were to put in several of the displayable items at one time, there could be some issues arise where papyrus is trying to handle too much at once. You will need to test to see if there are any timing issues when dealing with multiple displayable items. If there are you may consider using a button, lever or some other activator to go through the contents of the container and display what needs to be displayed. Similar code as the second approach but not needing SKSE to have access to when the container menu closes. And yes, both formlists would need to be matching. The item in one list should have its display variant at the same index in the other list. Link to comment Share on other sites More sharing options...
cumbrianlad Posted March 15, 2020 Author Share Posted March 15, 2020 Yeah, that could cause problems. For players dowmloading my mod part way through a play, they could potentially have all of the display items in some chest and try to add all of them at once. The reason I said 'no' to the SKSE option is that I don't want players to require it. I'll apply the script (No SKSE) and test it to destruction. I have a clean save with almost every display item that I need in a chest. I'll use that save and try to add close to 21 items that need to be displayed at one time. If my clean save doesn't have enough of them. I'll play without the mod loaded to get the rest, before testing. Link to comment Share on other sites More sharing options...
cumbrianlad Posted March 16, 2020 Author Share Posted March 16, 2020 I need your help again, I'm afraid. I added the script to the container minus the 'return to player' part. I set up all the static display objects to be 'Initially Disabled'. I made the 2 Form Lists and assigned their properties to the script on the chest. Nothing was enabled, when valid items were added to the chest. I then added a few debug lines to the 'OnItemAdded' event. Specifically, they were ("Checking for valid item"), ("Valid item has index"+index) and ("Trying to enable item") Testing brought all 3 notifications up and the indices were correct for each item, so the amethyst paragon was index 15 in both lists and the debug notification was "Valid item has index 15". To me, the problem lies in the game not knowing what to enable, so it does nothing. The DisplayList form list points to the base items, not the specific incidence of that item in the render window. Is that the issue? Link to comment Share on other sites More sharing options...
IsharaMeradin Posted March 16, 2020 Share Posted March 16, 2020 The display form list needs to point to your pre-placed displays rather than the base objects. When you have displays in the render window, the cell window should have a listing of all the objects. Find the correct display there and drag and drop into the form list. Link to comment Share on other sites More sharing options...
cumbrianlad Posted March 16, 2020 Author Share Posted March 16, 2020 Ah. Thanks. I'll try that. Edit: Bingo! It works. So far i've only tested with the items I had in my clean save but they all appear on cue. I have little doubt that the rest won't work. I'll still test by adding all 'displayable items' in one go, in case the game engine doesn't like it, but my gut feeling is that since it's dealing with the items one at a time it will stack them... we'll see. I added 10 items in one go without an issue. I never knew that I could select items for a FormList this way, either. You've turned a beautiful display into one that adds 'imersion' to the mod. That and your script has taught me a great deal... many thanks! I have already added a line to the script description that says "Thanks to IsharaMeredin of Nexus for help with this script" Link to comment Share on other sites More sharing options...
Recommended Posts