Book Closing Event

Post » Fri Nov 16, 2012 3:53 pm

OnRead fires when a book is opened. I'd like something to happen when a book is closed.

I've tried the obvious - OnClose - and it doesn't fire. I seem to recall mention of an event on exiting menu mode which might work, but my search-fu has failed me in this regard.

I can use debug.wait, but the book has five pages and I'd like them to have a chance to read it all first.

Another approach would be to set an OnUpdate loop and activate when the player was no longer reading - it I knew how to tell when the player was reading.

Any ideas, anyone?
User avatar
naomi
 
Posts: 3400
Joined: Tue Jul 11, 2006 2:58 pm

Post » Fri Nov 16, 2012 8:15 am

I have a solution will post shortly, just need to move to other pc to grab script to use
User avatar
Ladymorphine
 
Posts: 3441
Joined: Wed Nov 08, 2006 2:22 pm

Post » Fri Nov 16, 2012 8:15 am

This is the script that i used to test with, in fact i didn't actually think about this until i saw you post. I like the idea so much, i am going to leave it in. Any one know if there is a way a way to check to see if the player reads all the pages first?

Spoiler
Event OnRead()Player = Game.GetPlayer()utility.wait(1)  if !NMQ001.IsCompleted()   while Utility.IsInMenuMode()	debug.notification("Reading")   endwhile	Player.AddSpell(SP_AshmelechArmour_NECMAS, False)	 Player.AddPerk(Pk_AshmelechArmour_NECMAS)	  Player.AddSpell(SP_AvronsShield_NECMAS, False)	   Player.Addperk(Pk_AvronsShield_NECMAS)		Player.Addperk(PK_ModSpellCost_NECMAS)		 UISpellLearned_NECMAS.Play(player)		 debug.notification("You have learnt how to conjure magical armour")		EndIf  EndEvent

The lines to note are Event OnRead(), utility.wait(1), and most importantly while Utility.IsInMenuMode and EndWhile

Until the while event is filled, the rest of the script will not complete. The script completes once out of menu mode. Reading a document is classed as being in menu mode.

UPDATE - After testing this in game, i found that this works ok for a single item, however noticed issues occurring when used on multiple scripts and also if used on items that were included within quests
User avatar
james tait
 
Posts: 3385
Joined: Fri Jun 22, 2007 6:26 pm

Post » Fri Nov 16, 2012 3:30 pm

Until the while event is filled, the rest of the script will not complete. The script completes once out of menu mode. Reading a document is classed as being in menu mode

IsInMenuMode - that was it. And under Utility too.

Thanks heilghast, that's twice you've saved my life today :)
User avatar
cassy
 
Posts: 3368
Joined: Mon Mar 05, 2007 12:57 am

Post » Fri Nov 16, 2012 6:36 pm

No probs, don't forget you need to encapsulate IsInMenuMode with While and Endwhile.
I put the uitility.wait(1) to give time for the book to be opened
User avatar
Danger Mouse
 
Posts: 3393
Joined: Sat Oct 07, 2006 9:55 am

Post » Fri Nov 16, 2012 7:20 pm

This is actually really handy thanks guys :)
User avatar
Marcin Tomkow
 
Posts: 3399
Joined: Sun Aug 05, 2007 12:31 pm

Post » Fri Nov 16, 2012 5:07 pm

Correct me if I'm wrong, but if you're reading a book from your inventory, wouldn't this not trigger until after you leave the inventory menu?
User avatar
Joey Bel
 
Posts: 3487
Joined: Sun Jan 07, 2007 9:44 am

Post » Fri Nov 16, 2012 5:41 pm

In case anyone's interested, here's my eventual solution:

Spoiler

Scriptname SSG_BoundItemBook_S extends ObjectReference  Spell Property BoundItem AutoActor pauto state Unread	event onread()		GoToState("Read")		p = game.GetPlayer()		;debug.MessageBox("reading book")		;		; don't give the spell out twice		;		if p.hasspell(BoundItem)			Return		EndIf		RegisterForSingleUpdate(2)	EndEventEndStatestate Read	event onread()	EndEventEndStateevent OnUpdate()	;debug.MessageBox("update")	;	; do nothing while the player is still reading	;	; we'll use a shorter update loop here since nothing much is likely to happen	;	if Utility.IsInMenuMode()		;debug.MessageBox("still in menu mode")		RegisterForSingleUpdate(0.2)		Return	EndIf	;debug.MessageBox("adding")	p.AddSpell(BoundItem, true)EndEvent

[edit]

Correct me if I'm wrong, but if you're reading a book from your inventory, wouldn't this not trigger until after you leave the inventory menu?

Yes, I suppose so. But then you'd open it when you pick it up (or at least you will as I have it set up) and when you store it, that will kick off the script.

Not perfect but it will do for my purposes.
User avatar
SWagg KId
 
Posts: 3488
Joined: Sat Nov 17, 2007 8:26 am

Post » Fri Nov 16, 2012 5:45 pm

It definitely works for books guaranteed to be placed out in the world.
User avatar
Kyra
 
Posts: 3365
Joined: Mon Jan 29, 2007 8:24 am

Post » Fri Nov 16, 2012 3:47 pm

Correct me if I'm wrong, but if you're reading a book from your inventory, wouldn't this not trigger until after you leave the inventory menu?

