OnActivate breaking script

Post » Sat Aug 14, 2010 12:40 pm

Okay, so I've had (most of) this script for a while, and I went back to adjust what topics are added when it's used:

begin artif_tools_journalshort dooncemessagebox "artif_tools_journal running!" ;runs *once*, should appear constantly!if (OnActivate == 1)	messagebox "Activating!" 	Activate	messagebox "Activated!"	if (doonce == 0)		messagebox "Doonce entered"		set doonce to 1		Journal artif_enable 5		player -> addtopic "Create Small Tools"		player -> addtopic "Create Wand"		messagebox "Topics added!"		stopscript artif_tools_journal	endifendifend artif_tools_journal


This script is attached to a book, and is supposed to add a journal entry and two topics when the player picks it up. The messageboxes were added while I tried to figure out where the script was breaking. At the moment, all that happens is that the "artif_tools_journal running!" box appears once when the player enters the cell, and then the book behaves like any book. The original script didn't have the messageboxes obviously; but the only change that should have been made was the player -> addtopic "Create Wand" line.

I've also been trying different approaches, and it seems like every time I do an OnActivate in a script on that book, it breaks. Once I remove the OnActivate it works. So how do the Bethesda scripts do this?
User avatar
Madison Poo
 
Posts: 3414
Joined: Wed Oct 24, 2007 9:09 pm

Post » Sat Aug 14, 2010 2:23 pm

begin artif_tools_journalshort doonceif (OnActivate == 1)     if (doonce == 0)              Set doonce to 1              Journal "artif_enable" 5	AddTopic "Create Small Tools"	AddTopic "Create Wand"             Activate    else             Activate    endifendifEnd

User avatar
Russell Davies
 
Posts: 3429
Joined: Wed Nov 07, 2007 5:01 am

Post » Sat Aug 14, 2010 10:04 pm

I went ahead and tried out that script as-is, with the same result. And when I seeded messageboxes in that, I got one "script running" message, and then it quit before getting inside the onactivate conditional. Like I said before, removing the onactivate check clears it up; but I can't figure out what's causing it to break there in the first place.
User avatar
Hot
 
Posts: 3433
Joined: Sat Dec 01, 2007 6:22 pm

Post » Sat Aug 14, 2010 10:41 pm

Activate is a whiny bheetch when it comes to books. Scratch it and work through OnPCAdd instead, for a one-time trigger you don't need anything more complex anyway. If you specifically want OnActivate to work, though, there's a script in the MSFD for that.
User avatar
Andrea P
 
Posts: 3400
Joined: Mon Feb 12, 2007 7:45 am

Post » Sat Aug 14, 2010 11:35 am

Books and scrolls need special scripting in order to work properly. The original MW scripted books are flaky at best. This script has never failed me though:

Begin PGA_SpellScrollShort OnPCEquipShort PCSkipEquipShort ActionFlagShort doOnce; PCSkipEquip is set to 1 every time the book is equipped from your inventory.If ( PCSkipEquip == 1 )	Set PCSkipEquip To 0	Set ActionFlag To 1	ReturnEndIf; These lines are important, otherwise the book cannot be picked up from the ground.If ( MenuMode == 1 )	ReturnEndIfIf ( ActionFlag == 1 )	If ( doOnce == 0 )		;Do your stuff here		Set doOnce To 1	Endif	Set ActionFlag To 0EndIf; For activating the book when it is placed in the game world.If ( OnActivate == 1 )	Set ActionFlag To 1	ActivateEndIfEnd


ActionFlag can go above or below the MenuMode return, depending on what you want to do.
User avatar
April D. F
 
Posts: 3346
Joined: Wed Mar 21, 2007 8:41 pm

Post » Sat Aug 14, 2010 8:59 am

The problem with checking for PCEquip or inventory is that this is supposed to fire when the player first reads the book, which is placed in the world! OnActivate isn't the only picky one... :P

I did get back the original script that used to work, and it's also stopped working. I'll have to think on this a bit, and figure out if there's some other way that makes sense in the context of the mod to add this journal entry. Would still like to know why the blasted thing stopped working, though...
User avatar
herrade
 
Posts: 3469
Joined: Thu Apr 05, 2007 1:09 pm

Post » Sat Aug 14, 2010 10:17 am

Check my script again. It checks for both OnActivate and OnPCEquip. The OnActivate block is at the bottom under everything else. It has to be under the menumode check or it won't work properly. You need the OnPCEquip block as well, because if the player picks up the book while menumode is open and drops it in inventory, they won't read the book and OnActivate will not register. This leaves a contingency if they do this and read the book later.
User avatar
marina
 
