예제 #1
0
        public RawMapEntity CreateEntity(MapObjectSpawnDescriptor fromDescriptor)
        {
            MapEntityDataDescriptor template = m_editorCore.Templates.MapEntityDataDescriptors.Find(x => x.FourCC == fromDescriptor.FourCC);

            RawMapEntity obj = new RawMapEntity();

            obj.FourCC = fromDescriptor.FourCC;
            obj.Fields = new PropertyCollection();

            // stupid copy paste

            // See if our template list has a complex version of this file, otherwise grab the default.
            MapObjectDataDescriptor complexDescriptor = m_editorCore.Templates.MapObjectDataDescriptors.Find(x => x.FourCC == fromDescriptor.FourCC && x.TechnicalName == fromDescriptor.TechnicalName);

            if (complexDescriptor == null)
            {
                complexDescriptor = m_editorCore.Templates.DefaultMapObjectDataDescriptor;
            }

            // Determine which field we need to remove, and then insert in the other fields (in order) where it used to be.
            foreach (var fieldToReplace in complexDescriptor.DataOverrides)
            {
                for (int k = 0; k < template.Fields.Count; k++)
                {
                    if (template.Fields[k].FieldName == fieldToReplace.ParameterName)
                    {
                        // Remove the old field.
                        template.Fields.RemoveAt(k);

                        // Now insert the new fields starting at the location of the one we just replaced.
                        template.Fields.InsertRange(k, fieldToReplace.Values);
                        break;
                    }
                }
            }

            // Finally initialize the fields using default values.
            for (int i = 0; i < template.Fields.Count; i++)
            {
                var          templateProperty = template.Fields[i];
                string       propertyName     = templateProperty.FieldName;
                PropertyType type             = templateProperty.FieldType;
                object       value            = GetDefaultValue(templateProperty);

                if (propertyName == "Name")
                {
                    value = fromDescriptor.TechnicalName;
                }

                obj.Fields.Properties.Add(new Property(propertyName, type, value));
            }

            return(obj);
        }
예제 #2
0
        public void LoadTemplates(string entityDescriptorPath, string objectDescriptorPath)
        {
            // Load Entity Data, which describes the layout of various entities in a map.
            DirectoryInfo mapEntityDescriptorDirectory = new DirectoryInfo(entityDescriptorPath);

            MapEntityDataDescriptors = new List <MapEntityDataDescriptor>();

            foreach (var file in mapEntityDescriptorDirectory.GetFiles())
            {
                var template = JsonConvert.DeserializeObject <MapEntityDataDescriptor>(File.ReadAllText(file.FullName));
                MapEntityDataDescriptors.Add(template);
            }

            // Then load the Object Data, which describes the layout of specific actors since their parameters change
            // depending on the actor used.
            DirectoryInfo objDataDI = new DirectoryInfo(objectDescriptorPath);

            MapObjectDataDescriptors = new List <MapObjectDataDescriptor>();

            foreach (var file in objDataDI.GetFiles())
            {
                var descriptor = JsonConvert.DeserializeObject <MapObjectDataDescriptor>(File.ReadAllText(file.FullName));
                MapObjectDataDescriptors.Add(descriptor);

                if (descriptor.TechnicalName == "DEFAULT_TEMPLATE")
                {
                    if (DefaultMapObjectDataDescriptor != null)
                    {
                        WLog.Warning(LogCategory.EntityLoading, null, "Found multiple default MapObjectDataDescriptors, ignoring.");
                        continue;
                    }

                    DefaultMapObjectDataDescriptor = descriptor;
                }
            }

            if (DefaultMapObjectDataDescriptor == null)
            {
                throw new FileNotFoundException("Default MapObjectDataDescriptor not found!", objectDescriptorPath);
            }
        }