Yes you are correct. However since reading a book which is not in your inventory, still classifies the player as being in MenuMode.

However, i would be interested to learn if there is another command/function that can specifically determine when a book in the players inventory has been read and closed,and then "do something" whilst still within the Menu
User avatar
Solina971
 
Posts: 3421
Joined: Thu Mar 29, 2007 6:40 am

Post » Fri Nov 16, 2012 7:54 am

"Reading" books in vanilla seems to be encouraging a quick routine of open, see if skill increases, shut again for many players - rather then encouraging them to actually read the book. Would it be possible to add a timer script to each page, so that you'd need to have each page of the book open for (for example) 5 seconds - enough time to actually read the book before the skill increases?
User avatar
Steve Fallon
 
Posts: 3503
Joined: Thu Aug 23, 2007 12:29 am

Post » Fri Nov 16, 2012 8:20 am

"Reading" books in vanilla seems to be encouraging a quick routine of open, see if skill increases, shut again for many players - rather then encouraging them to actually read the book. Would it be possible to add a timer script to each page, so that you'd need to have each page of the book open for (for example) 5 seconds - enough time to actually read the book before the skill increases?

I resemble that comment!

I did wonder about registering for the animation event that turned the page, assuming that's how it was done. I wouldn't know how to proceed though
User avatar
Tanya Parra
 
Posts: 3435
Joined: Fri Jul 28, 2006 5:15 am

Post » Fri Nov 16, 2012 8:01 pm

"Reading" books in vanilla seems to be encouraging a quick routine of open, see if skill increases, shut again for many players - rather then encouraging them to actually read the book. Would it be possible to add a timer script to each page, so that you'd need to have each page of the book open for (for example) 5 seconds - enough time to actually read the book before the skill increases?

While this sounds like a good idea, I'm not sure if it actually is. Maybe every once in a while as a reward to the voracious readers, but with anything approaching regularity it quickly gets old and people who aren't interested will just speed flip through pages anyway. Breadcrumbs are better than fish hooks. The more closely you try to regulate it to make people read, the fewer that will enjoy the act of reading, as a result of the fundamental attribution error so famous in psychology.
User avatar
SiLa
 
Posts: 3447
Joined: Tue Jun 13, 2006 7:52 am

Post » Fri Nov 16, 2012 12:04 pm

if you put RegisterForSingleUpdate in the OnRead block, it will create a new thread and wait until the book is closed to fire OnUpdate

Utility.Wait also works (waits until the book is closed before actually "waiting")
User avatar
Natalie J Webster
 
Posts: 3488
Joined: Tue Jul 25, 2006 1:35 pm

Post » Fri Nov 16, 2012 4:44 pm

if you put RegisterForSingleUpdate in the OnRead block, it will create a new thread and wait until the book is closed to fire OnUpdate

Utility.Wait also works (waits until the book is closed before actually "waiting")

This would still have the limitation that it doesn't work until you've left the inventory, if you've accessed the book from your menu, correct?
User avatar
Scott
 
Posts: 3385
Joined: Fri Nov 30, 2007 2:59 am

Post » Fri Nov 16, 2012 1:06 pm

yes it will wait until you are completely out of menu mode. i actually prefer this because when the OnUpdate block is run you are guaranteed to have the code run in its most current state with all variable/property values updated. that is something which cannot be guaranteed if you put the code on hold with a condition, while loop or utility.wait inside of the OnRead block
User avatar
abi
 
Posts: 3405
Joined: Sat Nov 11, 2006 7:17 am

Post » Fri Nov 16, 2012 8:19 pm

yes it will wait until you are completely out of menu mode. i actually prefer this because when the OnUpdate block is run you are guaranteed to have the code run in its most current state with all variable/property values updated. that is something which cannot be guaranteed if you put the code on hold with a condition, while loop or utility.wait inside of the OnRead block

Apologies for highjacking this thread slightly, i had encountered the issues described by Amethyst (my original post has been updated to reflect this), however i am trying to modify my onread events to incoporate Register for Single Update, however the update doesn't fire.
Spoiler
Event OnRead()  RegisterForSingleUpdate(5)EndEventEvent OnUpdate()if !NMQ001.IsComplete()  Player.AddSpell(CustomArmour)EndEvent



Can someone point out what i'm doing wrong, all my properties are correctly filled. If i change the script just purely to OnRead the spell is added to the player
User avatar
Elizabeth Davis
 
Posts: 3406
Joined: Sat Aug 18, 2007 10:30 am

Post » Fri Nov 16, 2012 6:52 pm

first of all you need to close your if condition with EndIf, secondly the register time (5 seconds) is kind of a long time. you only need it enough to force a new thread (0.2) should do fine

also you should consider putting a boolean guard or state change so that it doesnt continuously run the code each time the book is read
User avatar
WTW
 
Posts: 3313
Joined: Wed May 30, 2007 7:48 pm

Post » Fri Nov 16, 2012 10:02 am

first of all you need to close your if condition with EndIf, secondly the register time (5 seconds) is kind of a long time. you only need it enough to force a new thread (0.2) should do fine

also you should consider putting a boolean guard or state change so that it doesnt continuously run the code each time the book is read

Thanks Amethyst, the endif was just a typo, the script is on another pc,
Will give this a try
User avatar
Bethany Short
 
Posts: 3450
Joined: Fri Jul 14, 2006 11:47 am


Return to V - Skyrim