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)); } }
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); }
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); }