public void Start() { if (!groupList.ContainsKey(actionName) && !customGroupList.ContainsKey(actionName)) { JUtil.LogErrorMessage(this, "Action \"{0}\" is not supported.", actionName); return; } // Parse the needs-electric-charge here. if (!string.IsNullOrEmpty(needsElectricCharge)) { switch (needsElectricCharge.ToLowerInvariant().Trim()) { case "true": case "yes": case "1": needsElectricChargeValue = true; break; case "false": case "no": case "0": needsElectricChargeValue = false; break; } } if (groupList.ContainsKey(actionName)) { oldState = vessel.ActionGroups[groupList[actionName]]; } else { isCustomAction = true; switch (actionName) { case "intlight": persistentVarName = internalLightName; lightObjects = internalModel.FindModelComponents <Light>(); needsElectricChargeValue |= string.IsNullOrEmpty(needsElectricCharge) || needsElectricChargeValue; break; case "plugin": persistentVarName = string.Empty; foreach (ConfigNode node in GameDatabase.Instance.GetConfigNodes("PROP")) { if (node.GetValue("name") == internalProp.propName) { foreach (ConfigNode pluginConfig in node.GetNodes("MODULE")[moduleID].GetNodes("PLUGINACTION")) { if (pluginConfig.HasValue("name") && pluginConfig.HasValue("actionMethod")) { if (!InstantiateHandler(pluginConfig, this, out actionHandler, out stateHandler)) { JUtil.LogErrorMessage(this, "Failed to instantiate action handler {0}", pluginConfig.GetValue("name")); } else { isPluginAction = true; break; } } } } } if (actionHandler == null) { actionName = "dummy"; JUtil.LogMessage(this, "Plugin handlers did not start, reverting to dummy mode."); } break; default: persistentVarName = "switch" + internalProp.propID + "_" + moduleID; break; } if (!string.IsNullOrEmpty(perPodPersistenceName)) { persistentVarName = perPodPersistenceName; } persistence = new PersistenceAccessor(part); } if (needsElectricChargeValue) { comp = RasterPropMonitorComputer.Instantiate(internalProp); comp.UpdateRefreshRates(lightCheckRate, lightCheckRate); } // set up the toggle switch if (!string.IsNullOrEmpty(switchTransform)) { SmarterButton.CreateButton(internalProp, switchTransform, Click); } if (isCustomAction) { if (isPluginAction && stateHandler != null) { oldState = stateHandler(); } else { if (!string.IsNullOrEmpty(persistentVarName)) { oldState = customGroupList[actionName] = (persistence.GetBool(persistentVarName) ?? oldState); if (actionName == "intlight") { // We have to restore lighting after reading the // persistent variable. SetInternalLights(customGroupList[actionName]); } } } } if (!string.IsNullOrEmpty(animationName)) { // Set up the animation Animation[] animators = animateExterior ? part.FindModelAnimators(animationName) : internalProp.FindModelAnimators(animationName); if (animators.Length > 0) { anim = animators[0]; } else { JUtil.LogErrorMessage(this, "Could not find animation \"{0}\" on {2} \"{1}\"", animationName, animateExterior ? part.name : internalProp.name, animateExterior ? "part" : "prop"); return; } anim[animationName].wrapMode = WrapMode.Once; if (oldState ^ reverse) { anim[animationName].speed = float.MaxValue; anim[animationName].normalizedTime = 0; } else { anim[animationName].speed = float.MinValue; anim[animationName].normalizedTime = 1; } anim.Play(animationName); } else if (!string.IsNullOrEmpty(coloredObject)) { // Set up the color shift. colorShiftRenderer = internalProp.FindModelComponent <Renderer>(coloredObject); disabledColorValue = ConfigNode.ParseColor32(disabledColor); enabledColorValue = ConfigNode.ParseColor32(enabledColor); colorShiftRenderer.material.SetColor(colorName, (oldState ^ reverse ? enabledColorValue : disabledColorValue)); } else { JUtil.LogMessage(this, "Warning, neither color nor animation are defined."); } audioOutput = JUtil.SetupIVASound(internalProp, switchSound, switchSoundVolume, false); startupComplete = true; }
private void UpdateOdometer() { double thisUpdate = Planetarium.GetUniversalTime(); float dT = (float)(thisUpdate - lastUpdate) * odometerRotationScalar; float value; if (!string.IsNullOrEmpty(perPodPersistenceName)) { bool state = persistence.GetBool(perPodPersistenceName) ?? false; value = comp.ProcessVariable((state) ? altVariable : variable).MassageToFloat(); } else { value = comp.ProcessVariable(variable).MassageToFloat(); } // Make sure the value isn't going to be a problem. if (float.IsNaN(value)) { value = 0.0f; } if (value < 0.0f) { signGoalCoord = 0.625f; } else if (value > 0.0f) { signGoalCoord = 0.875f; } else { signGoalCoord = 0.75f; } signCurrentCoord = JUtil.DualLerp(signCurrentCoord, signGoalCoord, 0.0f, 1.0f, dT); value = Mathf.Abs(value); if (oMode == OdometerMode.SI) { float leadingDigitExponent; if (value < 0.001f) { leadingDigitExponent = -3.0f; } else { leadingDigitExponent = Mathf.Floor(Mathf.Log10(value)); } // siExponent is the location relative to the original decimal of // the SI prefix. Is is always the greatest multiple-of-3 less // than the leadingDigitExponent. int siIndex = (int)Mathf.Floor(leadingDigitExponent / 3.0f); if (siIndex > 3) { siIndex = 3; } int siExponent = siIndex * 3; prefixGoalCoord = (float)(siIndex + 1) * 0.125f; prefixCurrentCoord = JUtil.DualLerp(prefixCurrentCoord, prefixGoalCoord, 0.0f, 1.0f, dT); float scaledValue = value / Mathf.Pow(10.0f, (float)(siExponent - 3)); int intValue = (int)(scaledValue); for (int i = 5; i >= 0; --i) { float thisCoord = (float)(intValue % 10) / 10.0f; if (i == 5) { // So we can display fractional values: // However, we also quantize it to make it easier to // read during the transition from 9 to 0. thisCoord = Mathf.Floor((scaledValue % 10.0f) * 2.0f) / 20.0f; } intValue = intValue / 10; goalCoordinate[i] = thisCoord; } } else if (oMode == OdometerMode.TIME_HHHMMSS) { // Clamp the value value = Mathf.Min(value, 59.0f + 59.0f * 60.0f + 999.0f * 60.0f * 24.0f); // seconds float thisCoord = Mathf.Floor((value % 10.0f) * 2.0f) / 20.0f; goalCoordinate[6] = thisCoord; int intValue = (int)(value) / 10; // tens of seconds thisCoord = (float)(intValue % 6) / 10.0f; goalCoordinate[5] = thisCoord; intValue /= 6; // minutes thisCoord = (float)(intValue % 10) / 10.0f; goalCoordinate[4] = thisCoord; intValue /= 10; // tens of minutes thisCoord = (float)(intValue % 6) / 10.0f; goalCoordinate[3] = thisCoord; intValue /= 6; for (int i = 2; i >= 0; --i) { thisCoord = (float)(intValue % 10) / 10.0f; intValue = intValue / 10; goalCoordinate[i] = thisCoord; } } else { int intValue = (int)(value); for (int i = 7; i >= 0; --i) { float thisCoord = (float)(intValue % 10) / 10.0f; if (i == 7) { thisCoord = Mathf.Floor((value % 10.0f) * 2.0f) / 20.0f; } intValue = intValue / 10; goalCoordinate[i] = thisCoord; } } // Update interpolants for (int i = 0; i < 8; ++i) { if (currentCoordinate[i] != goalCoordinate[i]) { float startingPoint; float endingPoint; if (Mathf.Abs(currentCoordinate[i] - goalCoordinate[i]) <= 0.5f) { startingPoint = currentCoordinate[i]; endingPoint = goalCoordinate[i]; } else if (goalCoordinate[i] < currentCoordinate[i]) { startingPoint = currentCoordinate[i]; endingPoint = goalCoordinate[i] + 1.0f; } else { startingPoint = currentCoordinate[i] + 1.0f; endingPoint = goalCoordinate[i]; } // This lerp causes a rotation that starts quickly but // slows down close to the goal. It actually looks // pretty good for typical incrementing counts, while the // rapid spinning of small values is chaotic enough that // you can't really tell what's going on, anyway. float goal = JUtil.DualLerp(startingPoint, endingPoint, 0.0f, 1.0f, dT); if (goal > 1.0f) { goal -= 1.0f; } currentCoordinate[i] = goal; } } lastUpdate = thisUpdate; }
private void Start() { InstallationPathWarning.Warn("SCANsatRPM"); // Arrrgh. if (!string.IsNullOrEmpty(iconColorSelf)) iconColorSelfValue = ConfigNode.ParseColor32(iconColorSelf); if (!string.IsNullOrEmpty(iconColorTarget)) iconColorTargetValue = ConfigNode.ParseColor32(iconColorTarget); if (!string.IsNullOrEmpty(iconColorUnvisitedAnomaly)) iconColorUnvisitedAnomalyValue = ConfigNode.ParseColor32(iconColorUnvisitedAnomaly); if (!string.IsNullOrEmpty(iconColorVisitedAnomaly)) iconColorVisitedAnomalyValue = ConfigNode.ParseColor32(iconColorVisitedAnomaly); if (!string.IsNullOrEmpty(iconColorShadow)) iconColorShadowValue = ConfigNode.ParseColor32(iconColorShadow); if (!string.IsNullOrEmpty(iconColorAP)) iconColorAPValue = ConfigNode.ParseColor32(iconColorAP); if (!string.IsNullOrEmpty(iconColorPE)) iconColorPEValue = ConfigNode.ParseColor32(iconColorPE); if (!string.IsNullOrEmpty(iconColorANDN)) iconColorANDNValue = ConfigNode.ParseColor32(iconColorANDN); if (!string.IsNullOrEmpty(iconColorNode)) iconColorNodeValue = ConfigNode.ParseColor32(iconColorNode); if (!string.IsNullOrEmpty(trailColor)) trailColorValue = ConfigNode.ParseColor32(trailColor); // Referencing the parent project should work, shouldn't it. persistentVarName = "scansat" + internalProp.propID; persistence = new PersistenceAccessor(part); showLines = persistence.GetBool(persistentVarName + "lines") ?? true; trailMaterial = JUtil.DrawLineMaterial(); LeaveTrail(); if (!string.IsNullOrEmpty(scaleBar) && !string.IsNullOrEmpty(scaleLabels) && !string.IsNullOrEmpty(scaleLevels)) { scaleBarTexture = GameDatabase.Instance.GetTexture(scaleBar, false); scaleLabelTexture = GameDatabase.Instance.GetTexture(scaleLabels, false); var scales = new List<float>(); foreach (string scl in scaleLevels.Split(',')) { float scale; if (float.TryParse(scl.Trim(), out scale)) scales.Add(scale / 1000); } scaleLevelValues = scales.ToArray(); Array.Sort(scaleLevelValues); scaleLabelSpan = 1f / scaleLevelValues.Length; } // Now the fun bit: Locate all cfg files depicting map features anywhere. foreach (ConfigNode node in GameDatabase.Instance.GetConfigNodes ("JSISCANSATVECTORMARK")) { mapMarkup.Add(new MapMarkupLine(node)); } startupComplete = true; }
public void Start() { if (HighLogic.LoadedSceneIsEditor) { return; } try { if (!groupList.ContainsKey(actionName) && !customGroupList.ContainsKey(actionName)) { JUtil.LogErrorMessage(this, "Action \"{0}\" is not supported.", actionName); return; } // Parse the needs-electric-charge here. if (!string.IsNullOrEmpty(needsElectricCharge)) { switch (needsElectricCharge.ToLowerInvariant().Trim()) { case "true": case "yes": case "1": needsElectricChargeValue = true; break; case "false": case "no": case "0": needsElectricChargeValue = false; break; } } // Now parse consumeOnToggle and consumeWhileActive... if (!string.IsNullOrEmpty(consumeOnToggle)) { string[] tokens = consumeOnToggle.Split(','); if (tokens.Length == 3) { consumeOnToggleName = tokens[0].Trim(); if (!(PartResourceLibrary.Instance.GetDefinition(consumeOnToggleName) != null && float.TryParse(tokens[1].Trim(), NumberStyles.Any, CultureInfo.InvariantCulture, out consumeOnToggleAmount))) { JUtil.LogErrorMessage(this, "Could not parse \"{0}\"", consumeOnToggle); } switch (tokens[2].Trim().ToLower()) { case "on": consumingOnToggleUp = true; break; case "off": consumingOnToggleDown = true; break; case "both": consumingOnToggleUp = true; consumingOnToggleDown = true; break; default: JUtil.LogErrorMessage(this, "So should I consume resources when turning on, turning off, or both in \"{0}\"?", consumeOnToggle); break; } } } if (!string.IsNullOrEmpty(consumeWhileActive)) { string[] tokens = consumeWhileActive.Split(','); if (tokens.Length == 2) { consumeWhileActiveName = tokens[0].Trim(); if (!(PartResourceLibrary.Instance.GetDefinition(consumeWhileActiveName) != null && float.TryParse(tokens[1].Trim(), NumberStyles.Any, CultureInfo.InvariantCulture, out consumeWhileActiveAmount))) { JUtil.LogErrorMessage(this, "Could not parse \"{0}\"", consumeWhileActive); } else { consumingWhileActive = true; JUtil.LogMessage(this, "Switch in prop {0} prop id {1} will consume {2} while active at a rate of {3}", internalProp.propName, internalProp.propID, consumeWhileActiveName, consumeWhileActiveAmount); } } } if (groupList.ContainsKey(actionName)) { currentState = vessel.ActionGroups[groupList[actionName]]; } else { isCustomAction = true; switch (actionName) { case "intlight": persistentVarName = internalLightName; lightObjects = internalModel.FindModelComponents <Light>(); needsElectricChargeValue |= string.IsNullOrEmpty(needsElectricCharge) || needsElectricChargeValue; break; case "plugin": persistentVarName = string.Empty; foreach (ConfigNode node in GameDatabase.Instance.GetConfigNodes("PROP")) { if (node.GetValue("name") == internalProp.propName) { foreach (ConfigNode pluginConfig in node.GetNodes("MODULE")[moduleID].GetNodes("PLUGINACTION")) { if (pluginConfig.HasValue("name") && pluginConfig.HasValue("actionMethod")) { if (!InstantiateHandler(pluginConfig, this, out actionHandler, out stateHandler)) { JUtil.LogErrorMessage(this, "Failed to instantiate action handler {0}", pluginConfig.GetValue("name")); } else { isPluginAction = true; break; } } } } } if (actionHandler == null) { actionName = "dummy"; JUtil.LogMessage(this, "Plugin handlers did not start, reverting to dummy mode."); } break; default: persistentVarName = "switch" + internalProp.propID + "_" + moduleID; break; } if (!string.IsNullOrEmpty(perPodPersistenceName)) { persistentVarName = perPodPersistenceName; } persistence = new PersistenceAccessor(part); } if (needsElectricChargeValue) { comp = RasterPropMonitorComputer.Instantiate(internalProp); comp.UpdateRefreshRates(lightCheckRate, lightCheckRate); } // set up the toggle switch if (!string.IsNullOrEmpty(switchTransform)) { SmarterButton.CreateButton(internalProp, switchTransform, Click); } if (isCustomAction) { if (isPluginAction && stateHandler != null) { currentState = stateHandler(); } else { if (!string.IsNullOrEmpty(persistentVarName)) { currentState = customGroupList[actionName] = (persistence.GetBool(persistentVarName) ?? currentState); if (actionName == "intlight") { // We have to restore lighting after reading the // persistent variable. SetInternalLights(customGroupList[actionName]); } } } } if (!string.IsNullOrEmpty(animationName)) { // Set up the animation Animation[] animators = animateExterior ? part.FindModelAnimators(animationName) : internalProp.FindModelAnimators(animationName); if (animators.Length > 0) { anim = animators[0]; } else { JUtil.LogErrorMessage(this, "Could not find animation \"{0}\" on {2} \"{1}\"", animationName, animateExterior ? part.name : internalProp.name, animateExterior ? "part" : "prop"); return; } anim[animationName].wrapMode = WrapMode.Once; if (currentState ^ reverse) { anim[animationName].speed = float.MaxValue; anim[animationName].normalizedTime = 0; } else { anim[animationName].speed = float.MinValue; anim[animationName].normalizedTime = 1; } anim.Play(animationName); } else if (!string.IsNullOrEmpty(coloredObject)) { // Set up the color shift. colorShiftRenderer = internalProp.FindModelComponent <Renderer>(coloredObject); disabledColorValue = ConfigNode.ParseColor32(disabledColor); enabledColorValue = ConfigNode.ParseColor32(enabledColor); colorShiftRenderer.material.SetColor(colorName, (currentState ^ reverse ? enabledColorValue : disabledColorValue)); } else { JUtil.LogMessage(this, "Warning, neither color nor animation are defined."); } audioOutput = JUtil.SetupIVASound(internalProp, switchSound, switchSoundVolume, false); startupComplete = true; } catch { JUtil.AnnoyUser(this); enabled = false; throw; } }