Aller au contenu

Photo

Script is running, even though the checks should fail


  • Veuillez vous connecter pour répondre
24 réponses à ce sujet

#1
LordNyvek

LordNyvek
  • Members
  • 109 messages
Okay, I load up my module, create a brand new character. I run it over to my trigger, and it triggers somehow. I have 2 checks that a brand new character should fail. Here's my code:

void main()
{
	object oPC = GetFirstPC(); // player
	object oKeyOfQuinari = GetObjectByTag("kod_plot_KeyOfQuinari"); // item needed to trigger the event
	int pashinScene = GetLocalInt(oPC, "pashinScene"); // int to determine if this has been triggered before
		
	if(GetLocalInt(oPC, "pashinScene") != 1) // if this is 1, then it's played before.  otherwise, play it.
	{
		if (GetFirstItemInInventory(oPC) == oKeyOfQuinari) // if the player has the music box, show the scene
		{
			ActionStartConversation(oPC, "pashin_cutscene", FALSE, FALSE, FALSE, FALSE); // scene to be played
			SetLocalInt(oPC, "pashinScene", 1); // once it's played, set the int to 1 so it doesn't play again
		}
	}
}

You can see what I'm trying to do in the comments. Basically, I wanna check an int that I place on the character. If it's 1, then nothing happens. If it's anything BUT 1, then do the next check. Next check is for an item in the inventory of the player. If it's there, play the scene and set the int to 1. If not, do nothing. However, on a brand new character where both of these checks should fail, the scene is still triggered. Thanks for any help.

#2
LordNyvek

LordNyvek
  • Members
  • 109 messages
On a side note, looking through some of the scripts that were provided for us, namely the "x2_inc_switches" file, I'm noticing something that to me seems really silly. There's a switch called "MODULE_SWITCH_ENABLE_TAGBASED_SCRIPT". Now, if this is set to TRUE, it disables execution of tagbased scripts. Shouldn't it be the opposite, based upon the name of the const? I mean, when I see MODULE_SWITCH_ENABLE_TAGBASED_SCRIPT = TRUE, I think "okay, this is enabled". But apparently I'm wrong in my thinking.



Anyway, sorry about the mini rant. Just trying to solve this issue and finding some strange things.

#3
Morbane

Morbane
  • Members
  • 1 883 messages
Try the script in the next post - it compiles but i did not test it ...

Hope it helps =]

Modifié par Morbane, 16 septembre 2010 - 03:05 .


#4
Morbane

Morbane
  • Members
  • 1 883 messages
#include "nw_i0_tool"
void main()
{
object oPC = GetFirstPC(); // player
//object oKeyOfQuinari = GetObjectByTag("kod_plot_KeyOfQuinari"); // item needed to trigger the event
//int pashinScene = GetLocalInt(oPC, "pashinScene"); // int to determine if this has been triggered before

if(GetLocalInt(oPC, "pashinScene") != 1) // if this is 1, then it's played before. otherwise, play it.
{

if (CheckPartyForItem(oPC, "kod_plot_KeyOfQuinari") == TRUE) // if the player has the music box, show the scene
{
ActionStartConversation(oPC, "pashin_cutscene", FALSE, FALSE, FALSE, FALSE); // scene to be played
SetLocalInt(oPC, "pashinScene", 1); // once it's played, set the int to 1 so it doesn't play again
}
}
}

Modifié par Morbane, 16 septembre 2010 - 03:11 .


#5
LordNyvek

LordNyvek
  • Members
  • 109 messages
Alright, so my original script up there seems too convoluted, at least in my eyes. So, what I've attempted (this is key word here) is this:



I created an int variable in the module properties called pashinScene (I assume this is a global variable, am I wrong in this?). I set this to 20 by default. Now, I've enabled tag based script switches, and created a script with the same name as the tag of my item, keyofquinari. This script *should* trigger when the item is acquired, and change pashinScene to 0(Using SetGlobalInt()). I changed the above script to be just a check if pashinScene was 0, and then run the Conversation and set pashinScene to 1.



Now, I load up my module to play. I run over the trigger, and nothing happens. As it should be. So, I acquire the item from a nearby chest. I run over the trigger again, and nothing happens? So confused because it *should* have worked. So, I reload the module to play and turn on debug mode to check my variables. I run DM_GetVarint pashinScene, and it's 0? Am I missing how DM_GetVarint is supposed to work? Is there a better way to check the variables? Thanks again!

#6
LordNyvek

LordNyvek
  • Members
  • 109 messages
