internal MASComponentAnimationPlayer(ConfigNode config, InternalProp prop, MASFlightComputer comp)
            : base(config, prop, comp)
        {
            bool exterior = false;

            if (!config.TryGetValue("animation", ref animationName))
            {
                if (!config.TryGetValue("externalAnimation", ref animationName) || string.IsNullOrEmpty(animationName))
                {
                    throw new ArgumentException("Invalid or missing 'externalAnimation' or 'animation' in ANIMATION_PLAYER " + name);
                }

                exterior = true;
            }

            // Set up the animation.
            Animation[] animators = (exterior) ? prop.part.FindModelAnimators(animationName) : prop.FindModelAnimators(animationName);
            if (animators.Length == 0)
            {
                animators = (exterior) ? prop.part.FindModelAnimators() : prop.FindModelAnimators();
                Utility.LogWarning(this, "Did not find{0}animation {1} for ANIMATION_PLAYER {2}.  Valid animation names are:",
                                   (exterior) ? " external " : " ", animationName, name);
                foreach (var a in animators)
                {
                    if (a.clip != null)
                    {
                        Utility.LogWarning(this, "... \"{0}\"", a.clip.name);
                    }
                }
                throw new ArgumentException("Unable to find" + ((exterior) ? " external " : " ") + "animation " + animationName + " for ANIMATION_PLAYER " + name);
            }
            animation      = animators[0];
            animationState = animation[animationName];

            if (!config.TryGetValue("loop", ref loop))
            {
                loop = false;
            }
            animationState.wrapMode = (loop) ? WrapMode.Loop : WrapMode.Once;

            string animationSpeedString = string.Empty;

            if (config.TryGetValue("animationSpeed", ref animationSpeedString))
            {
                variableRegistrar.RegisterVariableChangeCallback(animationSpeedString, AnimationSpeedCallback);
            }

            string variableName = string.Empty;

            if (!config.TryGetValue("variable", ref variableName) || string.IsNullOrEmpty(variableName))
            {
                throw new ArgumentException("Invalid or missing 'variable' in ANIMATION_PLAYER " + name);
            }
            variableName = variableName.Trim();

            variableRegistrar.RegisterVariableChangeCallback(variableName, VariableCallback);
        }
        public static Animation GetAnimation(InternalProp prop, ConfigNode configuration, string configKey, out string configValue)
        {
            configValue = "";
            bool success = configuration.TryGetValue(configKey, ref configValue);

            if (success)
            {
                Animation[] animations = prop.FindModelAnimators(configValue);
                if (animations.Length > 0)
                {
                    return(animations[0]);
                }
                else
                {
                    throw new ArgumentException("InternalProp \"" + prop.name +
                                                "\" does not have animations (config node " + configuration.id + ")");
                }
            }
            else
            {
                throw new ArgumentException(configKey + " not specified for " +
                                            prop.name + " (config node " + configuration.id + ")");
            }
        }
        public VariableAnimationSet(ConfigNode node, InternalProp thisProp, RasterPropMonitorComputer rpmComp, JSIVariableAnimator parent)
        {
            varAnim = parent;
            onChangeDelegate = (Action<float>)Delegate.CreateDelegate(typeof(Action<float>), this, "OnChange");
            part = thisProp.part;

            if (!node.HasData)
            {
                throw new ArgumentException("No data?!");
            }

            string[] tokens = { };

            if (node.HasValue("scale"))
            {
                tokens = node.GetValue("scale").Split(',');
            }

            if (tokens.Length != 2)
            {
                throw new ArgumentException("Could not parse 'scale' parameter.");
            }

            string variableName = string.Empty;
            if (node.HasValue("variableName"))
            {
                variableName = node.GetValue("variableName").Trim();
            }
            else if (node.HasValue("stateMethod"))
            {
                string stateMethod = node.GetValue("stateMethod").Trim();
                // Verify the state method actually exists
                Func<bool> stateFunction = (Func<bool>)rpmComp.GetMethod(stateMethod, thisProp, typeof(Func<bool>));
                if (stateFunction != null)
                {
                    variableName = "PLUGIN_" + stateMethod;
                }
                else
                {
                    throw new ArgumentException("Unrecognized stateMethod");
                }
            }
            else
            {
                throw new ArgumentException("Missing variable name.");
            }

            if (node.HasValue("modulo"))
            {
                variable = new VariableOrNumberRange(rpmComp, variableName, tokens[0], tokens[1], node.GetValue("modulo"));
                usesModulo = true;
            }
            else
            {
                variable = new VariableOrNumberRange(rpmComp, variableName, tokens[0], tokens[1]);
                usesModulo = false;
            }

            // That takes care of the scale, now what to do about that scale:
            if (node.HasValue("reverse"))
            {
                if (!bool.TryParse(node.GetValue("reverse"), out reverse))
                {
                    throw new ArgumentException("So is 'reverse' true or false?");
                }
            }

            if (node.HasValue("animationName"))
            {
                animationName = node.GetValue("animationName");
                if (node.HasValue("animationSpeed"))
                {
                    animationSpeed = float.Parse(node.GetValue("animationSpeed"));

                    if (reverse)
                    {
                        animationSpeed = -animationSpeed;
                    }
                }
                else
                {
                    animationSpeed = 0.0f;
                }
                Animation[] anims = node.HasValue("animateExterior") ? thisProp.part.FindModelAnimators(animationName) : thisProp.FindModelAnimators(animationName);
                if (anims.Length > 0)
                {
                    onAnim = anims[0];
                    onAnim.enabled = true;
                    onAnim[animationName].speed = 0;
                    onAnim[animationName].normalizedTime = reverse ? 1f : 0f;
                    looping = node.HasValue("loopingAnimation");
                    if (looping)
                    {
                        onAnim[animationName].wrapMode = WrapMode.Loop;
                        onAnim.wrapMode = WrapMode.Loop;
                        onAnim[animationName].speed = animationSpeed;
                        mode = Mode.LoopingAnimation;
                    }
                    else
                    {
                        onAnim[animationName].wrapMode = WrapMode.Once;
                        mode = Mode.Animation;
                    }
                    onAnim.Play();
                    alwaysActive = node.HasValue("animateExterior");
                }
                else
                {
                    throw new ArgumentException("Animation could not be found.");
                }

                if (node.HasValue("stopAnimationName"))
                {
                    stopAnimationName = node.GetValue("stopAnimationName");
                    anims = node.HasValue("animateExterior") ? thisProp.part.FindModelAnimators(stopAnimationName) : thisProp.FindModelAnimators(stopAnimationName);
                    if (anims.Length > 0)
                    {
                        offAnim = anims[0];
                        offAnim.enabled = true;
                        offAnim[stopAnimationName].speed = 0;
                        offAnim[stopAnimationName].normalizedTime = reverse ? 1f : 0f;
                        if (looping)
                        {
                            offAnim[stopAnimationName].wrapMode = WrapMode.Loop;
                            offAnim.wrapMode = WrapMode.Loop;
                            offAnim[stopAnimationName].speed = animationSpeed;
                            mode = Mode.LoopingAnimation;
                        }
                        else
                        {
                            offAnim[stopAnimationName].wrapMode = WrapMode.Once;
                            mode = Mode.Animation;
                        }
                    }
                }
            }
            else if (node.HasValue("activeColor") && node.HasValue("passiveColor") && node.HasValue("coloredObject"))
            {
                string colorNameString = "_EmissiveColor";
                if (node.HasValue("colorName"))
                {
                    colorNameString = node.GetValue("colorName");
                }
                colorName = Shader.PropertyToID(colorNameString);

                if (reverse)
                {
                    activeColor = JUtil.ParseColor32(node.GetValue("passiveColor"), thisProp.part, ref rpmComp);
                    passiveColor = JUtil.ParseColor32(node.GetValue("activeColor"), thisProp.part, ref rpmComp);
                }
                else
                {
                    passiveColor = JUtil.ParseColor32(node.GetValue("passiveColor"), thisProp.part, ref rpmComp);
                    activeColor = JUtil.ParseColor32(node.GetValue("activeColor"), thisProp.part, ref rpmComp);
                }
                Renderer colorShiftRenderer = thisProp.FindModelComponent<Renderer>(node.GetValue("coloredObject"));
                affectedMaterial = colorShiftRenderer.material;
                affectedMaterial.SetColor(colorName, passiveColor);
                mode = Mode.Color;
            }
            else if (node.HasValue("controlledTransform") && node.HasValue("localRotationStart") && node.HasValue("localRotationEnd"))
            {
                controlledTransform = thisProp.FindModelTransform(node.GetValue("controlledTransform").Trim());
                initialRotation = controlledTransform.localRotation;
                if (node.HasValue("longPath"))
                {
                    longPath = true;
                    if (reverse)
                    {
                        vectorEnd = ConfigNode.ParseVector3(node.GetValue("localRotationStart"));
                        vectorStart = ConfigNode.ParseVector3(node.GetValue("localRotationEnd"));
                    }
                    else
                    {
                        vectorStart = ConfigNode.ParseVector3(node.GetValue("localRotationStart"));
                        vectorEnd = ConfigNode.ParseVector3(node.GetValue("localRotationEnd"));
                    }
                }
                else
                {
                    if (reverse)
                    {
                        rotationEnd = Quaternion.Euler(ConfigNode.ParseVector3(node.GetValue("localRotationStart")));
                        rotationStart = Quaternion.Euler(ConfigNode.ParseVector3(node.GetValue("localRotationEnd")));
                    }
                    else
                    {
                        rotationStart = Quaternion.Euler(ConfigNode.ParseVector3(node.GetValue("localRotationStart")));
                        rotationEnd = Quaternion.Euler(ConfigNode.ParseVector3(node.GetValue("localRotationEnd")));
                    }
                }
                mode = Mode.Rotation;
            }
            else if (node.HasValue("controlledTransform") && node.HasValue("localTranslationStart") && node.HasValue("localTranslationEnd"))
            {
                controlledTransform = thisProp.FindModelTransform(node.GetValue("controlledTransform").Trim());
                initialPosition = controlledTransform.localPosition;
                if (reverse)
                {
                    vectorEnd = ConfigNode.ParseVector3(node.GetValue("localTranslationStart"));
                    vectorStart = ConfigNode.ParseVector3(node.GetValue("localTranslationEnd"));
                }
                else
                {
                    vectorStart = ConfigNode.ParseVector3(node.GetValue("localTranslationStart"));
                    vectorEnd = ConfigNode.ParseVector3(node.GetValue("localTranslationEnd"));
                }
                mode = Mode.Translation;
            }
            else if (node.HasValue("controlledTransform") && node.HasValue("localScaleStart") && node.HasValue("localScaleEnd"))
            {
                controlledTransform = thisProp.FindModelTransform(node.GetValue("controlledTransform").Trim());
                initialScale = controlledTransform.localScale;
                if (reverse)
                {
                    vectorEnd = ConfigNode.ParseVector3(node.GetValue("localScaleStart"));
                    vectorStart = ConfigNode.ParseVector3(node.GetValue("localScaleEnd"));
                }
                else
                {
                    vectorStart = ConfigNode.ParseVector3(node.GetValue("localScaleStart"));
                    vectorEnd = ConfigNode.ParseVector3(node.GetValue("localScaleEnd"));
                }
                mode = Mode.Scale;
            }
            else if (node.HasValue("controlledTransform") && node.HasValue("textureLayers") && node.HasValue("textureShiftStart") && node.HasValue("textureShiftEnd"))
            {
                affectedMaterial = thisProp.FindModelTransform(node.GetValue("controlledTransform").Trim()).GetComponent<Renderer>().material;
                var textureLayers = node.GetValue("textureLayers").Split(',');
                for (int i = 0; i < textureLayers.Length; ++i)
                {
                    textureLayer.Add(textureLayers[i].Trim());
                }

                if (reverse)
                {
                    textureShiftEnd = ConfigNode.ParseVector2(node.GetValue("textureShiftStart"));
                    textureShiftStart = ConfigNode.ParseVector2(node.GetValue("textureShiftEnd"));
                }
                else
                {
                    textureShiftStart = ConfigNode.ParseVector2(node.GetValue("textureShiftStart"));
                    textureShiftEnd = ConfigNode.ParseVector2(node.GetValue("textureShiftEnd"));
                }
                mode = Mode.TextureShift;
            }
            else if (node.HasValue("controlledTransform") && node.HasValue("textureLayers") && node.HasValue("textureScaleStart") && node.HasValue("textureScaleEnd"))
            {
                affectedMaterial = thisProp.FindModelTransform(node.GetValue("controlledTransform").Trim()).GetComponent<Renderer>().material;
                var textureLayers = node.GetValue("textureLayers").Split(',');
                for (int i = 0; i < textureLayers.Length; ++i)
                {
                    textureLayer.Add(textureLayers[i].Trim());
                }

                if (reverse)
                {
                    textureScaleEnd = ConfigNode.ParseVector2(node.GetValue("textureScaleStart"));
                    textureScaleStart = ConfigNode.ParseVector2(node.GetValue("textureScaleEnd"));
                }
                else
                {
                    textureScaleStart = ConfigNode.ParseVector2(node.GetValue("textureScaleStart"));
                    textureScaleEnd = ConfigNode.ParseVector2(node.GetValue("textureScaleEnd"));
                }
                mode = Mode.TextureScale;
            }
            else
            {
                throw new ArgumentException("Cannot initiate any of the possible action modes.");
            }

            if (!(node.HasValue("maxRateChange") && float.TryParse(node.GetValue("maxRateChange"), out maxRateChange)))
            {
                maxRateChange = 0.0f;
            }
            if (maxRateChange >= 60.0f)
            {
                // Animation rate is too fast to even notice @60Hz
                maxRateChange = 0.0f;
            }
            else
            {
                lastAnimUpdate = Planetarium.GetUniversalTime();
            }

            if (node.HasValue("threshold"))
            {
                threshold = ConfigNode.ParseVector2(node.GetValue("threshold"));
            }

            resourceAmount = 0.0f;
            if (threshold != Vector2.zero)
            {
                thresholdMode = true;

                float min = Mathf.Min(threshold.x, threshold.y);
                float max = Mathf.Max(threshold.x, threshold.y);
                threshold.x = min;
                threshold.y = max;

                if (node.HasValue("flashingDelay"))
                {
                    flashingDelay = double.Parse(node.GetValue("flashingDelay"));
                }

                if (node.HasValue("alarmSound"))
                {
                    alarmSoundVolume = 0.5f;
                    if (node.HasValue("alarmSoundVolume"))
                    {
                        alarmSoundVolume = float.Parse(node.GetValue("alarmSoundVolume"));
                    }
                    audioOutput = JUtil.SetupIVASound(thisProp, node.GetValue("alarmSound"), alarmSoundVolume, false);
                    if (node.HasValue("alarmMustPlayOnce"))
                    {
                        if (!bool.TryParse(node.GetValue("alarmMustPlayOnce"), out alarmMustPlayOnce))
                        {
                            throw new ArgumentException("So is 'alarmMustPlayOnce' true or false?");
                        }
                    }
                    if (node.HasValue("alarmShutdownButton"))
                    {
                        SmarterButton.CreateButton(thisProp, node.GetValue("alarmShutdownButton"), AlarmShutdown);
                    }
                    if (node.HasValue("alarmSoundLooping"))
                    {
                        if (!bool.TryParse(node.GetValue("alarmSoundLooping"), out alarmSoundLooping))
                        {
                            throw new ArgumentException("So is 'alarmSoundLooping' true or false?");
                        }
                        audioOutput.audio.loop = alarmSoundLooping;
                    }

                    inIVA = (CameraManager.Instance.currentCameraMode == CameraManager.CameraMode.IVA);

                    GameEvents.OnCameraChange.Add(OnCameraChange);
                }

                if (node.HasValue("resourceAmount"))
                {
                    resourceAmount = float.Parse(node.GetValue("resourceAmount"));

                    if (node.HasValue("resourceName"))
                    {
                        resourceName = node.GetValue("resourceName");
                    }
                    else
                    {
                        resourceName = "ElectricCharge";
                    }
                }

                TurnOff(Planetarium.GetUniversalTime());
            }

            rpmComp.RegisterVariableCallback(variable.variableName, onChangeDelegate);
        }
        public VariableAnimationSet(ConfigNode node, InternalProp thisProp)
        {
            part = thisProp.part;

            if (!node.HasData)
            {
                throw new ArgumentException("No data?!");
            }

            comp = RasterPropMonitorComputer.Instantiate(thisProp);

            string[] tokens = { };

            if (node.HasValue("scale"))
            {
                tokens = node.GetValue("scale").Split(',');
            }

            if (tokens.Length != 2)
            {
                throw new ArgumentException("Could not parse 'scale' parameter.");
            }

            if (node.HasValue("variableName"))
            {
                string variableName;
                variableName = node.GetValue("variableName").Trim();
                scaleEnds[2] = new VariableOrNumber(variableName, this);
            }
            else if (node.HasValue("stateMethod"))
            {
                Func<bool> stateFunction = (Func<bool>)comp.GetMethod(node.GetValue("stateMethod").Trim(), thisProp, typeof(Func<bool>));
                if (stateFunction != null)
                {
                    scaleEnds[2] = new VariableOrNumber(stateFunction, this);
                }
                else
                {
                    throw new ArgumentException("Unrecognized stateMethod");
                }
            }
            else
            {
                throw new ArgumentException("Missing variable name.");
            }

            scaleEnds[0] = new VariableOrNumber(tokens[0], this);
            scaleEnds[1] = new VariableOrNumber(tokens[1], this);

            // That takes care of the scale, now what to do about that scale:

            if (node.HasValue("reverse"))
            {
                if (!bool.TryParse(node.GetValue("reverse"), out reverse))
                {
                    throw new ArgumentException("So is 'reverse' true or false?");
                }
            }

            if (node.HasValue("animationName"))
            {
                animationName = node.GetValue("animationName");
                if (node.HasValue("animationSpeed"))
                {
                    animationSpeed = float.Parse(node.GetValue("animationSpeed"));

                    if (reverse)
                    {
                        animationSpeed = -animationSpeed;
                    }
                }
                else
                {
                    animationSpeed = 0.0f;
                }
                Animation[] anims = node.HasValue("animateExterior") ? thisProp.part.FindModelAnimators(animationName) : thisProp.FindModelAnimators(animationName);
                if (anims.Length > 0)
                {
                    onAnim = anims[0];
                    onAnim.enabled = true;
                    onAnim[animationName].speed = 0;
                    onAnim[animationName].normalizedTime = reverse ? 1f : 0f;
                    looping = node.HasValue("loopingAnimation");
                    if (looping)
                    {
                        onAnim[animationName].wrapMode = WrapMode.Loop;
                        onAnim.wrapMode = WrapMode.Loop;
                        onAnim[animationName].speed = animationSpeed;
                        mode = Mode.LoopingAnimation;
                    }
                    else
                    {
                        onAnim[animationName].wrapMode = WrapMode.Once;
                        mode = Mode.Animation;
                    }
                    onAnim.Play();
                    alwaysActive = node.HasValue("animateExterior");
                }
                else
                {
                    throw new ArgumentException("Animation could not be found.");
                }

                if (node.HasValue("stopAnimationName"))
                {
                    stopAnimationName = node.GetValue("stopAnimationName");
                    anims = node.HasValue("animateExterior") ? thisProp.part.FindModelAnimators(stopAnimationName) : thisProp.FindModelAnimators(stopAnimationName);
                    if (anims.Length > 0)
                    {
                        offAnim = anims[0];
                        offAnim.enabled = true;
                        offAnim[stopAnimationName].speed = 0;
                        offAnim[stopAnimationName].normalizedTime = reverse ? 1f : 0f;
                        if (looping)
                        {
                            offAnim[stopAnimationName].wrapMode = WrapMode.Loop;
                            offAnim.wrapMode = WrapMode.Loop;
                            offAnim[stopAnimationName].speed = animationSpeed;
                            mode = Mode.LoopingAnimation;
                        }
                        else
                        {
                            offAnim[stopAnimationName].wrapMode = WrapMode.Once;
                            mode = Mode.Animation;
                        }
                    }
                }
            }
            else if (node.HasValue("activeColor") && node.HasValue("passiveColor") && node.HasValue("coloredObject"))
            {
                if (node.HasValue("colorName"))
                    colorName = node.GetValue("colorName");
                passiveColor = ConfigNode.ParseColor32(node.GetValue("passiveColor"));
                activeColor = ConfigNode.ParseColor32(node.GetValue("activeColor"));
                colorShiftRenderer = thisProp.FindModelComponent<Renderer>(node.GetValue("coloredObject"));
                colorShiftRenderer.material.SetColor(colorName, reverse ? activeColor : passiveColor);
                mode = Mode.Color;
            }
            else if (node.HasValue("controlledTransform") && node.HasValue("localRotationStart") && node.HasValue("localRotationEnd"))
            {
                controlledTransform = thisProp.FindModelTransform(node.GetValue("controlledTransform").Trim());
                initialRotation = controlledTransform.localRotation;
                if (node.HasValue("longPath"))
                {
                    longPath = true;
                    vectorStart = ConfigNode.ParseVector3(node.GetValue("localRotationStart"));
                    vectorEnd = ConfigNode.ParseVector3(node.GetValue("localRotationEnd"));
                }
                else
                {
                    rotationStart = Quaternion.Euler(ConfigNode.ParseVector3(node.GetValue("localRotationStart")));
                    rotationEnd = Quaternion.Euler(ConfigNode.ParseVector3(node.GetValue("localRotationEnd")));
                }
                mode = Mode.Rotation;
            }
            else if (node.HasValue("controlledTransform") && node.HasValue("localTranslationStart") && node.HasValue("localTranslationEnd"))
            {
                controlledTransform = thisProp.FindModelTransform(node.GetValue("controlledTransform").Trim());
                initialPosition = controlledTransform.localPosition;
                vectorStart = ConfigNode.ParseVector3(node.GetValue("localTranslationStart"));
                vectorEnd = ConfigNode.ParseVector3(node.GetValue("localTranslationEnd"));
                mode = Mode.Translation;
            }
            else if (node.HasValue("controlledTransform") && node.HasValue("localScaleStart") && node.HasValue("localScaleEnd"))
            {
                controlledTransform = thisProp.FindModelTransform(node.GetValue("controlledTransform").Trim());
                initialScale = controlledTransform.localScale;
                vectorStart = ConfigNode.ParseVector3(node.GetValue("localScaleStart"));
                vectorEnd = ConfigNode.ParseVector3(node.GetValue("localScaleEnd"));
                mode = Mode.Scale;
            }
            else if (node.HasValue("controlledTransform") && node.HasValue("textureLayers") && node.HasValue("textureShiftStart") && node.HasValue("textureShiftEnd"))
            {
                affectedMaterial = thisProp.FindModelTransform(node.GetValue("controlledTransform").Trim()).renderer.material;
                textureLayer = node.GetValue("textureLayers");
                textureShiftStart = ConfigNode.ParseVector2(node.GetValue("textureShiftStart"));
                textureShiftEnd = ConfigNode.ParseVector2(node.GetValue("textureShiftEnd"));
                mode = Mode.TextureShift;
            }
            else if (node.HasValue("controlledTransform") && node.HasValue("textureLayers") && node.HasValue("textureScaleStart") && node.HasValue("textureScaleEnd"))
            {
                affectedMaterial = thisProp.FindModelTransform(node.GetValue("controlledTransform").Trim()).renderer.material;
                textureLayer = node.GetValue("textureLayers");
                textureScaleStart = ConfigNode.ParseVector2(node.GetValue("textureScaleStart"));
                textureScaleEnd = ConfigNode.ParseVector2(node.GetValue("textureScaleEnd"));
                mode = Mode.TextureScale;
            }
            else
            {
                throw new ArgumentException("Cannot initiate any of the possible action modes.");
            }

            if (node.HasValue("threshold"))
            {
                threshold = ConfigNode.ParseVector2(node.GetValue("threshold"));
            }

            resourceAmount = 0.0f;
            if (threshold != Vector2.zero)
            {
                thresholdMode = true;

                float min = Mathf.Min(threshold.x, threshold.y);
                float max = Mathf.Max(threshold.x, threshold.y);
                threshold.x = min;
                threshold.y = max;

                if (node.HasValue("flashingDelay"))
                {
                    flashingDelay = double.Parse(node.GetValue("flashingDelay"));
                }

                if (node.HasValue("alarmSound"))
                {
                    alarmSoundVolume = 0.5f;
                    if (node.HasValue("alarmSoundVolume"))
                        alarmSoundVolume = float.Parse(node.GetValue("alarmSoundVolume"));
                    audioOutput = JUtil.SetupIVASound(thisProp, node.GetValue("alarmSound"), alarmSoundVolume, false);
                    if (node.HasValue("alarmMustPlayOnce"))
                    {
                        if (!bool.TryParse(node.GetValue("alarmMustPlayOnce"), out alarmMustPlayOnce))
                            throw new ArgumentException("So is 'alarmMustPlayOnce' true or false?");
                    }
                    if (node.HasValue("alarmShutdownButton"))
                        SmarterButton.CreateButton(thisProp, node.GetValue("alarmShutdownButton"), AlarmShutdown);
                    if (node.HasValue("alarmSoundLooping"))
                    {
                        if (!bool.TryParse(node.GetValue("alarmSoundLooping"), out alarmSoundLooping))
                            throw new ArgumentException("So is 'alarmSoundLooping' true or false?");
                        audioOutput.audio.loop = alarmSoundLooping;
                    }
                }

                if (node.HasValue("resourceAmount"))
                {
                    resourceAmount = float.Parse(node.GetValue("resourceAmount"));
                }

                TurnOff();
            }
        }
        public VariableAnimationSet(ConfigNode node, InternalProp thisProp)
        {
            part = thisProp.part;

            if (!node.HasData)
            {
                throw new ArgumentException("No data?!");
            }

            string[] tokens = { };

            if (node.HasValue("scale"))
            {
                tokens = node.GetValue("scale").Split(',');
            }

            if (tokens.Length != 2)
            {
                throw new ArgumentException("Could not parse 'scale' parameter.");
            }

            if (node.HasValue("variableName"))
            {
                string variableName;
                variableName = node.GetValue("variableName").Trim();
                scaleEnds[2] = new VariableOrNumber(variableName, this);
            }
            else if (node.HasValue("stateMethod"))
            {
                RPMVesselComputer comp          = RPMVesselComputer.Instance(part.vessel);
                Func <bool>       stateFunction = (Func <bool>)comp.GetMethod(node.GetValue("stateMethod").Trim(), thisProp, typeof(Func <bool>));
                if (stateFunction != null)
                {
                    scaleEnds[2] = new VariableOrNumber(stateFunction, this);
                }
                else
                {
                    throw new ArgumentException("Unrecognized stateMethod");
                }
            }
            else
            {
                throw new ArgumentException("Missing variable name.");
            }

            scaleEnds[0] = new VariableOrNumber(tokens[0], this);
            scaleEnds[1] = new VariableOrNumber(tokens[1], this);

            // That takes care of the scale, now what to do about that scale:

            if (node.HasValue("reverse"))
            {
                if (!bool.TryParse(node.GetValue("reverse"), out reverse))
                {
                    throw new ArgumentException("So is 'reverse' true or false?");
                }
            }

            if (node.HasValue("animationName"))
            {
                animationName = node.GetValue("animationName");
                if (node.HasValue("animationSpeed"))
                {
                    animationSpeed = float.Parse(node.GetValue("animationSpeed"));

                    if (reverse)
                    {
                        animationSpeed = -animationSpeed;
                    }
                }
                else
                {
                    animationSpeed = 0.0f;
                }
                Animation[] anims = node.HasValue("animateExterior") ? thisProp.part.FindModelAnimators(animationName) : thisProp.FindModelAnimators(animationName);
                if (anims.Length > 0)
                {
                    onAnim         = anims[0];
                    onAnim.enabled = true;
                    onAnim[animationName].speed          = 0;
                    onAnim[animationName].normalizedTime = reverse ? 1f : 0f;
                    looping = node.HasValue("loopingAnimation");
                    if (looping)
                    {
                        onAnim[animationName].wrapMode = WrapMode.Loop;
                        onAnim.wrapMode             = WrapMode.Loop;
                        onAnim[animationName].speed = animationSpeed;
                        mode = Mode.LoopingAnimation;
                    }
                    else
                    {
                        onAnim[animationName].wrapMode = WrapMode.Once;
                        mode = Mode.Animation;
                    }
                    onAnim.Play();
                    alwaysActive = node.HasValue("animateExterior");
                }
                else
                {
                    throw new ArgumentException("Animation could not be found.");
                }

                if (node.HasValue("stopAnimationName"))
                {
                    stopAnimationName = node.GetValue("stopAnimationName");
                    anims             = node.HasValue("animateExterior") ? thisProp.part.FindModelAnimators(stopAnimationName) : thisProp.FindModelAnimators(stopAnimationName);
                    if (anims.Length > 0)
                    {
                        offAnim         = anims[0];
                        offAnim.enabled = true;
                        offAnim[stopAnimationName].speed          = 0;
                        offAnim[stopAnimationName].normalizedTime = reverse ? 1f : 0f;
                        if (looping)
                        {
                            offAnim[stopAnimationName].wrapMode = WrapMode.Loop;
                            offAnim.wrapMode = WrapMode.Loop;
                            offAnim[stopAnimationName].speed = animationSpeed;
                            mode = Mode.LoopingAnimation;
                        }
                        else
                        {
                            offAnim[stopAnimationName].wrapMode = WrapMode.Once;
                            mode = Mode.Animation;
                        }
                    }
                }
            }
            else if (node.HasValue("activeColor") && node.HasValue("passiveColor") && node.HasValue("coloredObject"))
            {
                if (node.HasValue("colorName"))
                {
                    colorName = node.GetValue("colorName");
                }
                passiveColor       = ConfigNode.ParseColor32(node.GetValue("passiveColor"));
                activeColor        = ConfigNode.ParseColor32(node.GetValue("activeColor"));
                colorShiftRenderer = thisProp.FindModelComponent <Renderer>(node.GetValue("coloredObject"));
                colorShiftRenderer.material.SetColor(colorName, reverse ? activeColor : passiveColor);
                mode = Mode.Color;
            }
            else if (node.HasValue("controlledTransform") && node.HasValue("localRotationStart") && node.HasValue("localRotationEnd"))
            {
                controlledTransform = thisProp.FindModelTransform(node.GetValue("controlledTransform").Trim());
                initialRotation     = controlledTransform.localRotation;
                if (node.HasValue("longPath"))
                {
                    longPath    = true;
                    vectorStart = ConfigNode.ParseVector3(node.GetValue("localRotationStart"));
                    vectorEnd   = ConfigNode.ParseVector3(node.GetValue("localRotationEnd"));
                }
                else
                {
                    rotationStart = Quaternion.Euler(ConfigNode.ParseVector3(node.GetValue("localRotationStart")));
                    rotationEnd   = Quaternion.Euler(ConfigNode.ParseVector3(node.GetValue("localRotationEnd")));
                }
                mode = Mode.Rotation;
            }
            else if (node.HasValue("controlledTransform") && node.HasValue("localTranslationStart") && node.HasValue("localTranslationEnd"))
            {
                controlledTransform = thisProp.FindModelTransform(node.GetValue("controlledTransform").Trim());
                initialPosition     = controlledTransform.localPosition;
                vectorStart         = ConfigNode.ParseVector3(node.GetValue("localTranslationStart"));
                vectorEnd           = ConfigNode.ParseVector3(node.GetValue("localTranslationEnd"));
                mode = Mode.Translation;
            }
            else if (node.HasValue("controlledTransform") && node.HasValue("localScaleStart") && node.HasValue("localScaleEnd"))
            {
                controlledTransform = thisProp.FindModelTransform(node.GetValue("controlledTransform").Trim());
                initialScale        = controlledTransform.localScale;
                vectorStart         = ConfigNode.ParseVector3(node.GetValue("localScaleStart"));
                vectorEnd           = ConfigNode.ParseVector3(node.GetValue("localScaleEnd"));
                mode = Mode.Scale;
            }
            else if (node.HasValue("controlledTransform") && node.HasValue("textureLayers") && node.HasValue("textureShiftStart") && node.HasValue("textureShiftEnd"))
            {
                affectedMaterial  = thisProp.FindModelTransform(node.GetValue("controlledTransform").Trim()).renderer.material;
                textureLayer      = node.GetValue("textureLayers");
                textureShiftStart = ConfigNode.ParseVector2(node.GetValue("textureShiftStart"));
                textureShiftEnd   = ConfigNode.ParseVector2(node.GetValue("textureShiftEnd"));
                mode = Mode.TextureShift;
            }
            else if (node.HasValue("controlledTransform") && node.HasValue("textureLayers") && node.HasValue("textureScaleStart") && node.HasValue("textureScaleEnd"))
            {
                affectedMaterial  = thisProp.FindModelTransform(node.GetValue("controlledTransform").Trim()).renderer.material;
                textureLayer      = node.GetValue("textureLayers");
                textureScaleStart = ConfigNode.ParseVector2(node.GetValue("textureScaleStart"));
                textureScaleEnd   = ConfigNode.ParseVector2(node.GetValue("textureScaleEnd"));
                mode = Mode.TextureScale;
            }
            else
            {
                throw new ArgumentException("Cannot initiate any of the possible action modes.");
            }

            if (node.HasValue("threshold"))
            {
                threshold = ConfigNode.ParseVector2(node.GetValue("threshold"));
            }

            resourceAmount = 0.0f;
            if (threshold != Vector2.zero)
            {
                thresholdMode = true;

                float min = Mathf.Min(threshold.x, threshold.y);
                float max = Mathf.Max(threshold.x, threshold.y);
                threshold.x = min;
                threshold.y = max;

                if (node.HasValue("flashingDelay"))
                {
                    flashingDelay = double.Parse(node.GetValue("flashingDelay"));
                }

                if (node.HasValue("alarmSound"))
                {
                    alarmSoundVolume = 0.5f;
                    if (node.HasValue("alarmSoundVolume"))
                    {
                        alarmSoundVolume = float.Parse(node.GetValue("alarmSoundVolume"));
                    }
                    audioOutput = JUtil.SetupIVASound(thisProp, node.GetValue("alarmSound"), alarmSoundVolume, false);
                    if (node.HasValue("alarmMustPlayOnce"))
                    {
                        if (!bool.TryParse(node.GetValue("alarmMustPlayOnce"), out alarmMustPlayOnce))
                        {
                            throw new ArgumentException("So is 'alarmMustPlayOnce' true or false?");
                        }
                    }
                    if (node.HasValue("alarmShutdownButton"))
                    {
                        SmarterButton.CreateButton(thisProp, node.GetValue("alarmShutdownButton"), AlarmShutdown);
                    }
                    if (node.HasValue("alarmSoundLooping"))
                    {
                        if (!bool.TryParse(node.GetValue("alarmSoundLooping"), out alarmSoundLooping))
                        {
                            throw new ArgumentException("So is 'alarmSoundLooping' true or false?");
                        }
                        audioOutput.audio.loop = alarmSoundLooping;
                    }
                }

                if (node.HasValue("resourceAmount"))
                {
                    resourceAmount = float.Parse(node.GetValue("resourceAmount"));
                }

                TurnOff();
            }
        }
        public CallbackAnimationSet(ConfigNode node, string variableName, InternalProp thisProp)
        {
            currentState = false;

            if (!node.HasData)
            {
                throw new ArgumentException("No data?!");
            }

            string[] tokens = { };

            if (node.HasValue("scale"))
            {
                tokens = node.GetValue("scale").Split(',');
            }

            if (tokens.Length != 2)
            {
                throw new ArgumentException("Could not parse 'scale' parameter.");
            }

            variable = new VariableOrNumberRange(variableName, tokens[0], tokens[1]);

            // That takes care of the scale, now what to do about that scale:
            if (node.HasValue("reverse"))
            {
                if (!bool.TryParse(node.GetValue("reverse"), out reverse))
                {
                    throw new ArgumentException("So is 'reverse' true or false?");
                }
            }

            if (node.HasValue("animationName"))
            {
                animationName = node.GetValue("animationName");
                if (node.HasValue("animationSpeed"))
                {
                    animationSpeed = float.Parse(node.GetValue("animationSpeed"));

                    if (reverse)
                    {
                        animationSpeed = -animationSpeed;
                    }
                }
                else
                {
                    animationSpeed = 0.0f;
                }
                Animation[] anims = node.HasValue("animateExterior") ? thisProp.part.FindModelAnimators(animationName) : thisProp.FindModelAnimators(animationName);
                if (anims.Length > 0)
                {
                    onAnim         = anims[0];
                    onAnim.enabled = true;
                    onAnim[animationName].speed          = 0;
                    onAnim[animationName].normalizedTime = reverse ? 1f : 0f;
                    looping = node.HasValue("loopingAnimation");
                    if (looping)
                    {
                        onAnim[animationName].wrapMode = WrapMode.Loop;
                        onAnim.wrapMode             = WrapMode.Loop;
                        onAnim[animationName].speed = animationSpeed;
                        mode = Mode.LoopingAnimation;
                    }
                    else
                    {
                        onAnim[animationName].wrapMode = WrapMode.Once;
                        mode = Mode.Animation;
                    }
                    onAnim.Play();
                    //alwaysActive = node.HasValue("animateExterior");
                }
                else
                {
                    throw new ArgumentException("Animation could not be found.");
                }

                if (node.HasValue("stopAnimationName"))
                {
                    stopAnimationName = node.GetValue("stopAnimationName");
                    anims             = node.HasValue("animateExterior") ? thisProp.part.FindModelAnimators(stopAnimationName) : thisProp.FindModelAnimators(stopAnimationName);
                    if (anims.Length > 0)
                    {
                        offAnim         = anims[0];
                        offAnim.enabled = true;
                        offAnim[stopAnimationName].speed          = 0;
                        offAnim[stopAnimationName].normalizedTime = reverse ? 1f : 0f;
                        if (looping)
                        {
                            offAnim[stopAnimationName].wrapMode = WrapMode.Loop;
                            offAnim.wrapMode = WrapMode.Loop;
                            offAnim[stopAnimationName].speed = animationSpeed;
                            mode = Mode.LoopingAnimation;
                        }
                        else
                        {
                            offAnim[stopAnimationName].wrapMode = WrapMode.Once;
                            mode = Mode.Animation;
                        }
                    }
                }
            }
            else if (node.HasValue("activeColor") && node.HasValue("passiveColor") && node.HasValue("coloredObject"))
            {
                if (node.HasValue("colorName"))
                {
                    colorName = node.GetValue("colorName");
                }
                if (reverse)
                {
                    activeColor  = ConfigNode.ParseColor32(node.GetValue("passiveColor"));
                    passiveColor = ConfigNode.ParseColor32(node.GetValue("activeColor"));
                }
                else
                {
                    passiveColor = ConfigNode.ParseColor32(node.GetValue("passiveColor"));
                    activeColor  = ConfigNode.ParseColor32(node.GetValue("activeColor"));
                }
                Renderer colorShiftRenderer = thisProp.FindModelComponent <Renderer>(node.GetValue("coloredObject"));
                affectedMaterial = colorShiftRenderer.material;
                affectedMaterial.SetColor(colorName, passiveColor);
                mode = Mode.Color;
            }
            else if (node.HasValue("controlledTransform") && node.HasValue("localRotationStart") && node.HasValue("localRotationEnd"))
            {
                controlledTransform = thisProp.FindModelTransform(node.GetValue("controlledTransform").Trim());
                initialRotation     = controlledTransform.localRotation;
                if (node.HasValue("longPath"))
                {
                    longPath = true;
                    if (reverse)
                    {
                        vectorEnd   = ConfigNode.ParseVector3(node.GetValue("localRotationStart"));
                        vectorStart = ConfigNode.ParseVector3(node.GetValue("localRotationEnd"));
                    }
                    else
                    {
                        vectorStart = ConfigNode.ParseVector3(node.GetValue("localRotationStart"));
                        vectorEnd   = ConfigNode.ParseVector3(node.GetValue("localRotationEnd"));
                    }
                }
                else
                {
                    if (reverse)
                    {
                        rotationEnd   = Quaternion.Euler(ConfigNode.ParseVector3(node.GetValue("localRotationStart")));
                        rotationStart = Quaternion.Euler(ConfigNode.ParseVector3(node.GetValue("localRotationEnd")));
                    }
                    else
                    {
                        rotationStart = Quaternion.Euler(ConfigNode.ParseVector3(node.GetValue("localRotationStart")));
                        rotationEnd   = Quaternion.Euler(ConfigNode.ParseVector3(node.GetValue("localRotationEnd")));
                    }
                }
                mode = Mode.Rotation;
            }
            else if (node.HasValue("controlledTransform") && node.HasValue("localTranslationStart") && node.HasValue("localTranslationEnd"))
            {
                controlledTransform = thisProp.FindModelTransform(node.GetValue("controlledTransform").Trim());
                initialPosition     = controlledTransform.localPosition;
                if (reverse)
                {
                    vectorEnd   = ConfigNode.ParseVector3(node.GetValue("localTranslationStart"));
                    vectorStart = ConfigNode.ParseVector3(node.GetValue("localTranslationEnd"));
                }
                else
                {
                    vectorStart = ConfigNode.ParseVector3(node.GetValue("localTranslationStart"));
                    vectorEnd   = ConfigNode.ParseVector3(node.GetValue("localTranslationEnd"));
                }
                mode = Mode.Translation;
            }
            else if (node.HasValue("controlledTransform") && node.HasValue("localScaleStart") && node.HasValue("localScaleEnd"))
            {
                controlledTransform = thisProp.FindModelTransform(node.GetValue("controlledTransform").Trim());
                initialScale        = controlledTransform.localScale;
                if (reverse)
                {
                    vectorEnd   = ConfigNode.ParseVector3(node.GetValue("localScaleStart"));
                    vectorStart = ConfigNode.ParseVector3(node.GetValue("localScaleEnd"));
                }
                else
                {
                    vectorStart = ConfigNode.ParseVector3(node.GetValue("localScaleStart"));
                    vectorEnd   = ConfigNode.ParseVector3(node.GetValue("localScaleEnd"));
                }
                mode = Mode.Scale;
            }
            else if (node.HasValue("controlledTransform") && node.HasValue("textureLayers") && node.HasValue("textureShiftStart") && node.HasValue("textureShiftEnd"))
            {
                affectedMaterial = thisProp.FindModelTransform(node.GetValue("controlledTransform").Trim()).GetComponent <Renderer>().material;
                var textureLayers = node.GetValue("textureLayers").Split(',');
                for (int i = 0; i < textureLayers.Length; ++i)
                {
                    textureLayer.Add(textureLayers[i].Trim());
                }

                if (reverse)
                {
                    textureShiftEnd   = ConfigNode.ParseVector2(node.GetValue("textureShiftStart"));
                    textureShiftStart = ConfigNode.ParseVector2(node.GetValue("textureShiftEnd"));
                }
                else
                {
                    textureShiftStart = ConfigNode.ParseVector2(node.GetValue("textureShiftStart"));
                    textureShiftEnd   = ConfigNode.ParseVector2(node.GetValue("textureShiftEnd"));
                }
                mode = Mode.TextureShift;
            }
            else if (node.HasValue("controlledTransform") && node.HasValue("textureLayers") && node.HasValue("textureScaleStart") && node.HasValue("textureScaleEnd"))
            {
                affectedMaterial = thisProp.FindModelTransform(node.GetValue("controlledTransform").Trim()).GetComponent <Renderer>().material;
                var textureLayers = node.GetValue("textureLayers").Split(',');
                for (int i = 0; i < textureLayers.Length; ++i)
                {
                    textureLayer.Add(textureLayers[i].Trim());
                }

                if (reverse)
                {
                    textureScaleEnd   = ConfigNode.ParseVector2(node.GetValue("textureScaleStart"));
                    textureScaleStart = ConfigNode.ParseVector2(node.GetValue("textureScaleEnd"));
                }
                else
                {
                    textureScaleStart = ConfigNode.ParseVector2(node.GetValue("textureScaleStart"));
                    textureScaleEnd   = ConfigNode.ParseVector2(node.GetValue("textureScaleEnd"));
                }
                mode = Mode.TextureScale;
            }
            else
            {
                throw new ArgumentException("Cannot initiate any of the possible action modes.");
            }

            TurnOff();
        }
            internal NumericInput(ConfigNode node, InternalProp internalProp)
            {
                if (!node.HasValue("switchTransform"))
                {
                    throw new Exception("USERINPUTSET missing switchTransform");
                }

                // XNOR!
                if (!(node.HasValue("increment") ^ node.HasNode("incrementCurve")))
                {
                    throw new Exception("USERINPUTSET missing increment or incrementCurve, or it has both");
                }

                if (node.HasValue("increment") && !float.TryParse(node.GetValue("increment"), out increment))
                {
                    throw new Exception("USERINPUTSET bad increment");
                }
                else if (node.HasNode("incrementCurve"))
                {
                    ConfigNode incNode = node.GetNode("incrementCurve");
                    string[]   keys    = incNode.GetValues("key");
                    incrementCurve = new FloatCurve();
                    for (int i = 0; i < keys.Length; ++i)
                    {
                        string[] values = keys[i].Split(' ');
                        if (values.Length == 2)
                        {
                            incrementCurve.Add(float.Parse(values[0]), float.Parse(values[1]));
                        }
                        else if (values.Length == 4)
                        {
                            incrementCurve.Add(float.Parse(values[0]), float.Parse(values[1]), float.Parse(values[2]), float.Parse(values[3]));
                        }
                        else
                        {
                            JUtil.LogErrorMessage(this, "Found a curve key with {0} entries?!?", values.Length);
                        }
                    }
                    pressAndHold = true;
                }

                if (node.HasValue("reverse"))
                {
                    bool.TryParse(node.GetValue("reverse"), out reverse);
                }

                if (node.HasValue("animationName"))
                {
                    animationName = node.GetValue("animationName").Trim();
                }

                float switchSoundVolume = 0.5f;

                if (node.HasValue("switchSoundVolume") && !float.TryParse("switchSoundVolume", out switchSoundVolume))
                {
                    switchSoundVolume = 0.5f;
                }

                if (node.HasValue("switchSound"))
                {
                    audioOutput = JUtil.SetupIVASound(internalProp, node.GetValue("switchSound").Trim(), switchSoundVolume, false);
                }

                if (node.HasValue("customSpeed") && !float.TryParse("customSpeed", out customSpeed))
                {
                    customSpeed = 1.0f;
                }

                if (!string.IsNullOrEmpty(animationName))
                {
                    // Set up the animation
                    Animation[] animators = internalProp.FindModelAnimators(animationName);
                    if (animators.Length > 0)
                    {
                        anim = animators[0];
                    }
                    else
                    {
                        JUtil.LogErrorMessage(this, "Could not find animation \"{0}\" on prop \"{1}\"",
                                              animationName, internalProp.name);
                        return;
                    }
                    anim[animationName].wrapMode = WrapMode.Once;

                    if (reverse)
                    {
                        anim[animationName].speed          = float.MaxValue;
                        anim[animationName].normalizedTime = 0.0f;
                    }
                    else
                    {
                        anim[animationName].speed          = float.MinValue;
                        anim[animationName].normalizedTime = 1.0f;
                    }
                    anim.Play(animationName);
                }

                string switchTransform = node.GetValue("switchTransform");

                if (incrementCurve != null)
                {
                    SmarterButton.CreateButton(internalProp, switchTransform, TimedClick, TimedRelease);
                }
                else
                {
                    SmarterButton.CreateButton(internalProp, switchTransform, Click, TimedRelease);
                }
            }
