# File generated by Wizard 2.9.0 on Feb 8, 2026.
# File generated by Wizard 2.9.0 on Feb 3, 2026.
# File generated by Wizard 2.9.0 on Dec 26, 2024.
   processor sta WSF_SCRIPT_PROCESSOR 
      update_interval 10 s
      
      script_variables          
         double orbitLength = 20000000;
         string state = "";
         //
         string PointOrName1 = "XL04";
         string zoneType1 = "polygon";
         double Radius = 50000;
         bool iscrea = false;
         bool isaddfuel = false;
         WsfGeoPoint p1 = WsfGeoPoint.Construct("16:16:24.77n 146:53:27.50e");
      end_script_variables
     
     
      script bool RecvTask()
         bool rev = false;
         string sojna = PLATFORM->plat1Name;
         if(sojna.Contains("j"))
         {
            rev = true;
         }
         return rev;   
      end_script

     
   //
   //@ flyZone to a point
   //
   script void flyZone(string PointOrName,string zoneType)
         if(zoneType == "circle")
         {
            WsfGeoPoint p = p.Construct(PointOrName);
            PLATFORM.GoToSpeed(1000,999,true);
            PLATFORM.GoToLocation(p);
         }
         else if(zoneType == "polygon")
         {
            WsfZone zone = zone.FindZone(PointOrName);
            PLATFORM.GoToSpeed(1000,999,true);
            PLATFORM.GoToLocation(zone.Location());
         }
   end_script   
   
   //
   //@ bool
   script bool isInZone(string PointOrName,string zoneType)
         if(zoneType == "circle")
         {
            WsfGeoPoint p = p.Construct(PointOrName);
            return(PLATFORM.Location().GroundRangeTo(p) <= 10);
         }
         else if(zoneType == "polygon")
         {
            WsfZone zone = zone.FindZone(PointOrName);
            return(PLATFORM.Location().GroundRangeTo(zone.Location()) <= 10000);
         }
         return false;
   end_script
   

   //
   // @ generateCirclePoints
   //
   script Array<WsfGeoPoint> generateCirclePoints(string Center , double radius)
      WsfGeoPoint center = WsfGeoPoint.Construct(Center);
      Array<WsfGeoPoint> circlePoints = {};
      double earthRadius = 6371000.0;
      double angularDistance = radius / earthRadius;
      Array<double> angles = {10,20,30,40,50,60,70,80,90,100,110,120,130,140,150,160,170,180,190,200,210,220,230,240,250,260,270,280,290,300,310,320,330,340,350,360};
      foreach(double angle in angles)
      {
         double latCenter = center.Latitude() * MATH.PI() / 180.0;
         double lonCenter = center.Longitude() * MATH.PI() / 180.0;
         
         double lat = MATH.ASin(MATH.Sin(latCenter)
                      * MATH.Cos(angularDistance) 
                      + MATH.Cos(latCenter) 
                      * MATH.Sin(angularDistance) 
                      * MATH.Cos(angle));
         double lon = lonCenter + MATH.ATan2(MATH.Sin(angle) 
                                             * MATH.Sin(angularDistance) 
                                             * MATH.Cos(latCenter) 
                                             ,MATH.Cos(angularDistance) 
                                             - MATH.Sin(latCenter) 
                                             * MATH.Sin(lat));

         circlePoints.PushBack(WsfGeoPoint.Construct(lat*180.0/MATH.PI(),lon * 180.0 / MATH.PI(),5000));
      }
      return circlePoints;
   end_script
   
   
   //
   //@ circle execute
   //
   script  void executecircularPatrol()           
      Array<WsfGeoPoint> circlePoints = generateCirclePoints(PointOrName1,Radius);
      WsfRoute route;
      WsfRoute r1 = route.Create("lx");
      foreach(WsfGeoPoint vertex in circlePoints)
      {
         vertex.SetAltitudeHAE(10000);
         r1.Append(vertex,1500);
      }
      r1.Waypoint(0).SetLabel("start");
      r1.Waypoint(r1.Size() - 1).SetGoToLabel("start");
      PLATFORM.FollowRoute(r1);
      r1.Print();
   end_script
   
   
   //
   // @ bounds execute 
   //
   script  void executeBoundsAreaPatrol()
      WsfZone zone = zone.FindZone(PointOrName1);           
      Array<WsfGeoPoint> boundsPoints = zone.PolyPoints();
      WsfRoute route;
      WsfRoute r1 = route.Create("lx");
      foreach(WsfGeoPoint vertex in boundsPoints)
      {
         vertex.SetAltitudeHAE(10000);
         r1.Append(vertex,1500);
      }
      r1.Waypoint(0).SetLabel("start");
      r1.Waypoint(r1.Size() - 1).SetGoToLabel("start");
      PLATFORM.FollowRoute(r1);

   end_script   
   
   //
   //execute once patrol
   //
   script void executeOncePatrol()
      if(zoneType1 == "circle")
      {
         executecircularPatrol();
      }
      else if( zoneType1 == "polygon")
      {
         executeBoundsAreaPatrol();
      }
   end_script
   //

 //
 script void TurnOnJam()
 WsfProcessor pro = (WsfProcessor)PLATFORM.Processor("jamming");
   if(pro.IsTurnedOff())
   {
      pro.TurnOn();
   }
 end_script
 //
 script void TurnOffJam()
 WsfProcessor proc = (WsfProcessor)PLATFORM.Processor("jamming");
   if(proc.IsTurnedOn())   
   {
      proc.TurnOff();   
   }     
 end_script
 
 
 
    script bool isontime()
   return true;
   end_script
