Aller au contenu

Photo

Looping Scripts


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

#1
Doc Valentine

Doc Valentine
  • Members
  • 9 messages
I have a feeling that I am going to be asking a lot of annoying NWN type scripting questions. Now that I have the basics of my script working, I was wondering if there is a way to loop a script. It seems like it should be pretty basic. I checked the creature_core script and I didn't see any onHeartbeat type events. Normally, I would just use ExecuteScript at the end of the script, but seeing as that has been depreciated, I'm not sure exactly how to do this.

#2
Craig Graff

Craig Graff
  • Members
  • 608 messages
DelayEvent is the function you want. You can look at pre410cr_genlock_emissary.nss for an example of this (though maybe not the most straightforward one).

#3
Nattfodd

Nattfodd
  • Members
  • 321 messages
The Event driven system should accomplish this kind of needs. Have you checked all possible EVENT_TYPE_*?
For the creatures, here http://social.biowar...Creature_events , you can find some events that engine sends to creature script. There is the HEART_BEAT event too.

Modifié par Nattfodd, 19 janvier 2010 - 01:34 .


#4
Doc Valentine

Doc Valentine
  • Members
  • 9 messages
Okay, first of all I would like to thank you both for that suggestion. I was able to get the script looping perfectly, and that will help much in the future. I have run into a situation however, it seems that now whenever my NPC opens a door durring the script process, he will complete the process, but no longer repeat it. Is there some way that I can make it so that he continues to repeat the script, even after interacting with other objects such as doors?

Here is the script so far:

#include "log_h"
#include "utility_h"
#include "wrappers_h"
#include "events_h"

void main()
{
  object oPerson = GetObjectByTag("dgman");
  object oWay1 = GetObjectByTag("per_way_1");
  object oWay2 = GetObjectByTag("per_way_2");
  object oWay3 = GetObjectByTag("per_way_3");
  object oWay4 = GetObjectByTag("per_way_4");
  object oWay5 = GetObjectByTag("per_way_5");
  object oWay6 = GetObjectByTag("per_way_6");
  object oWay7 = GetObjectByTag("per_way_7");
  object oWay8 = GetObjectByTag("per_way_8");
  location lPoint1 = GetLocation(oWay1);
  location lPoint2 = GetLocation(oWay2);
  location lPoint3 = GetLocation(oWay3); 
  location lPoint4 = GetLocation(oWay4);
  location lPoint5 = GetLocation(oWay5);
  location lPoint6 = GetLocation(oWay6);
  location lPoint7 = GetLocation(oWay7);
  location lPoint8 = GetLocation(oWay8);   
  event ev = GetCurrentEvent();
  int nEventType = GetEventType(ev);
  string sDebug;
  object oPC = GetHero();
  object oParty = GetParty(oPC);
  int nEventHandled = FALSE;
    object[] aoObject1 = GetNearestObject(oPerson, OBJECT_TYPE_PLACEABLE);
    command cUseObject = CommandUseObject(aoObject1[0], PLACEABLE_ACTION_OPEN);
 
    switch(nEventType)
    {
         case EVENT_TYPE_SPAWN:
         {   
   AddCommand (oPerson, CommandMoveToLocation (lPoint1, FALSE, FALSE), FALSE,
    FALSE, COMMAND_ADDBEHAVIOR_DONTCLEAR);
   AddCommand (oPerson, CommandMoveToLocation (lPoint2, FALSE, FALSE), FALSE,
    FALSE, COMMAND_ADDBEHAVIOR_DONTCLEAR);
   AddCommand (oPerson, CommandMoveToLocation (lPoint3, FALSE, FALSE), FALSE,
    FALSE, COMMAND_ADDBEHAVIOR_DONTCLEAR);
   AddCommand (oPerson, CommandMoveToLocation (lPoint4, FALSE, FALSE), FALSE,
    FALSE, COMMAND_ADDBEHAVIOR_DONTCLEAR);
   AddCommand (oPerson, CommandMoveToLocation (lPoint5, FALSE, FALSE), FALSE,
    FALSE, COMMAND_ADDBEHAVIOR_DONTCLEAR);
   AddCommand (oPerson, CommandMoveToLocation (lPoint6, FALSE, FALSE), FALSE,
    FALSE, COMMAND_ADDBEHAVIOR_DONTCLEAR);
   AddCommand (oPerson, CommandMoveToLocation (lPoint7, FALSE, FALSE), FALSE,
    FALSE, COMMAND_ADDBEHAVIOR_DONTCLEAR);
   AddCommand (oPerson, CommandMoveToLocation (lPoint8, FALSE, FALSE), FALSE,
    FALSE, COMMAND_ADDBEHAVIOR_DONTCLEAR);
             break;
         }      
    }
   

       
    if (!nEventHandled)
    {
        HandleEvent(ev, R"test.ncs");
    }
     
}  

#5
Craig Graff

Craig Graff
  • Members
  • 608 messages
You could set bStatic to TRUE, but really you are better off with something that reevaluates when a command is complete. The ambient system can do what you want, or you can use EVENT_TYPE_CUSTOM_COMMAND_COMPLETE. There was at least a brief time when in addition to setting AI_CUSTOM_AI_ACTIVE to 1, it was useful in certain situations to set AMBIENT_SYSTEM_STATE to 19, which may or may not still be the case (David Sitar would know, if he sees this).