Example #8
0
        // TODO: Support 'reverse'?
        internal MASComponentAnimationPlayer(ConfigNode config, InternalProp prop, MASFlightComputer comp)
            : base(config, prop, comp)
        {
            bool exterior = false;

            if (!config.TryGetValue("animation", ref animationName))
            {
                if (!config.TryGetValue("externalAnimation", ref animationName) || string.IsNullOrEmpty(animationName))
                {
                    throw new ArgumentException("Invalid or missing 'externalAnimation' or 'animation' in ANIMATION_PLAYER " + name);
                }

                exterior = true;
            }

            // Set up the animation.
            Animation[] animators = (exterior) ? prop.part.FindModelAnimators(animationName) : prop.FindModelAnimators(animationName);
            if (animators.Length == 0)
            {
                throw new ArgumentException("Unable to find" + ((exterior) ? " external " : " ") + "animation " + animationName + " for ANIMATION_PLAYER " + name);
            }
            animation               = animators[0];
            animationState          = animation[animationName];
            animationState.wrapMode = WrapMode.Once;

            config.TryGetValue("animationSpeed", ref animationSpeed);

            string variableName = string.Empty;

            if (!config.TryGetValue("variable", ref variableName) || string.IsNullOrEmpty(variableName))
            {
                throw new ArgumentException("Invalid or missing 'variable' in ANIMATION_PLAYER " + name);
            }
            variableName = variableName.Trim();

            variableRegistrar.RegisterVariableChangeCallback(variableName, VariableCallback);
        }
        /// <summary>
        /// Initialize and configure the callback handler.
        /// </summary>
        /// <param name="node"></param>
        /// <param name="variableName"></param>
        /// <param name="thisProp"></param>
        public CallbackAnimationSet(ConfigNode node, string variableName, InternalProp thisProp)
        {
            currentState = false;

            if (!node.HasData)
            {
                throw new ArgumentException("No data?!");
            }

            string[] tokens = { };

            if (node.HasValue("scale"))
            {
                tokens = node.GetValue("scale").Split(',');
            }

            if (tokens.Length != 2)
            {
                throw new ArgumentException("Could not parse 'scale' parameter.");
            }

            RasterPropMonitorComputer rpmComp = RasterPropMonitorComputer.Instantiate(thisProp, true);
            variable = new VariableOrNumberRange(rpmComp, variableName, tokens[0], tokens[1]);

            // That takes care of the scale, now what to do about that scale:
            if (node.HasValue("reverse"))
            {
                if (!bool.TryParse(node.GetValue("reverse"), out reverse))
                {
                    throw new ArgumentException("So is 'reverse' true or false?");
                }
            }

            if (node.HasValue("flash"))
            {
                if(!bool.TryParse(node.GetValue("flash"), out flash))
                {
                    throw new ArgumentException("So is 'reverse' true or false?");
                }
            }
            else
            {
                flash = false;
            }

            if (node.HasValue("alarmSound"))
            {
                alarmSoundVolume = 0.5f;
                if (node.HasValue("alarmSoundVolume"))
                {
                    alarmSoundVolume = float.Parse(node.GetValue("alarmSoundVolume"));
                }
                audioOutput = JUtil.SetupIVASound(thisProp, node.GetValue("alarmSound"), alarmSoundVolume, false);
                if (node.HasValue("alarmMustPlayOnce"))
                {
                    if (!bool.TryParse(node.GetValue("alarmMustPlayOnce"), out alarmMustPlayOnce))
                    {
                        throw new ArgumentException("So is 'alarmMustPlayOnce' true or false?");
                    }
                }
                if (node.HasValue("alarmShutdownButton"))
                {
                    SmarterButton.CreateButton(thisProp, node.GetValue("alarmShutdownButton"), AlarmShutdown);
                }
                if (node.HasValue("alarmSoundLooping"))
                {
                    if (!bool.TryParse(node.GetValue("alarmSoundLooping"), out alarmSoundLooping))
                    {
                        throw new ArgumentException("So is 'alarmSoundLooping' true or false?");
                    }
                    audioOutput.audio.loop = alarmSoundLooping;
                }

                inIVA = (CameraManager.Instance.currentCameraMode == CameraManager.CameraMode.IVA);

                GameEvents.OnCameraChange.Add(CameraChangeCallback);
            }

            if (node.HasValue("animationName"))
            {
                animationName = node.GetValue("animationName");
                if (node.HasValue("animationSpeed"))
                {
                    animationSpeed = float.Parse(node.GetValue("animationSpeed"));

                    if (reverse)
                    {
                        animationSpeed = -animationSpeed;
                    }
                }
                else
                {
                    animationSpeed = 0.0f;
                }
                Animation[] anims = node.HasValue("animateExterior") ? thisProp.part.FindModelAnimators(animationName) : thisProp.FindModelAnimators(animationName);
                if (anims.Length > 0)
                {
                    onAnim = anims[0];
                    onAnim.enabled = true;
                    onAnim[animationName].speed = 0;
                    onAnim[animationName].normalizedTime = reverse ? 1f : 0f;
                    looping = node.HasValue("loopingAnimation");
                    if (looping)
                    {
                        onAnim[animationName].wrapMode = WrapMode.Loop;
                        onAnim.wrapMode = WrapMode.Loop;
                        onAnim[animationName].speed = animationSpeed;
                        mode = Mode.LoopingAnimation;
                    }
                    else
                    {
                        onAnim[animationName].wrapMode = WrapMode.Once;
                        mode = Mode.Animation;
                    }
                    onAnim.Play();
                    //alwaysActive = node.HasValue("animateExterior");
                }
                else
                {
                    throw new ArgumentException("Animation "+ animationName +" could not be found.");
                }

                if (node.HasValue("stopAnimationName"))
                {
                    stopAnimationName = node.GetValue("stopAnimationName");
                    anims = node.HasValue("animateExterior") ? thisProp.part.FindModelAnimators(stopAnimationName) : thisProp.FindModelAnimators(stopAnimationName);
                    if (anims.Length > 0)
                    {
                        offAnim = anims[0];
                        offAnim.enabled = true;
                        offAnim[stopAnimationName].speed = 0;
                        offAnim[stopAnimationName].normalizedTime = reverse ? 1f : 0f;
                        if (looping)
                        {
                            offAnim[stopAnimationName].wrapMode = WrapMode.Loop;
                            offAnim.wrapMode = WrapMode.Loop;
                            offAnim[stopAnimationName].speed = animationSpeed;
                            mode = Mode.LoopingAnimation;
                        }
                        else
                        {
                            offAnim[stopAnimationName].wrapMode = WrapMode.Once;
                            mode = Mode.Animation;
                        }
                    }
                }
            }
            else if (node.HasValue("activeColor") && node.HasValue("passiveColor") && node.HasValue("coloredObject"))
            {
                string colorNameString = "_EmissiveColor";
                if (node.HasValue("colorName"))
                {
                    colorNameString = node.GetValue("colorName");
                }
                colorName = Shader.PropertyToID(colorNameString);

                if (reverse)
                {
                    activeColor = JUtil.ParseColor32(node.GetValue("passiveColor"), thisProp.part, ref rpmComp);
                    passiveColor = JUtil.ParseColor32(node.GetValue("activeColor"), thisProp.part, ref rpmComp);
                }
                else
                {
                    passiveColor = JUtil.ParseColor32(node.GetValue("passiveColor"), thisProp.part, ref rpmComp);
                    activeColor = JUtil.ParseColor32(node.GetValue("activeColor"), thisProp.part, ref rpmComp);
                }
                Renderer colorShiftRenderer = thisProp.FindModelComponent<Renderer>(node.GetValue("coloredObject"));
                affectedMaterial = colorShiftRenderer.material;
                affectedMaterial.SetColor(colorName, passiveColor);
                mode = Mode.Color;
            }
            else if (node.HasValue("controlledTransform") && node.HasValue("localRotationStart") && node.HasValue("localRotationEnd"))
            {
                controlledTransform = thisProp.FindModelTransform(node.GetValue("controlledTransform").Trim());
                initialRotation = controlledTransform.localRotation;
                if (node.HasValue("longPath"))
                {
                    longPath = true;
                    if (reverse)
                    {
                        vectorEnd = ConfigNode.ParseVector3(node.GetValue("localRotationStart"));
                        vectorStart = ConfigNode.ParseVector3(node.GetValue("localRotationEnd"));
                    }
                    else
                    {
                        vectorStart = ConfigNode.ParseVector3(node.GetValue("localRotationStart"));
                        vectorEnd = ConfigNode.ParseVector3(node.GetValue("localRotationEnd"));
                    }
                }
                else
                {
                    if (reverse)
                    {
                        rotationEnd = Quaternion.Euler(ConfigNode.ParseVector3(node.GetValue("localRotationStart")));
                        rotationStart = Quaternion.Euler(ConfigNode.ParseVector3(node.GetValue("localRotationEnd")));
                    }
                    else
                    {
                        rotationStart = Quaternion.Euler(ConfigNode.ParseVector3(node.GetValue("localRotationStart")));
                        rotationEnd = Quaternion.Euler(ConfigNode.ParseVector3(node.GetValue("localRotationEnd")));
                    }
                }
                mode = Mode.Rotation;
            }
            else if (node.HasValue("controlledTransform") && node.HasValue("localTranslationStart") && node.HasValue("localTranslationEnd"))
            {
                controlledTransform = thisProp.FindModelTransform(node.GetValue("controlledTransform").Trim());
                initialPosition = controlledTransform.localPosition;
                if (reverse)
                {
                    vectorEnd = ConfigNode.ParseVector3(node.GetValue("localTranslationStart"));
                    vectorStart = ConfigNode.ParseVector3(node.GetValue("localTranslationEnd"));
                }
                else
                {
                    vectorStart = ConfigNode.ParseVector3(node.GetValue("localTranslationStart"));
                    vectorEnd = ConfigNode.ParseVector3(node.GetValue("localTranslationEnd"));
                }
                mode = Mode.Translation;
            }
            else if (node.HasValue("controlledTransform") && node.HasValue("localScaleStart") && node.HasValue("localScaleEnd"))
            {
                controlledTransform = thisProp.FindModelTransform(node.GetValue("controlledTransform").Trim());
                initialScale = controlledTransform.localScale;
                if (reverse)
                {
                    vectorEnd = ConfigNode.ParseVector3(node.GetValue("localScaleStart"));
                    vectorStart = ConfigNode.ParseVector3(node.GetValue("localScaleEnd"));
                }
                else
                {
                    vectorStart = ConfigNode.ParseVector3(node.GetValue("localScaleStart"));
                    vectorEnd = ConfigNode.ParseVector3(node.GetValue("localScaleEnd"));
                }
                mode = Mode.Scale;
            }
            else if (node.HasValue("controlledTransform") && node.HasValue("textureLayers") && node.HasValue("textureShiftStart") && node.HasValue("textureShiftEnd"))
            {
                affectedMaterial = thisProp.FindModelTransform(node.GetValue("controlledTransform").Trim()).GetComponent<Renderer>().material;
                var textureLayers = node.GetValue("textureLayers").Split(',');
                for (int i = 0; i < textureLayers.Length; ++i)
                {
                    textureLayer.Add(textureLayers[i].Trim());
                }

                if (reverse)
                {
                    textureShiftEnd = ConfigNode.ParseVector2(node.GetValue("textureShiftStart"));
                    textureShiftStart = ConfigNode.ParseVector2(node.GetValue("textureShiftEnd"));
                }
                else
                {
                    textureShiftStart = ConfigNode.ParseVector2(node.GetValue("textureShiftStart"));
                    textureShiftEnd = ConfigNode.ParseVector2(node.GetValue("textureShiftEnd"));
                }
                mode = Mode.TextureShift;
            }
            else if (node.HasValue("controlledTransform") && node.HasValue("textureLayers") && node.HasValue("textureScaleStart") && node.HasValue("textureScaleEnd"))
            {
                affectedMaterial = thisProp.FindModelTransform(node.GetValue("controlledTransform").Trim()).GetComponent<Renderer>().material;
                var textureLayers = node.GetValue("textureLayers").Split(',');
                for (int i = 0; i < textureLayers.Length; ++i)
                {
                    textureLayer.Add(textureLayers[i].Trim());
                }

                if (reverse)
                {
                    textureScaleEnd = ConfigNode.ParseVector2(node.GetValue("textureScaleStart"));
                    textureScaleStart = ConfigNode.ParseVector2(node.GetValue("textureScaleEnd"));
                }
                else
                {
                    textureScaleStart = ConfigNode.ParseVector2(node.GetValue("textureScaleStart"));
                    textureScaleEnd = ConfigNode.ParseVector2(node.GetValue("textureScaleEnd"));
                }
                mode = Mode.TextureScale;
            }
            else
            {
                throw new ArgumentException("Cannot initiate any of the possible action modes.");
            }

            TurnOff();
        }
            internal NumericInput(ConfigNode node, InternalProp internalProp)
            {
                if (!node.HasValue("switchTransform"))
                {
                    throw new Exception("USERINPUTSET missing switchTransform");
                }

                // XNOR!
                if (!(node.HasValue("increment") ^ node.HasNode("incrementCurve")))
                {
                    throw new Exception("USERINPUTSET missing increment or incrementCurve, or it has both");
                }

                if (node.HasValue("increment") && !float.TryParse(node.GetValue("increment"), out increment))
                {
                    throw new Exception("USERINPUTSET bad increment");
                }
                else if (node.HasNode("incrementCurve"))
                {
                    ConfigNode incNode = node.GetNode("incrementCurve");
                    string[] keys = incNode.GetValues("key");
                    incrementCurve = new FloatCurve();
                    for (int i = 0; i < keys.Length; ++i)
                    {
                        string[] values = keys[i].Split(' ');
                        if (values.Length == 2)
                        {
                            incrementCurve.Add(float.Parse(values[0]), float.Parse(values[1]));
                        }
                        else if (values.Length == 4)
                        {
                            incrementCurve.Add(float.Parse(values[0]), float.Parse(values[1]), float.Parse(values[2]), float.Parse(values[3]));
                        }
                        else
                        {
                            JUtil.LogErrorMessage(this, "Found a curve key with {0} entries?!?", values.Length);
                        }
                    }
                    pressAndHold = true;
                }

                if (node.HasValue("reverse"))
                {
                    bool.TryParse(node.GetValue("reverse"), out reverse);
                }

                if (node.HasValue("animationName"))
                {
                    animationName = node.GetValue("animationName").Trim();
                }

                float switchSoundVolume = 0.5f;
                if (node.HasValue("switchSoundVolume") && !float.TryParse("switchSoundVolume", out switchSoundVolume))
                {
                    switchSoundVolume = 0.5f;
                }

                if (node.HasValue("switchSound"))
                {
                    audioOutput = JUtil.SetupIVASound(internalProp, node.GetValue("switchSound").Trim(), switchSoundVolume, false);
                }

                if (node.HasValue("customSpeed") && !float.TryParse("customSpeed", out customSpeed))
                {
                    customSpeed = 1.0f;
                }

                if (!string.IsNullOrEmpty(animationName))
                {
                    // Set up the animation
                    Animation[] animators = internalProp.FindModelAnimators(animationName);
                    if (animators.Length > 0)
                    {
                        anim = animators[0];
                    }
                    else
                    {
                        JUtil.LogErrorMessage(this, "Could not find animation \"{0}\" on prop \"{1}\"",
                            animationName, internalProp.name);
                        return;
                    }
                    anim[animationName].wrapMode = WrapMode.Once;

                    if (reverse)
                    {
                        anim[animationName].speed = float.MaxValue;
                        anim[animationName].normalizedTime = 0.0f;

                    }
                    else
                    {
                        anim[animationName].speed = float.MinValue;
                        anim[animationName].normalizedTime = 1.0f;
                    }
                    anim.Play(animationName);
                }

                string switchTransform = node.GetValue("switchTransform");
                if (incrementCurve != null)
                {
                    SmarterButton.CreateButton(internalProp, switchTransform, TimedClick, TimedRelease);
                }
                else
                {
                    SmarterButton.CreateButton(internalProp, switchTransform, Click, TimedRelease);
                }
            }