////////////////////////////////////////////////////////////////////

   script_variables 
      string tankerName = "yy20_1";
      bool isrecvMessage = false;
      string proName = "task_mgr";
   end_script_variables
   
   script bool isRefuelRequired()
      WsfFuel fuel = PLATFORM.Fuel();
      if(fuel.IsValid())
      {
         double i = fuel.MaximumQuantity();
         double j = i * 0.45;
         if(fuel.QuantityRemaining() <= j)
         {
            return true;
         }
      }
      return false;
   end_script

   script void sendRefuelMessage(string tankname)
      if(WsfSimulation.FindPlatform(tankname).IsValid())
      {
         WsfComm trackComm = WsfSimulation.FindPlatform(tankname).Comm("sub_net");
         WsfMessage warningMessage = WsfMessage();
         warningMessage.SetType("FUELING");
         warningMessage.SetSubType(PLATFORM.Name());
         PLATFORM.Comm("sub_net").SendMessage(warningMessage,trackComm);      
      }
      else
      {
         writeln(PLATFORM.Name()," is inVaild");
      }
   end_script
   
   on_message 
      type CANFUEL
         script 
            WsfMessage warningMessage = (WsfMessage)MESSAGE;
            isrecvMessage = true;
         end_script
      
      type default
         script 
            writeln(PLATFORM.Name()," Report: Message received");
         end_script      
   end_on_message   
   
   script bool isRecvMessage()
      return isrecvMessage;
   end_script
   
   script void gotoTanker()
         WsfPlatform p = WsfSimulation.FindPlatform(tankerName);
         if(p.IsValid())
         {  
            PLATFORM.GoToSpeed(p.Speed() * 1.5,999);
            PLATFORM.GoToLocation(p.Location()); 
         }   
   end_script
   
   script bool isShift()
         WsfPlatform p = WsfSimulation.FindPlatform(tankerName);
         if(p.IsValid())
         {  
            if(PLATFORM.GroundRangeTo(p) <= 10000)
            {
               return true;
            }
         }
      return false;
   end_script
   
   script void shift()
      WsfPlatform p = WsfSimulation.FindPlatform(tankerName);
      if(p.IsValid())
      {  
         PLATFORM.GoToSpeed(p.Speed() * 1.1,999);
         PLATFORM.GoToLocation(p.Location());
      }     
   end_script
   
   script bool isRefuelOk()
      WsfFuel fuel = PLATFORM.Fuel();
      if(fuel.IsValid())
      {
         if(fuel.QuantityRemaining() >= fuel.MaximumQuantity() - 300)
         {

            isrecvMessage = false;
            isaddfuel = true;
            return true;
         }
         return false;  
      }
      return true;    
   end_script
   
//////////////////////////////////////////////////////////////////////////////////
  execute at_time 1 s relative  
         SetState("STARTJA");
 end_execute

      
state STARTJA
   next_state DETECTEDJA
      return isontime();
   end_next_state
end_state 


state DETECTEDJA
   on_entry   
      flyZone(PointOrName1,zoneType1); 
   end_on_entry
   
   next_state AREAPATROLJA  
      return (isInZone(PointOrName1,zoneType1));
   end_next_state
   
   //
end_state

state AREAPATROLJA
   on_entry  
      executeOncePatrol();  
   end_on_entry
   next_state SENDMESSAGE
         return isRefuelRequired();
   end_next_state
end_state

state Jamming
   on_entry  
      TurnOnJam();  
   end_on_entry
   
   next_state SENDMESSAGE
         return isRefuelRequired();
   end_next_state
         
   on_exit 
      TurnOffJam();
   end_on_exit
end_state


   state SENDMESSAGE
      on_entry 
         sendRefuelMessage(tankerName);
      end_on_entry
      
      next_state GOTOTANKER
         return isRecvMessage() && !isaddfuel;
      end_next_state
      
      on_exit 
      end_on_exit
   end_state
   
   state GOTOTANKER
      on_entry 
         
      end_on_entry
      
      next_state SHIFTFLY
         gotoTanker();
         return isShift();
      end_next_state
      
      on_exit 
      end_on_exit
   end_state
   
   state SHIFTFLY
      on_entry 
      end_on_entry
      
      next_state STARTJA
         shift();
         return isRefuelOk();
      end_next_state
      
      on_exit
            PLATFORM.GoToLocation(p1);
            PROCESSOR.TurnOff();
      end_on_exit
   end_state
      
end_processor
