public void InitializeSuffixes() { AddSuffix("CANREVERT", new Suffix <BooleanValue>(CanRevert)); AddSuffix("CANREVERTTOLAUNCH", new Suffix <BooleanValue>(CanRevertToLaunch)); AddSuffix("CANREVERTTOEDITOR", new Suffix <BooleanValue>(CanRevvertToEditor)); AddSuffix("REVERTTOLAUNCH", new NoArgsVoidSuffix(RevertToLaunch)); AddSuffix("REVERTTOEDITOR", new NoArgsVoidSuffix(RevertToEditor)); AddSuffix("REVERTTO", new OneArgsSuffix <StringValue>(RevertTo)); AddSuffix("CANQUICKSAVE", new Suffix <BooleanValue>(CanQuicksave)); AddSuffix("QUICKSAVE", new NoArgsVoidSuffix(QuickSave)); AddSuffix("QUICKLOAD", new NoArgsVoidSuffix(QuickLoad)); AddSuffix("QUICKSAVETO", new OneArgsSuffix <StringValue>(QuickSaveTo)); AddSuffix("QUICKLOADFROM", new OneArgsSuffix <StringValue>(QuickLoadFrom)); AddSuffix("QUICKSAVELIST", new Suffix <ListValue>(GetQuicksaveList)); AddSuffix("ORIGINEDITOR", new Suffix <StringValue>(OriginatingEditor)); AddSuffix("DEFAULTLOADDISTANCE", new Suffix <LoadDistanceValue>(() => new LoadDistanceValue(PhysicsGlobals.Instance.VesselRangesDefault))); AddSuffix("ACTIVEVESSEL", new SetSuffix <VesselTarget>(() => VesselTarget.CreateOrGetExisting(FlightGlobals.ActiveVessel, shared), SetActiveVessel)); AddSuffix(new string[] { "FORCESETACTIVEVESSEL", "FORCEACTIVE" }, new OneArgsSuffix <VesselTarget>(ForceSetActiveVessel)); AddSuffix("HOURSPERDAY", new Suffix <ScalarValue>(GetHoursPerDay)); AddSuffix("DEBUGLOG", new OneArgsSuffix <StringValue>(DebugLog)); AddSuffix("GETCRAFT", new TwoArgsSuffix <CraftTemplate, StringValue, StringValue>(GetCraft)); AddSuffix("LAUNCHCRAFT", new OneArgsSuffix <CraftTemplate>(LaunchShip)); AddSuffix("LAUNCHCRAFTFROM", new TwoArgsSuffix <CraftTemplate, StringValue>(LaunchShip)); AddSuffix("CRAFTLIST", new Suffix <ListValue>(CraftTemplate.GetAllTemplates)); AddSuffix("SWITCHVESSELWATCHERS", new NoArgsSuffix <UniqueSetValue <UserDelegate> >(() => shared.DispatchManager.CurrentDispatcher.GetSwitchVesselNotifyees())); AddSuffix("TIMEWARP", new Suffix <TimeWarpValue>(() => TimeWarpValue.Instance)); }
public override OrbitableVelocity GetVelocitiesAtUT(TimeSpan timeStamp) { CelestialBody parent = Body.KOSExtensionGetParentBody(); if (parent == null) // only if Body is Sun and therefore has no parent, then do more complex work instead because KSP didn't provide a way itself { Vector3d futureOrbitalVel; CelestialBody soiBody = Shared.Vessel.mainBody; if (soiBody.orbit != null) { futureOrbitalVel = soiBody.orbit.GetFrameVelAtUT(timeStamp.ToUnixStyleTime()); } else { futureOrbitalVel = -1 * VesselTarget.CreateOrGetExisting(Shared.Vessel, Shared).GetVelocitiesAtUT(timeStamp).Orbital.ToVector3D(); } Vector swappedVel = new Vector(futureOrbitalVel.x, futureOrbitalVel.z, futureOrbitalVel.y); // swap Y and Z because KSP API is weird. // Also invert directions because the above gives vel of my body rel to sun, and I want vel of sun rel to my body: return(new OrbitableVelocity(-swappedVel, -swappedVel)); } var orbVel = new Vector(Orbit.getOrbitalVelocityAtUT(timeStamp.ToUnixStyleTime())); orbVel = new Vector(orbVel.X, orbVel.Z, orbVel.Y); // swap Y and Z because KSP API is weird. var surfVel = new Vector(Body.orbit.GetVel() - parent.getRFrmVel(Body.position)); return(new OrbitableVelocity(orbVel, surfVel)); }
/// <summary> /// Factory method you should use instead of the constructor for this class. /// This will construct a new instance if and only if there isn't already /// an instance made for this particular kOSProcessor, for the given vessel /// (Uniqueness determinied by the vessel's GUID). /// If an instance already exists it will return a reference to that instead of making /// a new one. /// The reason this enforcement is needed is because VesselTarget has callback hooks /// that prevent orphaning and garbage collection. (The delegate inserted /// into KSP's GameEvents counts as a reference to the VesselTarget.) /// Using this factory method instead of a constructor prevents having thousands of stale /// instances of VesselTarget, which was the cause of Github issue #1980. /// </summary> /// <returns>The or get.</returns> /// <param name="Target">Target.</param> /// <param name="Shared">Shared.</param> public static VesselTarget CreateOrGetExisting(Vessel target, SharedObjects shared) { if (instanceCache == null) { instanceCache = new Dictionary <InstanceKey, WeakReference>(); } InstanceKey key = new InstanceKey { ProcessorId = shared.Processor.KOSCoreId, VesselId = target.id }; if (instanceCache.ContainsKey(key)) { WeakReference weakRef = instanceCache[key]; if (weakRef.IsAlive) { return((VesselTarget)weakRef.Target); } else { instanceCache.Remove(key); } } // If it either wasn't in the cache, or it was but the GC destroyed it by now, make a new one: VesselTarget newlyConstructed = new VesselTarget(target, shared); instanceCache.Add(key, new WeakReference(newlyConstructed)); return(newlyConstructed); }
public object VesselShortcutGetter(SharedObjects shared, string name) { ISuffixResult suffix = new VesselTarget(shared).GetSuffix(name); if (! suffix.HasValue) suffix.Invoke(shared.Cpu); return suffix.Value; }
public void ForceSetActiveVessel(VesselTarget vesselTarget) { Vessel vessel = vesselTarget.Vessel; if (!vessel.isActiveVessel) { FlightGlobals.ForceSetActiveVessel(vessel); } }
private void InitializeSuffixes() { AddSuffix("NAME", new SetSuffix <StringValue>(() => dockedVesselInfo.name, SetName)); AddSuffix("UID", new Suffix <StringValue>(() => dockedVesselInfo.rootPartUId.ToString())); AddSuffix("VESSEL", new Suffix <VesselTarget>(() => VesselTarget.CreateOrGetExisting(parts[0].vessel, shared))); AddSuffix("PARTS", new Suffix <ListValue>(() => PartValueFactory.Construct(parts, shared))); AddSuffix("DOCKINGPORTS", new Suffix <ListValue>(() => DockingPortValue.PartsToList(parts, shared))); AddSuffix("RESOURCES", new Suffix <ListValue>(GetResourceManifest)); }
private static BooleanValue RTHasKSCConnection(VesselTarget tgtVessel) { bool result = false; if (RemoteTechHook.IsAvailable(tgtVessel.Vessel.id)) { result = RemoteTechHook.Instance.HasConnectionToKSC(tgtVessel.Vessel.id); } return result; }
private static ScalarValue RTGetKSCDelay(VesselTarget tgtVessel) { double waitTotal = 0; if (RemoteTechHook.IsAvailable(tgtVessel.Vessel.id) && tgtVessel.Vessel.GetVesselCrew().Count == 0) { waitTotal = RemoteTechHook.Instance.GetSignalDelayToKSC(tgtVessel.Vessel.id); } return waitTotal; }
private static bool RTHasConnection(VesselTarget tgtVessel) { bool result = false; if (RemoteTechHook.IsAvailable(tgtVessel.Vessel.id)) { result = RemoteTechHook.Instance.HasAnyConnection(tgtVessel.Vessel.id); } return result; }
private static bool RTHasLocalControl(VesselTarget tgtVessel) { bool result = false; if (RemoteTechHook.IsAvailable(tgtVessel.Vessel.id)) { result = RemoteTechHook.Instance.HasLocalControl(tgtVessel.Vessel.id); } return result; }
public Hooks(VesselTarget target) : base(target) { GameEvents.onVesselDestroy.Add(OnVesselDestroy); GameEvents.onVesselPartCountChanged.Add(OnVesselPartCountChanged); GameEvents.onStageActivate.Add(OnStageActive); GameEvents.onPartPriorityChanged.Add(OnPartPriorityChanged); GameEvents.onDockingComplete.Add(OnDockingComplete); GameEvents.onPartDeCouple.Add(OnPartDecouple); GameEvents.StageManager.OnGUIStageAdded.Add(OnStageAdded); GameEvents.StageManager.OnGUIStageRemoved.Add(OnStageRemoved); GameEvents.StageManager.OnGUIStageSequenceModified.Add(OnStageModified); hooked = true; }
public static Message Create(object content, double sentAt, double receivedAt, VesselTarget sender, string processor) { if (content is SerializableStructure) { return new Message(new SafeSerializationMgr(null).Dump(content as SerializableStructure), sentAt, receivedAt, sender); } else if (content is PrimitiveStructure) { return new Message(content as PrimitiveStructure, sentAt, receivedAt, sender); } else { throw new KOSCommunicationException("Only serializable types and primitives can be sent in a message"); } }
/// <summary> /// Factory method you should use instead of the constructor for this class. /// This will construct a new instance if and only if there isn't already /// an instance made for this particular kOSProcessor, for the given vessel /// (Uniqueness determinied by the vessel's GUID). /// If an instance already exists it will return a reference to that instead of making /// a new one. /// The reason this enforcement is needed is because VesselTarget has callback hooks /// that prevent orphaning and garbage collection. (The delegate inserted /// into KSP's GameEvents counts as a reference to the VesselTarget.) /// Using this factory method instead of a constructor prevents having thousands of stale /// instances of VesselTarget, which was the cause of Github issue #1980. /// </summary> public static VesselTarget CreateOrGetExisting(Vessel target, SharedObjects shared) { var key = new InstanceKey(shared.Processor, target); WeakReference wref; if (instanceCache == null) { instanceCache = new Dictionary <InstanceKey, WeakReference>(); } else if (instanceCache.TryGetValue(key, out wref)) { var it = wref.Target as VesselTarget; if (it?.disposed == false) { return(it); } instanceCache.Remove(key); } // If it either wasn't in the cache, or it was but the GC destroyed it by now, make a new one: var newlyConstructed = new VesselTarget(target, shared); instanceCache.Add(key, new WeakReference(newlyConstructed)); return(newlyConstructed); }
public override void Execute(SharedObjects shared) { string vesselName = PopValueAssert(shared).ToString(); AssertArgBottomAndConsume(shared); var result = new VesselTarget(VesselUtils.GetVesselByName(vesselName, shared.Vessel), shared); ReturnValue = result; }
private kList GetTargetList(SharedObjects shared) { kList list = new kList(); list.AddColumn("Vessel Name", 25, ColumnAlignment.Left); list.AddColumn("Distance", 12, ColumnAlignment.Right, "0.0"); double commRange = VesselUtils.GetCommRange(shared.Vessel); foreach (Vessel vessel in FlightGlobals.Vessels) { if (vessel != shared.Vessel) { var vT = new VesselTarget(vessel, shared.Vessel); if (vT.IsInRange(commRange)) { list.AddItem(vT.Vessel.vesselName, vT.GetDistance()); } } } return list; }
public Message(PrimitiveStructure content, double sentAt, double receivedAt, VesselTarget sender) : base(content, sentAt, receivedAt) { Vessel = sender.GetGuid().ToString(); }
protected bool Equals(VesselTarget other) { return Vessel.Equals(other.Vessel); }
public override void Evaluate() { switch (RegexMatch.Groups[1].Value.ToUpper()) { case "BODIES": StdOut(""); StdOut("Name Distance"); StdOut("-------------------------------------"); foreach (var body in FlightGlobals.fetch.bodies) { StdOut(body.bodyName.PadLeft(14) + " " + Vector3d.Distance(body.position, Vessel.GetWorldPos3D())); } StdOut(""); break; case "TARGETS": StdOut(""); StdOut("Vessel Name Distance"); StdOut("-------------------------------------"); var commRange = VesselUtils.GetCommRange(Vessel); foreach (var vessel in FlightGlobals.Vessels) { if (vessel == Vessel) continue; var vT = new VesselTarget(vessel, this); if (RemoteTechHook.Instance != null) { if (RemoteTechHook.Instance.GetSignalDelayToSatellite(Vessel.id, vessel.id) != Double.PositiveInfinity) { StdOut(vT.Vessel.vesselName.PadRight(24) + " " + vT.GetDistance().ToString("0.0").PadLeft(8)); } } else { if (vT.IsInRange(commRange)) { StdOut(vT.Vessel.vesselName.PadRight(24) + " " + vT.GetDistance().ToString("0.0").PadLeft(8)); } } } StdOut(""); break; case "RESOURCES": StdOut(""); StdOut("Stage Resource Name Amount"); StdOut("------------------------------------------------"); foreach (var part in Vessel.Parts) { foreach (PartResource resource in part.Resources) { StdOut(part.inverseStage.ToString(CultureInfo.InvariantCulture) + " " + resource.resourceName.PadRight(20) + " " + resource.amount.ToString("0.00").PadLeft(8)); } } break; case "PARTS": StdOut("------------------------------------------------"); foreach (var part in Vessel.Parts) { StdOut(part.ConstructID + " " + part.partInfo.name); } break; case "ENGINES": StdOut("------------------------------------------------"); foreach (var part in VesselUtils.GetListOfActivatedEngines(Vessel)) { foreach (PartModule module in part.Modules) { if (!(module is ModuleEngines)) continue; var engineMod = (ModuleEngines) module; StdOut(part.uid + " " + part.inverseStage.ToString(CultureInfo.InvariantCulture) + " " + engineMod.moduleName); } } break; case "SENSORS": StdOut(""); StdOut("Part Name Sensor Type"); StdOut("------------------------------------------------"); foreach (var part in Vessel.Parts) { foreach (PartModule module in part.Modules) { var sensor = module as ModuleEnviroSensor; if (sensor == null) continue; if (part.partInfo.name.Length > 37) StdOut(part.partInfo.title.PadRight(34) + "... " + sensor.sensorType); else StdOut(part.partInfo.title.PadRight(37) + " " + sensor.sensorType); } } break; } State = ExecutionState.DONE; }
public override void Execute(SharedObjects shared) { string vesselName = shared.Cpu.PopValue().ToString(); var result = new VesselTarget(VesselUtils.GetVesselByName(vesselName, shared.Vessel), shared); shared.Cpu.PushStack(result); }
protected bool Equals(VesselTarget other) { return(Vessel.Equals(other.Vessel)); }
private kList GetTargetList(SharedObjects shared) { var list = new kList(); list.AddColumn("Vessel Name", 25, ColumnAlignment.Left); list.AddColumn("Distance", 12, ColumnAlignment.Right, "0.0"); foreach (Vessel vessel in FlightGlobals.Vessels) { if (vessel == shared.Vessel) continue; var vT = new VesselTarget(vessel, shared); list.AddItem(vT.Vessel.vesselName, vT.GetDistance()); } return list; }