void apply_to_others(Action <ModuleTCA> action)
 {
     if (TCA.CFG.Squad == 0 || !SquadMode)
     {
         return;
     }
     for (int i = 0, num_vessels = FlightGlobals.Vessels.Count; i < num_vessels; i++)
     {
         var v = FlightGlobals.Vessels[i];
         if (v == null || v == VSL.vessel || !v.loaded)
         {
             continue;
         }
         var tca = ModuleTCA.EnabledTCA(v);
         if (tca == null || !tca.Controllable ||
             tca.CFG.Squad == 0 || tca.CFG.Squad != TCA.CFG.Squad)
         {
             continue;
         }
         //try to reach packed vessels
         if (v.packed)
         {
             var dist = (v.transform.position - VSL.vessel.transform.position).magnitude;
             var sit  = v.vesselRanges.GetSituationRanges(v.situation);
             sit.pack   = dist * 1.5f;
             sit.unpack = dist * 1.2f;
             v.GoOffRails();
         }
         action(tca);
     }
     Message("Squad Action Executed");
 }
Exemple #2
0
        bool ComputeManeuver(Vessel v, out Vector3d maneuver)
        {
            maneuver = Vector3d.zero;
            //calculate distance
            var dir  = (v.CurrentCoM - VSL.Physics.wCoM);
            var dist = dir.magnitude;

            dir /= dist;
            //first try to get TCA from other vessel and get vessel's R and Exhaust
            var       vR  = 0f;
            var       vB  = new Bounds();
            Transform vT  = null;
            var       tca = ModuleTCA.EnabledTCA(v);

            if (tca != null)
            {
//				if(tca.CPS != null &&
//				   tca.CPS.IsActive &&
//				   VSL.Physics.M > tca.VSL.Physics.M &&
//				   VSL.vessel.srfSpeed > v.srfSpeed) //test
//					return false;
                vR = tca.VSL.Geometry.R;
                vB = tca.VSL.Geometry.B;
                vT = tca.VSL.refT;
            }
            else             //do a raycast
            {
                RaycastHit raycastHit;
                if (Physics.SphereCast(VSL.Geometry.C + dir * (VSL.Geometry.R + 0.1f), VSL.Geometry.R, dir,
                                       out raycastHit, dist, RadarMask))
                {
                    vR = (raycastHit.point - v.CurrentCoM).magnitude;
                }
                vT = v.ReferenceTransform;
                vB = v.Bounds(vT);
                vB.Encapsulate(v.EnginesExhaust());
            }
            //compute course correction
            var dV         = VSL.vessel.srf_velocity - v.srf_velocity + (VSL.vessel.acceleration - v.acceleration) * CPS.LookAheadTime;
            var thrershold = -1f;

            if (v.LandedOrSplashed)
            {
                thrershold = 0;
            }
            else if (Dangerous.Contains(v.id))
            {
                thrershold = CPS.SafeDistance;
            }
            if (AvoideVessel(VSL, dir, dist, dV, vR, vB, vT, out maneuver, thrershold))
            {
                Dangerous.Add(v.id);
            }
            else
            {
                Dangerous.Remove(v.id);
            }
            return(!maneuver.IsZero());
        }
Exemple #3
0
 protected bool GetTCA()
 {
     if (FlightGlobals.ActiveVessel != null)
     {
         TCA = ModuleTCA.EnabledTCA(FlightGlobals.ActiveVessel);
     }
     return(TCA != null);
 }
Exemple #4
0
        void apply_to_others(Action <ModuleTCA> action)
        {
            if (TCA.CFG.Squad == 0 || !SquadMode)
            {
                return;
            }
            bool executed = false;

            for (int i = 0, num_vessels = FlightGlobals.Vessels.Count; i < num_vessels; i++)
            {
                var v = FlightGlobals.Vessels[i];
                if (v == null || v == VSL.vessel || !v.loaded)
                {
                    continue;
                }
                var tca = ModuleTCA.EnabledTCA(v);
                if (tca == null || !tca.Available)
                {
                    continue;
                }
                if (tca.CFG.Squad == 0 || tca.CFG.Squad != TCA.CFG.Squad)
                {
                    continue;
                }
                if (!is_comm_reachable(tca))
                {
                    continue;
                }
                //try to reach packed vessels
                UnpackVessel(TCA.vessel, v);
                action(tca);
                executed = true;
            }
            if (executed)
            {
                Message("Squad Action Executed");
            }
        }
Exemple #5
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];
        }