Esempio n. 1
0
 void reset_formation()
 {
     Maneuvering = false;
     Formation   = null;
     fnode       = null;
     tVSL        = null;
     tPN         = null;
 }
Esempio n. 2
0
 public void UpdateFormation(List <FormationNode> formation)
 {
     if (formation == null)
     {
         reset_formation();
     }
     else
     {
         Formation = formation; fnode = null;
     }
 }
Esempio n. 3
0
        void update_formation_info()
        {
            tVSL = CFG.Target.GetVessel();
            if (tVSL == null)
            {
                reset_formation();
                CanManeuver = false;
                return;
            }
            if (tPN == null || !tPN.Valid)
            {
                tTCA = ModuleTCA.EnabledTCA(tVSL);
                tPN  = tTCA != null?tTCA.GetModule <PointNavigator>() : null;
            }
            var only_count = false;

            if (tVSL.srf_velocity.sqrMagnitude < C.FormationSpeedSqr)
            {
                reset_formation(); CanManeuver = false; only_count = true;
            }
            //update followers
            var offset       = 0f;
            var can_maneuver = true;

            all_followers.Clear();
            for (int i = 0, num_vessels = FlightGlobals.Vessels.Count; i < num_vessels; i++)
            {
                var v = FlightGlobals.Vessels[i];
                if (v == null || v.packed || !v.loaded)
                {
                    continue;
                }
                var tca = ModuleTCA.EnabledTCA(v);
                if (tca != null &&
                    (tca.vessel == VSL.vessel ||
                     tca.CFG.Nav[Navigation.FollowTarget] &&
                     tca.CFG.Target.GetTarget() != null &&
                     tca.CFG.Target.GetTarget() == CFG.Target.GetTarget()))
                {
                    var vPN = tca.GetModule <PointNavigator>();
                    if (vPN == null)
                    {
                        continue;
                    }
                    all_followers.Add(v.id, vPN);
                    if (offset < vPN.VSL.Geometry.R)
                    {
                        offset = vPN.VSL.Geometry.R;
                    }
                    if (v.id != VSL.vessel.id)
                    {
                        can_maneuver &= !vPN.Maneuvering ||
                                        (Maneuvering && VSL.vessel.id.CompareTo(v.id) > 0);
                    }
                }
            }
            if (only_count)
            {
                return;
            }
            CanManeuver = can_maneuver;
            var follower_index = all_followers.IndexOfKey(VSL.vessel.id);

            if (follower_index == 0)
            {
                var forward     = tVSL == null? Vector3d.zero : -tVSL.srf_velocity.normalized;
                var side        = Vector3d.Cross(VSL.Physics.Up, forward).normalized;
                var num_offsets = all_followers.Count + (all_followers.Count % 2);
                offset *= 2;
                var target_size = tTCA != null? tTCA.VSL.Geometry.D : Utils.ClampL(Math.Pow(tVSL.totalMass, 1 / 3f), 1);
                if (offset < target_size)
                {
                    offset = (float)target_size;
                }
                offset *= C.MinDistance;
                if (Formation == null || Formation.Count != num_offsets || FormationUpdateTimer.TimePassed)
                {
                    FormationUpdateTimer.Reset();
                    Formation = new List <FormationNode>(num_offsets);
                    for (int i = 0; i < num_offsets; i++)
                    {
                        Formation.Add(new FormationNode(tVSL, i, forward, side, offset));
                    }
                    all_followers.ForEach(p => p.Value.UpdateFormation(Formation));
                }
                else
                {
                    for (int i = 0; i < num_offsets; i++)
                    {
                        Formation[i].Update(forward, side, offset);
                    }
                }
            }
            keep_formation = Formation != null;
            if (Formation == null || fnode != null)
            {
                return;
            }
            //compute follower offset
            var min_d   = -1f;
            var min_off = 0;

            for (int i = 0; i < Formation.Count; i++)
            {
                var node = Formation[i];
                if (node.Follower != null)
                {
                    continue;
                }
                var d = node.Distance(VSL.vessel);
                if (min_d < 0 || min_d > d)
                {
                    min_d   = d;
                    min_off = i;
                }
            }
            Formation[min_off].Follower = VSL.vessel;
            fnode = Formation[min_off];
        }
 void update_formation_info()
 {
     tVSL = CFG.Target.GetVessel();
     if(tVSL == null) { reset_formation(); CanManeuver = false; return; }
     if(tPN == null || !tPN.TCA.Valid || tPN.VSL.vessel != tVSL)
     {
         tTCA = ModuleTCA.EnabledTCA(tVSL);
         if(tTCA != null) tPN = tTCA.GetModule<PointNavigator>();
     }
     var only_count = false;
     if(tVSL.srf_velocity.sqrMagnitude < PN.FormationSpeedSqr)
     { reset_formation(); CanManeuver = false; only_count = true; }
     //update followers
     var offset = 0f;
     var can_maneuver = true;
     all_followers.Clear();
     for(int i = 0, num_vessels = FlightGlobals.Vessels.Count; i < num_vessels; i++)
     {
         var v = FlightGlobals.Vessels[i];
         if(v == null || v.packed || !v.loaded) continue;
         var tca = ModuleTCA.EnabledTCA(v);
         if(tca != null &&
            (tca.vessel == VSL.vessel ||
             tca.CFG.Nav[Navigation.FollowTarget] &&
             tca.CFG.Target.GetTarget() != null &&
             tca.CFG.Target.GetTarget() == CFG.Target.GetTarget()))
         {
             var vPN = tca.GetModule<PointNavigator>();
             if(vPN == null) continue;
             all_followers.Add(v.id, vPN);
             if(offset < vPN.VSL.Geometry.R)
                 offset = vPN.VSL.Geometry.R;
             if(v.id != VSL.vessel.id)
                 can_maneuver &= !vPN.Maneuvering ||
                     (Maneuvering && VSL.vessel.id.CompareTo(v.id) > 0);
         }
     }
     if(only_count) return;
     CanManeuver = can_maneuver;
     var follower_index = all_followers.IndexOfKey(VSL.vessel.id);
     if(follower_index == 0)
     {
         var forward = tVSL == null? Vector3d.zero : -tVSL.srf_velocity.normalized;
         var side = Vector3d.Cross(VSL.Physics.Up, forward).normalized;
         var num_offsets = all_followers.Count+(all_followers.Count%2);
         offset *= 2;
         var target_size = tTCA != null? tTCA.VSL.Geometry.D : Utils.ClampL(Math.Pow(tVSL.totalMass, 1/3f), 1);
         if(offset < target_size) offset = (float)target_size;
         offset *= PN.MinDistance;
         if(Formation == null || Formation.Count != num_offsets || FormationUpdateTimer.TimePassed)
         {
             FormationUpdateTimer.Reset();
             Formation = new List<FormationNode>(num_offsets);
             for(int i = 0; i < num_offsets; i++)
                 Formation.Add(new FormationNode(tVSL, i, forward, side, offset));
             all_followers.ForEach(p => p.Value.UpdateFormation(Formation));
         }
         else for(int i = 0; i < num_offsets; i++)
             Formation[i].Update(forward, side, offset);
     }
     keep_formation = Formation != null;
     if(Formation == null || fnode != null) return;
     //compute follower offset
     var min_d   = -1f;
     var min_off = 0;
     for(int i = 0; i < Formation.Count; i++)
     {
         var node = Formation[i];
         if(node.Follower != null) continue;
         var d = node.Distance(VSL.vessel);
         if(min_d < 0 || min_d > d)
         {
             min_d = d;
             min_off = i;
         }
     }
     Formation[min_off].Follower = VSL.vessel;
     fnode = Formation[min_off];
 }
 void reset_formation()
 {
     Maneuvering = false;
     Formation = null;
     fnode = null;
 }
 public void UpdateFormation(List<FormationNode> formation)
 {
     if(formation == null) reset_formation();
     else { Formation = formation; fnode = null; }
 }