After a little bit of testing, this seems to be the default behavior for MiscItems. Tested with the bobbleheads and the OnActivate in the BobbleheadPerkScript doesn't fire if the bobblehead is taken from a container. Anyway ... figured out a work around, at least for my use case. You need to use the OnContainerChanged event instead, or as well. In my case, I wan to add a perk when the player first collects the item, from where ever it may be. I also only want this to only happen the first time the player picks up/retrieves the item. So here's the code I came up with:
Scriptname MyActivateTest extends ObjectReference
bool OnlyOnce
Perk Property PerkToAdd Auto Const
Event OnActivate(ObjectReference akActionRef)
DoStuff("Hello World from OnActivate")
EndEvent
Event OnContainerChanged(ObjectReference akNewContainer, ObjectReference akOldContainer)
if akNewContainer == Game.GetPlayer()
DoStuff("Hello World from OnContainerChanged")
endIf
endEvent
Function DoStuff(String message)
if OnlyOnce == false
game.GetPlayer().AddPerk(PerkToAdd)
Debug.Notification(message)
OnlyOnce = true
endif
EndFunction
Seems to work, although will probably be more efficient if the OnlyOnce check is done before the container check. Just guessing, but an object equality check is usually less peformant than a boolean check - certainly is in C#, so probably is in papyrus too. Hope this helps out anyone else that comes across this gotcha.