/// <summary>Read Effect from string array, as in ini files, /// optionally starting from specified index /// <remarks>Does not check if correct format</remarks></summary> /// <param name="str">Array of strings, one for each line</param> /// <param name="i">Optional, Array index to start reading from /// by default is zero</param> public int ReadFromArray(String[] str, int i = 0) { // Check here if there are comments PARSE_COMMENTS_STATE commentsState = PARSE_COMMENTS_STATE.NotCommentLine; while (i < str.Length && (commentsState = IniCommon.ParseLineComments(str[i], commentsState)) >= 0) { // Store comments if (!String.IsNullOrEmpty(Comments)) Comments += "\r\n" + str[i]; else Comments = str[i]; i++; } // Read AniTitle and Amount AniTitle = str[i].Substring(1, str[0].Length - 2); i++; Amount = UInt16.Parse(str[i].Split('=')[1]); i++; if (Amount > 0x0FFF) throw new ArgumentOutOfRangeException("Amount", "cannot fit in a signed short, while should be 16 or lower"); // Check if remaining lines are enough for the amount of parts if (str.Length - i < Amount * 4 + 7) throw new ArgumentOutOfRangeException("str", "there are too few lines to read Effect, expected at least " + (4 * Amount + 7).ToString() + ", while remaining " + (str.Length - i).ToString()); Part = new List<EffectPart>(Amount); // Read every Part for (int j = 0; j < Amount; j++) { EffectPart ep = new EffectPart(); i += ep.ReadFromArray(str, i); Part.Add(ep); } // Read the rest of data Delay = UInt32.Parse(str[i].Substring(1, str[0].Length - 2)); i++; LoopTime = UInt32.Parse(str[i].Substring(1, str[0].Length - 2)); i++; FrameInterval = UInt32.Parse(str[i].Substring(1, str[0].Length - 2)); i++; LoopInterval = UInt32.Parse(str[i].Substring(1, str[0].Length - 2)); i++; OffsetX = float.Parse(str[i].Substring(1, str[0].Length - 2)); i++; OffsetY = float.Parse(str[i].Substring(1, str[0].Length - 2)); i++; OffsetZ = float.Parse(str[i].Substring(1, str[0].Length - 2)); i++; if (i < str.Length && str[i].StartsWith("Billboard")) { Billboard = (Byte.Parse(str[i].Split('=')[1]) != 0); i++; } if (i < str.Length && str[i].StartsWith("ColorEnable")) { ColorEnable = (COLOR_ENABLE)Byte.Parse(str[i].Split('=')[1]); i++; } if (i < str.Length && str[i].StartsWith("Lev")) { Level = Byte.Parse(str[i].Split('=')[1]); i++; } if (i < str.Length && !String.IsNullOrWhiteSpace(str[i]) && str[i].Contains("=")) { Unknown = Byte.Parse(str[i].Split('=')[1]); i++; } return i; }
/// <summary>Check if provided instance has the same values</summary> /// <returns>Return true if same values</returns> public Boolean Equals(EffectPart E) { if ((E.EffectId != this.EffectId)) return false; if ((E.TextureId != this.TextureId)) return false; if ((E.Scale != this.Scale)) return false; if ((E.Asb != this.Asb)) return false; if ((E.Adb != this.Adb)) return false; if ((E.ZBuffer != this.ZBuffer)) return false; if ((E.Billboard != this.Billboard)) return false; return true; }
/// <summary>New instance from byte array, as in dbc Effe binary file /// </summary> /// <param name="b">Data read from binary dbc file</param> public Effect(Byte[] b) { if (b.Length < 34) // Bytes 32 and 33 contains the amount { new Effect(); } else { Amount = BitConverter.ToUInt16(b, 32); Part = new List<EffectPart>(Amount); if (b.Length < 66 + 16 * Amount) { new Effect(); } else { // Check AniTitle length int c = 0; while (b[c] != 0 & c < 32) c++; // Read AniTitle AniTitle = Common.enc.GetString(b, 0, c); // Read all fixed lenght fields Delay = BitConverter.ToUInt32(b, 34); LoopTime = BitConverter.ToUInt32(b, 38); FrameInterval = BitConverter.ToUInt32(b, 42); LoopInterval = BitConverter.ToUInt32(b, 46); OffsetX = BitConverter.ToSingle(b, 50); OffsetY = BitConverter.ToSingle(b, 54); OffsetZ = BitConverter.ToSingle(b, 58); Billboard = (b[62] != 0); ColorEnable = (COLOR_ENABLE)b[63]; Level = b[64]; Unknown = b[65]; Byte[] be = new Byte[16]; for (int i = 0; i < Amount; i++) { Buffer.BlockCopy(b, 66 + i * 16, be, 0, 16); EffectPart e = new EffectPart(be); Part.Add(e); } } } }