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"); }
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()); }
protected bool GetTCA() { if (FlightGlobals.ActiveVessel != null) { TCA = ModuleTCA.EnabledTCA(FlightGlobals.ActiveVessel); } return(TCA != null); }
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"); } }
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]; }