Example #11
0
        /// <summary>
        /// Initialize and configure the callback handler.
        /// </summary>
        /// <param name="node"></param>
        /// <param name="variableName"></param>
        /// <param name="thisProp"></param>
        public CallbackAnimationSet(ConfigNode node, string variableName, InternalProp thisProp)
        {
            currentState = false;

            if (!node.HasData)
            {
                throw new ArgumentException("No data?!");
            }

            string[] tokens = { };

            if (node.HasValue("scale"))
            {
                tokens = node.GetValue("scale").Split(',');
            }

            if (tokens.Length != 2)
            {
                throw new ArgumentException("Could not parse 'scale' parameter.");
            }

            RasterPropMonitorComputer rpmComp = RasterPropMonitorComputer.Instantiate(thisProp, true);

            variable = new VariableOrNumberRange(rpmComp, variableName, tokens[0], tokens[1]);

            // That takes care of the scale, now what to do about that scale:
            if (node.HasValue("reverse"))
            {
                if (!bool.TryParse(node.GetValue("reverse"), out reverse))
                {
                    throw new ArgumentException("So is 'reverse' true or false?");
                }
            }

            if (node.HasValue("flash"))
            {
                if (!bool.TryParse(node.GetValue("flash"), out flash))
                {
                    throw new ArgumentException("So is 'reverse' true or false?");
                }
            }
            else
            {
                flash = false;
            }

            if (node.HasValue("alarmSound"))
            {
                alarmSoundVolume = 0.5f;
                if (node.HasValue("alarmSoundVolume"))
                {
                    alarmSoundVolume = float.Parse(node.GetValue("alarmSoundVolume"));
                }
                audioOutput = JUtil.SetupIVASound(thisProp, node.GetValue("alarmSound"), alarmSoundVolume, false);
                if (node.HasValue("alarmMustPlayOnce"))
                {
                    if (!bool.TryParse(node.GetValue("alarmMustPlayOnce"), out alarmMustPlayOnce))
                    {
                        throw new ArgumentException("So is 'alarmMustPlayOnce' true or false?");
                    }
                }
                if (node.HasValue("alarmShutdownButton"))
                {
                    SmarterButton.CreateButton(thisProp, node.GetValue("alarmShutdownButton"), AlarmShutdown);
                }
                if (node.HasValue("alarmSoundLooping"))
                {
                    if (!bool.TryParse(node.GetValue("alarmSoundLooping"), out alarmSoundLooping))
                    {
                        throw new ArgumentException("So is 'alarmSoundLooping' true or false?");
                    }
                    audioOutput.audio.loop = alarmSoundLooping;
                }

                inIVA = (CameraManager.Instance.currentCameraMode == CameraManager.CameraMode.IVA);

                GameEvents.OnCameraChange.Add(CameraChangeCallback);
            }

            if (node.HasValue("animationName"))
            {
                animationName = node.GetValue("animationName");
                if (node.HasValue("animationSpeed"))
                {
                    animationSpeed = float.Parse(node.GetValue("animationSpeed"));

                    if (reverse)
                    {
                        animationSpeed = -animationSpeed;
                    }
                }
                else
                {
                    animationSpeed = 0.0f;
                }
                Animation[] anims = node.HasValue("animateExterior") ? thisProp.part.FindModelAnimators(animationName) : thisProp.FindModelAnimators(animationName);
                if (anims.Length > 0)
                {
                    onAnim         = anims[0];
                    onAnim.enabled = true;
                    onAnim[animationName].speed          = 0;
                    onAnim[animationName].normalizedTime = reverse ? 1f : 0f;
                    looping = node.HasValue("loopingAnimation");
                    if (looping)
                    {
                        onAnim[animationName].wrapMode = WrapMode.Loop;
                        onAnim.wrapMode             = WrapMode.Loop;
                        onAnim[animationName].speed = animationSpeed;
                        mode = Mode.LoopingAnimation;
                    }
                    else
                    {
                        onAnim[animationName].wrapMode = WrapMode.Once;
                        mode = Mode.Animation;
                    }
                    onAnim.Play();
                    //alwaysActive = node.HasValue("animateExterior");
                }
                else
                {
                    throw new ArgumentException("Animation " + animationName + " could not be found.");
                }

                if (node.HasValue("stopAnimationName"))
                {
                    stopAnimationName = node.GetValue("stopAnimationName");
                    anims             = node.HasValue("animateExterior") ? thisProp.part.FindModelAnimators(stopAnimationName) : thisProp.FindModelAnimators(stopAnimationName);
                    if (anims.Length > 0)
                    {
                        offAnim         = anims[0];
                        offAnim.enabled = true;
                        offAnim[stopAnimationName].speed          = 0;
                        offAnim[stopAnimationName].normalizedTime = reverse ? 1f : 0f;
                        if (looping)
                        {
                            offAnim[stopAnimationName].wrapMode = WrapMode.Loop;
                            offAnim.wrapMode = WrapMode.Loop;
                            offAnim[stopAnimationName].speed = animationSpeed;
                            mode = Mode.LoopingAnimation;
                        }
                        else
                        {
                            offAnim[stopAnimationName].wrapMode = WrapMode.Once;
                            mode = Mode.Animation;
                        }
                    }
                }
            }
            else if (node.HasValue("activeColor") && node.HasValue("passiveColor") && node.HasValue("coloredObject"))
            {
                string colorNameString = "_EmissiveColor";
                if (node.HasValue("colorName"))
                {
                    colorNameString = node.GetValue("colorName");
                }
                colorName = Shader.PropertyToID(colorNameString);

                if (reverse)
                {
                    activeColor  = JUtil.ParseColor32(node.GetValue("passiveColor"), thisProp.part, ref rpmComp);
                    passiveColor = JUtil.ParseColor32(node.GetValue("activeColor"), thisProp.part, ref rpmComp);
                }
                else
                {
                    passiveColor = JUtil.ParseColor32(node.GetValue("passiveColor"), thisProp.part, ref rpmComp);
                    activeColor  = JUtil.ParseColor32(node.GetValue("activeColor"), thisProp.part, ref rpmComp);
                }
                Renderer colorShiftRenderer = thisProp.FindModelComponent <Renderer>(node.GetValue("coloredObject"));
                affectedMaterial = colorShiftRenderer.material;
                affectedMaterial.SetColor(colorName, passiveColor);
                mode = Mode.Color;
            }
            else if (node.HasValue("controlledTransform") && node.HasValue("localRotationStart") && node.HasValue("localRotationEnd"))
            {
                controlledTransform = thisProp.FindModelTransform(node.GetValue("controlledTransform").Trim());
                initialRotation     = controlledTransform.localRotation;
                if (node.HasValue("longPath"))
                {
                    longPath = true;
                    if (reverse)
                    {
                        vectorEnd   = ConfigNode.ParseVector3(node.GetValue("localRotationStart"));
                        vectorStart = ConfigNode.ParseVector3(node.GetValue("localRotationEnd"));
                    }
                    else
                    {
                        vectorStart = ConfigNode.ParseVector3(node.GetValue("localRotationStart"));
                        vectorEnd   = ConfigNode.ParseVector3(node.GetValue("localRotationEnd"));
                    }
                }
                else
                {
                    if (reverse)
                    {
                        rotationEnd   = Quaternion.Euler(ConfigNode.ParseVector3(node.GetValue("localRotationStart")));
                        rotationStart = Quaternion.Euler(ConfigNode.ParseVector3(node.GetValue("localRotationEnd")));
                    }
                    else
                    {
                        rotationStart = Quaternion.Euler(ConfigNode.ParseVector3(node.GetValue("localRotationStart")));
                        rotationEnd   = Quaternion.Euler(ConfigNode.ParseVector3(node.GetValue("localRotationEnd")));
                    }
                }
                mode = Mode.Rotation;
            }
            else if (node.HasValue("controlledTransform") && node.HasValue("localTranslationStart") && node.HasValue("localTranslationEnd"))
            {
                controlledTransform = thisProp.FindModelTransform(node.GetValue("controlledTransform").Trim());
                initialPosition     = controlledTransform.localPosition;
                if (reverse)
                {
                    vectorEnd   = ConfigNode.ParseVector3(node.GetValue("localTranslationStart"));
                    vectorStart = ConfigNode.ParseVector3(node.GetValue("localTranslationEnd"));
                }
                else
                {
                    vectorStart = ConfigNode.ParseVector3(node.GetValue("localTranslationStart"));
                    vectorEnd   = ConfigNode.ParseVector3(node.GetValue("localTranslationEnd"));
                }
                mode = Mode.Translation;
            }
            else if (node.HasValue("controlledTransform") && node.HasValue("localScaleStart") && node.HasValue("localScaleEnd"))
            {
                controlledTransform = thisProp.FindModelTransform(node.GetValue("controlledTransform").Trim());
                initialScale        = controlledTransform.localScale;
                if (reverse)
                {
                    vectorEnd   = ConfigNode.ParseVector3(node.GetValue("localScaleStart"));
                    vectorStart = ConfigNode.ParseVector3(node.GetValue("localScaleEnd"));
                }
                else
                {
                    vectorStart = ConfigNode.ParseVector3(node.GetValue("localScaleStart"));
                    vectorEnd   = ConfigNode.ParseVector3(node.GetValue("localScaleEnd"));
                }
                mode = Mode.Scale;
            }
            else if (node.HasValue("controlledTransform") && node.HasValue("textureLayers") && node.HasValue("textureShiftStart") && node.HasValue("textureShiftEnd"))
            {
                affectedMaterial = thisProp.FindModelTransform(node.GetValue("controlledTransform").Trim()).GetComponent <Renderer>().material;
                var textureLayers = node.GetValue("textureLayers").Split(',');
                for (int i = 0; i < textureLayers.Length; ++i)
                {
                    textureLayer.Add(textureLayers[i].Trim());
                }

                if (reverse)
                {
                    textureShiftEnd   = ConfigNode.ParseVector2(node.GetValue("textureShiftStart"));
                    textureShiftStart = ConfigNode.ParseVector2(node.GetValue("textureShiftEnd"));
                }
                else
                {
                    textureShiftStart = ConfigNode.ParseVector2(node.GetValue("textureShiftStart"));
                    textureShiftEnd   = ConfigNode.ParseVector2(node.GetValue("textureShiftEnd"));
                }
                mode = Mode.TextureShift;
            }
            else if (node.HasValue("controlledTransform") && node.HasValue("textureLayers") && node.HasValue("textureScaleStart") && node.HasValue("textureScaleEnd"))
            {
                affectedMaterial = thisProp.FindModelTransform(node.GetValue("controlledTransform").Trim()).GetComponent <Renderer>().material;
                var textureLayers = node.GetValue("textureLayers").Split(',');
                for (int i = 0; i < textureLayers.Length; ++i)
                {
                    textureLayer.Add(textureLayers[i].Trim());
                }

                if (reverse)
                {
                    textureScaleEnd   = ConfigNode.ParseVector2(node.GetValue("textureScaleStart"));
                    textureScaleStart = ConfigNode.ParseVector2(node.GetValue("textureScaleEnd"));
                }
                else
                {
                    textureScaleStart = ConfigNode.ParseVector2(node.GetValue("textureScaleStart"));
                    textureScaleEnd   = ConfigNode.ParseVector2(node.GetValue("textureScaleEnd"));
                }
                mode = Mode.TextureScale;
            }
            else
            {
                throw new ArgumentException("Cannot initiate any of the possible action modes.");
            }

            TurnOff();
        }