Esempio n. 1
0
        public Sequence(string unit, string name, MiniYaml info)
        {
            var srcOverride = info.Value;

            Name = name;
            var d         = info.NodesDict;
            var offset    = float2.Zero;
            var blendMode = BlendMode.Alpha;

            try
            {
                if (d.ContainsKey("Start"))
                {
                    Start = int.Parse(d["Start"].Value);
                }

                if (d.ContainsKey("Offset"))
                {
                    offset = FieldLoader.GetValue <float2>("Offset", d["Offset"].Value);
                }

                if (d.ContainsKey("BlendMode"))
                {
                    blendMode = FieldLoader.GetValue <BlendMode>("BlendMode", d["BlendMode"].Value);
                }

                // Apply offset to each sprite in the sequence
                // Different sequences may apply different offsets to the same frame
                sprites = Game.modData.SpriteLoader.LoadAllSprites(srcOverride ?? unit).Select(
                    s => new Sprite(s.sheet, s.bounds, s.offset + offset, s.channel, blendMode)).ToArray();

                if (!d.ContainsKey("Length"))
                {
                    Length = 1;
                }
                else if (d["Length"].Value == "*")
                {
                    Length = sprites.Length - Start;
                }
                else
                {
                    Length = int.Parse(d["Length"].Value);
                }

                if (d.ContainsKey("Stride"))
                {
                    Stride = int.Parse(d["Stride"].Value);
                }
                else
                {
                    Stride = Length;
                }

                if (d.ContainsKey("Facings"))
                {
                    var f = int.Parse(d["Facings"].Value);
                    Facings        = Math.Abs(f);
                    reverseFacings = f < 0;
                }
                else
                {
                    Facings = 1;
                }

                if (d.ContainsKey("Tick"))
                {
                    Tick = int.Parse(d["Tick"].Value);
                }
                else
                {
                    Tick = 40;
                }

                if (d.ContainsKey("Transpose"))
                {
                    transpose = bool.Parse(d["Transpose"].Value);
                }

                if (d.ContainsKey("Frames"))
                {
                    Frames = Array.ConvertAll <string, int>(d["Frames"].Value.Split(','), int.Parse);
                }

                if (d.ContainsKey("ShadowStart"))
                {
                    ShadowStart = int.Parse(d["ShadowStart"].Value);
                }
                else
                {
                    ShadowStart = -1;
                }

                if (d.ContainsKey("ShadowZOffset"))
                {
                    WRange r;
                    if (WRange.TryParse(d["ShadowZOffset"].Value, out r))
                    {
                        ShadowZOffset = r.Range;
                    }
                }
                else
                {
                    ShadowZOffset = -5;
                }

                if (d.ContainsKey("ZOffset"))
                {
                    WRange r;
                    if (WRange.TryParse(d["ZOffset"].Value, out r))
                    {
                        ZOffset = r.Range;
                    }
                }

                if (Length > Stride)
                {
                    throw new InvalidOperationException(
                              "{0}: Sequence {1}.{2}: Length must be <= stride"
                              .F(info.Nodes[0].Location, unit, name));
                }

                if (Start < 0 || Start + Facings * Stride > sprites.Length || ShadowStart + Facings * Stride > sprites.Length)
                {
                    throw new InvalidOperationException(
                              "{6}: Sequence {0}.{1} uses frames [{2}..{3}] of SHP `{4}`, but only 0..{5} actually exist"
                              .F(unit, name, Start, Start + Facings * Stride - 1, srcOverride ?? unit, sprites.Length - 1,
                                 info.Nodes[0].Location));
                }
            }
            catch (FormatException f)
            {
                throw new FormatException("Failed to parse sequences for {0}.{1} at {2}:\n{3}".F(unit, name, info.Nodes[0].Location, f));
            }
        }
