| 1 | using System; | 
 
 
 
 
 | 2 | using System.Collections.Generic; | 
 
 
 
 
 | 3 | using System.Xml; | 
 
 
 
 
 | 4 | using Oni.Metadata; | 
 
 
 
 
 | 5 |  | 
 
 
 
 
 | 6 | namespace Oni.Xml | 
 
 
 
 
 | 7 | { | 
 
 
 
 
 | 8 | internal class ObjcXmlImporter : RawXmlImporter | 
 
 
 
 
 | 9 | { | 
 
 
 
 
 | 10 | private readonly Dictionary<ObjectMetadata.TypeTag, Action> typeReaders = new Dictionary<ObjectMetadata.TypeTag, Action>(); | 
 
 
 
 
 | 11 | private int nextId; | 
 
 
 
 
 | 12 |  | 
 
 
 
 
 | 13 | private ObjcXmlImporter(XmlReader xml, BinaryWriter writer) | 
 
 
 
 
 | 14 | : base(xml, writer) | 
 
 
 
 
 | 15 | { | 
 
 
 
 
 | 16 | InitTypeReaders(typeReaders); | 
 
 
 
 
 | 17 | } | 
 
 
 
 
 | 18 |  | 
 
 
 
 
 | 19 | public static void Import(XmlReader xml, BinaryWriter writer) | 
 
 
 
 
 | 20 | { | 
 
 
 
 
 | 21 | var importer = new ObjcXmlImporter(xml, writer); | 
 
 
 
 
 | 22 | importer.Import(); | 
 
 
 
 
 | 23 | } | 
 
 
 
 
 | 24 |  | 
 
 
 
 
 | 25 | private void Import() | 
 
 
 
 
 | 26 | { | 
 
 
 
 
 | 27 | Writer.Write(39); | 
 
 
 
 
 | 28 |  | 
 
 
 
 
 | 29 | nextId = 1; | 
 
 
 
 
 | 30 |  | 
 
 
 
 
 | 31 | while (Xml.IsStartElement()) | 
 
 
 
 
 | 32 | { | 
 
 
 
 
 | 33 | int objectStartPosition = Writer.Position; | 
 
 
 
 
 | 34 | Writer.Write(0); | 
 
 
 
 
 | 35 |  | 
 
 
 
 
 | 36 | BeginStruct(objectStartPosition); | 
 
 
 
 
 | 37 |  | 
 
 
 
 
 | 38 | ReadObject(); | 
 
 
 
 
 | 39 |  | 
 
 
 
 
 | 40 | Writer.Position = Utils.Align4(Writer.Position); | 
 
 
 
 
 | 41 |  | 
 
 
 
 
 | 42 | int objectSize = Writer.Position - objectStartPosition - 4; | 
 
 
 
 
 | 43 | Writer.WriteAt(objectStartPosition, objectSize); | 
 
 
 
 
 | 44 | } | 
 
 
 
 
 | 45 |  | 
 
 
 
 
 | 46 | Writer.Write(0); | 
 
 
 
 
 | 47 | } | 
 
 
 
 
 | 48 |  | 
 
 
 
 
 | 49 | private ObjectMetadata.TypeTag ReadObject() | 
 
 
 
 
 | 50 | { | 
 
 
 
 
 | 51 | var id = Xml.GetAttribute("Id"); | 
 
 
 
 
 | 52 | int objectId = string.IsNullOrEmpty(id) ? nextId++ : XmlConvert.ToInt32(id); | 
 
 
 
 
 | 53 | var objectTag = Xml.GetAttribute("Type"); | 
 
 
 
 
 | 54 |  | 
 
 
 
 
 | 55 | if (objectTag == null) | 
 
 
 
 
 | 56 | objectTag = Xml.LocalName; | 
 
 
 
 
 | 57 |  | 
 
 
 
 
 | 58 | var objectType = MetaEnum.Parse<ObjectMetadata.TypeTag>(objectTag); | 
 
 
 
 
 | 59 |  | 
 
 
 
 
 | 60 | Xml.ReadStartElement(); | 
 
 
 
 
 | 61 | Xml.MoveToContent(); | 
 
 
 
 
 | 62 |  | 
 
 
 
 
 | 63 | Writer.Write((int)objectType); | 
 
 
 
 
 | 64 | Writer.Write(objectId); | 
 
 
 
 
 | 65 | ObjectMetadata.Header.Accept(this); | 
 
 
 
 
 | 66 | typeReaders[objectType](); | 
 
 
 
 
 | 67 |  | 
 
 
 
 
 | 68 | Xml.ReadEndElement(); | 
 
 
 
 
 | 69 |  | 
 
 
 
 
 | 70 | return objectType; | 
 
 
 
 
 | 71 | } | 
 
 
 
 
 | 72 |  | 
 
 
 
 
 | 73 | private void ReadCharacter() | 
 
 
 
 
 | 74 | { | 
 
 
 
 
 | 75 | ObjectMetadata.Character.Accept(this); | 
 
 
 
 
 | 76 | } | 
 
 
 
 
 | 77 |  | 
 
 
 
 
 | 78 | private void ReadCombatProfile() | 
 
 
 
 
 | 79 | { | 
 
 
 
 
 | 80 | ObjectMetadata.CombatProfile.Accept(this); | 
 
 
 
 
 | 81 | } | 
 
 
 
 
 | 82 |  | 
 
 
 
 
 | 83 | private void ReadConsole() | 
 
 
 
 
 | 84 | { | 
 
 
 
 
 | 85 | Xml.ReadStartElement(); | 
 
 
 
 
 | 86 | Xml.MoveToContent(); | 
 
 
 
 
 | 87 |  | 
 
 
 
 
 | 88 | ReadStruct(ObjectMetadata.Console); | 
 
 
 
 
 | 89 | ReadEventList(); | 
 
 
 
 
 | 90 |  | 
 
 
 
 
 | 91 | Xml.ReadEndElement(); | 
 
 
 
 
 | 92 | } | 
 
 
 
 
 | 93 |  | 
 
 
 
 
 | 94 | private void ReadDoor() | 
 
 
 
 
 | 95 | { | 
 
 
 
 
 | 96 | Xml.ReadStartElement(); | 
 
 
 
 
 | 97 | Xml.MoveToContent(); | 
 
 
 
 
 | 98 |  | 
 
 
 
 
 | 99 | ReadStruct(ObjectMetadata.Door); | 
 
 
 
 
 | 100 | ReadEventList(); | 
 
 
 
 
 | 101 |  | 
 
 
 
 
 | 102 | Xml.ReadEndElement(); | 
 
 
 
 
 | 103 | } | 
 
 
 
 
 | 104 |  | 
 
 
 
 
 | 105 | private void ReadFlag() | 
 
 
 
 
 | 106 | { | 
 
 
 
 
 | 107 | ObjectMetadata.Flag.Accept(this); | 
 
 
 
 
 | 108 | } | 
 
 
 
 
 | 109 |  | 
 
 
 
 
 | 110 | private void ReadFurniture() | 
 
 
 
 
 | 111 | { | 
 
 
 
 
 | 112 | ObjectMetadata.Furniture.Accept(this); | 
 
 
 
 
 | 113 | } | 
 
 
 
 
 | 114 |  | 
 
 
 
 
 | 115 | private struct MeleeMove | 
 
 
 
 
 | 116 | { | 
 
 
 
 
 | 117 | public int Type; | 
 
 
 
 
 | 118 | public float[] Params; | 
 
 
 
 
 | 119 | } | 
 
 
 
 
 | 120 |  | 
 
 
 
 
 | 121 | private void ReadMeleeProfile() | 
 
 
 
 
 | 122 | { | 
 
 
 
 
 | 123 | Xml.ReadStartElement(); | 
 
 
 
 
 | 124 | Xml.MoveToContent(); | 
 
 
 
 
 | 125 |  | 
 
 
 
 
 | 126 | ReadStruct(ObjectMetadata.MeleeProfile); | 
 
 
 
 
 | 127 |  | 
 
 
 
 
 | 128 | int countFieldsPosition = Writer.Position; | 
 
 
 
 
 | 129 | Writer.Write(0); | 
 
 
 
 
 | 130 | Writer.Write(0); | 
 
 
 
 
 | 131 | Writer.Write(0); | 
 
 
 
 
 | 132 | Writer.Write(0); | 
 
 
 
 
 | 133 |  | 
 
 
 
 
 | 134 | int attackCount = 0; | 
 
 
 
 
 | 135 | int evadeCount = 0; | 
 
 
 
 
 | 136 | int maneuverCount = 0; | 
 
 
 
 
 | 137 | var moves = new List<MeleeMove>(); | 
 
 
 
 
 | 138 |  | 
 
 
 
 
 | 139 | attackCount = ReadMeleeTechniques("Attacks", moves); | 
 
 
 
 
 | 140 | evadeCount = ReadMeleeTechniques("Evades", moves); | 
 
 
 
 
 | 141 | maneuverCount = ReadMeleeTechniques("Maneuvers", moves); | 
 
 
 
 
 | 142 |  | 
 
 
 
 
 | 143 | foreach (var move in moves) | 
 
 
 
 
 | 144 | { | 
 
 
 
 
 | 145 | Writer.Write(move.Type); | 
 
 
 
 
 | 146 | Writer.Write(move.Params); | 
 
 
 
 
 | 147 | } | 
 
 
 
 
 | 148 |  | 
 
 
 
 
 | 149 | int oldPosition = Writer.Position; | 
 
 
 
 
 | 150 | Writer.Position = countFieldsPosition; | 
 
 
 
 
 | 151 | Writer.Write(attackCount); | 
 
 
 
 
 | 152 | Writer.Write(evadeCount); | 
 
 
 
 
 | 153 | Writer.Write(maneuverCount); | 
 
 
 
 
 | 154 | Writer.Write(moves.Count); | 
 
 
 
 
 | 155 | Writer.Position = oldPosition; | 
 
 
 
 
 | 156 |  | 
 
 
 
 
 | 157 | Xml.ReadEndElement(); | 
 
 
 
 
 | 158 | } | 
 
 
 
 
 | 159 |  | 
 
 
 
 
 | 160 | private int ReadMeleeTechniques(string xmlName, List<MeleeMove> moves) | 
 
 
 
 
 | 161 | { | 
 
 
 
 
 | 162 | if (Xml.IsStartElement(xmlName) && Xml.IsEmptyElement) | 
 
 
 
 
 | 163 | { | 
 
 
 
 
 | 164 | Xml.Skip(); | 
 
 
 
 
 | 165 | return 0; | 
 
 
 
 
 | 166 | } | 
 
 
 
 
 | 167 |  | 
 
 
 
 
 | 168 | Xml.ReadStartElement(xmlName); | 
 
 
 
 
 | 169 | Xml.MoveToContent(); | 
 
 
 
 
 | 170 |  | 
 
 
 
 
 | 171 | int techniqueCount = 0; | 
 
 
 
 
 | 172 |  | 
 
 
 
 
 | 173 | for (; Xml.IsStartElement("Technique"); techniqueCount++) | 
 
 
 
 
 | 174 | { | 
 
 
 
 
 | 175 | Xml.ReadStartElement(); | 
 
 
 
 
 | 176 | Xml.MoveToContent(); | 
 
 
 
 
 | 177 |  | 
 
 
 
 
 | 178 | ReadStruct(ObjectMetadata.MeleeTechnique); | 
 
 
 
 
 | 179 | int moveCountPosition = Writer.Position; | 
 
 
 
 
 | 180 | Writer.Write(0); | 
 
 
 
 
 | 181 | Writer.Write(moves.Count); | 
 
 
 
 
 | 182 |  | 
 
 
 
 
 | 183 | int moveCount = 0; | 
 
 
 
 
 | 184 |  | 
 
 
 
 
 | 185 | if (Xml.IsStartElement("Moves") && Xml.IsEmptyElement) | 
 
 
 
 
 | 186 | { | 
 
 
 
 
 | 187 | Xml.Skip(); | 
 
 
 
 
 | 188 | } | 
 
 
 
 
 | 189 | else | 
 
 
 
 
 | 190 | { | 
 
 
 
 
 | 191 | Xml.ReadStartElement("Moves"); | 
 
 
 
 
 | 192 | Xml.MoveToContent(); | 
 
 
 
 
 | 193 |  | 
 
 
 
 
 | 194 | for (; Xml.IsStartElement(); moveCount++) | 
 
 
 
 
 | 195 | { | 
 
 
 
 
 | 196 | ReadMeleeMove(moves); | 
 
 
 
 
 | 197 | } | 
 
 
 
 
 | 198 |  | 
 
 
 
 
 | 199 | Xml.ReadEndElement(); | 
 
 
 
 
 | 200 | } | 
 
 
 
 
 | 201 |  | 
 
 
 
 
 | 202 | Xml.ReadEndElement(); | 
 
 
 
 
 | 203 |  | 
 
 
 
 
 | 204 | Writer.WriteAt(moveCountPosition, moveCount); | 
 
 
 
 
 | 205 | } | 
 
 
 
 
 | 206 |  | 
 
 
 
 
 | 207 | Xml.ReadEndElement(); | 
 
 
 
 
 | 208 |  | 
 
 
 
 
 | 209 | return techniqueCount; | 
 
 
 
 
 | 210 | } | 
 
 
 
 
 | 211 |  | 
 
 
 
 
 | 212 | private void ReadMeleeMove(List<MeleeMove> moves) | 
 
 
 
 
 | 213 | { | 
 
 
 
 
 | 214 | var category = (ObjectMetadata.MeleeMoveCategory)Enum.Parse(typeof(ObjectMetadata.MeleeMoveCategory), Xml.LocalName); | 
 
 
 
 
 | 215 |  | 
 
 
 
 
 | 216 | var typeText = Xml.GetAttribute("Type"); | 
 
 
 
 
 | 217 | int type; | 
 
 
 
 
 | 218 | var moveParams = new float[3]; | 
 
 
 
 
 | 219 |  | 
 
 
 
 
 | 220 | switch (category) | 
 
 
 
 
 | 221 | { | 
 
 
 
 
 | 222 | default: | 
 
 
 
 
 | 223 | case ObjectMetadata.MeleeMoveCategory.Attack: | 
 
 
 
 
 | 224 | type = Convert.ToInt32(MetaEnum.Parse<ObjectMetadata.MeleeMoveAttackType>(typeText)); | 
 
 
 
 
 | 225 | break; | 
 
 
 
 
 | 226 | case ObjectMetadata.MeleeMoveCategory.Evade: | 
 
 
 
 
 | 227 | type = Convert.ToInt32(MetaEnum.Parse<ObjectMetadata.MeleeMoveEvadeType>(typeText)); | 
 
 
 
 
 | 228 | break; | 
 
 
 
 
 | 229 | case ObjectMetadata.MeleeMoveCategory.Throw: | 
 
 
 
 
 | 230 | type = Convert.ToInt32(MetaEnum.Parse<ObjectMetadata.MeleeMoveThrowType>(typeText)); | 
 
 
 
 
 | 231 | break; | 
 
 
 
 
 | 232 |  | 
 
 
 
 
 | 233 | case ObjectMetadata.MeleeMoveCategory.Position: | 
 
 
 
 
 | 234 | ObjectMetadata.MeleeMovePositionType positionType = MetaEnum.Parse<ObjectMetadata.MeleeMovePositionType>(typeText); | 
 
 
 
 
 | 235 |  | 
 
 
 
 
 | 236 | if ((ObjectMetadata.MeleeMovePositionType.RunForward <= positionType | 
 
 
 
 
 | 237 | && positionType <= ObjectMetadata.MeleeMovePositionType.RunBack) | 
 
 
 
 
 | 238 | || ObjectMetadata.MeleeMovePositionType.CloseForward <= positionType) | 
 
 
 
 
 | 239 | { | 
 
 
 
 
 | 240 | moveParams[0] = XmlConvert.ToSingle(Xml.GetAttribute("MinRunInDist")); | 
 
 
 
 
 | 241 | moveParams[1] = XmlConvert.ToSingle(Xml.GetAttribute("MaxRunInDist")); | 
 
 
 
 
 | 242 | moveParams[2] = XmlConvert.ToSingle(Xml.GetAttribute("ToleranceRange")); | 
 
 
 
 
 | 243 | } | 
 
 
 
 
 | 244 |  | 
 
 
 
 
 | 245 | type = Convert.ToInt32(positionType); | 
 
 
 
 
 | 246 | break; | 
 
 
 
 
 | 247 |  | 
 
 
 
 
 | 248 | case ObjectMetadata.MeleeMoveCategory.Maneuver: | 
 
 
 
 
 | 249 | type = Convert.ToInt32(MetaEnum.Parse<ObjectMetadata.MeleeMoveManeuverType>(typeText)); | 
 
 
 
 
 | 250 | ObjectMetadata.MeleeMoveTypeInfo typeInfo = ObjectMetadata.MeleeMoveManeuverTypeInfo[type]; | 
 
 
 
 
 | 251 |  | 
 
 
 
 
 | 252 | for (int k = 0; k < typeInfo.ParamNames.Length; k++) | 
 
 
 
 
 | 253 | moveParams[k] = XmlConvert.ToSingle(Xml.GetAttribute(typeInfo.ParamNames[k])); | 
 
 
 
 
 | 254 |  | 
 
 
 
 
 | 255 | break; | 
 
 
 
 
 | 256 | } | 
 
 
 
 
 | 257 |  | 
 
 
 
 
 | 258 | moves.Add(new MeleeMove() | 
 
 
 
 
 | 259 | { | 
 
 
 
 
 | 260 | Type = (((int)category) << 24) | (type & 0xffffff), | 
 
 
 
 
 | 261 | Params = moveParams | 
 
 
 
 
 | 262 | }); | 
 
 
 
 
 | 263 |  | 
 
 
 
 
 | 264 | Xml.Skip(); | 
 
 
 
 
 | 265 | } | 
 
 
 
 
 | 266 |  | 
 
 
 
 
 | 267 | private void ReadNeutralBehavior() | 
 
 
 
 
 | 268 | { | 
 
 
 
 
 | 269 | Xml.ReadStartElement(); | 
 
 
 
 
 | 270 | Xml.MoveToContent(); | 
 
 
 
 
 | 271 |  | 
 
 
 
 
 | 272 | ReadStruct(ObjectMetadata.NeutralBehavior); | 
 
 
 
 
 | 273 | int countFieldPosition = Writer.Position; | 
 
 
 
 
 | 274 | Writer.WriteUInt16(0); | 
 
 
 
 
 | 275 | ReadStruct(ObjectMetadata.NeutralBehaviorParams); | 
 
 
 
 
 | 276 |  | 
 
 
 
 
 | 277 | Xml.ReadStartElement("DialogLines"); | 
 
 
 
 
 | 278 | short count = 0; | 
 
 
 
 
 | 279 |  | 
 
 
 
 
 | 280 | for (; Xml.IsStartElement("DialogLine"); count++) | 
 
 
 
 
 | 281 | ObjectMetadata.NeutralBehaviorDialogLine.Accept(this); | 
 
 
 
 
 | 282 |  | 
 
 
 
 
 | 283 | Xml.ReadEndElement(); | 
 
 
 
 
 | 284 | Xml.ReadEndElement(); | 
 
 
 
 
 | 285 |  | 
 
 
 
 
 | 286 | Writer.WriteAt(countFieldPosition, count); | 
 
 
 
 
 | 287 | } | 
 
 
 
 
 | 288 |  | 
 
 
 
 
 | 289 | private void ReadParticle() | 
 
 
 
 
 | 290 | { | 
 
 
 
 
 | 291 | ObjectMetadata.Particle.Accept(this); | 
 
 
 
 
 | 292 | } | 
 
 
 
 
 | 293 |  | 
 
 
 
 
 | 294 | private void ReadPatrolPath() | 
 
 
 
 
 | 295 | { | 
 
 
 
 
 | 296 | Xml.ReadStartElement(); | 
 
 
 
 
 | 297 | Xml.MoveToContent(); | 
 
 
 
 
 | 298 |  | 
 
 
 
 
 | 299 | ReadStruct(ObjectMetadata.PatrolPath); | 
 
 
 
 
 | 300 | int lengthFieldPosition = Writer.Position; | 
 
 
 
 
 | 301 | Writer.Write(0); | 
 
 
 
 
 | 302 | ReadStruct(ObjectMetadata.PatrolPathInfo); | 
 
 
 
 
 | 303 |  | 
 
 
 
 
 | 304 | int count = 0; | 
 
 
 
 
 | 305 | bool isEmpty = Xml.IsEmptyElement; | 
 
 
 
 
 | 306 |  | 
 
 
 
 
 | 307 | Xml.ReadStartElement("Points"); | 
 
 
 
 
 | 308 |  | 
 
 
 
 
 | 309 | if (!isEmpty) | 
 
 
 
 
 | 310 | { | 
 
 
 
 
 | 311 | int loopStart = -1; | 
 
 
 
 
 | 312 |  | 
 
 
 
 
 | 313 | for (; Xml.IsStartElement(); count++) | 
 
 
 
 
 | 314 | { | 
 
 
 
 
 | 315 | if (ReadPatrolPathPoint()) | 
 
 
 
 
 | 316 | loopStart = count; | 
 
 
 
 
 | 317 | } | 
 
 
 
 
 | 318 |  | 
 
 
 
 
 | 319 | if (loopStart != -1) | 
 
 
 
 
 | 320 | { | 
 
 
 
 
 | 321 | if (loopStart == 0) | 
 
 
 
 
 | 322 | { | 
 
 
 
 
 | 323 | Writer.Write((int)ObjectMetadata.PatrolPathPointType.Loop); | 
 
 
 
 
 | 324 | } | 
 
 
 
 
 | 325 | else | 
 
 
 
 
 | 326 | { | 
 
 
 
 
 | 327 | Writer.Write((int)ObjectMetadata.PatrolPathPointType.LoopFrom); | 
 
 
 
 
 | 328 | Writer.Write(loopStart); | 
 
 
 
 
 | 329 | } | 
 
 
 
 
 | 330 |  | 
 
 
 
 
 | 331 | if (Xml.NodeType == XmlNodeType.EndElement && Xml.LocalName == "Loop") | 
 
 
 
 
 | 332 | Xml.ReadEndElement(); | 
 
 
 
 
 | 333 | } | 
 
 
 
 
 | 334 |  | 
 
 
 
 
 | 335 | Xml.ReadEndElement(); | 
 
 
 
 
 | 336 | } | 
 
 
 
 
 | 337 |  | 
 
 
 
 
 | 338 | Xml.ReadEndElement(); | 
 
 
 
 
 | 339 |  | 
 
 
 
 
 | 340 | Writer.WriteAt(lengthFieldPosition, count); | 
 
 
 
 
 | 341 | } | 
 
 
 
 
 | 342 |  | 
 
 
 
 
 | 343 | private bool ReadPatrolPathPoint() | 
 
 
 
 
 | 344 | { | 
 
 
 
 
 | 345 | var pointType = MetaEnum.Parse<ObjectMetadata.PatrolPathPointType>(Xml.LocalName); | 
 
 
 
 
 | 346 |  | 
 
 
 
 
 | 347 | switch (pointType) | 
 
 
 
 
 | 348 | { | 
 
 
 
 
 | 349 | case ObjectMetadata.PatrolPathPointType.Loop: | 
 
 
 
 
 | 350 | if (Xml.IsEmptyElement) | 
 
 
 
 
 | 351 | { | 
 
 
 
 
 | 352 | Xml.Skip(); | 
 
 
 
 
 | 353 | } | 
 
 
 
 
 | 354 | else | 
 
 
 
 
 | 355 | { | 
 
 
 
 
 | 356 | Xml.ReadStartElement(); | 
 
 
 
 
 | 357 | Xml.MoveToContent(); | 
 
 
 
 
 | 358 | } | 
 
 
 
 
 | 359 | return true; | 
 
 
 
 
 | 360 | } | 
 
 
 
 
 | 361 |  | 
 
 
 
 
 | 362 | Writer.Write((int)pointType); | 
 
 
 
 
 | 363 |  | 
 
 
 
 
 | 364 | switch (pointType) | 
 
 
 
 
 | 365 | { | 
 
 
 
 
 | 366 | case ObjectMetadata.PatrolPathPointType.Stop: | 
 
 
 
 
 | 367 | case ObjectMetadata.PatrolPathPointType.StopLooking: | 
 
 
 
 
 | 368 | case ObjectMetadata.PatrolPathPointType.StopScanning: | 
 
 
 
 
 | 369 | case ObjectMetadata.PatrolPathPointType.FreeFacing: | 
 
 
 
 
 | 370 | break; | 
 
 
 
 
 | 371 |  | 
 
 
 
 
 | 372 | case ObjectMetadata.PatrolPathPointType.IgnorePlayer: | 
 
 
 
 
 | 373 | Writer.WriteByte(Xml.GetAttribute("Value") == "Yes" ? 1 : 0); | 
 
 
 
 
 | 374 | break; | 
 
 
 
 
 | 375 |  | 
 
 
 
 
 | 376 | case ObjectMetadata.PatrolPathPointType.ForkScript: | 
 
 
 
 
 | 377 | case ObjectMetadata.PatrolPathPointType.CallScript: | 
 
 
 
 
 | 378 | Writer.Write(XmlConvert.ToInt16(Xml.GetAttribute("ScriptId"))); | 
 
 
 
 
 | 379 | break; | 
 
 
 
 
 | 380 |  | 
 
 
 
 
 | 381 | case ObjectMetadata.PatrolPathPointType.MoveToFlag: | 
 
 
 
 
 | 382 | case ObjectMetadata.PatrolPathPointType.LookAtFlag: | 
 
 
 
 
 | 383 | case ObjectMetadata.PatrolPathPointType.MoveAndFaceFlag: | 
 
 
 
 
 | 384 | Writer.Write(XmlConvert.ToInt16(Xml.GetAttribute("FlagId"))); | 
 
 
 
 
 | 385 | break; | 
 
 
 
 
 | 386 |  | 
 
 
 
 
 | 387 | case ObjectMetadata.PatrolPathPointType.MovementMode: | 
 
 
 
 
 | 388 | Writer.Write(Convert.ToInt32(MetaEnum.Parse<ObjectMetadata.PatrolPathMovementMode>(Xml.GetAttribute("Mode")))); | 
 
 
 
 
 | 389 | break; | 
 
 
 
 
 | 390 |  | 
 
 
 
 
 | 391 | case ObjectMetadata.PatrolPathPointType.LockFacing: | 
 
 
 
 
 | 392 | Writer.Write(Convert.ToInt32(MetaEnum.Parse<ObjectMetadata.PatrolPathFacing>(Xml.GetAttribute("Facing")))); | 
 
 
 
 
 | 393 | break; | 
 
 
 
 
 | 394 |  | 
 
 
 
 
 | 395 | case ObjectMetadata.PatrolPathPointType.Pause: | 
 
 
 
 
 | 396 | Writer.Write(XmlConvert.ToInt32(Xml.GetAttribute("Frames"))); | 
 
 
 
 
 | 397 | break; | 
 
 
 
 
 | 398 |  | 
 
 
 
 
 | 399 | case ObjectMetadata.PatrolPathPointType.GlanceAtFlagFor: | 
 
 
 
 
 | 400 | Writer.Write(XmlConvert.ToInt16(Xml.GetAttribute("FlagId"))); | 
 
 
 
 
 | 401 | Writer.Write(XmlConvert.ToInt32(Xml.GetAttribute("Frames"))); | 
 
 
 
 
 | 402 | break; | 
 
 
 
 
 | 403 |  | 
 
 
 
 
 | 404 | case ObjectMetadata.PatrolPathPointType.Scan: | 
 
 
 
 
 | 405 | Writer.Write(XmlConvert.ToInt16(Xml.GetAttribute("Frames"))); | 
 
 
 
 
 | 406 | Writer.Write(XmlConvert.ToSingle(Xml.GetAttribute("Rotation"))); | 
 
 
 
 
 | 407 | break; | 
 
 
 
 
 | 408 |  | 
 
 
 
 
 | 409 | case ObjectMetadata.PatrolPathPointType.MoveThroughFlag: | 
 
 
 
 
 | 410 | case ObjectMetadata.PatrolPathPointType.MoveNearFlag: | 
 
 
 
 
 | 411 | Writer.Write(XmlConvert.ToInt16(Xml.GetAttribute("FlagId"))); | 
 
 
 
 
 | 412 | Writer.Write(XmlConvert.ToSingle(Xml.GetAttribute("Distance"))); | 
 
 
 
 
 | 413 | break; | 
 
 
 
 
 | 414 |  | 
 
 
 
 
 | 415 | case ObjectMetadata.PatrolPathPointType.MoveToFlagLookAndWait: | 
 
 
 
 
 | 416 | Writer.Write(XmlConvert.ToInt16(Xml.GetAttribute("Frames"))); | 
 
 
 
 
 | 417 | Writer.Write(XmlConvert.ToInt16(Xml.GetAttribute("FlagId"))); | 
 
 
 
 
 | 418 | Writer.Write(XmlConvert.ToSingle(Xml.GetAttribute("Rotation"))); | 
 
 
 
 
 | 419 | break; | 
 
 
 
 
 | 420 |  | 
 
 
 
 
 | 421 | case ObjectMetadata.PatrolPathPointType.FaceToFlagAndFire: | 
 
 
 
 
 | 422 | Writer.Write(XmlConvert.ToInt16(Xml.GetAttribute("FlagId"))); | 
 
 
 
 
 | 423 | Writer.Write(XmlConvert.ToInt16(Xml.GetAttribute("Frames"))); | 
 
 
 
 
 | 424 | Writer.Write(XmlConvert.ToSingle(Xml.GetAttribute("Spread"))); | 
 
 
 
 
 | 425 | break; | 
 
 
 
 
 | 426 |  | 
 
 
 
 
 | 427 | case ObjectMetadata.PatrolPathPointType.LookAtPoint: | 
 
 
 
 
 | 428 | case ObjectMetadata.PatrolPathPointType.MoveToPoint: | 
 
 
 
 
 | 429 | Writer.Write(XmlConvert.ToSingle(Xml.GetAttribute("X"))); | 
 
 
 
 
 | 430 | Writer.Write(XmlConvert.ToSingle(Xml.GetAttribute("Y"))); | 
 
 
 
 
 | 431 | Writer.Write(XmlConvert.ToSingle(Xml.GetAttribute("Z"))); | 
 
 
 
 
 | 432 | break; | 
 
 
 
 
 | 433 |  | 
 
 
 
 
 | 434 | case ObjectMetadata.PatrolPathPointType.MoveThroughPoint: | 
 
 
 
 
 | 435 | Writer.Write(XmlConvert.ToSingle(Xml.GetAttribute("X"))); | 
 
 
 
 
 | 436 | Writer.Write(XmlConvert.ToSingle(Xml.GetAttribute("Y"))); | 
 
 
 
 
 | 437 | Writer.Write(XmlConvert.ToSingle(Xml.GetAttribute("Z"))); | 
 
 
 
 
 | 438 | Writer.Write(XmlConvert.ToSingle(Xml.GetAttribute("Distance"))); | 
 
 
 
 
 | 439 | break; | 
 
 
 
 
 | 440 |  | 
 
 
 
 
 | 441 | default: | 
 
 
 
 
 | 442 | throw new NotSupportedException(string.Format("Unsupported path point type {0}", pointType)); | 
 
 
 
 
 | 443 | } | 
 
 
 
 
 | 444 |  | 
 
 
 
 
 | 445 | Xml.Skip(); | 
 
 
 
 
 | 446 |  | 
 
 
 
 
 | 447 | return false; | 
 
 
 
 
 | 448 | } | 
 
 
 
 
 | 449 |  | 
 
 
 
 
 | 450 | private void ReadPowerUp() | 
 
 
 
 
 | 451 | { | 
 
 
 
 
 | 452 | ObjectMetadata.PowerUp.Accept(this); | 
 
 
 
 
 | 453 | } | 
 
 
 
 
 | 454 |  | 
 
 
 
 
 | 455 | private void ReadSound() | 
 
 
 
 
 | 456 | { | 
 
 
 
 
 | 457 | Xml.ReadStartElement(); | 
 
 
 
 
 | 458 | Xml.MoveToContent(); | 
 
 
 
 
 | 459 |  | 
 
 
 
 
 | 460 | ReadStruct(ObjectMetadata.Sound); | 
 
 
 
 
 | 461 |  | 
 
 
 
 
 | 462 | var volumeType = MetaEnum.Parse<ObjectMetadata.SoundVolumeType>(Xml.LocalName); | 
 
 
 
 
 | 463 |  | 
 
 
 
 
 | 464 | Writer.Write((int)volumeType); | 
 
 
 
 
 | 465 |  | 
 
 
 
 
 | 466 | switch (volumeType) | 
 
 
 
 
 | 467 | { | 
 
 
 
 
 | 468 | case ObjectMetadata.SoundVolumeType.Box: | 
 
 
 
 
 | 469 | MetaType.BoundingBox.Accept(this); | 
 
 
 
 
 | 470 | break; | 
 
 
 
 
 | 471 |  | 
 
 
 
 
 | 472 | case ObjectMetadata.SoundVolumeType.Sphere: | 
 
 
 
 
 | 473 | ObjectMetadata.SoundSphere.Accept(this); | 
 
 
 
 
 | 474 | break; | 
 
 
 
 
 | 475 | } | 
 
 
 
 
 | 476 |  | 
 
 
 
 
 | 477 | ReadStruct(ObjectMetadata.SoundParams); | 
 
 
 
 
 | 478 |  | 
 
 
 
 
 | 479 | if (volumeType == ObjectMetadata.SoundVolumeType.Sphere) | 
 
 
 
 
 | 480 | Writer.Skip(16); | 
 
 
 
 
 | 481 |  | 
 
 
 
 
 | 482 | Xml.ReadEndElement(); | 
 
 
 
 
 | 483 | } | 
 
 
 
 
 | 484 |  | 
 
 
 
 
 | 485 | private void ReadTriggerVolume() | 
 
 
 
 
 | 486 | { | 
 
 
 
 
 | 487 | ObjectMetadata.TriggerVolume.Accept(this); | 
 
 
 
 
 | 488 | } | 
 
 
 
 
 | 489 |  | 
 
 
 
 
 | 490 | private void ReadTrigger() | 
 
 
 
 
 | 491 | { | 
 
 
 
 
 | 492 | Xml.ReadStartElement(); | 
 
 
 
 
 | 493 | Xml.MoveToContent(); | 
 
 
 
 
 | 494 |  | 
 
 
 
 
 | 495 | ReadStruct(ObjectMetadata.Trigger); | 
 
 
 
 
 | 496 | ReadEventList(); | 
 
 
 
 
 | 497 |  | 
 
 
 
 
 | 498 | Xml.ReadEndElement(); | 
 
 
 
 
 | 499 | } | 
 
 
 
 
 | 500 |  | 
 
 
 
 
 | 501 | private void ReadTurret() | 
 
 
 
 
 | 502 | { | 
 
 
 
 
 | 503 | ObjectMetadata.Turret.Accept(this); | 
 
 
 
 
 | 504 | } | 
 
 
 
 
 | 505 |  | 
 
 
 
 
 | 506 | private void ReadWeapon() | 
 
 
 
 
 | 507 | { | 
 
 
 
 
 | 508 | ObjectMetadata.Weapon.Accept(this); | 
 
 
 
 
 | 509 | } | 
 
 
 
 
 | 510 |  | 
 
 
 
 
 | 511 | private void ReadEventList() | 
 
 
 
 
 | 512 | { | 
 
 
 
 
 | 513 | int countFieldPosition = Writer.Position; | 
 
 
 
 
 | 514 | Writer.WriteUInt16(0); | 
 
 
 
 
 | 515 |  | 
 
 
 
 
 | 516 | if (Xml.IsStartElement("Events") && Xml.IsEmptyElement) | 
 
 
 
 
 | 517 | { | 
 
 
 
 
 | 518 | Xml.ReadStartElement(); | 
 
 
 
 
 | 519 | return; | 
 
 
 
 
 | 520 | } | 
 
 
 
 
 | 521 |  | 
 
 
 
 
 | 522 | Xml.ReadStartElement("Events"); | 
 
 
 
 
 | 523 | Xml.MoveToContent(); | 
 
 
 
 
 | 524 |  | 
 
 
 
 
 | 525 | short eventCount = 0; | 
 
 
 
 
 | 526 |  | 
 
 
 
 
 | 527 | while (Xml.IsStartElement()) | 
 
 
 
 
 | 528 | { | 
 
 
 
 
 | 529 | var eventType = MetaEnum.Parse<ObjectMetadata.EventType>(Xml.Name); | 
 
 
 
 
 | 530 |  | 
 
 
 
 
 | 531 | Writer.Write((short)eventType); | 
 
 
 
 
 | 532 |  | 
 
 
 
 
 | 533 | switch (eventType) | 
 
 
 
 
 | 534 | { | 
 
 
 
 
 | 535 | case ObjectMetadata.EventType.None: | 
 
 
 
 
 | 536 | break; | 
 
 
 
 
 | 537 | case ObjectMetadata.EventType.Script: | 
 
 
 
 
 | 538 | Writer.Write(Xml.GetAttribute("Function"), 32); | 
 
 
 
 
 | 539 | break; | 
 
 
 
 
 | 540 | default: | 
 
 
 
 
 | 541 | Writer.Write(XmlConvert.ToInt16(Xml.GetAttribute("TargetId"))); | 
 
 
 
 
 | 542 | break; | 
 
 
 
 
 | 543 | } | 
 
 
 
 
 | 544 |  | 
 
 
 
 
 | 545 | eventCount++; | 
 
 
 
 
 | 546 | Xml.Skip(); | 
 
 
 
 
 | 547 | } | 
 
 
 
 
 | 548 |  | 
 
 
 
 
 | 549 | Writer.WriteAt(countFieldPosition, eventCount); | 
 
 
 
 
 | 550 | Xml.ReadEndElement(); | 
 
 
 
 
 | 551 | } | 
 
 
 
 
 | 552 |  | 
 
 
 
 
 | 553 | private void InitTypeReaders(Dictionary<ObjectMetadata.TypeTag, Action> typeReaders) | 
 
 
 
 
 | 554 | { | 
 
 
 
 
 | 555 | typeReaders.Add(ObjectMetadata.TypeTag.CHAR, ReadCharacter); | 
 
 
 
 
 | 556 | typeReaders.Add(ObjectMetadata.TypeTag.CMBT, ReadCombatProfile); | 
 
 
 
 
 | 557 | typeReaders.Add(ObjectMetadata.TypeTag.CONS, ReadConsole); | 
 
 
 
 
 | 558 | typeReaders.Add(ObjectMetadata.TypeTag.DOOR, ReadDoor); | 
 
 
 
 
 | 559 | typeReaders.Add(ObjectMetadata.TypeTag.FLAG, ReadFlag); | 
 
 
 
 
 | 560 | typeReaders.Add(ObjectMetadata.TypeTag.FURN, ReadFurniture); | 
 
 
 
 
 | 561 | typeReaders.Add(ObjectMetadata.TypeTag.MELE, ReadMeleeProfile); | 
 
 
 
 
 | 562 | typeReaders.Add(ObjectMetadata.TypeTag.NEUT, ReadNeutralBehavior); | 
 
 
 
 
 | 563 | typeReaders.Add(ObjectMetadata.TypeTag.PART, ReadParticle); | 
 
 
 
 
 | 564 | typeReaders.Add(ObjectMetadata.TypeTag.PATR, ReadPatrolPath); | 
 
 
 
 
 | 565 | typeReaders.Add(ObjectMetadata.TypeTag.PWRU, ReadPowerUp); | 
 
 
 
 
 | 566 | typeReaders.Add(ObjectMetadata.TypeTag.SNDG, ReadSound); | 
 
 
 
 
 | 567 | typeReaders.Add(ObjectMetadata.TypeTag.TRGV, ReadTriggerVolume); | 
 
 
 
 
 | 568 | typeReaders.Add(ObjectMetadata.TypeTag.TRIG, ReadTrigger); | 
 
 
 
 
 | 569 | typeReaders.Add(ObjectMetadata.TypeTag.TURR, ReadTurret); | 
 
 
 
 
 | 570 | typeReaders.Add(ObjectMetadata.TypeTag.WEAP, ReadWeapon); | 
 
 
 
 
 | 571 | } | 
 
 
 
 
 | 572 | } | 
 
 
 
 
 | 573 | } |