Is it possible to cancel commands that were issued with DelayCommand? I tried ClearAllActions(), but that didn't seem to help.
Aborting a delayed command
Débuté par
Tchos
, juil. 08 2013 10:36
#1
Posté 08 juillet 2013 - 10:36
#2
Posté 08 juillet 2013 - 12:26
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
Posté 08 juillet 2013 - 12:43
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
Posté 08 juillet 2013 - 02:25
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.
If she's walking a WP and you're using a HB, you could even specify which barks to fire between which waypoints.
#5
Posté 08 juillet 2013 - 03:11
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
Posté 08 juillet 2013 - 04:08
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.
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
Posté 08 juillet 2013 - 04:20
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
Posté 08 juillet 2013 - 04:22
I woul follow the suggestion of EpicFetus. As wrapper, you could use something like this:
EDIT: and, of course, call it with
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
Posté 08 juillet 2013 - 04:28
Ah, I think I see now. This could work. I'll try it.
#10
Posté 08 juillet 2013 - 04:33
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.
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
Posté 08 juillet 2013 - 05:04
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
Posté 08 juillet 2013 - 05:14
LOL. too kind Tchos.
Glad it worked! :-)
Glad it worked! :-)
#13
Posté 19 juillet 2013 - 11:49
@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
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
Posté 19 juillet 2013 - 11:58
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
Posté 20 juillet 2013 - 12:09
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
Posté 20 juillet 2013 - 05:24
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
THANKS Tchos!
I appreciate your sharing





Retour en haut







