Ulic and Cay Posted August 27, 2007 Share Posted August 27, 2007 I wrote the below script for an NPC and have it fire OnHeartbeat. void sub1(int intParam1) { if ((!GetIsConversationActive())) { switch (intParam1) { case 0: BarkString(OBJECT_SELF, StrRef0); break; case 1: BarkString(OBJECT_SELF, StrRef1); break; case 2: BarkString(OBJECT_SELF, StrRef2); break; } } } void main() { if ((!GetLocalBoolean(OBJECT_SELF, 5))) { SetLocalBoolean(OBJECT_SELF, 5, 1); ClearAllActions(); ActionWait(4.0); ActionMoveToObject(GetObjectByTag("WP_YIMA_FUTZ1", 0), 0, 1.0); ActionPlayAnimation(102, 1.0, 1.0); ActionWait(5.0); ActionMoveToObject(GetObjectByTag("WP_YIMA_FUTZ2", 0), 0, 1.0); ActionPlayAnimation(103, 1.0, 1.0); ActionDoCommand(sub1(0)); ActionWait(4.0); ActionMoveToObject(GetObjectByTag("WP_YIMA_FUTZ1", 0), 0, 1.0); ActionWait(4.0); ActionMoveToObject(GetObjectByTag("WP_YIMA_FUTZ3", 0), 0, 1.0); SetFacingPoint(GetPositionFromLocation(GetLocation(GetObjectByTag("WP_LOOK_07")))); ActionPlayAnimation(5, 1.0, -1.0); ActionWait(1.0); ActionDoCommand(sub1(1)); ActionPlayAnimation(102, 1.0, 1.0); ActionWait(3.0); ActionMoveToObject(GetObjectByTag("WP_COM_YIMA", 0), 0, 1.0); ActionWait(4.0); SetFacingPoint(GetPositionFromLocation(GetLocation(GetObjectByTag("WP_COM_YIMA")))); ActionDoCommand(sub1(2)); ActionPlayAnimation(5, 1.0, -1.0); ActionDoCommand(SetLocalBoolean(OBJECT_SELF, 5, 0)); } } It works fine but if I interrupt the NPC by initiating a dialog, when the dialog ends the NPC just stands there. How can I set it up so that the NPC will return to what it was doing before I initiated the dialog? Link to comment Share on other sites More sharing options...
stoffe Posted August 27, 2007 Share Posted August 27, 2007 I wrote the below script for an NPC and have it fire OnHeartbeat. void main() { if ((!GetLocalBoolean(OBJECT_SELF, 5))) { SetLocalBoolean(OBJECT_SELF, 5, 1); (snip) ActionDoCommand(SetLocalBoolean(OBJECT_SELF, 5, 0)); } } It works fine but if I interrupt the NPC by initiating a dialog, when the dialog ends the NPC just stands there. How can I set it up so that the NPC will return to what it was doing before I initiated the dialog? The problem is how you handle the flow control of the script. Since a heartbeat script runs roughly every 3 seconds you use a LocalBoolean to block your long sequence of actions from overlapping, and then reset the boolean as the final action. The problem with this is that if the NPC is interrupted for any reason that causes its action queue to be cleared (combat, dialog, etc) your LocalBoolean will never be reset since the action that resets it gets flushed from the action queue before it has a chance to run. There are a couple of ways around this that I can think of: Modify the OnDialogEnd event script to reset this LocalBoolean to FALSE whenever the NPC exits dialog. Also modify the OnCombatRound event script to reset the LocalBoolean to FALSE whenever the NPC enters combat. Modify your heartbeat script not to queue the whole sequence at once, but rather take advantage of the repeating nature of a heartbeat script to perform one step at a time, and then use a LocalNumber as a step counter to indicate how far along the sequence the NPC has come. Then the whole sequence wouldn't be flushed if the action queue is cleared, and at most the NPC would repeat the interrupted step again before moving on to the next. Link to comment Share on other sites More sharing options...
Ulic and Cay Posted August 27, 2007 Author Share Posted August 27, 2007 That second solution is exactly what I was looking for. Thanks a ton. I tried it out and it works, however, my NPC won't stop moving around now during the dialog. Here's a shortened version of what I think you're suggesting my script should look like. Let me know if this is what you had in mind and if you can come up with another neat way for me to stop my NPC from moving while I'm talking to her. void main() { int iLN = GetLocalNumber(OBJECT_SELF, 12); if ((iLN == 0))) { ClearAllActions(); ActionWait(4.0); SetLocalNumber(OBJECT_SELF, 12, 1); } else { if ((iLN == 1)) { ActionMoveToObject(GetObjectByTag("WP_YIMA_FUTZ1", 0), 0, 1.0); SetLocalNumber(OBJECT_SELF, 12, 2); } else { if ((iLN == 2)) { ActionPlayAnimation(102, 1.0, 1.0); ActionWait(5.0); SetLocalNumber(OBJECT_SELF, 12, 3); } else { if ((iLN == 3)) { SetLocalNumber(OBJECT_SELF, 12, 0); } } } } } Link to comment Share on other sites More sharing options...
stoffe Posted August 27, 2007 Share Posted August 27, 2007 That second solution is exactly what I was looking for. Thanks a ton. I tried it out and it works, however, my NPC won't stop moving around now during the dialog. You can use the GetIsInConversation() and GetIsInCombat() functions to check if the character is in conversation or in combat to block out the rest of your actions in the meanwhile. Link to comment Share on other sites More sharing options...
Ulic and Cay Posted August 27, 2007 Author Share Posted August 27, 2007 Oh of course. Things seem so obvious once you tell me how to do it stoffe. Thanks again for your help. Link to comment Share on other sites More sharing options...
Recommended Posts
Archived
This topic is now archived and is closed to further replies.