Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -570,8 +570,10 @@ SAS modes: `StabilityAssist`, `Prograde`, `Retrograde`, `Normal`, `Antinormal`,
| `tar.o.trueAnomaly` | Target true anomaly (deg) |
| `tar.o.orbitingBody` | Target reference body |
| `tar.o.orbitPatches` | Target orbit patches |
| `tar.availableVessels` | Array of targetable vessels — `[{ index, name, type, situation, body, position }, …]` |
| `tar.setTargetBody[index]` | **Action:** set target to body |
| `tar.setTargetVessel[index]` | **Action:** set target to vessel |
| `tar.setTargetVessel[index]` | **Action:** set target to vessel (use `tar.availableVessels` to get `index`) |
| `tar.switchVessel[index]` | **Action:** fly to vessel by `index` — same as Tracking Station "Fly" |
| `tar.clearTarget` | **Action:** clear target |

</details>
Expand Down
85 changes: 85 additions & 0 deletions Telemachus/src/NavigationHandlers.cs
Original file line number Diff line number Diff line change
Expand Up @@ -268,6 +268,60 @@ object TargetRelativePositionAtUTForOrbitPatch(DataSources ds)
return orbitPatch.getRelativePositionAtUT(ut);
}

// --- Available Targets ---

// List the vessels currently eligible for `tar.setTargetVessel`,
// along with the integer index the action expects. Returned in
// `FlightGlobals.Vessels` order so the indexes match the action's
// contract one-for-one. Filters out Flag / EVA / Debris / Unknown
// by default (the bulk of `FlightGlobals.Vessels` for any sane
// career save), and the active vessel itself (no point targeting
// yourself).
//
// Position is reported in the active vessel's *local* frame via
// `transform.InverseTransformPoint` — Unity-local x/y/z. The client
// derives distance / bearing / elevation from the vector; we don't
// ship those server-side.
[TelemetryAPI("tar.availableVessels", "Available target vessels with their setTargetVessel indices",
Plotable = false, Category = "target", ReturnType = "object")]
object AvailableVessels(DataSources ds)
{
var list = new List<Dictionary<string, object>>();
var vessels = FlightGlobals.Vessels;
if (vessels == null) return list;
var active = ds.vessel;
Transform activeT = active != null ? active.transform : null;
for (int i = 0; i < vessels.Count; i++)
{
var v = vessels[i];
if (v == null) continue;
if (active != null && v == active) continue;
switch (v.vesselType)
{
case VesselType.Flag:
case VesselType.EVA:
case VesselType.Debris:
case VesselType.Unknown:
continue;
}
var entry = new Dictionary<string, object>
{
["index"] = i,
["name"] = v.GetName(),
["type"] = v.vesselType.ToString(),
["situation"] = v.situation.ToString(),
["body"] = v.mainBody != null ? v.mainBody.bodyName : "",
};
if (activeT != null)
{
var localPos = activeT.InverseTransformPoint(v.transform.position);
entry["position"] = new[] { localPos.x, localPos.y, localPos.z };
}
list.Add(entry);
}
return list;
}

// --- Target Actions ---

[TelemetryAPI("tar.setTargetBody", "Set Target to Celestial Body", IsAction = true, Category = "target", ReturnType = "int", Params = "int bodyId")]
Expand Down Expand Up @@ -295,6 +349,37 @@ object ClearTarget(DataSources ds)
return true;
}

[TelemetryAPI("tar.switchVessel",
"Fly to vessel by index — same as Tracking Station 'Fly'. " +
"Saves the current vessel's state first, then loads the target. " +
"Args: int vesselIndex (from tar.availableVessels.index). " +
"Returns true on dispatch; scene change is asynchronous.",
IsAction = true,
Category = "target",
ReturnType = "bool",
Params = "int vesselIndex")]
object SwitchVessel(DataSources ds)
{
if (ds.args == null || ds.args.Count == 0) return false;
if (!int.TryParse(ds.args[0], out int vesselIdx)) return false;
if (vesselIdx < 0 || vesselIdx >= FlightGlobals.Vessels.Count) return false;

if (HighLogic.CurrentGame == null) return false;

// Persist the current state before switching so the active
// vessel's mid-flight pose / fuel / heat / etc. is preserved
// and re-loaded when the operator switches back. Mirrors what
// the Tracking Station's "Fly" button does internally.
Game game = HighLogic.CurrentGame.Updated();
GamePersistence.SaveGame(
game,
"persistent",
HighLogic.SaveFolder,
SaveMode.OVERWRITE);
FlightDriver.StartAndFocusVessel(game, vesselIdx);
return true;
}

public override bool process(String API, out APIEntry result)
{
if (!base.process(API, out result))
Expand Down
Loading
Loading