| 1 | using System; | 
 
 
 
 
 | 2 | using System.Collections.Generic; | 
 
 
 
 
 | 3 | using System.Xml; | 
 
 
 
 
 | 4 | using Oni.Metadata; | 
 
 
 
 
 | 5 | using Oni.Particles; | 
 
 
 
 
 | 6 |  | 
 
 
 
 
 | 7 | namespace Oni.Xml | 
 
 
 
 
 | 8 | { | 
 
 
 
 
 | 9 | internal class OnieXmlImporter : RawXmlImporter | 
 
 
 
 
 | 10 | { | 
 
 
 
 
 | 11 | #region Private data | 
 
 
 
 
 | 12 | private List<ImpactEffect> impactEffects = new List<ImpactEffect>(); | 
 
 
 
 
 | 13 | private List<ImpactEffectSound> sounds = new List<ImpactEffectSound>(); | 
 
 
 
 
 | 14 | private List<ImpactEffectParticle> particles = new List<ImpactEffectParticle>(); | 
 
 
 
 
 | 15 | private Dictionary<string, int> materials = new Dictionary<string, int>(); | 
 
 
 
 
 | 16 | private List<KeyValuePair<string, int>> impactList; | 
 
 
 
 
 | 17 | private List<KeyValuePair<string, int>> materialList; | 
 
 
 
 
 | 18 | private List<ImpactNode> impactNodes; | 
 
 
 
 
 | 19 | private List<MaterialNode> materialNodes; | 
 
 
 
 
 | 20 | #endregion | 
 
 
 
 
 | 21 |  | 
 
 
 
 
 | 22 | private OnieXmlImporter(XmlReader xml, BinaryWriter writer) | 
 
 
 
 
 | 23 | : base(xml, writer) | 
 
 
 
 
 | 24 | { | 
 
 
 
 
 | 25 | } | 
 
 
 
 
 | 26 |  | 
 
 
 
 
 | 27 | public static void Import(XmlReader xml, BinaryWriter writer) | 
 
 
 
 
 | 28 | { | 
 
 
 
 
 | 29 | var importer = new OnieXmlImporter(xml, writer); | 
 
 
 
 
 | 30 | importer.Read(); | 
 
 
 
 
 | 31 | importer.Write(); | 
 
 
 
 
 | 32 | } | 
 
 
 
 
 | 33 |  | 
 
 
 
 
 | 34 | #region private class ImpactLookupNode | 
 
 
 
 
 | 35 |  | 
 
 
 
 
 | 36 | private class ImpactNode | 
 
 
 
 
 | 37 | { | 
 
 
 
 
 | 38 | private int impactIndex; | 
 
 
 
 
 | 39 | private List<MaterialNode> materialNodes; | 
 
 
 
 
 | 40 |  | 
 
 
 
 
 | 41 | public ImpactNode(int impactIndex) | 
 
 
 
 
 | 42 | { | 
 
 
 
 
 | 43 | this.impactIndex = impactIndex; | 
 
 
 
 
 | 44 | this.materialNodes = new List<MaterialNode>(); | 
 
 
 
 
 | 45 | } | 
 
 
 
 
 | 46 |  | 
 
 
 
 
 | 47 | public int ImpactIndex | 
 
 
 
 
 | 48 | { | 
 
 
 
 
 | 49 | get | 
 
 
 
 
 | 50 | { | 
 
 
 
 
 | 51 | return impactIndex; | 
 
 
 
 
 | 52 | } | 
 
 
 
 
 | 53 | } | 
 
 
 
 
 | 54 |  | 
 
 
 
 
 | 55 | public List<MaterialNode> MaterialNodes | 
 
 
 
 
 | 56 | { | 
 
 
 
 
 | 57 | get | 
 
 
 
 
 | 58 | { | 
 
 
 
 
 | 59 | return materialNodes; | 
 
 
 
 
 | 60 | } | 
 
 
 
 
 | 61 | } | 
 
 
 
 
 | 62 | } | 
 
 
 
 
 | 63 |  | 
 
 
 
 
 | 64 | #endregion | 
 
 
 
 
 | 65 | #region private class MaterialLookupNode | 
 
 
 
 
 | 66 |  | 
 
 
 
 
 | 67 | private class MaterialNode | 
 
 
 
 
 | 68 | { | 
 
 
 
 
 | 69 | private int materialIndex; | 
 
 
 
 
 | 70 | private List<ImpactEffect> impactEffects; | 
 
 
 
 
 | 71 |  | 
 
 
 
 
 | 72 | public MaterialNode(int materialIndex) | 
 
 
 
 
 | 73 | { | 
 
 
 
 
 | 74 | this.materialIndex = materialIndex; | 
 
 
 
 
 | 75 | this.impactEffects = new List<ImpactEffect>(); | 
 
 
 
 
 | 76 | } | 
 
 
 
 
 | 77 |  | 
 
 
 
 
 | 78 | public int MaterialIndex | 
 
 
 
 
 | 79 | { | 
 
 
 
 
 | 80 | get | 
 
 
 
 
 | 81 | { | 
 
 
 
 
 | 82 | return materialIndex; | 
 
 
 
 
 | 83 | } | 
 
 
 
 
 | 84 | } | 
 
 
 
 
 | 85 |  | 
 
 
 
 
 | 86 | public List<ImpactEffect> ImpactEffects | 
 
 
 
 
 | 87 | { | 
 
 
 
 
 | 88 | get | 
 
 
 
 
 | 89 | { | 
 
 
 
 
 | 90 | return impactEffects; | 
 
 
 
 
 | 91 | } | 
 
 
 
 
 | 92 | } | 
 
 
 
 
 | 93 | } | 
 
 
 
 
 | 94 |  | 
 
 
 
 
 | 95 | #endregion | 
 
 
 
 
 | 96 |  | 
 
 
 
 
 | 97 | private void Read() | 
 
 
 
 
 | 98 | { | 
 
 
 
 
 | 99 | impactList = new List<KeyValuePair<string, int>>(); | 
 
 
 
 
 | 100 |  | 
 
 
 
 
 | 101 | while (Xml.IsStartElement("Impact")) | 
 
 
 
 
 | 102 | { | 
 
 
 
 
 | 103 | int impactIndex = impactList.Count; | 
 
 
 
 
 | 104 | var impactName = Xml.GetAttribute("Name"); | 
 
 
 
 
 | 105 | impactList.Add(new KeyValuePair<string, int>(impactName, impactIndex)); | 
 
 
 
 
 | 106 |  | 
 
 
 
 
 | 107 | if (Xml.IsEmptyElement) | 
 
 
 
 
 | 108 | { | 
 
 
 
 
 | 109 | Xml.ReadStartElement(); | 
 
 
 
 
 | 110 | continue; | 
 
 
 
 
 | 111 | } | 
 
 
 
 
 | 112 |  | 
 
 
 
 
 | 113 | Xml.ReadStartElement(); | 
 
 
 
 
 | 114 |  | 
 
 
 
 
 | 115 | while (Xml.IsStartElement("Material")) | 
 
 
 
 
 | 116 | { | 
 
 
 
 
 | 117 | var materialName = Xml.GetAttribute("Name"); | 
 
 
 
 
 | 118 | int materialIndex; | 
 
 
 
 
 | 119 |  | 
 
 
 
 
 | 120 | if (!materials.TryGetValue(materialName, out materialIndex)) | 
 
 
 
 
 | 121 | { | 
 
 
 
 
 | 122 | materialIndex = materials.Count; | 
 
 
 
 
 | 123 | materials.Add(materialName, materialIndex); | 
 
 
 
 
 | 124 | } | 
 
 
 
 
 | 125 |  | 
 
 
 
 
 | 126 | if (Xml.IsEmptyElement) | 
 
 
 
 
 | 127 | { | 
 
 
 
 
 | 128 | Xml.ReadStartElement(); | 
 
 
 
 
 | 129 | continue; | 
 
 
 
 
 | 130 | } | 
 
 
 
 
 | 131 |  | 
 
 
 
 
 | 132 | Xml.ReadStartElement(); | 
 
 
 
 
 | 133 |  | 
 
 
 
 
 | 134 | while (Xml.IsStartElement("ImpactEffect")) | 
 
 
 
 
 | 135 | { | 
 
 
 
 
 | 136 | Xml.ReadStartElement(); | 
 
 
 
 
 | 137 |  | 
 
 
 
 
 | 138 | var impactEffect = new ImpactEffect(Xml, impactName, materialName) | 
 
 
 
 
 | 139 | { | 
 
 
 
 
 | 140 | ImpactIndex = impactIndex, | 
 
 
 
 
 | 141 | MaterialIndex = materialIndex | 
 
 
 
 
 | 142 | }; | 
 
 
 
 
 | 143 |  | 
 
 
 
 
 | 144 | if (impactEffect.Sound != null) | 
 
 
 
 
 | 145 | { | 
 
 
 
 
 | 146 | impactEffect.SoundIndex = sounds.Count; | 
 
 
 
 
 | 147 | sounds.Add(impactEffect.Sound); | 
 
 
 
 
 | 148 | } | 
 
 
 
 
 | 149 | else | 
 
 
 
 
 | 150 | { | 
 
 
 
 
 | 151 | impactEffect.SoundIndex = -1; | 
 
 
 
 
 | 152 | } | 
 
 
 
 
 | 153 |  | 
 
 
 
 
 | 154 | if (impactEffect.Particles != null && impactEffect.Particles.Length > 0) | 
 
 
 
 
 | 155 | { | 
 
 
 
 
 | 156 | impactEffect.ParticleIndex = particles.Count; | 
 
 
 
 
 | 157 | particles.AddRange(impactEffect.Particles); | 
 
 
 
 
 | 158 | } | 
 
 
 
 
 | 159 | else | 
 
 
 
 
 | 160 | { | 
 
 
 
 
 | 161 | impactEffect.ParticleIndex = -1; | 
 
 
 
 
 | 162 | } | 
 
 
 
 
 | 163 |  | 
 
 
 
 
 | 164 | impactEffects.Add(impactEffect); | 
 
 
 
 
 | 165 |  | 
 
 
 
 
 | 166 | Xml.ReadEndElement(); | 
 
 
 
 
 | 167 | } | 
 
 
 
 
 | 168 |  | 
 
 
 
 
 | 169 | Xml.ReadEndElement(); | 
 
 
 
 
 | 170 | } | 
 
 
 
 
 | 171 |  | 
 
 
 
 
 | 172 | Xml.ReadEndElement(); | 
 
 
 
 
 | 173 | } | 
 
 
 
 
 | 174 |  | 
 
 
 
 
 | 175 | materialList = new List<KeyValuePair<string, int>>(materials); | 
 
 
 
 
 | 176 | materialList.Sort((x, y) => x.Value.CompareTo(y.Value)); | 
 
 
 
 
 | 177 |  | 
 
 
 
 
 | 178 | impactNodes = new List<ImpactNode>(); | 
 
 
 
 
 | 179 | materialNodes = new List<MaterialNode>(); | 
 
 
 
 
 | 180 |  | 
 
 
 
 
 | 181 | foreach (var impact in impactList) | 
 
 
 
 
 | 182 | { | 
 
 
 
 
 | 183 | var impactNode = new ImpactNode(impact.Value); | 
 
 
 
 
 | 184 | impactNodes.Add(impactNode); | 
 
 
 
 
 | 185 |  | 
 
 
 
 
 | 186 | foreach (var material in materialList) | 
 
 
 
 
 | 187 | { | 
 
 
 
 
 | 188 | var materialNode = new MaterialNode(material.Value); | 
 
 
 
 
 | 189 |  | 
 
 
 
 
 | 190 | foreach (var effect in impactEffects) | 
 
 
 
 
 | 191 | { | 
 
 
 
 
 | 192 | if (effect.MaterialIndex == material.Value && effect.ImpactIndex == impact.Value) | 
 
 
 
 
 | 193 | materialNode.ImpactEffects.Add(effect); | 
 
 
 
 
 | 194 | } | 
 
 
 
 
 | 195 |  | 
 
 
 
 
 | 196 | if (materialNode.ImpactEffects.Count > 0) | 
 
 
 
 
 | 197 | { | 
 
 
 
 
 | 198 | impactNode.MaterialNodes.Add(materialNode); | 
 
 
 
 
 | 199 | materialNodes.Add(materialNode); | 
 
 
 
 
 | 200 | } | 
 
 
 
 
 | 201 | } | 
 
 
 
 
 | 202 | } | 
 
 
 
 
 | 203 | } | 
 
 
 
 
 | 204 |  | 
 
 
 
 
 | 205 | private void Write() | 
 
 
 
 
 | 206 | { | 
 
 
 
 
 | 207 | Writer.Write(2); | 
 
 
 
 
 | 208 | Writer.Write(impactList.Count); | 
 
 
 
 
 | 209 | Writer.Write(materialList.Count); | 
 
 
 
 
 | 210 | Writer.Write(particles.Count); | 
 
 
 
 
 | 211 | Writer.Write(sounds.Count); | 
 
 
 
 
 | 212 | Writer.Write(impactEffects.Count); | 
 
 
 
 
 | 213 | Writer.Write(materialNodes.Count); | 
 
 
 
 
 | 214 |  | 
 
 
 
 
 | 215 | foreach (KeyValuePair<string, int> impact in impactList) | 
 
 
 
 
 | 216 | { | 
 
 
 
 
 | 217 | Writer.Write(impact.Key, 128); | 
 
 
 
 
 | 218 | Writer.Write(0); | 
 
 
 
 
 | 219 | } | 
 
 
 
 
 | 220 |  | 
 
 
 
 
 | 221 | foreach (KeyValuePair<string, int> material in materialList) | 
 
 
 
 
 | 222 | { | 
 
 
 
 
 | 223 | Writer.Write(material.Key, 128); | 
 
 
 
 
 | 224 | Writer.Write(0); | 
 
 
 
 
 | 225 | } | 
 
 
 
 
 | 226 |  | 
 
 
 
 
 | 227 | int currentMaterialIndex = 0; | 
 
 
 
 
 | 228 |  | 
 
 
 
 
 | 229 | foreach (var impactNode in impactNodes) | 
 
 
 
 
 | 230 | { | 
 
 
 
 
 | 231 | Writer.WriteInt16(impactNode.ImpactIndex); | 
 
 
 
 
 | 232 | Writer.WriteInt16(impactNode.MaterialNodes.Count); | 
 
 
 
 
 | 233 | Writer.Write(currentMaterialIndex); | 
 
 
 
 
 | 234 |  | 
 
 
 
 
 | 235 | currentMaterialIndex += impactNode.MaterialNodes.Count; | 
 
 
 
 
 | 236 | } | 
 
 
 
 
 | 237 |  | 
 
 
 
 
 | 238 | foreach (var particle in particles) | 
 
 
 
 
 | 239 | { | 
 
 
 
 
 | 240 | particle.Write(Writer); | 
 
 
 
 
 | 241 | } | 
 
 
 
 
 | 242 |  | 
 
 
 
 
 | 243 | foreach (var sound in sounds) | 
 
 
 
 
 | 244 | { | 
 
 
 
 
 | 245 | sound.Write(Writer); | 
 
 
 
 
 | 246 | } | 
 
 
 
 
 | 247 |  | 
 
 
 
 
 | 248 | foreach (var materialNode in materialNodes) | 
 
 
 
 
 | 249 | { | 
 
 
 
 
 | 250 | foreach (var effect in materialNode.ImpactEffects) | 
 
 
 
 
 | 251 | effect.Write(Writer); | 
 
 
 
 
 | 252 | } | 
 
 
 
 
 | 253 |  | 
 
 
 
 
 | 254 | int currentImpactEffectIndex = 0; | 
 
 
 
 
 | 255 |  | 
 
 
 
 
 | 256 | foreach (var materialNode in materialNodes) | 
 
 
 
 
 | 257 | { | 
 
 
 
 
 | 258 | Writer.WriteInt16(materialNode.MaterialIndex); | 
 
 
 
 
 | 259 | Writer.WriteInt16(materialNode.ImpactEffects.Count); | 
 
 
 
 
 | 260 | Writer.Write(currentImpactEffectIndex); | 
 
 
 
 
 | 261 |  | 
 
 
 
 
 | 262 | currentImpactEffectIndex += materialNode.ImpactEffects.Count; | 
 
 
 
 
 | 263 | } | 
 
 
 
 
 | 264 | } | 
 
 
 
 
 | 265 | } | 
 
 
 
 
 | 266 | } |