#6
Doc Valentine

Doc Valentine
  • Members
  • 9 messages
The Ambient system does indeed seem to be the best way of making this work. However, it is very confusing to me. I took a look through the Wiki and it did a brief explanation of how to loop walking and how to set animation overrides for the character. But it did not really detail how I might have scripts that activate upon reaching a certain waypont, though I have seen a few functions for that when dealing with MovetoMultiLocation. So I guess if anyone knows the specific way in which I might do this, or knows of a tutorial I may have missed that will explain how to do this through the ambient system.



Thank you for all the help so far though Craig. I really do appreciate it

#7
BioSpirit

BioSpirit
  • Members
  • 261 messages

Craig Graff wrote...

DelayEvent is the function you want. You can look at pre410cr_genlock_emissary.nss for an example of this (though maybe not the most straightforward one).


What would it take to add a function "command CommandSignalEvent(event)" into the toolset. For an example in this particular case you need to know how long it takes to run the script in order to use DelayEvent(). Adding a SignalEvent() in a command queue would be more handy. I have used CommandUseAbility() to trigger EVENT_CUSTOM_COMMAND_COMPLETE but it isn't very intuitive approach.

#8
Nattfodd

Nattfodd
  • Members
  • 321 messages

Doc Valentine wrote...

The Ambient system does indeed seem to be the best way of making this work. However, it is very confusing to me. I took a look through the Wiki and it did a brief explanation of how to loop walking and how to set animation overrides for the character. But it did not really detail how I might have scripts that activate upon reaching a certain waypont, though I have seen a few functions for that when dealing with MovetoMultiLocation. So I guess if anyone knows the specific way in which I might do this, or knows of a tutorial I may have missed that will explain how to do this through the ambient system.

Thank you for all the help so far though Craig. I really do appreciate it


The lack of documentation in Toolset wiki is a known issue ;)

Both Ambient behaviour system or scripts, let you handle ambient animations of NPC creatures. You can choose according to your abilities. But both of them must follow some restricted rules.

The hardest of these rules is how to identify the animations that fulfill a custom sequence you want to do.

If you are lucky and not much exigent, you can find predefined ambient sequences into ambient_ai 2DA file with a little description. In that case you only need to set in the toolset area editor, two local variables of the creature: the AMBIENT_SYSTEM_STATE and the AMBIENT_ANIM_PATTERN with optionally AMBIENT_ANIM_FREQ (this is explained at http://social.biowar...bient_behaviour).

If you want, you can create a custom ambient_anim_patterns M2DA file (ambient_ai.xls into the source directory) to add a personalized sequence, choosing animations listed into ANIM_base, ANIM_combat or ANIM_placeables 2DAs. The previous link also explains how to set the fields of ambient_ai columns.

If you want more customization you can ask me and i can teach you how to identify the animations listed into ANIM_* 2DAs into the toolset (you will notice that the ANIM_* 2DA column called AnimName does not contain the name of the .ANI file) to let you see a preview of the animation.

#9
Craig Graff

Craig Graff
  • Members
  • 608 messages
Check out gentr_ambient.nss for more standard options.

#10
Nattfodd

Nattfodd
  • Members
  • 321 messages
Thanks i'll take a look.

I have a question: the low level functions are into script.ldf? There is a way to explore it without using the DAToolChest? I can't use it because it crash everytime.

#11
thebigMuh

thebigMuh
  • Members
  • 98 messages
You can extract script.ldf from the scripts.erf file in your install directory, it's a normal text file.



Ciao, muh!

#12
fluffyamoeba

fluffyamoeba
  • Members
  • 264 messages
Also look at the wiki, as all the scripts.ldf functions are in there

#13
Sunjammer

Sunjammer
  • Members
  • 925 messages
And of course there is the Lexicon's native functions category!

#14
Doc Valentine

Doc Valentine
  • Members
  • 9 messages
Well, after a days worth of tinkering, I have finally figured out how to work the heartbeat event on an NPC, or any object I guess. This is probably old news to most of you, but it took me a while to figure out. First of all, (from what I gathered) there isn't a heartbeat event innately set on the NPC, it has to be set via script either on the spawn event, or somewhere else, using this code:



void InitHeartbeat(



object oCreature, // object is self explanatory, the object to start the heartbeat for

float fInterval // the amount of time between heart beats



);



Now, the next part is also tricky because there are two heartbeat events, there is EVENT_TYPE_HEARTBEAT and EVENT_TYPE_HEARTBEAT2. EVENT_TYPE_HEARTBEAT2 is the one that will work with the script set above. Now, for the interval, I set it to the default NWN/Kotor heartbeat which is 6.0 seconds. Some situations may call for more or less, but I feel that's a pretty good start.



I'm hoping that by having the heartbeat set, the door issue will no longer be a problem. Before, I had a looping spawn script that got messed up when it was interrupted when the NPC opened a door that was blocking him. Since the heartbeat script activates every 6 seconds, interruptions shouldn't cause too much of an issue.



Either way, that's how it worked out for me.