[1114] | 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 | }
|
---|