public override void OnFixedUpdate() { if (FlightGlobals.fetch != null) { solar_force_d = 0; if (!IsEnabled) { return; } double sunlightFactor = 1.0; Vector3 sunVector = FlightGlobals.fetch.bodies[0].position - part.orgPos; if (!PluginHelper.lineOfSightToSun(vessel)) { sunlightFactor = 0.0f; } //Debug.Log("Detecting sunlight: " + sunlightFactor.ToString()); Vector3d solarForce = CalculateSolarForce() * sunlightFactor; //print(surfaceArea); Vector3d solar_accel = solarForce / vessel.GetTotalMass() / 1000.0 * TimeWarp.fixedDeltaTime; if (!this.vessel.packed) { vessel.ChangeWorldVelocity(solar_accel); } else { if (sunlightFactor > 0) { double temp1 = solar_accel.y; solar_accel.y = solar_accel.z; solar_accel.z = temp1; Vector3d position = vessel.orbit.getRelativePositionAtUT(Planetarium.GetUniversalTime()); Orbit orbit2 = new Orbit(vessel.orbit.inclination, vessel.orbit.eccentricity, vessel.orbit.semiMajorAxis, vessel.orbit.LAN, vessel.orbit.argumentOfPeriapsis, vessel.orbit.meanAnomalyAtEpoch, vessel.orbit.epoch, vessel.orbit.referenceBody); orbit2.UpdateFromStateVectors(position, vessel.orbit.vel + solar_accel, vessel.orbit.referenceBody, Planetarium.GetUniversalTime()); //print(orbit2.timeToAp); if (!double.IsNaN(orbit2.inclination) && !double.IsNaN(orbit2.eccentricity) && !double.IsNaN(orbit2.semiMajorAxis) && orbit2.timeToAp > TimeWarp.fixedDeltaTime) { vessel.orbit.inclination = orbit2.inclination; vessel.orbit.eccentricity = orbit2.eccentricity; vessel.orbit.semiMajorAxis = orbit2.semiMajorAxis; vessel.orbit.LAN = orbit2.LAN; vessel.orbit.argumentOfPeriapsis = orbit2.argumentOfPeriapsis; vessel.orbit.meanAnomalyAtEpoch = orbit2.meanAnomalyAtEpoch; vessel.orbit.epoch = orbit2.epoch; vessel.orbit.referenceBody = orbit2.referenceBody; vessel.orbit.Init(); //vessel.orbit.UpdateFromOrbitAtUT(orbit2, Planetarium.GetUniversalTime(), orbit2.referenceBody); vessel.orbit.UpdateFromUT(Planetarium.GetUniversalTime()); } } } solar_force_d = solarForce.magnitude; solar_acc_d = solar_accel.magnitude / TimeWarp.fixedDeltaTime; //print(solarForce.x.ToString() + ", " + solarForce.y.ToString() + ", " + solarForce.z.ToString()); } count++; }
public double getAvailablePower() { double power = 0; if (PluginHelper.lineOfSightToSun(vessel) && solar_power > 0) { double inv_square_mult = Math.Pow(Vector3d.Distance(vessel.transform.position, FlightGlobals.Bodies[PluginHelper.REF_BODY_KERBOL].transform.position), 2) / Math.Pow(Vector3d.Distance(FlightGlobals.Bodies[PluginHelper.REF_BODY_KERBIN].transform.position, FlightGlobals.Bodies[PluginHelper.REF_BODY_KERBOL].transform.position), 2); power = nuclear_power + solar_power / inv_square_mult; } else { power = nuclear_power; } return(power); }
public override void OnFixedUpdate() { String[] resources_to_supply = { FNResourceManager.FNRESOURCE_MEGAJOULES, FNResourceManager.FNRESOURCE_WASTEHEAT }; this.resources_to_supply = resources_to_supply; base.OnFixedUpdate(); ConfigNode config = PluginHelper.getPluginSaveFile(); float powerInputIncr = 0; float powerInputRelay = 0; int activeSatsIncr = 0; float rangelosses = 0; if (config != null && IsEnabled) { if (getResourceBarRatio(FNResourceManager.FNRESOURCE_WASTEHEAT) >= 0.95) { IsEnabled = false; deactivate_timer++; if (FlightGlobals.ActiveVessel == vessel && deactivate_timer > 2) { ScreenMessages.PostScreenMessage("Warning Dangerous Overheating Detected: Emergency microwave power shutdown occuring NOW!", 5.0f, ScreenMessageStyle.UPPER_CENTER); } return; } deactivate_timer = 0; //Check to see if active vessel is a relay - for now we do not want a relay to connect to another relay to prevent energy loops String aid = vessel.id.ToString(); if (config.HasValue(aid) == true) { String agenType = config.GetValue(aid + "type"); if (agenType == "relay") { aIsRelay = true; } else { aIsRelay = false; } } //if (activeCount % 100 == 0) { List <Vessel> vessels = FlightGlobals.Vessels; //print(vessels.Count.ToString() + "\n"); //loop through vessels and attempt to add any active sattilites foreach (Vessel vess in vessels) { String vid = vess.id.ToString(); String vname = vess.vesselName.ToString().ToLower(); //print(vid + "\n"); //prevent adding active vessel as sat, skip calculations on debris, only add vessels with config value and line of sight to active vessel if (vess.isActiveVessel == false && vname.IndexOf("debris") == -1 && config.HasValue(vid) == true && lineOfSightTo(vess) == true) { String powerinputsat = config.GetValue(vid); String vgenType = config.GetValue(vid + "type"); // if sat is not relay/nuclear check that it has line of site to sun // NOTE: we need to add a check for relay to check lineOfSiteToSource(vess), and if solar a lineOfSiteFromSourceToSun - to check that the source which it is relaying is still attached to it, and if it is a solar source that it is recieving solar energy if ((vgenType == "solar" && PluginHelper.lineOfSightToSun(vess)) || vgenType == "relay" || vgenType == "nuclear") { float inputPowerFixedAlt = 0; // = float.Parse (powerinputsat) * PluginHelper.getSatFloatCurve ().Evaluate ((float)FlightGlobals.Bodies [0].GetAltitude (vess.transform.position)); float distance = (float)Vector3d.Distance(vessel.transform.position, vess.transform.position); float powerdissip = (float)(Math.Tan(angle) * distance * Math.Tan(angle) * distance); powerdissip = Math.Max(powerdissip / collectorArea, 1); if (vgenType != "relay" && inputPowerFixedAlt > 0) { rangelosses += powerdissip; //Scale energy reception based on angle of reciever to transmitter Vector3d direction_vector = (vess.transform.position - vessel.transform.position).normalized; float facing_factor = Vector3.Dot(part.transform.up, direction_vector); facing_factor = Mathf.Max(0, facing_factor); powerInputIncr += inputPowerFixedAlt / powerdissip * facing_factor; activeSatsIncr++; connectedrelaysf = 0; //print ("warp: sat added - genType: " + vgenType); } // only attach to one relay IF no sattilites are available for direct connection else if (aIsRelay == false && activeSatsIncr < 1 && inputPowerFixedAlt > 0) { rangelosses = powerdissip; //Scale energy reception based on angle of reciever to transmitter Vector3d direction_vector = (vess.transform.position - vessel.transform.position).normalized; float facing_factor = Vector3.Dot(part.transform.up, direction_vector); facing_factor = Mathf.Max(0, facing_factor); powerInputRelay = inputPowerFixedAlt / powerdissip * facing_factor; connectedrelaysf = 1; activeSatsIncr = 0; //print ("warp: relay added"); } } } } float atmosphericefficiency = (float)Math.Exp(-FlightGlobals.getStaticPressure(vessel.transform.position) / 5); if (activeSatsIncr > 0 && powerInputIncr > 0) { this.rangelosses = rangelosses / activeSatsIncr; totefff = efficiency * atmosphericefficiency * 100 / rangelosses; powerInput = powerInputIncr * efficiency * atmosphericefficiency; connectedsatsf = activeSatsIncr; //print ("warp: connected sat"); } else if (connectedrelaysf > 0 && powerInputRelay > 0) { this.rangelosses = rangelosses / connectedrelaysf; totefff = efficiency * atmosphericefficiency * 100 / rangelosses; powerInput = powerInputRelay * efficiency * atmosphericefficiency; connectedsatsf = 0; //print("warp: connected relay"); } else { connectedrelaysf = 0; connectedsatsf = 0; powerInput = 0; //print ("warp: no active sats or relays available"); } //} } else { connectedrelaysf = 0; connectedsatsf = 0; powerInput = 0; } float powerInputMegajoules = powerInput / 1000.0f; supplyFNResource(powerInputMegajoules * TimeWarp.fixedDeltaTime, FNResourceManager.FNRESOURCE_MEGAJOULES); float waste_head_production = powerInput / 1000.0f / efficiency * (1.0f - efficiency); supplyFNResource(waste_head_production * TimeWarp.fixedDeltaTime, FNResourceManager.FNRESOURCE_WASTEHEAT); //activeCount++; }