void main()
{

  int nEventNum = GetUserDefinedEventNumber();

  string sWayPoint;
  object oWayPoint;
  int nWayPoint;
  string sNext;

  switch(nEventNum)
  {
    case 100:

    //OnSpawn
    // Get the tag of the nearest WayPoint
    // If it is WP_ + caller's tag, then start walking to it
    // and set the caller's WayPoint to match

    {
      oWayPoint = GetNearestObject(OBJECT_TYPE_WAYPOINT);
      if (GetIsObjectValid(oWayPoint))
      {
        sWayPoint = GetTag(oWayPoint);
        int nStrLen = GetStringLength(GetTag(OBJECT_SELF));
        string sSubStr = GetSubString(sWayPoint,3,nStrLen);
        if (sSubStr == GetTag(OBJECT_SELF))
        {
          nWayPoint = StringToInt(GetStringRight(sWayPoint,2));
          SetLocalInt(OBJECT_SELF,"CurrentWP",nWayPoint);
          ActionMoveToObject(oWayPoint,FALSE,1.0f);
        }
      }
      break;
    }

    case 200:

      // Someone is speaking to you, stop what you are doing and face them
    {
      ClearAllActions();
      object oCaller = GetNearestObjectByTag(GetTag(OBJECT_SELF));
      ActionDoCommand(SetFacingPoint(GetPosition(oCaller)));
      break;
    }

    case 1001:

      // OnHeartBeat
      // Find the caller's current WayPoint and start walking to it
      // If they are less than 2 meters from it, then go to next WayPoint
      // If the current WayPoint is invalid, then set it back to WayPoint 1

      nWayPoint = GetLocalInt(OBJECT_SELF,"CurrentWP");
      int nTens = nWayPoint / 10;
      sNext = IntToString(nTens) + GetStringRight(IntToString(nWayPoint),1);
      sWayPoint = "WP_" + GetTag(OBJECT_SELF) + "_" + sNext;
      oWayPoint = GetNearestObjectByTag(sWayPoint);
      if (GetIsObjectValid(oWayPoint))
      {
        ActionMoveToObject(oWayPoint,FALSE,1.0f);
        if (GetDistanceToObject(oWayPoint) < 2.0f)
        {
          ClearAllActions();
          nWayPoint++;
          SetLocalInt(OBJECT_SELF,"CurrentWP",nWayPoint);
        }
      }
      else
      {
        sWayPoint = "WP_" + GetTag(OBJECT_SELF) + "_01";
        oWayPoint = GetNearestObjectByTag(sWayPoint);
        SetLocalInt(OBJECT_SELF,"CurrentWP",1);
      }

      // Look for another creature with the same tag as the caller
      // If one is within 3 meters, then there is a 1 in 3 chance they
      // will stop and have a conversation

      object oCitizen = GetNearestObjectByTag(GetTag(OBJECT_SELF));
      if (GetIsObjectValid(oCitizen))
      {
        float fDist = GetDistanceBetween(OBJECT_SELF,oCitizen);
        int nRandom = d3();
        if ((fDist < 3.0f) && (nRandom == 1))
        {
          ClearAllActions();
          ActionDoCommand(SetFacingPoint(GetPosition(oCitizen)));
          int nDieRoll = d6();
          switch(nDieRoll)
          {
            case 1:
            {
              ActionPlayAnimation(ANIMATION_FIREFORGET_GREETING,1.0f);
              PlayVoiceChat(VOICE_CHAT_HELLO);
              ActionDoCommand(SignalEvent(oCitizen,EventUserDefined(200)));
              AssignCommand(oCitizen,ActionSpeakString("Yes. Hello to you."));
              break;
            }
            case 2:
            {
              ActionPlayAnimation(ANIMATION_LOOPING_TALK_NORMAL,1.0f,3.0f);
              ActionSpeakString("It's about time I stopped for some ale.");
              ActionPlayAnimation(ANIMATION_FIREFORGET_DRINK,1.0f);
              break;
            }
            case 3:
            {
              ActionPlayAnimation(ANIMATION_LOOPING_TALK_LAUGHING,1.0f,3.0f);
              PlayVoiceChat(VOICE_CHAT_LAUGH);
              break;
            }
            case 4:
            {
              ActionPlayAnimation(ANIMATION_LOOPING_TALK_FORCEFUL,1.0f,3.0f);
              PlayVoiceChat(VOICE_CHAT_FOLLOWME);
              ActionDoCommand(SignalEvent(oCitizen,EventUserDefined(200)));
              AssignCommand(oCitizen,ActionSpeakString("Yeah. I'm following you."));
              break;
            }
            case 5:
            {
              ActionPlayAnimation(ANIMATION_FIREFORGET_TAUNT,1.0f);
              ActionSpeakString("Stay outta my way.");
              break;
            }
            case 6:
            {
              ActionPlayAnimation(ANIMATION_FIREFORGET_PAUSE_SCRATCH_HEAD,1.0f);
              ActionSpeakString("Where was I going again?");
              break;
            }
          }
          if (GetIsObjectValid(oWayPoint))
            ActionMoveToObject(oWayPoint,FALSE,1.0f);
        }
        break;
      }
  }
}
