// op6_do_carpet
#include "rtsa_headerp"

float fnDistanceToDest(object oDest,object oNear)
{ // return distance between two flying carpet rides
  float fRet=0.0;
  int nX1;
  int nX2;
  int nY1;
  int nY2;
  int nA;
  int nB;
  int nD;
  string sName=GetName(oNear);
  string sParse=fnParse(sName);
  nX1=StringToInt(sParse);
  sName=fnRemoveParsed(sName,sParse);
  nY1=StringToInt(sName);
  sName=GetName(oDest);
  sParse=fnParse(sName);
  nX2=StringToInt(sParse);
  sName=fnRemoveParsed(sName,sParse);
  nY2=StringToInt(sName);
  //SendMessageToPC(GetFirstPC(),"("+IntToString(nX1)+","+IntToString(nY1)+") ("+IntToString(nX2)+","+IntToString(nY2)+")");
  nA=abs(nX1-nX2);
  nB=abs(nY1-nY2);
  //SendMessageToPC(GetFirstPC(),"abs(nX1-nX2)="+IntToString(nA));
  //SendMessageToPC(GetFirstPC(),"abs(nY1-nY2)="+IntToString(nB));
  nD=(nA*nA)+(nB*nB);
  //SendMessageToPC(GetFirstPC(),"(A+B)/2="+IntToString(nD));
  fRet=sqrt(IntToFloat(nD));
  return fRet;
} // fnDistanceToDest()

void fnDoCarpetRide(object oDest)
{ // do the carpet ride
  object oMe=OBJECT_SELF;
  object oNear=GetNearestObjectByTag("FLYING_CARPET");
  float fDist=fnDistanceToDest(oDest,oNear);
  object oCarpet=GetWaypointByTag("ON_FLYING_CARPET");
  effect eTo=EffectDisappearAppear(GetLocation(oCarpet));
  effect eFrom=EffectDisappearAppear(GetLocation(oDest));
  int nN;
  //SendMessageToPC(oMe,"oNear='"+GetName(GetArea(oNear))+"'  oDest='"+GetName(GetArea(oDest))+"'");
  //SendMessageToPC(oMe,"onCarpet='"+GetName(GetArea(oCarpet))+"'");
  if (!GetIsPC(oMe))ApplyEffectToObject(DURATION_TYPE_TEMPORARY,eTo,oMe,5.0);
  else { AssignCommand(oMe,ClearAllActions(TRUE)); AssignCommand(oMe,ActionJumpToObject(oCarpet)); }
  if (fDist<1.0) fDist=1.0;
  fDist=fDist*20.0;
  nN=FloatToInt(fDist);
  if (GetIsPC(oMe)) DelayCommand(5.0,AssignCommand(oMe,SpeakString("We should arrive in about "+IntToString(nN-4)+" seconds.")));
  if (!GetIsPC(oMe))DelayCommand(fDist,ApplyEffectToObject(DURATION_TYPE_TEMPORARY,eFrom,oMe,5.0));
  else { DelayCommand(fDist-0.1,AssignCommand(oMe,ClearAllActions(TRUE))); DelayCommand(fDist,AssignCommand(oMe,ActionJumpToObject(oDest))); }
} // fnDoCarpetRide()


void main()
{
    object oPC=GetPCSpeaker();
    int bBySelf=GetLocalInt(oPC,"bCarpetMyself");
    object oCr;
    int nParm=GetLocalInt(oPC,"nParm");
    int nBase=GetLocalInt(oPC,"nCarpetBase");
    int nC=0;
    object oDest;
    int nTarget=nBase+nParm;
    oDest=GetObjectByTag("FLYING_CARPET",nC);
    while(GetIsObjectValid(oDest)&&nC<(nTarget-1))
    { // find target
      nC++;
      oDest=GetObjectByTag("FLYING_CARPET",nC);
    } // find target
    if (GetIsObjectValid(oDest))
    { // target found
      AssignCommand(oPC,fnDoCarpetRide(oDest));
      oCr=GetAssociate(ASSOCIATE_TYPE_FAMILIAR,oPC,1);
      if (GetIsObjectValid(oCr)) AssignCommand(oCr,fnDoCarpetRide(oDest));
      oCr=GetAssociate(ASSOCIATE_TYPE_SUMMONED,oPC,1);
      if (GetIsObjectValid(oCr)) AssignCommand(oCr,fnDoCarpetRide(oDest));
      oCr=GetAssociate(ASSOCIATE_TYPE_DOMINATED,oPC,1);
      if (GetIsObjectValid(oCr)) AssignCommand(oCr,fnDoCarpetRide(oDest));
      oCr=GetAssociate(ASSOCIATE_TYPE_ANIMALCOMPANION,oPC,1);
      if (GetIsObjectValid(oCr)) AssignCommand(oCr,fnDoCarpetRide(oDest));
      oCr=GetAssociate(ASSOCIATE_TYPE_HENCHMAN,oPC,1);
      if (GetIsObjectValid(oCr)) AssignCommand(oCr,fnDoCarpetRide(oDest));
      oCr=GetAssociate(ASSOCIATE_TYPE_HENCHMAN,oPC,2);
      if (GetIsObjectValid(oCr)) AssignCommand(oCr,fnDoCarpetRide(oDest));
      oCr=GetAssociate(ASSOCIATE_TYPE_HENCHMAN,oPC,3);
      if (GetIsObjectValid(oCr)) AssignCommand(oCr,fnDoCarpetRide(oDest));
      oCr=GetNearestCreature(CREATURE_TYPE_PLAYER_CHAR,PLAYER_CHAR_IS_PC,oPC,1,CREATURE_TYPE_REPUTATION,REPUTATION_TYPE_FRIEND,CREATURE_TYPE_IS_ALIVE,TRUE);
      if (GetIsObjectValid(oCr)&&!bBySelf&&GetDistanceBetween(oPC,oCr)<6.0) AssignCommand(oCr,fnDoCarpetRide(oDest));
      oCr=GetNearestCreature(CREATURE_TYPE_PLAYER_CHAR,PLAYER_CHAR_IS_PC,oPC,2,CREATURE_TYPE_REPUTATION,REPUTATION_TYPE_FRIEND,CREATURE_TYPE_IS_ALIVE,TRUE);
      if (GetIsObjectValid(oCr)&&!bBySelf&&GetDistanceBetween(oPC,oCr)<6.0) AssignCommand(oCr,fnDoCarpetRide(oDest));
    } // target found
}