GamerTechChub Posted April 2, 2017 Share Posted April 2, 2017 Hello everyone. I'm working on a script that gives the player a Blank Tome whenever they use a spell tome, to make tomes more immersive. The script currently looks like this: Scriptname zzzBlankTomeScript extends ReferenceAlias Import Game Book Property Book01 Auto Keyword Property Keyword01 Auto ;--------------------------------------------- Event OnItemRemoved(Form akBaseItem, int aiItemCount, ObjectReference akItemReference, ObjectReference akDestContainer) If akBaseItem as Book Book Book02 = akBaseItem as Book If Book02.HasKeyword(Keyword01) && akItemReference.GetParentCell() != Game.GetPlayer().GetParentCell() && akDestContainer == None Game.GetPlayer().Additem(Book01, 1, true) EndIf EndIf EndEvent The creation kit page suggests that I add a 'AddInventoryEventFilter' but I'm not sure how to implement that or if I even need it. Does anyone know if I need to add a filter or how to add one. Link to comment Share on other sites More sharing options...
cdcooley Posted April 2, 2017 Share Posted April 2, 2017 You already have a good optimization by checking if you can cast the base form to Book. To use the inventory filter you would need to filter on every spell tome. Assuming you want this to work with books added by mods that would be too complicated to be worth the effort. Link to comment Share on other sites More sharing options...
ReDragon2013 Posted April 2, 2017 Share Posted April 2, 2017 (edited) As cdooley wrote, the use of AddInventoryFilter is not needed here. Nevertheless you could make your alias script a bit more comprehensive. zzzBlankTomePlayerAliasScript Scriptname zzzBlankTomePlayerAliasScript extends ReferenceAlias ; https://forums.nexusmods.com/index.php?/topic/5503987-addinventoryeventfilter/ ; gives the player a Blank Tome whenever he used a spell tome Book PROPERTY Book01 auto ; Blank tome // Are you sure a blank tome has a vanilla formID, not required DLC2? Keyword PROPERTY Keyword01 auto ; keyword of spell tome ; -- FUNCTION -- FUNCTION myF_GiveBook(ObjectReference akItemReference) ;----------------------------------------------------- cell c IF ( akItemReference ) ; IF (akItemReference != None) c = akItemReference.GetParentCell() ENDIF objectReference playerRef = self.GetReference() ; only valid for player alias script IF (c == playerRef.GetParentCell()) ; spell tome and player share the same cell, that means player has dropped the spell book ELSE playerRef.AddItem(Book01 as Form, 1, TRUE) ; give player a blank spell tome ENDIF ENDFUNCTION ;-- EVENTs -- "Waiting" + "Busy" ;============================= auto state Waiting ;================= EVENT OnItemRemoved(Form akBaseItem, Int aiItemCount, ObjectReference akItemReference, ObjectReference akDestContainer) IF ( akDestContainer ) RETURN ; - STOP - player is trading or moving the book into container ENDIF ;--------------------- IF (aiItemCount > 1) RETURN ; - STOP - more than one book, it should not be ENDIF ;--------------------- IF (akBaseItem as Book) ELSE RETURN ; - STOP - no kind of book ENDIF ;--------------------- from here: player could dropped a book to the ground /or/ has learnt a new spell IF (akBaseItem as Book).HasKeyword(Keyword01) gotoState("Busy") ; ### STATE ### myF_GiveBook(akItemReference) gotoState("Waiting") ; ### STATE ### back to auto state ENDIF ENDEVENT ;======= endState ;============================= state Busy ; nothing here ;========= ;EVENT OnItemRemoved(Form akBaseItem, Int aiItemCount, ObjectReference akItemReference, ObjectReference akDestContainer) ;ENDEVENT ;======= endState Edited April 5, 2017 by ReDragon2013 Link to comment Share on other sites More sharing options...
cdcooley Posted April 3, 2017 Share Posted April 3, 2017 In case you find ReDragon2013's code hard to follow, it's approximately equivalent to this change to the OnItemRemoved event from the original script. (ReDragon2013 writes code based on the way the compiler works. That generates the very best code from the computer's perspective but can be hard to read for humans. This has the same logical structure and core optimizations but misses out on the low-level optimizations except for the very first one.) Event OnItemRemoved(Form akBaseItem, int aiItemCount, ObjectReference akItemReference, ObjectReference akDestContainer) If akBaseItem as Book ; only books are interesting If akDestContainer == None && aiItemCount == 1 ; a single book not placed into a container If (akBaseItem as Book).HasKeyword(Keyword01) ; a spellbook ObjectReference PlayerRef = GetReference() If akItemReference == None || akItemReference.GetParentCell() != PlayerRef.GetParentCell() ; not dropped PlayerRef.Additem(Book01, 1, true) EndIf EndIf Endif EndIf EndEvent The only thing I've left out is the use of a state change. Generally I would encourage using states to optimize inventory code but in this case the code is already optimized to the point where the state would provide no practical benefit. The check to see if the item is a book remains as the first test since that's the most likely to fail and if it does the script will efficiently bypass the rest of the script. The second pair of checks to make sure it's a single book not placed into a container are next because they don't involve calling functions and so are very fast. The keyword check is next since it's the next most likely thing to fail which will skip the other checks. Explicitly checking to see if akItemReference is None simply avoids errors appearing in the log file while attempting a useless call to GetParentCell(). And finally using GetReference is faster for the system than calling Game.GetPlayer. Link to comment Share on other sites More sharing options...
Recommended Posts