Jump to content

[LE] [Script] Make an item (in this case, a book) delete itself when activated


Merrymac

Recommended Posts

I'm pretty sure the reason Delete() isn't working is because the function only works on references created in the game, as per the Delete Wiki page.

 

Try this script (note I haven't had a chance to see if it compiles) if you would rather not require SKSE:

Â

Scriptname _SCR_ScrollTomeLarge extends ObjectReference

LeveledItem Property RandomScroll auto

ObjectReference Property mycontainer = none Auto

Form Property mybaseobject Auto

Event OnContainerChanged(ObjectReference akNewContainer, ObjectReference akOldContainer)
	if (akNewContainer != none)
		mycontainer = akNewContainer
	endif
endEvent

Event OnInit()
	mybaseobject = Self.GetBaseObject()
	; in case Self.GetBaseObject() doesn't work in the OnRead, you can use
	; this variable instead.
endEvent

Event OnRead()
	Game.DisablePlayerControls(False, False, False, False, False, True)

	int ScrollAmount = Utility.RandomInt(5, 8)
	Game.GetPlayer().AddItem(RandomScroll, ScrollAmount)

	if (mycontainer != none)
		; we are in some container
		mycontainer.RemoveItem(Self.GetBaseObject(), mycontainer.GetItemCount(Self.GetBaseObject()), true)
	else
		Game.GetPlayer().RemoveItem(Self.GetBaseObject(), Game.GetPlayer().GetItemCount(Self.GetBaseObject()), true)
		; ^ just in case.
		Self.Disable()
	endif

	Game.EnablePlayerControls(False, False, False, False, False, True)
EndEvent
Edited by Reneer
Link to comment
Share on other sites

I'm pretty sure the reason Delete() isn't working is because the function only works on references created in the game, as per the Delete Wiki page.

 

Try this script (note I haven't had a chance to see if it compiles) if you would rather not require SKSE:

 

Hey, thanks!

 

I tried your script and it both looked promising and compiled fine, but wouldn't remove the tome, either in the inventory, a container or on the ground. I tried both with Self.GetBaseObject() and mybaseobject.

 

It might be fixable by keeping the individual book properties I have now, but I am also worried it won't fully cover reading a book from the player's inventory while accessing a container (seems like it would always try to remove the item from the container, if I'm reading it right) and/or reading a book from an NPC's inventory. Since the SKSE part feels like a safeguard against that, and perhaps other ways of reading books I don't know about, I think I'll just go with that.

Link to comment
Share on other sites

Hey, thanks!

 

I tried your script and it both looked promising and compiled fine, but wouldn't remove the tome, either in the inventory, a container or on the ground. I tried both with Self.GetBaseObject() and mybaseobject.

 

It might be fixable by keeping the individual book properties I have now, but I am also worried it won't fully cover reading a book from the player's inventory while accessing a container (seems like it would always try to remove the item from the container, if I'm reading it right) and/or reading a book from an NPC's inventory. Since the SKSE part feels like a safeguard against that, and perhaps other ways of reading books I don't know about, I think I'll just go with that.

Just so you know, I tested the script myself just now and it works perfectly fine on my end. The script removed the book after being read from both on-the-ground and from within the player's inventory.

 

Exact script I tested with:

Scriptname RenTestNoteScript extends ObjectReference

ObjectReference Property mycontainer = none Auto

Form Property mybaseobject Auto

Event OnContainerChanged(ObjectReference akNewContainer, ObjectReference akOldContainer)
	if (akNewContainer != none)
		mycontainer = akNewContainer
	endif
endEvent

Event OnInit()
	mybaseobject = Self.GetBaseObject()
	; in case Self.GetBaseObject() doesn't work in the OnRead, you can use
	; this variable instead.
endEvent

Event OnRead()
	if (mycontainer != none)
		debug.notification("mycontainer: " + mycontainer.GetFormID())
		; we are in some container
		mycontainer.RemoveItem(Self.GetBaseObject(), mycontainer.GetItemCount(Self.GetBaseObject()), true)
	else
		debug.notification("mycontainer: none")
		Game.GetPlayer().RemoveItem(Self.GetBaseObject(), Game.GetPlayer().GetItemCount(Self.GetBaseObject()), true)
		; ^ just in case.
		Self.Disable()
	endif
EndEvent
Edited by Reneer
Link to comment
Share on other sites

I don't know anything particular dangerous about using OnInit. I've only been told that isn't an event that you want to put your main code in, or any significant amount of coding for the that matter, just small enough to kick things off(like in Reneer's post). That said, I use it checking first time of 'something', or quick testing. Otherwise, I don't use it.

Edited by Lisselli
Link to comment
Share on other sites

OnInit blocks are processed before the object is fully loaded, and neither the object nor other script blocks will process until the oninit block is complete.

Correct, but in the vast majority of cases that doesn't really matter. And if it does matter then it is a simple fix: move the big code somewhere else. In this case it doesn't matter where the code within the OnInit is executed because the script is fully loaded once OnInit is called and the code is a simple function call.

Edited by Reneer
Link to comment
Share on other sites

  • Recently Browsing   0 members

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