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) ...