Jump to content

Papyrus Help: Pre-Stocking Bookshelf


Recommended Posts

Hey all!

As the title suggests, I've been trying to pre-stock the bookshelves in my player home with some goodies. I've discovered that adding them in directly to the bookshelf container results in them not displaying or counting towards the total. Likewise, adding them to the shelf and the container results in duplicate books when the container is updated in-game.

To get around this, I've written a script that can be added to the bookshelf container that adds the books using OnCellLoad - this does about half the job: the container count is accurate, and the books are in the container, but I still can't get them to display. I ended up pillaging a bunch of code from the original PlayerBookshelfContainer script to try to make the books display, and it all compiles, but still the books won't display until after the player activates the shelf for the first time.

I've attached the full script, since posting it seems to trigger Cloudfare to fight me.

And here's the breakdown of the bits in question, as well as the troubleshooting I've done so far:

  • This If statement is firing correctly, and Book01 is correctly defined, since the book is being added to the container:
    If Book01
      ThisChest.AddItem(Book01, 1, true)
      BookMarker01.PlaceAtMe(Book01)
    endIf
  • BookMarker01 is defined as an ObjectReference, and BookShelfBook01 as a Keyword it references, same as in the default script:
    Keyword Property BookShelfBook01 Auto
    ObjectReference Property BookMarker01 Auto Hidden
  • Also just like in the original script, the connection between the two is defined inside the Event, like this:
    BookMarker01 = GetLinkedRef(BookShelfBook01)
  • And all the referenced Keywords are on the object like they should be, as you can see here:

    Screenshot-2022-08-24-211759.png

 

As far as my amateur eyes can see, this should all be working, and as I said, it compiles fine, so my syntax appears to be correct. Any idea what I'm doing wrong? If not, is there a more elegant way to do this?

As always, thanks so much for your help!

Link to comment
Share on other sites

Take a look at the original script. You will see that within the OnActivate event there is a function call to a local function called UpdateBooks. This function is where the placing of books takes place. Despite the OnActivate event triggering at the beginning the usage of Wait makes the event pause until the container menu is closed. The aforementioned function then runs and well updates the books. I presume that this is why the books appear for you after the player character has accessed the container.

 

Something to try:

 

 

Basically, add your books and then remotely call the UpdateBooks function. The following assumes that you add this script alongside the original script such that there will be two scripts attached to the container object references (not base form).

Scriptname _SH_SCR_LoadBookshelf extends ObjectReference  

ObjectReference Property ThisChest Auto

Book[] Property myBook Auto
;fill array with books in desired order

Event OnCellLoad() 
EndEvent
    
State LetsDoThis
  Event OnBeginState()
    GotoState("") ; send the script to the empty state while continuing to process this event
    Int index = myBook.Length - 1
    While index >= 0
      Book myObject = myBook[index]
      If myObject
        ThisChest.AddItem(myObject,1,true)
      EndIf
      index -= 1
    EndWhile
    (ThisChest as PlayerBookShelfContainerScript).UpdateBooks()
  EndEvent
EndState

Auto State Waiting
  Event OnCellLoad()
    GotoState("LetsDoThis")
  EndEvent
EndState 

 

 

Link to comment
Share on other sites

Thanks Ishara! That worked like a charm, and the array is way more elegant than the way I was doing things (so thanks for showing me that, too!)

One thing I'm not understanding reading over your code is how you got around the issue of the script adding the book every time the cell loads. In my original script, I did this by forcing it to check for an XMarker before proceeding, and then disabling it when it was found:

If (FirstLoadMarker.IsEnabled()) ; This ensures the books are only added once, not every time the cell loads.

   FirstLoadMarker.Disable()

Your code doesn't use that extra step, but still doesn't cause the books to respawn. Can you show me how you did that?

Link to comment
Share on other sites

  • Recently Browsing   0 members

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