Author Topic: Canceling a delayed AssignCommand  (Read 419 times)

Legacy_Kato -

  • Hero Member
  • *****
  • Posts: 747
  • Karma: +0/-0
Canceling a delayed AssignCommand
« on: November 15, 2011, 01:04:26 am »


               Hi,

Since ClearAllActions() only cancels non-delayed standard actions, how can one cancel a delayed AssignCommand, knowing that the command is a standard function(not an Action* one)? Would it make sense to pass the delayed command as an argument to ActionDoCommand(), so that it can be cancelled anytime with ClearAllActions()?

Hopefully this not unclear, thanks for reading.


Kato 
               
               

               
            

Legacy_FunkySwerve

  • Hero Member
  • *****
  • Posts: 2325
  • Karma: +0/-0
Canceling a delayed AssignCommand
« Reply #1 on: November 15, 2011, 01:30:33 am »


               Pass a check along with the commands, which returns the delayed function if a condition is met. It can be as simple as a variable set on an object, which you can set at any point, 'cancelling' the actions.

Funky
               
               

               
            

Legacy_Kato -

  • Hero Member
  • *****
  • Posts: 747
  • Karma: +0/-0
Canceling a delayed AssignCommand
« Reply #2 on: November 15, 2011, 01:55:39 am »


               

FunkySwerve wrote...

Pass a check along with the commands, which returns the delayed function if a condition is met. It can be as simple as a variable set on an object, which you can set at any point, 'cancelling' the actions.

Just to make sure I understand: You mean that nothing will happen when the delayed command is executed if a given condition is not met? I guess that the delayed call itself staying in memory up to the delai expiration is not something to worry about, then?
               
               

               


                     Modifié par Kato_Yang, 15 novembre 2011 - 01:59 .
                     
                  


            

Legacy_FunkySwerve

  • Hero Member
  • *****
  • Posts: 2325
  • Karma: +0/-0
Canceling a delayed AssignCommand
« Reply #3 on: November 15, 2011, 05:46:39 am »


               That's correct. In cases like this there's not much you can do to cancel the DelayCommand itself, UNLESS you want to have create a special object to run it, and delete that object (meaning it can no longer perform the DC). I have no idea if that would actually create a savings, however, so I wouldn't bother.

Funky
               
               

               
            

Legacy_Kato -

  • Hero Member
  • *****
  • Posts: 747
  • Karma: +0/-0
Canceling a delayed AssignCommand
« Reply #4 on: November 15, 2011, 05:56:12 am »


               Okay tyvm Funky.

Kato
               
               

               
            

Legacy_Lord Sullivan

  • Hero Member
  • *****
  • Posts: 671
  • Karma: +0/-0
Canceling a delayed AssignCommand
« Reply #5 on: November 15, 2011, 09:31:50 am »


               One of the ways to go about it would be to put your conditional code in a separate script and
make the DelayCommand( time, execute script);

This way the delay is in motion until the command execution still, but the condition code will
be the deciding factor on "IF (condition) THEN {execute this code}"
               
               

               
            

Legacy_Shadooow

  • Hero Member
  • *****
  • Posts: 7698
  • Karma: +0/-0
Canceling a delayed AssignCommand
« Reply #6 on: November 15, 2011, 01:44:06 pm »


               here is a sample code how to cancel delayed action/function for specific target

Example presumes there are two triggers, when PC enters trigger A he have to get to the trigger B within 60seconds otherwise guards will find him and send to jail

code for trigger A:

void DoSomething(object oPC)
{
 if(GetLocalInt(OBJECT_SELF,"DoSomething_"+ObjectToString(oPC)))
 {
 //cancel the teleport, PC made it in time
 return;
 }
//actual code to do something, like teleport to prison
AssignCommand(oPC, ClearAllActions());
AssignCommand(oPC, ActionJumpToObject(GetObjectByTag("JAIL")));
}

void main()
{
object oPC = GetEnteringObject();
DelayCommand(60.0, DoSomething(oPC));
}


code for trigger B

void main()
{
object oPC = GetEnteringObject();
object triggerA = GetObjectByTag("TRIGGER_A");
//cancel delay on trigger A from trigger B
SetLocalInt(triggerA,"DoSomething_"+ObjectToString(oPC),-1);
}


               
               

               


                     Modifié par ShaDoOoW, 15 novembre 2011 - 01:44 .
                     
                  


            

Legacy_Kato -

  • Hero Member
  • *****
  • Posts: 747
  • Karma: +0/-0
