1

PlayerBookShelfContainerScript support without overriding the script

This commit is contained in:
Eddoursul 2022-06-30 15:08:16 +02:00
parent 805d9948b8
commit 7c1a934d4e
4 changed files with 443 additions and 8 deletions

Binary file not shown.

View File

@ -8,6 +8,7 @@ Keyword Property LocTypePlayerHouse Auto
bool bAtHome = false bool bAtHome = false
int iFollowerIndex int iFollowerIndex
ObjectReference bookShelf = None
event OnInit() event OnInit()
@ -54,8 +55,12 @@ Event OnPlayerLoadGame()
if bAtHome if bAtHome
RegisterForModEvent("AT_HomeInventoryUpdate", "OnHomeInventoryUpdate") RegisterForModEvent("AT_HomeInventoryUpdate", "OnHomeInventoryUpdate")
RegisterForMenu("ContainerMenu")
GotoState("AtHome")
else else
UnregisterForModEvent("AT_HomeInventoryUpdate") UnregisterForModEvent("AT_HomeInventoryUpdate")
UnregisterForMenu("ContainerMenu")
GotoState("")
endif endif
EndEvent EndEvent
@ -67,8 +72,10 @@ Event OnLocationChange(Location akOldLoc, Location akNewLoc)
if bAtHome if bAtHome
RegisterForModEvent("AT_HomeInventoryUpdate", "OnHomeInventoryUpdate") RegisterForModEvent("AT_HomeInventoryUpdate", "OnHomeInventoryUpdate")
GotoState("AtHome")
elseif akOldLoc && akOldLoc.HasKeyword(LocTypePlayerHouse) elseif akOldLoc && akOldLoc.HasKeyword(LocTypePlayerHouse)
UnregisterForModEvent("AT_HomeInventoryUpdate") UnregisterForModEvent("AT_HomeInventoryUpdate")
GotoState("")
endif endif
int iCurrentFollowers = 0; int iCurrentFollowers = 0;
@ -102,6 +109,46 @@ event OnHomeInventoryUpdate(string eventName, string strArg, float numArg, Form
endevent endevent
state AtHome
event OnBeginState()
RegisterForMenu("ContainerMenu")
endevent
event OnEndState()
UnregisterForMenu("ContainerMenu")
endevent
event OnMenuOpen(String MenuName)
if ! bAtHome
GotoState("")
return
endif
ObjectReference currentContainer = GetCurrentContainer()
if currentContainer as PlayerBookShelfContainerScript
bookShelf = currentContainer
endif
endevent
event OnMenuClose(String MenuName)
if bookShelf
ObjectReference ref = bookShelf
bookShelf = None
Utility.wait(0.5)
int iLimit = 10
while iLimit > 0 && (ref as PlayerBookShelfContainerScript).GetState() == "PlacingBooks"
iLimit -= 1
Utility.wait(0.5)
endwhile
SyncCellStorage(ref.GetFormID())
endif
endevent
endstate
; NATIVE FUNCTIONS ; NATIVE FUNCTIONS
bool function IsLoaded() native global bool function IsLoaded() native global
@ -114,6 +161,8 @@ function RescanNewArtifacts() native global
ObjectReference function GetCellStorage() native global ObjectReference function GetCellStorage() native global
ObjectReference function GetCurrentContainer() native global
function SyncCellStorage(int FormID = 0) native global function SyncCellStorage(int FormID = 0) native global
Actor[] function GetPlayerFollowers() native global Actor[] function GetPlayerFollowers() native global

View File

@ -1,4 +1,5 @@
Scriptname PlayerBookShelfContainerScript extends ObjectReference Scriptname PlayerBookShelfContainerScript extends ObjectReference
{This script has been overhauled to fix several issues listed in USLEEP 3.0.1 - Bug #19515. This overhaul was contributed by Adria.}
import debug import debug
import utility import utility
@ -133,6 +134,7 @@ GlobalVariable Property BookShelfGlobal Auto
{Global showing whether or not the player has ever activated a bookshelf} {Global showing whether or not the player has ever activated a bookshelf}
EVENT OnCellLoad() EVENT OnCellLoad()
if AlreadyLoaded == FALSE if AlreadyLoaded == FALSE
;Trace("BOOKCASE - Running OnCellLoad()") ;Trace("BOOKCASE - Running OnCellLoad()")
@ -164,13 +166,23 @@ EVENT OnCellLoad()
AlreadyLoaded = TRUE AlreadyLoaded = TRUE
endif endif
endEVENT
; Check if this shelf has already been messed up by vanilla bug, and issue a warning in a log.
; Actual healing process will trigger when all books are removed from the display shelf.
;if !(CurrentBookAmount >= 0 && CurrentBookAmount <= MaxBooksAllowed && CurrentBookAmount == NumBooksOnShelf())
; Trace("BookShelfFix - An inconsistent bookshelf " + self + " found in " + self.GetCurrentLocation() + ", fix will be applied when you pull out all the books from the shelf.")
;endif
endEVENT
EVENT OnActivate(ObjectReference akActionRef) EVENT OnActivate(ObjectReference akActionRef)
; Removing all items from container as a precaution ; Removing all items from container as a precaution
;Trace("BOOKCASE - I've been ACTIVATED!") ;Trace("BOOKCASE - I've been ACTIVATED!")
;USLEEP 3.0.1 - Bug #19515
CleanInvalidPlacedBooks()
CurrentBookAmount = NumBooksOnShelf()
BlockActivate() BlockActivate()
;Trace("BOOKCASE - Blocking activate on all books") ;Trace("BOOKCASE - Blocking activate on all books")
;Trace("BOOKCASE - BookShelfTrigger01Ref = " + BookShelfTrigger01Ref) ;Trace("BOOKCASE - BookShelfTrigger01Ref = " + BookShelfTrigger01Ref)
@ -202,6 +214,17 @@ EVENT OnActivate(ObjectReference akActionRef)
Wait(0.25) Wait(0.25)
; The following will fire when the player leaves inventory ; The following will fire when the player leaves inventory
;USLEEP 3.0.1 - Bug #19515
; When display shelf becomes empty, reset it to fix corrupted shelves
if NumBooksOnShelf() == 0
RemoveAllItems(akTransferTo = Game.GetPlayer(), abRemoveQuestItems = true) ; make sure all the books are transfered into player's inventory
ClearDisplayShelf()
Wait(0.25) ; wait until RemoveAllItems() is (hopefully) done
CurrentBookAmount = 0
;Trace("BookShelfFix - Cleaned up bookshelf " + self + ". This is not an error.")
endif
;Trace("BOOKCASE - Out of Inventory so placing all the books") ;Trace("BOOKCASE - Out of Inventory so placing all the books")
UpdateBooks() UpdateBooks()
@ -394,7 +417,8 @@ endFunction
Function RemoveBooks(Form BookBase, Int BookAmount) Function RemoveBooks(Form BookBase, Int BookAmount)
; Find an empty book form and place the new book there ; Find the removed book form(s) and remove it from the display
While BookAmount > 0 While BookAmount > 0
if PlacedBook01 == BookBase if PlacedBook01 == BookBase
;Trace("BOOKCASE - PlacedBook01 matches, Removing this book") ;Trace("BOOKCASE - PlacedBook01 matches, Removing this book")
@ -572,7 +596,8 @@ ObjectReference Function UpdateSingleBook(Form TargetBook, ObjectReference Place
; Note - it would be more efficient to move the book to its home position if the desired ; Note - it would be more efficient to move the book to its home position if the desired
; book matches the placed book, but MoveTo doesn't work correctly with multi-part dynamic ; book matches the placed book, but MoveTo doesn't work correctly with multi-part dynamic
; objects. So we sidestep the issue by always deleting and placing ; objects. So we sidestep the issue by always deleting and placing
if PlacedBookRef ;USLEEP 3.0.1 - Bug #19515 added form ID check here.
if PlacedBookRef && PlacedBookRef.GetFormID()
PlacedBookRef.Disable() PlacedBookRef.Disable()
PlacedBookRef.Delete() PlacedBookRef.Delete()
endIf endIf
@ -611,14 +636,375 @@ Function UpdateBooks()
UnBlockActivate() ; Allow the player to mess with them UnBlockActivate() ; Allow the player to mess with them
GoToState("") ; Now allow books to be updated again GoToState("") ; Now allow books to be updated again
; Artifact Tracker
SendModEvent("AT_HomeInventoryUpdate")
EndFunction EndFunction
State PlacingBooks State PlacingBooks
Function UpdateBooks() Function UpdateBooks()
; Already updating books, so ignore ; Already updating books, so ignore
EndFunction EndFunction
EndState EndState
;
; ;USLEEP 3.0.1 - Bug #19515: Everything past this point is new stuff to support fixing the bookshelf containers.
;
Function PickUp(ObjectReference BookRef)
;Trace("BookShelfFix " + self + " PickUp() - " + BookRef + ", Base = " + BookRef.GetBaseObject())
if (BookRef && BookRef.GetBaseObject() as Book)
; Remove a display book first
if RemoveBookByRef(BookRef)
GoToState("PickingUp")
; Then remove a book in container
self.RemoveItem(BookRef.GetBaseObject(), 1)
Wait(0.25) ; wait for OnItemRemoved() event to fire
GoToState("")
endif
endIf
EndFunction
State PickingUp
; Used when a book has been picked up directly from the display
Event OnBeginState() ; You Shall Not Pass!
self.BlockActivation(True)
BlockActivate()
;Trace("BookShelfFix " + self + " PickingUp State - Entered State")
EndEvent
Event OnActivate(ObjectReference akActionRef)
EndEvent
Event OnItemRemoved(Form akBaseItem, int aiItemCount, ObjectReference akItemReference, ObjectReference akDestContainer)
;Trace("BookShelfFix " + self + " PickingUp State - Item " + akBaseItem + " removed from shelf inventory")
CurrentBookAmount -= aiItemCount
EndEvent
Event OnEndState()
;Trace("BookShelfFix " + self + " PickingUp State - Leaving State")
UnblockActivate()
self.BlockActivation(False)
EndEvent
EndState
Bool Function RemoveBookByRef(ObjectReference BookRef)
; If the book had been picked up directly, and if there were multiple copies of it on the shelf,
; we need to determine the exact location of the book rather than the first copy in a list.
; Returns True if BookRef has been successfully dismembered from the list or False when the book was missing
if !BookRef
return False
endif
int BookRefID = BookRef.GetFormID()
; These references could be a derivative of ObjectReference such as DefaultSetStageOnPlayerAcquireItem
; and would never match even if they were cast into ObjectReference, so compare their FormIDs rather than comparing them directly.
if PlacedBook01Ref && PlacedBook01Ref.GetFormID() == BookRefID
;Trace("BookShelfFix RemoveBookByRef() - PlacedBook01 matches, Removing this book")
PlacedBook01 = EmptyForm
PlacedBook01Ref = EmptyRef
elseif PlacedBook02Ref && PlacedBook02Ref.GetFormID() == BookRefID
;Trace("BookShelfFix RemoveBookByRef() - PlacedBook02 matches, Removing this book")
PlacedBook02 = EmptyForm
PlacedBook02Ref = EmptyRef
elseif PlacedBook03Ref && PlacedBook03Ref.GetFormID() == BookRefID
;Trace("BookShelfFix RemoveBookByRef() - PlacedBook03 matches, Removing this book")
PlacedBook03 = EmptyForm
PlacedBook03Ref = EmptyRef
elseif PlacedBook04Ref && PlacedBook04Ref.GetFormID() == BookRefID
;Trace("BookShelfFix RemoveBookByRef() - PlacedBook04 matches, Removing this book")
PlacedBook04 = EmptyForm
PlacedBook04Ref = EmptyRef
elseif PlacedBook05Ref && PlacedBook05Ref.GetFormID() == BookRefID
;Trace("BookShelfFix RemoveBookByRef() - PlacedBook05 matches, Removing this book")
PlacedBook05 = EmptyForm
PlacedBook05Ref = EmptyRef
elseif PlacedBook06Ref && PlacedBook06Ref.GetFormID() == BookRefID
;Trace("BookShelfFix RemoveBookByRef() - PlacedBook06 matches, Removing this book")
PlacedBook06 = EmptyForm
PlacedBook06Ref = EmptyRef
elseif PlacedBook07Ref && PlacedBook07Ref.GetFormID() == BookRefID
;Trace("BookShelfFix RemoveBookByRef() - PlacedBook07 matches, Removing this book")
PlacedBook07 = EmptyForm
PlacedBook07Ref = EmptyRef
elseif PlacedBook08Ref && PlacedBook08Ref.GetFormID() == BookRefID
;Trace("BookShelfFix RemoveBookByRef() - PlacedBook08 matches, Removing this book")
PlacedBook08 = EmptyForm
PlacedBook08Ref = EmptyRef
elseif PlacedBook09Ref && PlacedBook09Ref.GetFormID() == BookRefID
;Trace("BookShelfFix RemoveBookByRef() - PlacedBook09 matches, Removing this book")
PlacedBook09 = EmptyForm
PlacedBook09Ref = EmptyRef
elseif PlacedBook10Ref && PlacedBook10Ref.GetFormID() == BookRefID
;Trace("BookShelfFix RemoveBookByRef() - PlacedBook10 matches, Removing this book")
PlacedBook10 = EmptyForm
PlacedBook10Ref = EmptyRef
elseif PlacedBook11Ref && PlacedBook11Ref.GetFormID() == BookRefID
;Trace("BookShelfFix RemoveBookByRef() - PlacedBook11 matches, Removing this book")
PlacedBook11 = EmptyForm
PlacedBook11Ref = EmptyRef
elseif PlacedBook12Ref && PlacedBook12Ref.GetFormID() == BookRefID
;Trace("BookShelfFix RemoveBookByRef() - PlacedBook12 matches, Removing this book")
PlacedBook12 = EmptyForm
PlacedBook12Ref = EmptyRef
elseif PlacedBook13Ref && PlacedBook13Ref.GetFormID() == BookRefID
;Trace("BookShelfFix RemoveBookByRef() - PlacedBook13 matches, Removing this book")
PlacedBook13 = EmptyForm
PlacedBook13Ref = EmptyRef
elseif PlacedBook14Ref && PlacedBook14Ref.GetFormID() == BookRefID
;Trace("BookShelfFix RemoveBookByRef() - PlacedBook14 matches, Removing this book")
PlacedBook14 = EmptyForm
PlacedBook14Ref = EmptyRef
elseif PlacedBook15Ref && PlacedBook15Ref.GetFormID() == BookRefID
;Trace("BookShelfFix RemoveBookByRef() - PlacedBook15 matches, Removing this book")
PlacedBook15 = EmptyForm
PlacedBook15Ref = EmptyRef
elseif PlacedBook16Ref && PlacedBook16Ref.GetFormID() == BookRefID
;Trace("BookShelfFix RemoveBookByRef() - PlacedBook16 matches, Removing this book")
PlacedBook16 = EmptyForm
PlacedBook16Ref = EmptyRef
elseif PlacedBook17Ref && PlacedBook17Ref.GetFormID() == BookRefID
;Trace("BookShelfFix RemoveBookByRef() - PlacedBook17 matches, Removing this book")
PlacedBook17 = EmptyForm
PlacedBook17Ref = EmptyRef
elseif PlacedBook18Ref && PlacedBook18Ref.GetFormID() == BookRefID
;Trace("BookShelfFix RemoveBookByRef() - PlacedBook18 matches, Removing this book")
PlacedBook18 = EmptyForm
PlacedBook18Ref = EmptyRef
else
return False
endif
return True
EndFunction
Int Function NumBooksOnShelf()
; Count number of books displayed on shelf (not ones kept in inventory)
int bookCnt = 0
Form[] PlacedBookAr = new Form[18]
PlacedBookAr[0] = PlacedBook01
PlacedBookAr[1] = PlacedBook02
PlacedBookAr[2] = PlacedBook03
PlacedBookAr[3] = PlacedBook04
PlacedBookAr[4] = PlacedBook05
PlacedBookAr[5] = PlacedBook06
PlacedBookAr[6] = PlacedBook07
PlacedBookAr[7] = PlacedBook08
PlacedBookAr[8] = PlacedBook09
PlacedBookAr[9] = PlacedBook10
PlacedBookAr[10] = PlacedBook11
PlacedBookAr[11] = PlacedBook12
PlacedBookAr[12] = PlacedBook13
PlacedBookAr[13] = PlacedBook14
PlacedBookAr[14] = PlacedBook15
PlacedBookAr[15] = PlacedBook16
PlacedBookAr[16] = PlacedBook17
PlacedBookAr[17] = PlacedBook18
int i = 0
while (i < MaxBooksAllowed && i < 18)
if PlacedBookAr[i]
bookCnt += 1
endif
i += 1
endwhile
; Note that number of books in inventory could NOT match this number due to bugs in vanilla script
return bookCnt
EndFunction
Function ClearDisplayShelf()
; Clear BaseID row for display shelf and give back any books in incorrect slots to player
ObjectReference player = Game.GetPlayer()
;Trace("BookShelfFix - ClearDisplayShelf()")
if (MaxBooksAllowed < 1 && PlacedBook01)
player.AddItem(PlacedBook01, 1, true)
endif
if (MaxBooksAllowed < 2 && PlacedBook02)
player.AddItem(PlacedBook02, 1, true)
endif
if (MaxBooksAllowed < 3 && PlacedBook03)
player.AddItem(PlacedBook03, 1, true)
endif
if (MaxBooksAllowed < 4 && PlacedBook04)
player.AddItem(PlacedBook04, 1, true)
endif
if (MaxBooksAllowed < 5 && PlacedBook05)
player.AddItem(PlacedBook05, 1, true)
endif
if (MaxBooksAllowed < 6 && PlacedBook06)
player.AddItem(PlacedBook06, 1, true)
endif
if (MaxBooksAllowed < 7 && PlacedBook07)
player.AddItem(PlacedBook07, 1, true)
endif
if (MaxBooksAllowed < 8 && PlacedBook08)
player.AddItem(PlacedBook08, 1, true)
endif
if (MaxBooksAllowed < 9 && PlacedBook09)
player.AddItem(PlacedBook09, 1, true)
endif
if (MaxBooksAllowed < 10 && PlacedBook10)
player.AddItem(PlacedBook10, 1, true)
endif
if (MaxBooksAllowed < 11 && PlacedBook11)
player.AddItem(PlacedBook11, 1, true)
endif
if (MaxBooksAllowed < 12 && PlacedBook12)
player.AddItem(PlacedBook12, 1, true)
endif
if (MaxBooksAllowed < 13 && PlacedBook13)
player.AddItem(PlacedBook13, 1, true)
endif
if (MaxBooksAllowed < 14 && PlacedBook14)
player.AddItem(PlacedBook14, 1, true)
endif
if (MaxBooksAllowed < 15 && PlacedBook15)
player.AddItem(PlacedBook15, 1, true)
endif
if (MaxBooksAllowed < 16 && PlacedBook16)
player.AddItem(PlacedBook16, 1, true)
endif
if (MaxBooksAllowed < 17 && PlacedBook17)
player.AddItem(PlacedBook17, 1, true)
endif
if (MaxBooksAllowed < 18 && PlacedBook18)
player.AddItem(PlacedBook18, 1, true)
endif
PlacedBook01 = EmptyForm
PlacedBook02 = EmptyForm
PlacedBook03 = EmptyForm
PlacedBook04 = EmptyForm
PlacedBook05 = EmptyForm
PlacedBook06 = EmptyForm
PlacedBook07 = EmptyForm
PlacedBook08 = EmptyForm
PlacedBook09 = EmptyForm
PlacedBook10 = EmptyForm
PlacedBook11 = EmptyForm
PlacedBook12 = EmptyForm
PlacedBook13 = EmptyForm
PlacedBook14 = EmptyForm
PlacedBook15 = EmptyForm
PlacedBook16 = EmptyForm
PlacedBook17 = EmptyForm
PlacedBook18 = EmptyForm
EndFunction
Function CleanInvalidPlacedBooks()
; Clean invalid (nonexistent) forms off PlacedBook**. Invalid forms may be resulted in removed mods.
; Cleaning them will prevent them from eating up PlacedBook slots permanently.
if !(PlacedBook01 && PlacedBook01.GetFormID()) ; nonexistent forms are still cast into True, but their ID are always 0
PlacedBook01 = EmptyForm
endif
if !(PlacedBook02 && PlacedBook02.GetFormID())
PlacedBook02 = EmptyForm
endif
if !(PlacedBook03 && PlacedBook03.GetFormID())
PlacedBook03 = EmptyForm
endif
if !(PlacedBook04 && PlacedBook04.GetFormID())
PlacedBook04 = EmptyForm
endif
if !(PlacedBook05 && PlacedBook05.GetFormID())
PlacedBook05 = EmptyForm
endif
if !(PlacedBook06 && PlacedBook06.GetFormID())
PlacedBook06 = EmptyForm
endif
if !(PlacedBook07 && PlacedBook07.GetFormID())
PlacedBook07 = EmptyForm
endif
if !(PlacedBook08 && PlacedBook08.GetFormID())
PlacedBook08 = EmptyForm
endif
if !(PlacedBook09 && PlacedBook09.GetFormID())
PlacedBook09 = EmptyForm
endif
if !(PlacedBook10 && PlacedBook10.GetFormID())
PlacedBook10 = EmptyForm
endif
if !(PlacedBook11 && PlacedBook11.GetFormID())
PlacedBook11 = EmptyForm
endif
if !(PlacedBook12 && PlacedBook12.GetFormID())
PlacedBook12 = EmptyForm
endif
if !(PlacedBook13 && PlacedBook13.GetFormID())
PlacedBook13 = EmptyForm
endif
if !(PlacedBook14 && PlacedBook14.GetFormID())
PlacedBook14 = EmptyForm
endif
if !(PlacedBook15 && PlacedBook15.GetFormID())
PlacedBook15 = EmptyForm
endif
if !(PlacedBook16 && PlacedBook16.GetFormID())
PlacedBook16 = EmptyForm
endif
if !(PlacedBook17 && PlacedBook17.GetFormID())
PlacedBook17 = EmptyForm
endif
if !(PlacedBook18 && PlacedBook18.GetFormID())
PlacedBook18 = EmptyForm
endif
EndFunction
;USSEP 4.1.5 Bug #13862 - Added to reset all bookshelf form and reference pointers after the chest has been dumped by the prefabs script.
Function USSEP_ClearAllBookForms()
PlacedBook01 = EmptyForm
PlacedBook02 = EmptyForm
PlacedBook03 = EmptyForm
PlacedBook04 = EmptyForm
PlacedBook05 = EmptyForm
PlacedBook06 = EmptyForm
PlacedBook07 = EmptyForm
PlacedBook08 = EmptyForm
PlacedBook09 = EmptyForm
PlacedBook10 = EmptyForm
PlacedBook11 = EmptyForm
PlacedBook12 = EmptyForm
PlacedBook13 = EmptyForm
PlacedBook14 = EmptyForm
PlacedBook15 = EmptyForm
PlacedBook16 = EmptyForm
PlacedBook17 = EmptyForm
PlacedBook18 = EmptyForm
PlacedBook01Ref = EmptyRef
PlacedBook02Ref = EmptyRef
PlacedBook03Ref = EmptyRef
PlacedBook04Ref = EmptyRef
PlacedBook05Ref = EmptyRef
PlacedBook06Ref = EmptyRef
PlacedBook07Ref = EmptyRef
PlacedBook08Ref = EmptyRef
PlacedBook09Ref = EmptyRef
PlacedBook10Ref = EmptyRef
PlacedBook11Ref = EmptyRef
PlacedBook12Ref = EmptyRef
PlacedBook13Ref = EmptyRef
PlacedBook14Ref = EmptyRef
PlacedBook15Ref = EmptyRef
PlacedBook16Ref = EmptyRef
PlacedBook17Ref = EmptyRef
PlacedBook18Ref = EmptyRef
EndFunction