Esempio n. 2
0
        public static object GetValue(string fieldName, Type fieldType, string value, MemberInfo field)
        {
            if (value != null)
            {
                value = value.Trim();
            }

            if (fieldType == typeof(int))
            {
                int res;
                if (int.TryParse(value, out res))
                {
                    return(res);
                }
                return(InvalidValueAction(value, fieldType, fieldName));
            }

            else if (fieldType == typeof(ushort))
            {
                ushort res;
                if (ushort.TryParse(value, out res))
                {
                    return(res);
                }
                return(InvalidValueAction(value, fieldType, fieldName));
            }

            if (fieldType == typeof(long))
            {
                long res;
                if (long.TryParse(value, out res))
                {
                    return(res);
                }
                return(InvalidValueAction(value, fieldType, fieldName));
            }

            else if (fieldType == typeof(float))
            {
                float res;
                if (float.TryParse(value.Replace("%", ""), NumberStyles.Any, NumberFormatInfo.InvariantInfo, out res))
                {
                    return(res * (value.Contains('%') ? 0.01f : 1f));
                }
                return(InvalidValueAction(value, fieldType, fieldName));
            }

            else if (fieldType == typeof(decimal))
            {
                decimal res;
                if (decimal.TryParse(value.Replace("%", ""), NumberStyles.Any, NumberFormatInfo.InvariantInfo, out res))
                {
                    return(res * (value.Contains('%') ? 0.01m : 1m));
                }
                return(InvalidValueAction(value, fieldType, fieldName));
            }

            else if (fieldType == typeof(string))
            {
                if (field != null && field.HasAttribute <TranslateAttribute>())
                {
                    return(Regex.Replace(value, "@[^@]+@", m => Translate(m.Value.Substring(1, m.Value.Length - 2)), RegexOptions.Compiled));
                }
                return(value);
            }

            else if (fieldType == typeof(Color))
            {
                var parts = value.Split(',');
                if (parts.Length == 3)
                {
                    return(Color.FromArgb(int.Parse(parts[0]).Clamp(0, 255), int.Parse(parts[1]).Clamp(0, 255), int.Parse(parts[2]).Clamp(0, 255)));
                }
                if (parts.Length == 4)
                {
                    return(Color.FromArgb(int.Parse(parts[0]).Clamp(0, 255), int.Parse(parts[1]).Clamp(0, 255), int.Parse(parts[2]).Clamp(0, 255), int.Parse(parts[3]).Clamp(0, 255)));
                }
                return(InvalidValueAction(value, fieldType, fieldName));
            }

            else if (fieldType == typeof(HSLColor))
            {
                var parts = value.Split(',');

                // Allow old ColorRamp format to be parsed as HSLColor
                if (parts.Length == 3 || parts.Length == 4)
                {
                    return(new HSLColor(
                               (byte)int.Parse(parts[0]).Clamp(0, 255),
                               (byte)int.Parse(parts[1]).Clamp(0, 255),
                               (byte)int.Parse(parts[2]).Clamp(0, 255)));
                }

                return(InvalidValueAction(value, fieldType, fieldName));
            }

            else if (fieldType == typeof(Hotkey))
            {
                Hotkey res;
                if (Hotkey.TryParse(value, out res))
                {
                    return(res);
                }

                return(InvalidValueAction(value, fieldType, fieldName));
            }

            else if (fieldType == typeof(WRange))
            {
                WRange res;
                if (WRange.TryParse(value, out res))
                {
                    return(res);
                }

                return(InvalidValueAction(value, fieldType, fieldName));
            }

            else if (fieldType == typeof(WVec))
            {
                var parts = value.Split(',');
                if (parts.Length == 3)
                {
                    WRange rx, ry, rz;
                    if (WRange.TryParse(parts[0], out rx) && WRange.TryParse(parts[1], out ry) && WRange.TryParse(parts[2], out rz))
                    {
                        return(new WVec(rx, ry, rz));
                    }
                }

                return(InvalidValueAction(value, fieldType, fieldName));
            }

            else if (fieldType == typeof(WPos))
            {
                var parts = value.Split(',');
                if (parts.Length == 3)
                {
                    WRange rx, ry, rz;
                    if (WRange.TryParse(parts[0], out rx) && WRange.TryParse(parts[1], out ry) && WRange.TryParse(parts[2], out rz))
                    {
                        return(new WPos(rx, ry, rz));
                    }
                }

                return(InvalidValueAction(value, fieldType, fieldName));
            }

            else if (fieldType == typeof(WAngle))
            {
                int res;
                if (int.TryParse(value, out res))
                {
                    return(new WAngle(res));
                }
                return(InvalidValueAction(value, fieldType, fieldName));
            }

            else if (fieldType == typeof(WRot))
            {
                var parts = value.Split(',');
                if (parts.Length == 3)
                {
                    int rr, rp, ry;
                    if (int.TryParse(value, out rr) && int.TryParse(value, out rp) && int.TryParse(value, out ry))
                    {
                        return(new WRot(new WAngle(rr), new WAngle(rp), new WAngle(ry)));
                    }
                }

                return(InvalidValueAction(value, fieldType, fieldName));
            }

            else if (fieldType.IsEnum)
            {
                if (!Enum.GetNames(fieldType).Select(a => a.ToLower()).Contains(value.ToLower()))
                {
                    return(InvalidValueAction(value, fieldType, fieldName));
                }
                return(Enum.Parse(fieldType, value, true));
            }

            else if (fieldType == typeof(bool))
            {
                return(ParseYesNo(value, fieldType, fieldName));
            }

            else if (fieldType.IsArray)
            {
                if (value == null)
                {
                    return(Array.CreateInstance(fieldType.GetElementType(), 0));
                }

                var parts = value.Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries);

                var ret = Array.CreateInstance(fieldType.GetElementType(), parts.Length);
                for (int i = 0; i < parts.Length; i++)
                {
                    ret.SetValue(GetValue(fieldName, fieldType.GetElementType(), parts[i].Trim(), field), i);
                }
                return(ret);
            }

            else if (fieldType == typeof(int2))
            {
                var parts = value.Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries);
                return(new int2(int.Parse(parts[0]), int.Parse(parts[1])));
            }

            else if (fieldType == typeof(float2))
            {
                var   parts = value.Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries);
                float xx    = 0;
                float yy    = 0;
                float res;
                if (float.TryParse(parts[0].Replace("%", ""), out res))
                {
                    xx = res * (parts[0].Contains('%') ? 0.01f : 1f);
                }
                if (float.TryParse(parts[1].Replace("%", ""), out res))
                {
                    yy = res * (parts[1].Contains('%') ? 0.01f : 1f);
                }
                return(new float2(xx, yy));
            }

            else if (fieldType == typeof(Rectangle))
            {
                var parts = value.Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries);
                return(new Rectangle(int.Parse(parts[0]), int.Parse(parts[1]), int.Parse(parts[2]), int.Parse(parts[3])));
            }

            else if (fieldType.IsGenericType && fieldType.GetGenericTypeDefinition() == typeof(Bits <>))
            {
                var parts     = value.Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries);
                var argTypes  = new Type[] { typeof(string[]) };
                var argValues = new object[] { parts };
                return(fieldType.GetConstructor(argTypes).Invoke(argValues));
            }

            else if (fieldType.IsGenericType && fieldType.GetGenericTypeDefinition() == typeof(Nullable <>))
            {
                var innerType  = fieldType.GetGenericArguments().First();
                var innerValue = GetValue("Nullable<T>", innerType, value, field);
                return(fieldType.GetConstructor(new[] { innerType }).Invoke(new[] { innerValue }));
            }

            UnknownFieldAction("[Type] {0}".F(value), fieldType);
            return(null);
        }
