Aller au contenu

Photo

Aborting a delayed command


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

#1
Tchos

Tchos
  • Members
  • 5 063 messages
Is it possible to cancel commands that were issued with DelayCommand?  I tried ClearAllActions(), but that didn't seem to help.

#2
Darin

Darin
  • Members
  • 282 messages
You could use a wraper function with conditionals that you delay, so after fDelay seconds it first checks something then runs the command (such as GetIsAlive(oTarget) or some such nonsense). Depends what you want to do.

#3
Tchos

Tchos
  • Members
  • 5 063 messages
What's going on is that an NPC has some barks that she speaks with delayed commands as she roams waypoints. If the player interrupts her, she returns to the last waypoint and resumes her barks from what she was saying at that point. However, the delayed barks from before are still firing between the new ones, and it's the old ones I want to stop.

#4
ColorsFade

ColorsFade
  • Members
  • 1 270 messages
The solution might be to get rid of the delay and use a HB script instead, with a flag setting and a counter/timer to fire off the barks. When the creature is interrupted, the flag flips and the barks don't fire. When the interruption is over, the NPC travels back to the WP, and at that point the flag flips back on and the barks can resume every x seconds.

If she's walking a WP and you're using a HB, you could even specify which barks to fire between which waypoints.

#5
Tchos

Tchos
  • Members
  • 5 063 messages
That came to mind, but the whole thing is already in place and functioning with this system, so if there's a way to cancel a delayed command, it would be much simpler to do that than to recode the whole thing.

#6
ColorsFade

ColorsFade
  • Members
  • 1 270 messages
Don't think you can cancel delayed commands. They appear to be fire and forget.

The only other thing I can think of is to use a gc conditional on the barkstring on the conversation to check whether that bark is "valid" or not based on some condition. You need a way for a conversation conditional to cancel the bark line.

I'm not privy to all your code details, but here's something I'm imagining: Suppose each time the PC "interrupts" the character it causes a counter on the character to increment. When you assign the delayed commands you also assign a value to check (so you're just passing one additional parameter in whatever function you're calling).

So, when the character is first loaded into the area the counter is zero. All your delayed commands are assigned with a zero as well

DelayCommand(10.0f, DoMyFunction(count));

Inside the conversation gc you're checking the local int of the creature to see if it matches the value passed to DoMyFunction. If they don't match, you don't fire the bark.

Each time the PC interrupts the creature, the counter is incremented. So the old barks are firing with a parameter of zero, but the internal counter on the creature is now 1. The call returns instead of calling the DoConversation method (or whatever you're using).

Each subsequent time the PC "interrupts" the creature, the counter is incremented, and older barks won't fire.

#7
Tchos

Tchos
  • Members
  • 5 063 messages
It's not a conversation -- it's a series of delayed SpeakStrings which are enqueued at each waypoint she passes using the walkwaypoint system. I didn't want to have to convert them to a switch in her heartbeat (her heartbeat has the code that interrupts her movement and speech based on a condition), but if no cancellation ability exists, I may have to.

#8
diophant

diophant
  • Members
  • 116 messages
I woul follow the suggestion of EpicFetus. As wrapper, you could use something like this:
void barkstringWrapper(string s, int i)
{
  if (GetLocalInt(OBJECT_SELF, "iBarkstring") == i)
    SpeakString(s);
}
To cancel the delayed command, simply increase the local variable iBarkstring.

EDIT: and, of course, call it with 
DelayCommand(delay, brakstringWrapper("whatever", GetLocalInt(OBJECT_SELF, "iBarkstring"));

Modifié par diophant, 08 juillet 2013 - 04:24 .


#9
Tchos

Tchos
  • Members
  • 5 063 messages
Ah, I think I see now. This could work. I'll try it.

#10
ColorsFade

ColorsFade
  • Members
  • 1 270 messages
Yeah, same ideas as what I'm proposing, just without the conversation file.

You have to check against a variable to determine validity of an action (speak, DoConversation, whatever). Incrementing the counter and using it as a comparison point prevents old delayed commands from firing.

#11
Tchos

Tchos
  • Members
  • 5 063 messages
This accomplished the task. I tested it with many interruptions. I've put all three of your names in the script for the assistance. Thanks!

#12
ColorsFade

ColorsFade
  • Members
  • 1 270 messages
LOL. too kind Tchos.

Glad it worked! :-)

#13
Morbane

Morbane
  • Members
  • 1 883 messages
 @Tchos,
would you mind posting an example of your working script?
I get the concept and use wrappers all the time - just curious how your code looks.
:innocent:
Thanks,Mor

#14
Tchos

Tchos
  • Members
  • 5 063 messages
Certainly:

// This function suggested by EpicFetus, ColorsFade, and Diophant
void SpeakStringWrapper(string sBark, int i)
{
  if (GetLocalInt(OBJECT_SELF, "iBarkstring") == i)
    SpeakString(sBark);
}

void main()
{
int iCurrentWP = GetCurrentWaypoint();// the waypoint we just arrived at
//FaceAndPause (iCurrentWP, 1.0); // causes NPC to face direction of WP and wait 1 second
int iNode = 0;

switch (iCurrentWP)
    {
    case 1:
        iNode = GetLocalInt(OBJECT_SELF, "iBarkstring");
        SpeakStringWrapper("Sample string 1", iNode);
        DelayCommand(7.0, SpeakStringWrapper("Sample string 2", iNode));
        DelayCommand(14.0, SpeakStringWrapper("Sample string 3", iNode));
        FaceAndPause (iCurrentWP, 6.0);
        break;

    [more cases]

    }
}
//end

Modifié par Tchos, 20 juillet 2013 - 12:01 .


#15
Tchos

Tchos
  • Members
  • 5 063 messages
Oh, and importantly, there's this code in the section that interrupts the NPC:

int iNode = GetLocalInt(OBJECT_SELF, "iBarkstring");
iNode++;
SetLocalInt(OBJECT_SELF, "iBarkstring", iNode);


#16
Morbane

Morbane
  • Members
  • 1 883 messages

Tchos wrote...

Oh, and importantly, there's this code in the section that interrupts the NPC:

int iNode = GetLocalInt(OBJECT_SELF, "iBarkstring");
iNode++;
SetLocalInt(OBJECT_SELF, "iBarkstring", iNode);


this bit solved a huge problem - go figure, I ask for one thing and get twice the knowledge :wizard:

THANKS Tchos!

I appreciate your sharing :D