Posts: 3401
Joined: Tue Mar 13, 2007 10:02 pm

Post » Sat Aug 14, 2010 7:05 pm

Nice, I hadn't considered the possibility of them picking it up and dropping it in the inventory like that. Unfortunately, it *still* breaks for me once it reaches the onactivate check.
User avatar
Mr.Broom30
 
Posts: 3433
Joined: Thu Nov 08, 2007 2:05 pm

Post » Sat Aug 14, 2010 2:02 pm

Well, I'm still not sure why it broke, but it still works when I run off of the backup of the mod, before I made the change. Any hints on easy ways to combine the backup with the changes I've made since?
User avatar
GRAEME
 
Posts: 3363
Joined: Sat May 19, 2007 2:48 am

Post » Sat Aug 14, 2010 3:28 pm

You could delete the book and the script from the new plugin, and delete everything but the book and the script from the old one. Using something like TESAME, or EE, not the editor.

Then load them both up at the same time in the editor with either one active, and merge them.
User avatar
Marta Wolko
 
Posts: 3383
Joined: Mon Aug 28, 2006 6:51 am

Post » Sat Aug 14, 2010 6:41 pm

Here would be the form Bethesda used for The Pilgrim's Path. ...deceptively simple:

Begin AAABookSCIf ( GetJournalIndex "artif_enable" == 5 )	ReturnEndIfIf ( OnActivate == 1 )	AddTopic "Create Small Tools"	AddTopic "Create Wand"	Journal "artif_enable" 5	ActivateEndIfEnd

User avatar
Tyrone Haywood
 
Posts: 3472
Joined: Sun Apr 29, 2007 7:10 am

Post » Sat Aug 14, 2010 10:40 am

Okay, I stepped through the process again, and found the exact step that pushes the book script from functional to nonfunctional status. Starting out, I have this:
begin artif_tools_journalshort doonceif (OnActivate == 1)	Activate	if (doonce == 0)		set doonce to 1		Journal artif_enable 5		player -> addtopic "Create Small Tools"		stopscript artif_tools_journal	endifendifend


The journal entry gets added correctly, the dialogue option shows up fine, and if I do a 'player -> addtopic "Create Wand" ' in the console, that topic also becomes available and works as expected.

As soon as I update line 10 to this:
begin artif_tools_journalshort doonceif (OnActivate == 1)	Activate	if (doonce == 0)		set doonce to 1		Journal artif_enable 5		player -> addtopic "Create Wand"		stopscript artif_tools_journal	endifendifend


and make *no other changes*, any OnActivate on the book, and apparently anything involving the "Create Wand" topic, stops working. Even if I change the line back, it's broken. My guess is something is becoming corrupted somehow, but I can't get either EE or TESAME to work on my system, so this is tough to verify.

Anyone else run into something like this?
User avatar
Danger Mouse
 
Posts: 3393
Joined: Sat Oct 07, 2006 9:55 am

Post » Sat Aug 14, 2010 8:04 pm

You've made a change to dialogue which by itself could be grounds for seeming inconsistency. When a dialogue change is made, particularly when a deletion occurs, an entry is flagged for treatment but the operation isn't carried out 'on the fly' waiting instead for the next time the mod is reloaded. I don't know if that's what's happening in your case, but you could experiment with loading the mod again, make NO other changes, save it, then try running it again. You could also try writing the script fresh again, put BOTH addtopics in at once and see if they both come up.

The script I suggested above should work fine for your purposes. (I'm assuming you have only one copy of the book, is that right?). It worked fine in a little dummy mod I made. The journal was not updated nor were topics added until I picked up the book. The first time I picked up the book, both happened. Any subsequent activations of the book, whether from inventory or from the ground, saw the book operate normally.

Note in the example that 'Activate' follows all the other business, which I guess is key. Also note that having the operation happen only once is governed by the journal update, but could just as easily be governed by a 'DoOnce' variable. In that case, I'd reset the variable after the journal update and topic adds.

Finally, a word about form: Consider putting spaces around the parentheses. Consider removing spaces around the fix. In fact, I think you'll find the 'player ->' is not needed at all. Such changes won't make an apparent difference, but might have some subtle undertones.

Of course, make sure your topics are filtered properly in dialogue so that the characters you want to have it DO have it and that the topic is invisible simply because the wrong NPCs are speaking it.

And, as you are now no doubt aware, make a backup copy of your mod BEFORE making any changes to it. :)
User avatar
Ilona Neumann
 
