Aller au contenu

Photo

GetCurrentAction() returning ACTION_INVALID when object is moving.


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

#1
M. Rieder

M. Rieder
  • Members
  • 2 530 messages
Here is my script:

55if ((nOnOff == 0) && (nAbsoluteTime >= nTimeDisappear)&&
 56 (oDisappearWPT != OBJECT_INVALID))
 57{
 58AssignCommand (OBJECT_SELF,ActionForceMoveToLocation(lDisappearWPT));
 59int nCurrentAction = GetCurrentAction();
 60FloatingTextStringOnCreature(IntToString(nCurrentAction),GetFirstPC());
  61while (nCurrentAction == ACTION_MOVETOPOINT)
  62{
  63lCurrentLocation = GetLocation(OBJECT_SELF);
  64float fDistance = GetDistanceBetween(OBJECT_SELF,oDisappearWPT);
  65string sDistance = FloatToString(fDistance);
  66FloatingTextStringOnCreature(sDistance,GetFirstPC());
  67FloatingTextStringOnCreature("in_loop",GetFirstPC()); 
  68if (fDistance < 1.0)
  69 {
   70ApplyEffectToObject(DURATION_TYPE_PERMANENT,eSupernaturalScale,OBJECT_SELF);
  71 }
   72nCurrentAction = GetCurrentAction();
   
 73 }
 74SetLocalInt(OBJECT_SELF,"OnOff", 1);
 75}



Here is my problem:

The script will not enter the while loop at line number 61 because GetCurrentAction() at line 59 contiually returns ACTION_INVALID.

This is despite the fact that when I run the script, I can see the  NPC move to the designated waypoint, while the floating string is over my character showing the number for inavlid action.

I am absolutely stumped. Any suggestions.

I have not posted the entire script and if need be, I will. 

Modifié par M. Rieder, 28 juillet 2010 - 02:07 .


#2
SkywingvL

SkywingvL
  • Members
  • 351 messages
You probably don't want to write code like that. Remember that action queue actions execute asynchronously -- they only 'run' after your script returns. You can't structure a busy loop that simply tests for progress along movement like that as the object won't make forward progress until your script has returned. (This may include not even having the action queue entry you have added to the event queue set as the 'current action'.)

Modifié par SkywingvL, 28 juillet 2010 - 02:31 .


#3
M. Rieder

M. Rieder
  • Members
  • 2 530 messages

SkywingvL wrote...

You probably don't want to write code like that. Remember that action queue actions execute asynchronously -- they only 'run' after your script returns. You can't structure a busy loop that simply tests for progress along movement like that as the object won't make forward progress until your script has returned. (This may include not even having the action queue entry you have added to the event queue set as the 'current action'.)


I want the NPC to walk to a point then have an effect applied to them after they reach that point.  What are some good ways to script this?

Also, is there a resource that explains how the action cue works.  I do not fully understand it and it is making scripting difficult.

thanks for the help.

#4
diophant

diophant
  • Members
  • 116 messages
The action queue is, as the name says, a queue. In your script, you can add actions at the end of the queue. This does not change immediately the action of the NPC. The NPC always takes the first action from the queue, and performs it until it is completely finished. Then, it takes the next action from the queue. If the queue is empty, the NPC just stands there, doing nothing. There are a few more important things to know:
- The NPC does not take a new action from the queue during the execution of a script, even not when he has no current action (this was your problem). In this case, the new action is started immediately after the script finished.
- You can clear the action queue with ClearAllActions(); be aware, some of the default scripts do this, thus some of the actions you assigned never get executed. Imagine you assigned the NPC to walk towards you with ActionMoveToObject, and then to start a conversation with ActionStartConversation(). On his way, he meets some hostile critters, his perception script fires, and then the combat AI starts. The ActionStartConversation is in the queue, gets cancelled by a ClearAllActions() from the AI, and the convo never happens.
- Custom animations are not actions. You can put them into the action queue with ActionDoCommand(PlayCustomAnimation(...)), but the NPC does not wait with his next action until the animation ends. You can achieve this by adding the ActionWait with the correct time after the animation.
- Action queues are not stored when the game is saved.

Back to your problem: It depends on what you want to achieve. If it is for a cutscene, and cannot get interrupted, just add both actions:

ActionForceMoveToLocation(lDisappearWPT);
ActionDoCommand(ApplyEffectToObject(DURATION_TYPE_PERMANENT,eSupernaturalScale,OBJECT_SELF));

Btw. you only need AssignCommand when the actions should go to the queue of anyone else than OBJECT_SELF.

If the actions could get interrupted, and it's crucial that all of them will be performed, I normally use a state based system. Give the NPC a local integer called iState which stores the state of its current actions. Hanging around would be 0, on the way to the location 1, and being there would be 2. Now, check in the heartbeat script what the NPC is currently doing, and assign what he should do next. Your script might look something like this :

// don't stop the NPC from doing something useful, e.g., do not interrupt a fight
if (GetCurrentAction() != ACTION_INVALID)
    return;
int iState = GetLocalInt(OBJECT_SELF, "iState");
if (iState == 1)       // NPC should walk to the waypoint
{
    if (GetDistanceToObject(oWaypoint) < 1.0f)    // waypoint reached -> switch to state 2
    {
        SetLocalInt(OBJECT_SELF, "iState", 2);
        ApplyEffectToObject(DURATION_TYPE_PERMANENT,eSupernaturalScale,OBJECT_SELF);
    }
}
else if (iState == 2)    ...

#5
Shallina

Shallina
  • Members
  • 1 011 messages
Action queu, trigger for when the NPC reach his spot. and probably many other.

#6
M. Rieder

M. Rieder
  • Members
  • 2 530 messages
@ diophant



So all the functions that begin with "action" will add a command at the end of the action queue? So If I wanted an NPC to do several different things all I have to do is make sure they are functions that add to the end of the action queue and script them in the order I want and they will happen in that order, unless interrupted? That simplifies things a lot!



Also thanks for the explanation of "assigncommand". I had been puzzling over that. The state based scripting approach also appears useful. Thanks.







@ Shallina,



Thanks for the advice, that also sounds like it would be effective.

#7
M. Rieder

M. Rieder
  • Members
  • 2 530 messages
I just fixed my script. It worked perfectly on the first go. Thanks for your help everyone.

#8
diophant

diophant
  • Members
  • 116 messages

M. Rieder wrote...

@ diophant

So all the functions that begin with "action" will add a command at the end of the action queue? So If I wanted an NPC to do several different things all I have to do is make sure they are functions that add to the end of the action queue and script them in the order I want and they will happen in that order, unless interrupted? That simplifies things a lot!


Yes, that's how it works. Glad I could help!