static bool check_flag_placed(Vessel flag) { foreach (var part in flag.Parts) { var pname = part.name; //Telemagic.logTM($"{flag.vesselName} type {flag.GetType()} has pname {pname}"); if (pname == "flag") { return(true); Telemagic.logTM($"{display(part)}"); // find MODULE with name = FlagSite foreach (var module in part.Modules) { // and state = Placed Telemagic.logTM($"flag part module {part.name}"); //if (module.name == "FlagSite") { // bool placed = module.find("state").value("Placed"); // Telemagic.logTM("checking flag " + flag.name + ' ' + placed); // return placed; //} } } } return(false); }
public FuelTotals(Vessel vessel) { if (vessel?.parts != null) { foreach (var part in vessel.parts) { int nres = part.Resources.Count; for (int i = 0; i < nres; ++i) { PartResource resource = part.Resources[i]; if (resource.flowState && resource.isVisible) { var resourceName = resource.resourceName; FuelState fuelState; if (!this.ContainsKey(resourceName)) { fuelState = new FuelState(); fuelState.resourceName = resourceName; this[resourceName] = fuelState; } else { fuelState = this[resourceName]; } fuelState.amount += resource.amount; fuelState.maxAmount += resource.maxAmount; } } } foreach (var total in this) { Telemagic.logTM($"{vessel.vesselName} {total.Value.resourceName} {total.Value.amount} {total.Value.maxAmount}"); } } }
public void Update() { if (TimeWarp.CurrentRateIndex != 0) { TimeWarp.SetRate(0, true); Telemagic.logTM("cancel time warp"); } }
public Vessel BeginRefueling() { vessel = FlightGlobals.ActiveVessel; Telemagic.logTM($"current vessel is {vessel.vesselName}"); vesselFuelTotals = new FuelTotals(vessel); FuelTotals.transferred = 0; timeRemaining = refuelingDuration; if (!Telemagic.isOnFuelApron(vessel)) { sourceVessel = vessel.targetObject?.GetVessel(); if (sourceVessel != null) { sourceVesselFuelTotals = new FuelTotals(sourceVessel); Telemagic.logTM($"will refuel from {sourceVessel.vesselName}"); } } // for each resource, compute how much can be transferred. foreach (var resource in vesselFuelTotals) { var resourceName = resource.Key; // how much reserve capacity in the client vessel? var capacity = resource.Value.maxAmount - resource.Value.amount; var transferAmount = capacity; // assuming unlimited source // if there is a source Target, it will have finite resources. if (sourceVessel != null) { var sourceFuelState = sourceVesselFuelTotals?.getResource(resourceName); if (sourceFuelState != null) { if (sourceFuelState.amount < capacity) { transferAmount = sourceFuelState.amount; } } else { transferAmount = 0; } } resource.Value.targetTransferAmount = transferAmount; Telemagic.logTM($"will transfer {resource.Value.targetTransferAmount} of {resourceName}"); } return(vessel); }
/* First step is to consider every vessel within Max_refuel_radius and * determine whether it is a hub airport control tower. * [kmk] disable this */ public static void refuel_hub_airport(Vessel vessel) { disqual = null; /* Find all vessels within the refueling apron radius. One of them may be a hub control tower. * In that case, we can refuel. */ List <Vessel> nearby = find_locale(vessel.mainBody, vessel.longitude, vessel.latitude, Max_refuel_radius); foreach (var tower in nearby) { if (check_airport(tower)) { Telemagic.logTM($"refueling {vessel.vesselName}"); Telemagic.refuel(vessel); return; } } if (disqual != null) { Telemagic.message(vessel, $"{disqual} at {name}"); } }
//private double altAGL = 0; // Need to work out these in relation //private double altASL = 0; // to land or sea. /// <summary> /// Sets the vessel altitude to the current calculation. /// </summary> public void SetAltitudeToCurrent() { var pqs = Body.pqsController; if (pqs == null) { Destroy(this); return; } var alt = pqs.GetSurfaceHeight( QuaternionD.AngleAxis(Longitude, Vector3d.down) * QuaternionD.AngleAxis(Latitude, Vector3d.forward) * Vector3d.right) - pqs.radius; Telemagic.logTM("SetAltitudeToCurrent:: alt (pqs.GetSurfaceHeight) = " + alt); alt = Math.Max(alt, 0); // Underwater Altitude = GetComponent <Vessel>().altitude - alt; Telemagic.logTM("SetAltitudeToCurrent::"); Telemagic.logTM(" alt = Math.Max(alt, 0) := " + alt); Telemagic.logTM(" <Vessel>.altitude := " + Altitude); }
internal static void refuel(Vessel vessel, Vessel sourceVessel = null) { if (vessel.parts == null) { return; } logTM($"considering {vessel.vesselName} for refueling..."); // the intention here was to discover a way to equip a solo Kerbal with a flag. logTM($"{vessel.vesselName} is {vessel.RevealType()}"); if (vessel.isEVA) { foreach (var part in vessel.parts) { logTM($"{part.name} is {part.GetType()}"); if (part.name.Contains("kerbalEVA")) { logTM($"{Hub.display(part)}"); foreach (var mod in part.Modules) //vessel.vesselModules) { { logTM($"mod {mod.name}"); } foreach (var res in part.Resources) { logTM($"res {res.resourceName}"); } } } logTM($"that's all"); } // does the vessel have chutes? var repacked_chute_count = 0; foreach (var part in vessel.parts) { if (part.name.Contains("chute") || part.name.Contains("Drogue")) { logTM($"chute: {part.name} mods:{part.Modules.Count}"); foreach (var mod in part.Modules) { logTM($"mod {mod.name}"); if (mod.name.Contains("chute") || mod.name.Contains("Drogue")) { var chute = mod as ModuleParachute; if (chute != null && chute.deploymentState != ModuleParachute.deploymentStates.STOWED) { chute.Disarm(); chute.Repack(); repacked_chute_count++; } } } } else { var crew = part.protoModuleCrew; foreach (var member in crew) { logTM($"{member.name} in {vessel.vesselName}"); ///member. } } } if (repacked_chute_count > 0) { Telemagic.message(vessel, $"{repacked_chute_count} chutes repacked."); } // dynamic Fueler component to fuel the craft in "real-time"... FlightGlobals.ActiveVessel.gameObject.AddComponent <TelemagicFueler>(); }
public void Update() { if (vessel == null) { vessel = BeginRefueling(); Telemagic.logTM($"TelemagicFueler starting for {vessel?.vesselName}"); Telemagic.message(vessel, $"refueling has commenced..."); } if (vessel?.parts != null) { string resourceName; /* Cycle through all resources and replenish them. * * Cancel fueling if brakes are released or engines started. */ if (!Telemagic.enginesRunning(vessel) && Telemagic.brakesApplied(vessel) && timeRemaining > 0) { var deltaTime = Math.Min(Time.deltaTime, timeRemaining); timeRemaining -= deltaTime; int tankNumber = 0; foreach (var part in vessel.parts) { int nres = part.Resources.Count; for (int i = 0; i < nres; ++i) { PartResource resource = part.Resources[i]; if (resource.flowState && resource.isVisible) { tankNumber++; resourceName = resource.resourceName; FuelState fuelState = vesselFuelTotals.getResource(resourceName); if (fuelState == null) { continue; } // apportion the standard flow by available tank capacity as a ratio of total remaining capacity var transferAmount = 0.0; var capacity = resource.maxAmount - resource.amount; if (fuelState.amount < fuelState.maxAmount) { transferAmount = fuelState.targetTransferAmount * capacity / (fuelState.maxAmount - fuelState.amount) * deltaTime / refuelingDuration; } //Telemagic.logTM($"{vessel.vesselName} {tankNumber} {resourceName} {resource.amount} {resource.maxAmount} +{transferAmount} target {fuelState.targetTransferAmount}"); fuelState.actualTransferAmount += transferAmount; if (transferAmount > 0) { if (transferAmount > capacity) { transferAmount = capacity; } part.TransferResource(resource.info.id, transferAmount); } FuelTotals.transferred += transferAmount; } } } /* Update total amount transferred to client. */ foreach (var total in vesselFuelTotals) { total.Value.amount += total.Value.actualTransferAmount; //Telemagic.logTM($"{vessel.vesselName} {total.Value.resourceName} +{total.Value.actualTransferAmount} = {total.Value.amount}"); var sourceFuelState = sourceVesselFuelTotals?.getResource(total.Value.resourceName); if (sourceFuelState != null) { sourceFuelState.targetTransferAmount = total.Value.actualTransferAmount; sourceFuelState.actualTransferAmount = 0; } total.Value.actualTransferAmount = 0; } /* Debit the source vessel, if there is one. */ if (sourceVesselFuelTotals != null) { tankNumber = 0; foreach (var part in sourceVessel.parts) { int nparts = part.Resources.Count; for (int partx = 0; partx < nparts; partx++) { PartResource resource = part.Resources[partx]; //Telemagic.logTM($"Processing {resource.resourceName} in the source: {sourceVessel?.vesselName}"); if (resource.flowState && resource.isVisible) { tankNumber++; resourceName = resource.resourceName; // check that it is a resource that would have been drawn by the client FuelState fuelState = vesselFuelTotals.getResource(resourceName); if (fuelState != null && fuelState.targetTransferAmount > 0) { fuelState = sourceVesselFuelTotals.getResource(resourceName); // how much? var transferAmount = 0.0; if (fuelState.amount > 0) { transferAmount = resource.amount / fuelState.amount * fuelState.targetTransferAmount; } //Telemagic.logTM($"{sourceVessel.vesselName} {tankNumber} {resourceName} {resource.amount} {resource.maxAmount} -{transferAmount}"); fuelState.actualTransferAmount += transferAmount; part.TransferResource(resource.info.id, -transferAmount); FuelTotals.transferred -= transferAmount; } } } } // Update total amount withdrawn from source. foreach (var total in sourceVesselFuelTotals) { total.Value.amount -= total.Value.actualTransferAmount; //Telemagic.logTM($"{sourceVessel.vesselName} {total.Value.resourceName} -{total.Value.actualTransferAmount} = {total.Value.amount}"); } } return; } Telemagic.message(vessel, $"refueling complete."); } // finished Telemagic.logTM($"TelemagicFueler terminating for {vessel?.vesselName}"); Destroy(this); }
public void FixedUpdate() { var vessel = GetComponent <Vessel>(); if (vessel != FlightGlobals.ActiveVessel) { Destroy(this); return; } if (TimeWarp.CurrentRateIndex != 0) { TimeWarp.SetRate(0, true); Telemagic.logTM("cancel time warp"); } if (AlreadyTeleported) { if (vessel.LandedOrSplashed) { Destroy(this); } else { var accel = (vessel.srf_velocity + vessel.upAxis) * -0.5; vessel.ChangeWorldVelocity(accel); } } else { //NOT AlreadyTeleported //Still calculating var pqs = Body.pqsController; if (pqs == null) // The sun has no terrain. Everthing else has a PQScontroller. { Destroy(this); return; } var alt = pqs.GetSurfaceHeight(Body.GetRelSurfaceNVector(Latitude, Longitude)) - Body.Radius; var tmpAlt = Body.TerrainAltitude(Latitude, Longitude); double landHeight = FlightGlobals.ActiveVessel.altitude - FlightGlobals.ActiveVessel.pqsAltitude; double finalAltitude = 0.0; var checkAlt = FlightGlobals.ActiveVessel.altitude; var checkPQSAlt = FlightGlobals.ActiveVessel.pqsAltitude; double terrainAlt = GetTerrainAltitude(); Telemagic.logTM("-------------------"); Telemagic.logTM($"m1. Body.Radius = {Body.Radius}"); Telemagic.logTM("m2. PQS SurfaceHeight = " + pqs.GetSurfaceHeight(Body.GetRelSurfaceNVector(Latitude, Longitude))); Telemagic.logTM("alt ( m2 - m1 ) = " + alt); Telemagic.logTM("Body.TerrainAltitude = " + tmpAlt); Telemagic.logTM("checkAlt = " + checkAlt); Telemagic.logTM("checkPQSAlt = " + checkPQSAlt); Telemagic.logTM("landheight = " + landHeight); Telemagic.logTM("terrainAlt = " + terrainAlt); Telemagic.logTM("-------------------"); Telemagic.logTM($"Latitude: {Latitude} Longitude: {Longitude}"); Telemagic.logTM("-------------------"); alt = Math.Max(alt, 0d); // HoldVesselUnpack is in display frames, not physics frames Vector3d teleportPosition; if (!teleportedToLandingAlt) { Telemagic.logTM("teleportedToLandingAlt == false"); Telemagic.logTM("interimAltitude: " + InterimAltitude); Telemagic.logTM("Altitude: " + Altitude); if (InterimAltitude > Altitude) { if (Planetarium.GetUniversalTime() - lastUpdate >= 0.5) { InterimAltitude = InterimAltitude / 10; terrainAlt = GetTerrainAltitude(); if (InterimAltitude < terrainAlt) { InterimAltitude = terrainAlt + Altitude; } //InterimAltitude = terrainAlt + Altitude; teleportPosition = Body.GetWorldSurfacePosition(Latitude, Longitude, InterimAltitude) - Body.position; Telemagic.logTM("1. teleportPosition = " + teleportPosition); Telemagic.logTM("1. interimAltitude: " + InterimAltitude); if (lastUpdate != 0) { InterimAltitude = Altitude; } lastUpdate = Planetarium.GetUniversalTime(); } else { Telemagic.logTM("teleportPositionAltitude (no time change):"); teleportPosition = Body.GetWorldSurfacePosition(Latitude, Longitude, alt + InterimAltitude) - Body.position; Telemagic.logTM("2. teleportPosition = " + teleportPosition); Telemagic.logTM("2. alt: " + alt); Telemagic.logTM("2. interimAltitude: " + InterimAltitude); } } else { //InterimAltitude <= Altitude Telemagic.logTM("3. teleportedToLandingAlt sets to true"); landHeight = FlightGlobals.ActiveVessel.altitude - FlightGlobals.ActiveVessel.pqsAltitude; terrainAlt = GetTerrainAltitude(); //trying to find the correct altitude here. if (checkPQSAlt > terrainAlt) { alt = checkPQSAlt; } else { alt = terrainAlt; } if (alt == 0.0) { //now what? } teleportedToLandingAlt = true; //finalAltitude = alt + Altitude; if (alt < 0) { finalAltitude = Altitude; } else if (alt > 0) { finalAltitude = alt + Altitude; } else { finalAltitude = alt + Altitude; } teleportPosition = Body.GetWorldSurfacePosition(Latitude, Longitude, finalAltitude) - Body.position; Telemagic.logTM("3. teleportPosition = " + teleportPosition); Telemagic.logTM($"3. alt = {alt} Altitude = {Altitude} InterimAltitude = {InterimAltitude}"); Telemagic.logTM($"3. TerrainAlt = {terrainAlt} landHeight = {landHeight}"); } } else { Telemagic.logTM("teleportedToLandingAlt == true"); landHeight = FlightGlobals.ActiveVessel.altitude - FlightGlobals.ActiveVessel.pqsAltitude; terrainAlt = GetTerrainAltitude(); Telemagic.logTM($"4. finalAltitude = {finalAltitude}"); //finalAltitude = alt + Altitude; if (alt < 0) { finalAltitude = Altitude; } else if (alt > 0) { finalAltitude = alt + Altitude; } else { finalAltitude = alt + Altitude; } //teleportPosition = Body.GetRelSurfacePosition(Latitude, Longitude, finalAltitude); teleportPosition = Body.GetWorldSurfacePosition(Latitude, Longitude, finalAltitude) - Body.position; Telemagic.logTM("4. teleportPosition = " + teleportPosition); Telemagic.logTM($"4. alt = {alt} Altitude = { Altitude} InterimAltitude = { InterimAltitude}"); Telemagic.logTM($"4. TerrainAlt = {terrainAlt} landHeight = {landHeight}"); Telemagic.logTM("4. finalAltitude = " + finalAltitude); } var teleportVelocity = Vector3d.Cross(Body.angularVelocity, teleportPosition); // convert from world space to orbit space teleportPosition = teleportPosition.xzy; teleportVelocity = teleportVelocity.xzy; Telemagic.logTM("0. teleportPosition(xzy): " + teleportPosition); Telemagic.logTM("0. teleportVelocity(xzy): " + teleportVelocity); Telemagic.logTM("0. Body : " + Body); // counter for the momentary fall when on rails (about one second) teleportVelocity += teleportPosition.normalized * (Body.gravParameter / teleportPosition.sqrMagnitude); Quaternion rotation; if (SetRotation) { // Need to check vessel and find up for the root command pod vessel.ActionGroups.SetGroup(KSPActionGroup.SAS, false); //hopefully this disables SAS as it causes unknown results! var from = Vector3d.up; //Sensible default for all vessels if (vessel.displaylandedAt == "Runway" || vessel.vesselType.ToString() == "Plane") { from = vessel.vesselTransform.up; } var to = teleportPosition.xzy.normalized; rotation = Quaternion.FromToRotation(from, to); } else { var oldUp = vessel.orbit.pos.xzy.normalized; var newUp = teleportPosition.xzy.normalized; rotation = Quaternion.FromToRotation(oldUp, newUp) * vessel.vesselTransform.rotation; } var orbit = Telemagic.Clone(vessel.orbitDriver.orbit); orbit.UpdateFromStateVectors(teleportPosition, teleportVelocity, Body, Planetarium.GetUniversalTime()); Telemagic.SetOrbit(vessel, orbit); vessel.SetRotation(rotation); if (teleportedToLandingAlt) { AlreadyTeleported = true; Telemagic.logTM(" :FINISHED TELEPORTING:"); } } }