예제 #3
0
        private RawMapEntity LoadMapEntityFromStream(string chunkFourCC, EndianBinaryReader reader, MapEntityDataDescriptor template)
        {
            RawMapEntity obj = new RawMapEntity();

            obj.Fields = new PropertyCollection();
            obj.FourCC = chunkFourCC;

            // We're going to examine the Template's properties and load based on the current template type.
            for (int i = 0; i < template.Fields.Count; i++)
            {
                var          templateProperty = template.Fields[i];
                string       propertyName     = templateProperty.FieldName;
                PropertyType type             = templateProperty.FieldType;
                object       value            = null;

                switch (type)
                {
                case PropertyType.FixedLengthString:
                    value = reader.ReadString(templateProperty.Length).Trim(new[] { '\0' });
                    break;

                case PropertyType.String:
                    value = reader.ReadStringUntil('\0');
                    break;

                case PropertyType.Byte:
                    value = reader.ReadByte();
                    break;

                case PropertyType.Short:
                    value = reader.ReadInt16();
                    break;

                case PropertyType.Int32BitField:
                case PropertyType.Int32:
                    value = reader.ReadInt32();
                    break;

                case PropertyType.Float:
                    value = reader.ReadSingle();
                    break;

                case PropertyType.Vector3:
                    value = new Vector3(reader.ReadSingle(), reader.ReadSingle(), reader.ReadSingle());
                    break;

                case PropertyType.Vector2:
                    value = new Vector2(reader.ReadSingle(), reader.ReadSingle());
                    break;

                case PropertyType.Enum:
                    byte enumIndexBytes = reader.ReadByte();     // ToDo: Resolve to actual Enum later.
                    value = enumIndexBytes;
                    break;

                case PropertyType.ObjectReference:
                    // When we first resolve them, we're going to keep the value as the reference byte,
                    // and then when they are post-processed they'll be turned into a proper type.
                    value = (int)reader.ReadByte();
                    break;

                case PropertyType.ObjectReferenceShort:
                    // When we first resolve them, we're going to keep the value as the reference byte,
                    // and then when they are post-processed they'll be turned into a proper type.
                    value = (int)reader.ReadUInt16();
                    break;

                case PropertyType.ObjectReferenceArray:
                    // When we first resolve them, we're going to keep the value as the reference byte,
                    // and then when they are post-processed they'll be turned into a proper type.
                    var refList = new BindingList <object>();
                    for (int refArray = 0; refArray < templateProperty.Length; refArray++)
                    {
                        refList.Add((int)reader.ReadByte());
                    }
                    value = refList;
                    break;

                case PropertyType.XYRotation:
                {
                    Vector3 eulerAngles = new Vector3();
                    for (int f = 0; f < 2; f++)
                    {
                        eulerAngles[f] = (reader.ReadInt16() * (180 / 32786f));
                    }

                    Quaternion xAxis = Quaternion.FromAxisAngle(new Vector3(1, 0, 0), eulerAngles.X * MathE.Deg2Rad);
                    Quaternion yAxis = Quaternion.FromAxisAngle(new Vector3(0, 1, 0), eulerAngles.Y * MathE.Deg2Rad);

                    // Swizzling to the ZYX order seems to be the right one.
                    Quaternion finalRot = yAxis * xAxis;
                    value = finalRot;
                }
                break;

                case PropertyType.XYZRotation:
                {
                    Vector3 eulerAngles = new Vector3();
                    for (int f = 0; f < 3; f++)
                    {
                        eulerAngles[f] = (reader.ReadInt16() * (180 / 32786f));
                    }

                    Quaternion xAxis = Quaternion.FromAxisAngle(new Vector3(1, 0, 0), eulerAngles.X * MathE.Deg2Rad);
                    Quaternion yAxis = Quaternion.FromAxisAngle(new Vector3(0, 1, 0), eulerAngles.Y * MathE.Deg2Rad);
                    Quaternion zAxis = Quaternion.FromAxisAngle(new Vector3(0, 0, 1), eulerAngles.Z * MathE.Deg2Rad);

                    // Swizzling to the ZYX order seems to be the right one.
                    Quaternion finalRot = zAxis * yAxis * xAxis;
                    value = finalRot;
                }
                break;

                case PropertyType.YRotation:
                {
                    float yRotation = reader.ReadInt16() * (180 / 32786f);

                    Quaternion yAxis = Quaternion.FromAxisAngle(new Vector3(0, 1, 0), yRotation * MathE.Deg2Rad);
                    value = yAxis;
                }
                break;

                case PropertyType.Color32:
                    value = new Color32(reader.ReadByte(), reader.ReadByte(), reader.ReadByte(), reader.ReadByte());
                    break;

                case PropertyType.Color24:
                    value = new Color24(reader.ReadByte(), reader.ReadByte(), reader.ReadByte());
                    break;

                case PropertyType.Vector3Byte:
                    type  = PropertyType.Vector3Byte;
                    value = new Vector3(reader.ReadByte(), reader.ReadByte(), reader.ReadByte());
                    break;

                case PropertyType.Bits:
                    value = (byte)reader.ReadBits(templateProperty.Length);
                    break;
                }

                // This... this could get dicy. If the template we just read was a "Name" then we now have the technical name (and value)
                // of the object. We can then search for the MapObjectDataDescriptor that matches the technical name, and then edit the
                // remaining fields. However, this gets somewhat dicey, because we're modifying the length of the Fields array for templates
                // while iterating through it. However, the Name field always comes before any of the fields we'd want to modify, we're going to
                // do an in-place replacement of the fields (since Fields.Count will increase) and then we get free loading of the complex templates
                // without later post-processing them.
                if (templateProperty.FieldName == "Name")
                {
                    // See if our template list has a complex version of this file, otherwise grab the default.
                    MapObjectDataDescriptor complexDescriptor = m_editorCore.Templates.MapObjectDataDescriptors.Find(x => x.FourCC == chunkFourCC && x.TechnicalName == templateProperty.FieldName);
                    if (complexDescriptor == null)
                    {
                        complexDescriptor = m_editorCore.Templates.DefaultMapObjectDataDescriptor;
                    }

                    // Determine which field we need to remove, and then insert in the other fields (in order) where it used to be.
                    foreach (var fieldToReplace in complexDescriptor.DataOverrides)
                    {
                        for (int k = 0; k < template.Fields.Count; k++)
                        {
                            if (template.Fields[k].FieldName == fieldToReplace.ParameterName)
                            {
                                // Remove the old field.
                                template.Fields.RemoveAt(k);

                                // Now insert the new fields starting at the location of the one we just replaced.
                                template.Fields.InsertRange(k, fieldToReplace.Values);
                                break;
                            }
                        }
                    }
                }

                Property instanceProp = new Property(templateProperty.FieldName, type, value);
                obj.Fields.Properties.Add(instanceProp);
            }

            return(obj);
        }