using System; using System.Collections.Generic; using System.IO; namespace Oni.Game { internal class CharacterClass { public InstanceDescriptor Body; public InstanceDescriptor[] Textures; public IEnumerable Animations; public InstanceDescriptor Animation; public static CharacterClass Read(InstanceDescriptor descriptor) { return Read(descriptor, null); } public static CharacterClass Read(InstanceDescriptor descriptor, string animationName) { if (descriptor.Template.Tag != TemplateTag.ONCC) throw new ArgumentException(string.Format("The specified descriptor has a wrong template {0}", descriptor.Template.Tag), "descriptor"); var character = new CharacterClass(); InstanceDescriptor trma; InstanceDescriptor trac; using (var reader = descriptor.OpenRead(0xC34)) { character.Body = reader.ReadInstance(); trma = reader.ReadInstance(); reader.Skip(0x44); trac = reader.ReadInstance(); } if (trma != null) { using (var reader = trma.OpenRead(22)) character.Textures = reader.ReadInstanceArray(reader.ReadUInt16()); } var animationList = new List(); while (trac != null) { InstanceDescriptor childCollection; using (var reader = trac.OpenRead(16)) { childCollection = reader.ReadInstance(); reader.Skip(2); int count = reader.ReadUInt16(); for (int i = 0; i < count; i++) { reader.Skip(8); var tram = reader.ReadInstance(); if (tram != null) animationList.Add(tram); } } trac = childCollection; } character.Animations = animationList; if (string.Equals(Path.GetExtension(animationName), ".oni", StringComparison.OrdinalIgnoreCase)) { var file = descriptor.File.FileManager.OpenFile(animationName); if (file != null && file.Descriptors[0].Template.Tag == TemplateTag.TRAM) character.Animation = file.Descriptors[0]; } else { if (!string.IsNullOrEmpty(animationName) && !animationName.StartsWith("TRAM", StringComparison.Ordinal)) animationName = "TRAM" + animationName; foreach (var tram in animationList) { using (var animReader = tram.OpenRead(0x15A)) { int type = animReader.ReadInt16(); animReader.Skip(2); int fromState = animReader.ReadInt16(); int toState = animReader.ReadInt16(); animReader.Skip(6); int varient = animReader.ReadInt16(); if (!string.IsNullOrEmpty(animationName)) { if (tram.FullName == animationName) { character.Animation = tram; break; } } else { if (type == 6 && fromState == 7 && toState == 7 && varient == 0) { character.Animation = tram; break; } } } } if (!string.IsNullOrEmpty(animationName) && character.Animation == null) Console.Error.WriteLine("Animation {0} was not found", animationName); } return character; } } }