Esempio n. 3
0
        public static object GetValue(string field, Type fieldType, string x)
        {
            if (x != null)
            {
                x = x.Trim();
            }
            if (fieldType == typeof(int))
            {
                int res;
                if (int.TryParse(x, out res))
                {
                    return(res);
                }
                return(InvalidValueAction(x, fieldType, field));
            }

            else if (fieldType == typeof(ushort))
            {
                ushort res;
                if (ushort.TryParse(x, out res))
                {
                    return(res);
                }
                return(InvalidValueAction(x, fieldType, field));
            }

            else if (fieldType == typeof(float))
            {
                float res;
                if (float.TryParse(x.Replace("%", ""), NumberStyles.Any, NumberFormatInfo.InvariantInfo, out res))
                {
                    return(res * (x.Contains('%') ? 0.01f : 1f));
                }
                return(InvalidValueAction(x, fieldType, field));
            }

            else if (fieldType == typeof(decimal))
            {
                decimal res;
                if (decimal.TryParse(x.Replace("%", ""), NumberStyles.Any, NumberFormatInfo.InvariantInfo, out res))
                {
                    return(res * (x.Contains('%') ? 0.01m : 1m));
                }
                return(InvalidValueAction(x, fieldType, field));
            }

            else if (fieldType == typeof(string))
            {
                return(x);
            }

            else if (fieldType == typeof(Color))
            {
                var parts = x.Split(',');
                if (parts.Length == 3)
                {
                    return(Color.FromArgb(int.Parse(parts[0]).Clamp(0, 255), int.Parse(parts[1]).Clamp(0, 255), int.Parse(parts[2]).Clamp(0, 255)));
                }
                if (parts.Length == 4)
                {
                    return(Color.FromArgb(int.Parse(parts[0]).Clamp(0, 255), int.Parse(parts[1]).Clamp(0, 255), int.Parse(parts[2]).Clamp(0, 255), int.Parse(parts[3]).Clamp(0, 255)));
                }
                return(InvalidValueAction(x, fieldType, field));
            }

            else if (fieldType == typeof(HSLColor))
            {
                var parts = x.Split(',');
                // Allow old ColorRamp format to be parsed as HSLColor
                if (parts.Length == 3 || parts.Length == 4)
                {
                    return(new HSLColor(
                               (byte)int.Parse(parts[0]).Clamp(0, 255),
                               (byte)int.Parse(parts[1]).Clamp(0, 255),
                               (byte)int.Parse(parts[2]).Clamp(0, 255)));
                }

                return(InvalidValueAction(x, fieldType, field));
            }

            else if (fieldType == typeof(WRange))
            {
                WRange res;
                if (WRange.TryParse(x, out res))
                {
                    return(res);
                }

                return(InvalidValueAction(x, fieldType, field));
            }

            else if (fieldType == typeof(WVec))
            {
                var parts = x.Split(',');
                if (parts.Length == 3)
                {
                    WRange rx, ry, rz;
                    if (WRange.TryParse(parts[0], out rx) && WRange.TryParse(parts[1], out ry) && WRange.TryParse(parts[2], out rz))
                    {
                        return(new WVec(rx, ry, rz));
                    }
                }

                return(InvalidValueAction(x, fieldType, field));
            }

            else if (fieldType == typeof(WPos))
            {
                var parts = x.Split(',');
                if (parts.Length == 3)
                {
                    WRange rx, ry, rz;
                    if (WRange.TryParse(parts[0], out rx) && WRange.TryParse(parts[1], out ry) && WRange.TryParse(parts[2], out rz))
                    {
                        return(new WPos(rx, ry, rz));
                    }
                }

                return(InvalidValueAction(x, fieldType, field));
            }

            else if (fieldType == typeof(WAngle))
            {
                int res;
                if (int.TryParse(x, out res))
                {
                    return(new WAngle(res));
                }
                return(InvalidValueAction(x, fieldType, field));
            }

            else if (fieldType == typeof(WRot))
            {
                var parts = x.Split(',');
                if (parts.Length == 3)
                {
                    int rr, rp, ry;
                    if (int.TryParse(x, out rr) && int.TryParse(x, out rp) && int.TryParse(x, out ry))
                    {
                        return(new WRot(new WAngle(rr), new WAngle(rp), new WAngle(ry)));
                    }
                }
                return(InvalidValueAction(x, fieldType, field));
            }

            else if (fieldType.IsEnum)
            {
                if (!Enum.GetNames(fieldType).Select(a => a.ToLower()).Contains(x.ToLower()))
                {
                    return(InvalidValueAction(x, fieldType, field));
                }
                return(Enum.Parse(fieldType, x, true));
            }

            else if (fieldType == typeof(bool))
            {
                return(ParseYesNo(x, fieldType, field));
            }

            else if (fieldType.IsArray)
            {
                if (x == null)
                {
                    return(Array.CreateInstance(fieldType.GetElementType(), 0));
                }

                var parts = x.Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries);

                var ret = Array.CreateInstance(fieldType.GetElementType(), parts.Length);
                for (int i = 0; i < parts.Length; i++)
                {
                    ret.SetValue(GetValue(field, fieldType.GetElementType(), parts[i].Trim()), i);
                }
                return(ret);
            }
            else if (fieldType == typeof(int2))
            {
                var parts = x.Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries);
                return(new int2(int.Parse(parts[0]), int.Parse(parts[1])));
            }
            else if (fieldType == typeof(float2))
            {
                var   parts = x.Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries);
                float xx    = 0;
                float yy    = 0;
                float res;
                if (float.TryParse(parts[0].Replace("%", ""), out res))
                {
                    xx = res * (parts[0].Contains('%') ? 0.01f : 1f);
                }
                if (float.TryParse(parts[1].Replace("%", ""), out res))
                {
                    yy = res * (parts[1].Contains('%') ? 0.01f : 1f);
                }
                return(new float2(xx, yy));
            }
            else if (fieldType == typeof(Rectangle))
            {
                var parts = x.Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries);
                return(new Rectangle(int.Parse(parts[0]), int.Parse(parts[1]), int.Parse(parts[2]), int.Parse(parts[3])));
            }
            else if (fieldType.IsGenericType && fieldType.GetGenericTypeDefinition() == typeof(Bits <>))
            {
                var parts     = x.Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries);
                var argTypes  = new Type[] { typeof(string[]) };
                var argValues = new object[] { parts };
                return(fieldType.GetConstructor(argTypes).Invoke(argValues));
            }

            UnknownFieldAction("[Type] {0}".F(x), fieldType);
            return(null);
        }