Posts: 3308
Joined: Sat Aug 19, 2006 3:30 am

Post » Sat Aug 14, 2010 5:13 pm

Finally, a word about form: Consider putting spaces around the parentheses. Consider removing spaces around the fix. In fact, I think you'll find the 'player ->' is not needed at all. Such changes won't make an apparent difference, but might have some subtle undertones.

According to MSFD, the form used to write a script can indeed lead to strange problems, so you should indeed try these to fix your bug.
? Get used to always leaving spaces around parentheses and operators, sometimes it seems to cause problems if you don't: if ( variable == 1 ), not: if (variable==1). While this doesn’t matter most of the time it generates weird and almost untraceable errors sometimes, so you are much better off always leaving a space.
? The fix (->) is a little more complicated. If IDs are contained in quotes, you should not leave spaces around the fix: "Sirollus Saccus"->GetItemCount netch_leather_greaves. The above will work, but spaces around the fix would cause problems. (Thanks to Simpleton and DinkumThinkum for this info.) However, since it has also been reported that a lack of quotation marks can cause problems in combination with spaces round the fix, I'm going to recommend that you don't leave spaces round the fix at all (should be fine in all cases).

stopscript artif_tools_journal

The function stopscript doesn't have any effect when it is used in a local script (all the scripts that are attached to an activator, a NPC...) and it only works in global script. Instead, you can use something like 'if ( condition) - return - endif', which won't stop the script, but at least save a few FPS by preventing most of the script of running.
I would try something like that:
begin artif_tools_journalshort doonceif ( onactivate == 1 )	activate	if ( doonce == 0 )		set doonce to 1		Journal artif_enable 5		addtopic "Create Wand"	endifendifend

or with Stuporstar version:
Begin artif_tools_journalShort OnPCEquipShort PCSkipEquipShort ActionFlagShort doOnce; PCSkipEquip is set to 1 every time the book is equipped from your inventory.If ( PCSkipEquip == 1 )	Set PCSkipEquip To 0	Set ActionFlag To 1	ReturnEndIf; These lines are important, otherwise the book cannot be picked up from the ground.If ( MenuMode == 1 )	ReturnEndIfIf ( ActionFlag == 1 )	If ( doOnce == 0 )		Journal artif_enable 5		addtopic "Create Wand"		Set doOnce To 1	Endif	Set ActionFlag To 0EndIf; For activating the book when it is placed in the game world.If ( onactivate == 1 )	Set ActionFlag To 1	ActivateEndIfEnd

One more thing, each time you try a new version of your mod, you must do it with:
- a new game (maybe a little bit too much)
- with a savegame with which you have never used your mod before (the option I would prefer to use)
- you can also try to clean your savegame (use Wrye Mash for this) each time you upgrade your mod
User avatar
Roy Harris
 
Posts: 3463
Joined: Tue Sep 11, 2007 8:58 pm

Post » Sat Aug 14, 2010 2:00 pm

Indeed, the player is the only one that has a topic list which can be added to, so AddTopic is as automatically associated with the player as PlaceAtPC is.

And I can't help but wonder the reason for using a StopScript function on a local script. To the best of my knowledge, that function affects only global scripts, and has absolutely no effect whatsoever on a local script. Since this script is attached to a book, it's a local script and cannot be stopped using StopScript

Every script on every object which is currently loaded and in range of the player (same cell and 8 adjacent cells for exterior, same cell only for interiors) runs every frame. The game engine also runs every global script which is on the list of active global scripts. StartScript adds a script to this list. StopScript removes the script from that list. Note that it doesn't even stop the script from running during that frame... it just removes it from the list so it isn't run again next frame. Since It doesn't prevent a script attached to an object from running, it won't reduce script overhead, but telling the script engine every single frame to remove a script from the active global list that isn't there will certainly increase it.

That won't cause the problem you're having, but at the very least, it needlessly increases the size and complexity of the script. I doubt it would contribute very much to lag or reduce FPS by any noticeable amount unless you had many scripts doing it all at once, but it's a bad habit to get into.

[edit] Oops. Looks like Bjam covered that very well while I was stirring the rice for my General Tso's chicken. Oh well.
User avatar
jadie kell
 
Posts: 3497
Joined: Sat Jul 29, 2006 3:54 pm


Return to III - Morrowind