I apologize, Morbane. I'd started typing the above post, but forgot to post. When I did, you'd already written yours. :(

#7
Morbane

Morbane
  • Members
  • 1 883 messages
To seem to be trying and that is great - scripting is confusing - no doubt.



You might want to take a look at this:

http://nwvault.ign.c...s.Detail&id=124

#8
Kaldor Silverwand

Kaldor Silverwand
  • Members
  • 1 585 messages
I have a simple campaign in the vault called the Silverwand Sample Campaign which was designed to help provide examples of how to do the basic things needed in most campaigns, like simple quests, checking for items, conversations, tag-based scripting, etc. Sometimes looking at simple working versions is helpful. That was my intent anyway.



Regards

#9
_Knightmare_

_Knightmare_
  • Members
  • 643 messages
Tag based scripting is turned on by default in NWN2 (you need to turn it on in NWN1, but that's a seperate game).

For the tag based script to fire when aquired, you need to name the script: i_TagOfItem_aq
So in this case you need to name the script: i_keyofquinari_aq

There's many ways to go about what you are needing to do via script, here's my adaption of your original script (compiles but not tested in game):

void main()
{
object oPC = GetFirstPC(); // player

if(GetLocalInt(oPC, "pashinScene") != 1) // if this is 1, then it's played before. otherwise, play it.
{
object oItem = GetFirstItemInInventory(oPC); // Check the first item in the PC's general Inventory
while(GetIsObjectValid(oItem)) // Loop/search though all items in player's general inventory
{
if (GetTag(oItem) == "oKeyOfQuinari") // if the player has the music box (if item has correct tag), show the scene
{
// Get the PC's current location
location lLoc = GetLocation(oPC);
// Spawn in an IPoint to officially have the conversation with
object oIP = CreateObject(OBJECT_TYPE_PLACEABLE, "plc_ipoint ", lLoc, FALSE, "IP_KeyOfQuinari");
// Assign the command to the IPoint to begin the conversation
AssignCommand(oIP, ActionStartConversation(oPC, "pashin_cutscene", FALSE, FALSE, FALSE, FALSE)); // scene to be played
SetLocalInt(oPC, "pashinScene", 1); // once it's played, set the int to 1 so it doesn't play again
return; // Exit the loop/script since we have done what we needed to do
}
// If the first item looked at does not have the correct tag, look at the next item, then the next, then the next, etc.
oItem = GetNextItemInInventory(oPC);
}
}
}

Using this script there should be no reason to set a global variable on the module or to use any tag-based scripting.

Modifié par _Knightmare_, 16 septembre 2010 - 04:14 .


#10
MasterChanger

MasterChanger
  • Members
  • 686 messages
Yeah, my take is that the reason you got the music box playing the first time is kinda funny. If the key was not placed anywhere yet, GetObjectByTag("kod_plot_KeyOfQuinari") would return OBJECT_INVALID. If the PC had nothing in their inventory yet, GetFirstItemInInventory(oPC) would also result in OBJECT_INVALID, so they would be equal!



I'd say either Morbane's suggestion of CheckPartyForItem or _KM_'s suggestion of looping through the inventory would be fine. And you want to check the tag, rather than finding the object by tag and then comparing the object itself for equality.

#11
LordNyvek

LordNyvek
  • Members
  • 109 messages

_Knightmare_ wrote...

Tag based scripting is turned on by default in NWN2 (you need to turn it on in NWN1, but that's a seperate game).


That's contrary to what the file x2_mod_def_load states. 

// * Item Event Scripts: The game's default event scripts allow routing of all item related events    
// * into a single file, based on the tag of that item. If an item's tag is "test", it will fire a    
// * script called "test" when an item based event (equip, unequip, acquire, unacquire, activate,...)  
// * is triggered. Check "x2_it_example.nss" for an example.    // * This feature is disabled by default.
SetModuleSwitch (MODULE_SWITCH_ENABLE_TAGBASED_SCRIPTS, TRUE);

This seems to jive with what I'd mentioned before, about what the x2_inc_switches file states:

//------------------------------------------------------------------------------
// * Setting this switch to TRUE will disable execution of tagbased scripts that are enabled
// * by default when using the standard module events (x2_mod_def_*)
//------------------------------------------------------------------------------
const string MODULE_SWITCH_ENABLE_TAGBASED_SCRIPTS = "X2_SWITCH_ENABLE_TAGBASED_SCRIPTS";

So, in order to actually enable it, you must change the TRUE to FALSE.  Which, as I stated before, was confusing to me.  But it's 6.30am and maybe I'm just going about this all wrong.  I do appreciate all the help and suggestions, but for right now, I'm gonna sleep, and hopefully look at this with rested eyes tomorrow.  Thanks again for all the help!

Modifié par LordNyvek, 16 septembre 2010 - 04:29 .


#12
MasterChanger

MasterChanger
  • Members
  • 686 messages
OK, I think there's a bit of verbal jujitsu going on in those comments in x2_inc_switches that is misleading unless you follow it exactly. Here's the full section:
//------------------------------------------------------------------------------
// * Setting this switch to TRUE will disable execution of tagbased scripts that are enabled
// * by default when using the standard module events (x2_mod_def_*)
//------------------------------------------------------------------------------
const string MODULE_SWITCH_ENABLE_TAGBASED_SCRIPTS = "X2_SWITCH_ENABLE_TAGBASED_SCRIPTS";

//------------------------------------------------------------------------------
// * Only applies if MODULE_SWITCH_ENABLE_TAGBASED_SCRIPTS is true.
// This switch determines which type of tagbased scrtipting to use 
// (used in module events g_mod_*, x2_s3_hitcastspell, and x2_inc_spellhook)
// FALSE = use X2 version wherein all item events are in 1 script.      
// TRUE = use seperated scripts named "i_<tag>_<2 letter postfix>"
//------------------------------------------------------------------------------
const string MODULE_SWITCH_ENABLE_SEPERATE_ITEM_SCRIPTS = "NWN2_SEPERATE_ITEM_SCRIPTS";

My understanding is that the "x2 version" referred to here is what is now called "NWN1-style" as opposed to "NWN2-style" tag-based scripting. The difference is explained here. The NWN2 style would be the i_<tagofitem>_<eventsuffix>.

Not sure if this clears it up or not.

#13
_Knightmare_

_Knightmare_
  • Members
  • 643 messages
It could very well be that the function description was written in NWN1 (way before NWN2 was created) and just transferred between the games when NWN2 was developed (a large majority of the script functions fall into this category). For whatever reason the description was not updated for NWN2 (it's giving NWN1 instructions).

Anyway, I know for certain that tag-based scripts do work with the stock scripts/settings NWN2 comes with. I have written many of them and have never changed any lines in the x2_inc_switches script. I suggest returning any changes you made there to their original values/settings.

Modifié par _Knightmare_, 16 septembre 2010 - 06:18 .


#14
Morbane

Morbane
  • Members
  • 1 883 messages
Knightmare is absolutely correct. Nothing needed to be changed to use tag-based scripts.



Try this: http://pastebin.myrror.net/2704

#15
Lugaid of the Red Stripes

Lugaid of the Red Stripes
  • Members
  • 955 messages
The reason the function description wasn't changed is because they can still function that way in NWN2, setting the x2 module variables still allows you to use NWN1-style tag-based scripts. I use them instead of the NWN2-style scripts, simply because I like having a single script to handle all the different events.

#16
LordNyvek

LordNyvek
  • Members
  • 109 messages
First off, it came to my attention that "kod_plot_key_of_quinari" might be too long of a name for the switch to work. Something about 16 characters max. So, I changed the tag to "musicbox".



Just to be clear, I was never modifying x2_inc_switches. I modified x2_mod_def_load to change MODULE_SWITCH_ENABLE_TAGBASED_SCRIPTS = FALSE (instead of TRUE) and MODULE_SWITCH_ENABLE_SEPERATE_ITEM_SCRIPTS = FALSE (instead of TRUE). And that was causing my script (named "musicbox") not to work.



So, based on comments here, I reverted back to the default On Module Load Script (x2_mod_def_load). I changed my script name to "i_musicbox_aq", and added the code from Morbane's pastebin. Compiled and saved. I also got rid of my global variable, based upon the comments above. Ran my module, still no joy. I'm not giving up. In fact, I'm probably doing something REALLY silly that I'm missing. :(

#17
Morbane

Morbane
  • Members
  • 1 883 messages
Try changing this line:

AssignCommand(oItem, ActionStartConversation(oPC, "pashin_cutscene", FALSE, FALSE, FALSE, FALSE));



To:

AssignCommand(oPC, ActionStartConversation(oPC, "pashin_cutscene", FALSE, FALSE, FALSE, FALSE));



The PC will be talking to themself but it might help...

#18
Kaldor Silverwand

Kaldor Silverwand
  • Members
  • 1 585 messages
Don't expect too much accuracy in comments from people who don't know how to spell separate, default, and acquire.



One reason to use NWN2's version of tag-based scripting is that it allows people to import their own tag-based items into your module and have them work properly. I know of one person that wasn't happy that my Werewolf ring didn't work in someone else's module and the reason was that the module author used the NWN single file method. The NWN single file method is restrictive.



For debugging I suggest you simplify what you are doing and only add additional functions when you are sure something is working. First just have the acquire script do something very simple so that you can be sure that it is fired correctly when the item is acquired. Then add more complex functionality.



Regards

#19
_Knightmare_

_Knightmare_
  • Members
  • 643 messages

Kaldor Silverwand wrote...

Don't expect too much accuracy in comments from people who don't know how to spell separate, default, and acquire.


Yeah, and don't trust them before the second cup of morning coffee either! Posted Image

#20
LordNyvek

LordNyvek
  • Members
  • 109 messages
Okay. Here's an update to what's happening. I changed the i_musicbox_aq to just give some xp. This worked. It was brilliant. So, I changed it to instead of give xp, set a local int on the player:



SetLocalInt(oPC, "pashinScene", 0);



Now, if you guys remember the original post, I was getting the trigger to happen no matter what happened. So, the trigger script never changed. However, it won't trigger now.



void main()

{

object oPC = GetFirstEnteringPC(); // player



if (GetLocalInt(oPC, "pashinScene") == 0)

{

ActionStartConversation(oPC, "pashin_cutscene", FALSE, FALSE, FALSE, FALSE); // scene to be played

SetLocalInt(oPC, "pashinScene", 1); // once it's played, set the int to 1 so it doesn't play again

}

}



Essentially, what this cutscene does is show different points of a city while explaining things to the player. This worked before, even when I didn't want it to. Now, it doesn't work at all. Again, thank you to any and all who have helped, and continue to help.

#21
LordNyvek

LordNyvek
  • Members
  • 109 messages
Is it me, or is the BBCode on these forums useless?


#22
_Knightmare_

_Knightmare_
  • Members
  • 643 messages
Yes, the BBCode is pretty useless here.

What script event are you trying to fire the script from? GetFirstEnteringPC() only is useful when fired from an area's OnClientEnter and is really used to loop through the entering PCs. Try this version below, it is essentially the same but just adds in some feedback float text on the PC so you can see what parts of the script (if any) actually fire off. If you get no feedback text at all, then the whole script is not firing off:

void main()
{
object oPC = GetFirstPC(TRUE); // player's originally created character

FloatingTextStringOnCreature("Script fired off!", oPC); // Debug Message

if (GetLocalInt(oPC, "pashinScene") == 0)
{
FloatingTextStringOnCreature("pashinScene == 0", oPC); // Debug Message

ActionStartConversation(oPC, "pashin_cutscene", FALSE, FALSE, FALSE, FALSE); // scene to be played
SetLocalInt(oPC, "pashinScene", 1); // once it's played, set the int to 1 so it doesn't play again
}
}

I usually leave any Debug lines in the script even after I am finished using them, you can just comment them out when things work correctly. However, later on when something seems to be messed up, you can just uncomment the debug strings and again see where things are getting messed up.

Warning - only 1 cup of coffee so far... Posted Image

#23
LordNyvek

LordNyvek
  • Members
  • 109 messages
HAHAHAHA, remember when I told you guys I was probably doing something REALLY silly?! I was checking to see if pashinScene == 0! All variables that haven't ever been set == 0, apparently. When I changed GetFirstEnteringPC() to GetFirstPC(), the trigger would happen even if I hadn't found the time to set the local int to 0 (leading me to assume the variables thing). Soooo... I changed the items script to set the int to 1, and for the trigger to check that it equals 1, if it does, fire the conversation and set the variable to equal 2. Now everything is hunky fracking dory. :) Thanks guys, for all your help and support through this. :) I most assuredly learned something new today.

#24
_Knightmare_

_Knightmare_
  • Members
  • 643 messages

LordNyvek wrote...

HAHAHAHA, remember when I told you guys I was probably doing something REALLY silly?! I was checking to see if pashinScene == 0! All variables that haven't ever been set == 0, apparently. When I changed GetFirstEnteringPC() to GetFirstPC(), the trigger would happen even if I hadn't found the time to set the local int to 0 (leading me to assume the variables thing). Soooo... I changed the items script to set the int to 1, and for the trigger to check that it equals 1, if it does, fire the conversation and set the variable to equal 2. Now everything is hunky fracking dory. :) Thanks guys, for all your help and support through this. :) I most assuredly learned something new today.


Just to help you clarify:

All never set integer variables default starting at 0
All never set float variables default starting at 0.0 (which of course is the same as 0)
All never set string variables default starting at "" (an empty string).

Feedback text strings should be one of the first things you do when trying to debug a script. It will tell you when something is firing off, if something is firing but should not be, you can have it return the detected variables and see if they are what you expect them to be, etc. Overall a very useful habit to get in to. Perhaps I should add a section into my Scripting For Noobs tutorial that talks about doing that...

Modifié par _Knightmare_, 19 septembre 2010 - 02:37 .


#25
LordNyvek

LordNyvek
  • Members
  • 109 messages

_Knightmare_ wrote...

Just to help you clarify:

All never set integer variables default starting at 0
All never set float variables default starting at 0.0 (which of course is the same as 0)
All never set string variables default starting at "" (an empty string).


Right, what you said. :)  It's 4.30am, not only have I NOT had coffee, I've had no sleep, lmao.

Modifié par LordNyvek, 19 septembre 2010 - 02:35 .