void IFlightControlParameter.UpdateAutopilot(FlightCtrlState c) { if (Enabled) { c.wheelThrottle = (float)KOSMath.Clamp(Value, -1, 1); } }
public override void Set(object value) { var dblValue = System.Convert.ToDouble(value); base.Set(System.Math.Abs(stepIncrement) < 0.0001 ? KOSMath.Clamp(dblValue, min, max) : KOSMath.ClampToIndent(dblValue, min, max, stepIncrement)); }
public RgbaColor(float red, float green, float blue, float alpha = (float)1.0) : this() { Red = KOSMath.Clamp(red, 0, 255); Green = KOSMath.Clamp(green, 0, 255); Blue = KOSMath.Clamp(blue, 0, 255); Alpha = KOSMath.Clamp(alpha, 0, 255); }
public override void Execute(SafeSharedObjects shared) { double ang2 = GetDouble(PopValueAssert(shared)); double ang1 = GetDouble(PopValueAssert(shared)); AssertArgBottomAndConsume(shared); double result = KOSMath.DegreeFix(ang2 - ang1, -180); ReturnValue = result; }
private void SetRotation(Vector vectorValue) { if (vectorValue == null) { yaw = 0.0f; pitch = 0.0f; roll = 0.0f; } else { yaw = (float)KOSMath.Clamp(vectorValue.X, -1, 1); pitch = (float)KOSMath.Clamp(vectorValue.Y, -1, 1); roll = (float)KOSMath.Clamp(vectorValue.Z, -1, 1); } }
private void SetTranslation(Vector vectorValue) { if (vectorValue == null) { fore = 0.0f; top = 0.0f; starboard = 0.0f; } else { starboard = (float)KOSMath.Clamp(vectorValue.X, -1, 1); top = (float)KOSMath.Clamp(vectorValue.Y, -1, 1); fore = (float)KOSMath.Clamp(vectorValue.Z, -1, 1); } }
void IFlightControlParameter.UpdateValue(object value, SharedObjects shared) { if (!Enabled) { ((IFlightControlParameter)this).EnableControl(shared); } try { Value = KOSMath.Clamp(Convert.ToDouble(value), 0, 1); } catch { throw new KOSWrongControlValueTypeException( "THROTTLE", KOSNomenclature.GetKOSName(value.GetType()), string.Format("{0} in the range [0..1]", KOSNomenclature.GetKOSName(typeof(ScalarValue))) ); } }
/// <summary> /// Fix the strange too-large or too-small angle degrees that are sometimes /// returned by KSP, normalizing them into a constrained 360 degree range. /// </summary> /// <param name="inAngle">input angle in degrees</param> /// <param name="rangeStart"> /// Bottom of 360 degree range to normalize to. /// ( 0 means the range [0..360]), while -180 means [-180,180] ) /// </param> /// <returns>the same angle, normalized to the range given.</returns> public static double DegreeFix(double inAngle, double rangeStart) { // Use the kOS.Safe implementation to avoid duplicated code return(KOSMath.DegreeFix(inAngle, rangeStart)); }
/// <summary> /// Return true if the value given is allowed for the field given. This uses the hints from the GUI /// system to decide what is and isn't allowed. (For example if a GUI slider goes from 10 to 20 at /// increments of 2, then a value of 17 is not something you could achieve in the GUI, being only able /// to go from 16 to 18 skipping over 17, and therefore this routine would return false for trying to /// set it to 17). /// <br/><br/> /// Note that the value passed in may be altered (which is why it's ref) when it's not /// exactly legal, but it's CLOSE ENOUGH to be coerced into a legal value. For example, /// you set a slider to 10.45 and the slider only allows values on the 0.5 marks like 10, 10.5, 11. etc. /// Rather than deny the attempt, the value will be nudged to the nearest legal value. /// </summary> /// <param name="field">Which KSPField is being checked?</param> /// <param name="newVal">What is the value it's being set to? It is possible to /// alter the value to an acceptable replacement which is why it passes by ref</param> /// <param name="except">An exception you can choose to throw if you want, or null if the value is legal.</param> /// <returns>Is it legal?</returns> private bool IsLegalValue(BaseField field, ref Structure newVal, out KOSException except) { except = null; bool isLegal = true; Type fType = field.FieldInfo.FieldType; object convertedVal = newVal; // Using TryGetFieldUIControl() to obtain the control that goes with this // field is from advice from TriggerAU, of SQUAD, who gave that advice in // a forum post when I described the problems we were having with the servo // parts in Breaking Ground DLC. (There is some kind of work being done here // that seems to allow one field's ranges to override another's as the servo // parts need to do. This is work which doesn't seem to happen if you look at // the KSPField's control ranges directly): UI_Control control; if (!partModule.Fields.TryGetFieldUIControl(field.name, out control)) { throw new KOSInvalidFieldValueException("Field appears to have no UI control attached so kOS refuses to let a script change it."); } if (!control.controlEnabled) { except = new KOSInvalidFieldValueException("Field is read-only"); return(false); } if (!newVal.GetType().IsSubclassOf(fType)) { try { convertedVal = Convert.ChangeType(newVal, fType); } catch (InvalidCastException) { except = new KOSCastException(newVal.GetType(), fType); return(false); } catch (FormatException) { except = new KOSCastException(newVal.GetType(), fType); return(false); } } // Some of these are subclasses of each other, so don't change this to an if/else. // It's a series of if's on purpose so it checks all classes the control is derived from. if (control is UI_Toggle) { // Seems there's nothing to check here, but maybe later there will be? } if (control is UI_Label) { except = new KOSInvalidFieldValueException("Labels are read-only objects that can't be changed"); isLegal = false; } var vector2 = control as UI_Vector2; if (vector2 != null) { // I have no clue what this actually looks like in the UI? What is a // user editable 2-D vector widget? I've never seen this before. if (convertedVal != null) { var vec2 = (Vector2)convertedVal; if (vec2.x < vector2.minValueX || vec2.x > vector2.maxValueX || vec2.y < vector2.minValueY || vec2.y > vector2.maxValueY) { except = new KOSInvalidFieldValueException("Vector2 is outside of allowed range of values"); isLegal = false; } } } var range = control as UI_FloatRange; if (range != null) { float val = Convert.ToSingle(convertedVal); val = KOSMath.ClampToIndent(val, range.minValue, range.maxValue, range.stepIncrement); convertedVal = Convert.ToDouble(val); } newVal = FromPrimitiveWithAssert(convertedVal); return(isLegal); }
/// <summary> /// Return true if the value given is allowed for the field given. This uses the hints from the GUI /// system to decide what is and isn't allowed. (For example if a GUI slider goes from 10 to 20 at /// increments of 2, then a value of 17 is not something you could achieve in the GUI, being only able /// to go from 16 to 18 skipping over 17, and therefore this routine would return false for trying to /// set it to 17). /// <br/><br/> /// Note that the value passed in may be altered (which is why it's ref) when it's not /// exactly legal, but it's CLOSE ENOUGH to be coerced into a legal value. For example, /// you set a slider to 10.45 and the slider only allows values on the 0.5 marks like 10, 10.5, 11. etc. /// Rather than deny the attempt, the value will be nudged to the nearest legal value. /// </summary> /// <param name="field">Which KSPField is being checked?</param> /// <param name="newVal">What is the value it's being set to? It is possible to /// alter the value to an acceptable replacement which is why it passes by ref</param> /// <param name="except">An exception you can choose to throw if you want, or null if the value is legal.</param> /// <returns>Is it legal?</returns> private bool IsLegalValue(BaseField field, ref Structure newVal, out KOSException except) { except = null; bool isLegal = true; Type fType = field.FieldInfo.FieldType; object convertedVal = newVal; if (!IsEditable(field)) { except = new KOSInvalidFieldValueException("Field is read-only"); return(false); } if (!newVal.GetType().IsSubclassOf(fType)) { try { convertedVal = Convert.ChangeType(newVal, fType); } catch (InvalidCastException) { except = new KOSCastException(newVal.GetType(), fType); return(false); } catch (FormatException) { except = new KOSCastException(newVal.GetType(), fType); return(false); } } List <UI_Control> controls = GetFieldControls(field); // It's really normal for there to be only one control on a KSPField, but because // it's technically possible to have more than one according to the structure of // the API, this loop is here to check all of "them": foreach (UI_Control control in controls) { // Some of these are subclasses of each other, so don't change this to an if/else. // It's a series of if's on purpose so it checks all classes the control is derived from. if (control is UI_Toggle) { // Seems there's nothing to check here, but maybe later there will be? } if (control is UI_Label) { except = new KOSInvalidFieldValueException("Labels are read-only objects that can't be changed"); isLegal = false; } var vector2 = control as UI_Vector2; if (vector2 != null) { // I have no clue what this actually looks like in the UI? What is a // user editable 2-D vector widget? I've never seen this before. if (convertedVal != null) { var vec2 = (Vector2)convertedVal; if (vec2.x < vector2.minValueX || vec2.x > vector2.maxValueX || vec2.y < vector2.minValueY || vec2.y > vector2.maxValueY) { except = new KOSInvalidFieldValueException("Vector2 is outside of allowed range of values"); isLegal = false; } } } var range = control as UI_FloatRange; if (range != null) { float val = Convert.ToSingle(convertedVal); val = KOSMath.ClampToIndent(val, range.minValue, range.maxValue, range.stepIncrement); convertedVal = Convert.ToDouble(val); } if (!isLegal) { break; } } newVal = FromPrimitiveWithAssert(convertedVal); return(isLegal); }