Canceling a delayed AssignCommand
« Reply #7 on: November 15, 2011, 05:03:22 pm »


               Thank you all for the infos. My main concern was to remove the delayed call itself from memory at any given time, just like ClearAllActions() removes the action from the queue, so although it does not seem to be possible once DelayCommand() has been called, the proposed workarounds will be quite sufficient(I must admit I'm a fanatic of speed and performance, but I'm working on a cure lol). 

Kato
               
               

               


                     Modifié par Kato_Yang, 15 novembre 2011 - 05:14 .
                     
                  


            

Legacy_Shadooow

  • Hero Member
  • *****
  • Posts: 7698
  • Karma: +0/-0
Canceling a delayed AssignCommand
« Reply #8 on: November 15, 2011, 05:59:55 pm »


               Then if you create an object that will run the delaycommand itself and you destroy it like Funky suggest, you get exactly what you need. However I don't think that would improve efficieny as creating and destroying objects probably more CPU intensive than delay itself.
               
               

               
            

Legacy_WhiZard

  • Hero Member
  • *****
  • Posts: 2149
  • Karma: +0/-0
Canceling a delayed AssignCommand
« Reply #9 on: November 16, 2011, 12:56:52 am »


               Note: this can also be extended to thing you wouldn't normally think could be interrupted.

For example if I wanted in certain cases to halt an effect from its scheduled expiring, and have it expire later, I could alter such a script.

The unaltered script:
Effect eEffect = (Whatever);
ApplyEffectToObject(DURATION_TYPE_TEMPORARY, eEffect, oObject, 99.0);

Could be rewritten to:
Effect eEffect = (Whatever);
ApplyEffectToObject(DURATION_TYPE_PERMANENT, eEffect, oObject);
DelayCommand(99.0, CustomCommandRemoveEffect(oObject, eEffect));

This altered way can allow for the effect's duration to be extended so that it is removed later provided certain custom criteria are met.  And since the effect is being cycled through delay, you don't need to search the character for it; you already have it and can simply remove it any time the delayed command is executed with RemoveEffect().
               
               

               
            

Legacy_Kato -

  • Hero Member
  • *****
  • Posts: 747
  • Karma: +0/-0
Canceling a delayed AssignCommand
« Reply #10 on: November 16, 2011, 01:32:13 am »


               True, nice approach WhiZard, ty. '<img'>


Kato
               
               

               
            

Legacy_Shadooow

  • Hero Member
  • *****
  • Posts: 7698
  • Karma: +0/-0
Canceling a delayed AssignCommand
« Reply #11 on: November 16, 2011, 03:41:48 am »


               

WhiZard wrote...

Note: this can also be extended to thing you wouldn't normally think could be interrupted.

For example if I wanted in certain cases to halt an effect from its scheduled expiring, and have it expire later, I could alter such a script.

The unaltered script:
Effect eEffect = (Whatever);
ApplyEffectToObject(DURATION_TYPE_TEMPORARY, eEffect, oObject, 99.0);

Could be rewritten to:
Effect eEffect = (Whatever);
ApplyEffectToObject(DURATION_TYPE_PERMANENT, eEffect, oObject);
DelayCommand(99.0, CustomCommandRemoveEffect(oObject, eEffect));

This altered way can allow for the effect's duration to be extended so that it is removed later provided certain custom criteria are met.  And since the effect is being cycled through delay, you don't need to search the character for it; you already have it and can simply remove it any time the delayed command is executed with RemoveEffect().

Except that if the character logs out he have the effect indefinitely, but it does work and the issue I pointed out could be handled in OnClientEnter event like remove everything with id of -1 and permanent duration.
               
               

               


                     Modifié par ShaDoOoW, 16 novembre 2011 - 03:42 .
                     
                  


            

Legacy_FunkySwerve

  • Hero Member
  • *****
  • Posts: 2325
  • Karma: +0/-0
Canceling a delayed AssignCommand
« Reply #12 on: November 16, 2011, 05:37:59 am »


               You'd be better off timestamping in that instance, if feasible. Really, though, I wouldn't advocate that approach, for the reason Shad points to. If you're that eager to play with effect durations, there's always nwnx_structs' GetEffectDuration/Remaining functions (linux only, but hey).

Funky
               
               

               
            

Legacy_Kato -

  • Hero Member
  • *****
  • Posts: 747
  • Karma: +0/-0
Canceling a delayed AssignCommand
« Reply #13 on: November 16, 2011, 06:28:05 am »


               

ShaDoOoW wrote...
Except that if the character logs out he have the effect indefinitely...


Thanks for mentioning this, ShadoOow


Kato