Пример #1
0
        public override object Execute(List <string> args)
        {
            foreach (var material in Definition.Materials)
            {
                if (material.RenderMethod != null)
                {
                    Console.Write("Please enter the replacement {0:X8} index: ", material.RenderMethod.Index);
                }
                else
                {
                    Console.Write("Please enter the replace material #{0} index: ", Definition.Materials.IndexOf(material));
                }

                if (!CacheContext.TryGetTag(Console.ReadLine(), out material.RenderMethod))
                {
                    Console.WriteLine($"ERROR: Invalid shader specified. Using default shader.");
                    material.RenderMethod = CacheContext.GetTag <Shader>(@"shaders\default");
                }
            }

            using (var cacheStream = CacheContext.OpenCacheReadWrite())
                CacheContext.Serialize(cacheStream, Tag, Definition);

            Console.WriteLine("Done!");

            return(true);
        }
Пример #2
0
        private void saveAllTagsToolStripMenuItem_Click(object sender, EventArgs e)
        {
            var message = "Saved changes to the following tags successfully:\n";

            foreach (var entry in CurrentTags)
            {
                message += $"\n{SaveTagChanges(CacheContext.GetTag(entry.Key), entry.Value)}";
            }

            MessageBox.Show(message, "Save Tag Changes", MessageBoxButtons.OK);
        }
Пример #3
0
        public override object Execute(List <string> args)
        {
            if (args.Count < 2)
            {
                return(false);
            }

            //
            // Verify Blam tag instance
            //

            var unitName = args[0].ToLower();

            if (unitName != "spartan" && unitName != "elite")
            {
                Console.WriteLine("ERROR: Only 'spartan' and 'elite' armor variants are allowed.");
                return(false);
            }

            args.RemoveAt(0);

            var blamTagName = unitName == "spartan" ?
                              @"objects\characters\masterchief\mp_masterchief\mp_masterchief" :
                              @"objects\characters\elite\mp_elite\mp_elite";

            Console.Write($"Verifying {blamTagName}.render_model...");

            CacheFile.IndexItem blamTag = null;

            foreach (var tag in BlamCache.IndexItems)
            {
                if ((tag.GroupTag == "mode") && (tag.Name == blamTagName))
                {
                    blamTag = tag;
                    break;
                }
            }

            if (blamTag == null)
            {
                Console.WriteLine($"ERROR: Blam tag does not exist: {blamTagName}.render_model");
                return(true);
            }

            Console.WriteLine("done.");

            //
            // Load the Blam tag definition
            //

            var variantName = args[0];

            args.RemoveAt(0);

            CachedTagInstance edModeTag = null;
            var isScenery   = false;
            var regionNames = new List <string>();

            while (args.Count != 0)
            {
                switch (args[0].ToLower())
                {
                case "scenery":
                    isScenery = true;
                    args.RemoveAt(0);
                    break;

                case "replace:":
                    edModeTag = CacheContext.GetTag(args[1]);
                    args.RemoveAt(1);
                    args.RemoveAt(0);
                    break;

                case "regions:":
                    regionNames.AddRange(args.Skip(1));
                    args.Clear();
                    break;

                default:
                    throw new InvalidDataException($"{args}");
                }
            }

            var blamContext      = new CacheSerializationContext(ref BlamCache, blamTag);
            var edModeDefinition = BlamCache.Deserializer.Deserialize <RenderModel>(blamContext);

            var materials = edModeDefinition.Materials.Select(i => new RenderMaterial
            {
                BreakableSurfaceIndex = i.BreakableSurfaceIndex,
                Properties            = i.Properties,
                RenderMethod          = i.RenderMethod,
                Skins    = i.Skins,
                Unknown  = i.Unknown,
                Unknown2 = i.Unknown2,
                Unknown3 = i.Unknown3,
                Unknown4 = i.Unknown4
            }).ToList();

            edModeDefinition = (RenderModel)ConvertData(null, edModeDefinition, false);

            var variantRegions = new List <RenderModel.Region>();

            foreach (var region in edModeDefinition.Regions)
            {
                if (regionNames.Count != 0 && !regionNames.Contains(CacheContext.GetString(region.Name)))
                {
                    continue;
                }

                var variantRegion = new RenderModel.Region
                {
                    Name         = region.Name,
                    Permutations = new List <RenderModel.Region.Permutation>()
                };

                foreach (var permutation in region.Permutations)
                {
                    if (variantName == CacheContext.GetString(permutation.Name))
                    {
                        variantRegion.Permutations.Add(permutation);
                    }
                }

                variantRegions.Add(variantRegion);
            }

            var variantMeshes        = new List <int>();
            var variantMaterials     = new List <int>();
            var variantVertexBuffers = new List <int>();
            var variantIndexBuffers  = new List <int>();

            foreach (var region in variantRegions)
            {
                foreach (var permutation in region.Permutations)
                {
                    for (var i = permutation.MeshIndex; i < (short)(permutation.MeshIndex + permutation.MeshCount); i++)
                    {
                        var mesh = edModeDefinition.Geometry.Meshes[i];

                        foreach (var part in mesh.Parts)
                        {
                            if (part.MaterialIndex != -1 && !variantMaterials.Contains(part.MaterialIndex))
                            {
                                variantMaterials.Add(part.MaterialIndex);
                            }
                        }

                        foreach (var vertexBuffer in mesh.VertexBufferIndices)
                        {
                            if (vertexBuffer != ushort.MaxValue && !variantVertexBuffers.Contains(vertexBuffer))
                            {
                                variantVertexBuffers.Add(vertexBuffer);
                            }
                        }

                        foreach (var indexBuffer in mesh.IndexBufferIndices)
                        {
                            if (indexBuffer != ushort.MaxValue && !variantIndexBuffers.Contains(indexBuffer))
                            {
                                variantIndexBuffers.Add(indexBuffer);
                            }
                        }

                        if (!variantMeshes.Contains(i))
                        {
                            variantMeshes.Add(i);
                        }
                    }
                }
            }

            variantMeshes.Sort();
            variantMaterials.Sort();
            variantVertexBuffers.Sort();
            variantIndexBuffers.Sort();

            foreach (var meshIndex in variantMeshes)
            {
                var mesh = edModeDefinition.Geometry.Meshes[meshIndex];

                foreach (var part in mesh.Parts)
                {
                    if (part.MaterialIndex != -1)
                    {
                        part.MaterialIndex = (short)variantMaterials.IndexOf(part.MaterialIndex);
                    }
                }
            }

            foreach (var region in variantRegions)
            {
                foreach (var permutation in region.Permutations)
                {
                    if (permutation.MeshIndex != -1)
                    {
                        permutation.MeshIndex = (short)variantMeshes.IndexOf(permutation.MeshIndex);
                    }
                }
            }

            foreach (var meshIndex in variantMeshes)
            {
                var mesh = edModeDefinition.Geometry.Meshes[meshIndex];

                for (var i = 0; i < mesh.VertexBufferIndices.Length; i++)
                {
                    if (!variantVertexBuffers.Contains(mesh.VertexBufferIndices[i]))
                    {
                        mesh.VertexBufferIndices[i] = ushort.MaxValue;
                    }
                    else
                    {
                        mesh.VertexBufferIndices[i] = (ushort)variantVertexBuffers.IndexOf(mesh.VertexBufferIndices[i]);
                    }
                }

                for (var i = 0; i < mesh.IndexBufferIndices.Length; i++)
                {
                    if (!variantIndexBuffers.Contains(mesh.IndexBufferIndices[i]))
                    {
                        mesh.IndexBufferIndices[i] = ushort.MaxValue;
                    }
                    else
                    {
                        mesh.IndexBufferIndices[i] = (ushort)variantIndexBuffers.IndexOf(mesh.IndexBufferIndices[i]);
                    }
                }
            }

            edModeDefinition.Regions         = variantRegions;
            edModeDefinition.Geometry.Meshes = edModeDefinition.Geometry.Meshes.Where(i => variantMeshes.Contains(edModeDefinition.Geometry.Meshes.IndexOf(i))).ToList();

            //
            // Port Blam render_model materials
            //

            materials = materials.Where(i => variantMaterials.Contains(materials.IndexOf(i))).ToList();

            using (var stream = CacheContext.OpenTagCacheReadWrite())
            {
                for (var i = 0; i < materials.Count; i++)
                {
                    var material = materials[i];

                    if (material.RenderMethod.Index == -1)
                    {
                        continue;
                    }

                    var blamRenderMethod    = materials[i].RenderMethod;
                    var blamRenderMethodTag = BlamCache.IndexItems.GetItemByID(blamRenderMethod.Index);

                    var renderMethodExists = false;

                    foreach (var instance in CacheContext.TagCache.Index.FindAllInGroup("rm  "))
                    {
                        if (instance?.Name == blamRenderMethodTag.Name)
                        {
                            renderMethodExists    = true;
                            material.RenderMethod = instance;
                            break;
                        }
                    }

                    if (!renderMethodExists)
                    {
                        material.RenderMethod = CacheContext.GetTag <Shader>(@"shaders\invalid");
                    }
                }
            }

            edModeDefinition.Materials = materials;

            //
            // Load Blam resource data
            //

            var resourceData = BlamCache.GetRawFromID(edModeDefinition.Geometry.ZoneAssetHandle);

            if (resourceData == null)
            {
                Console.WriteLine("Blam render_geometry resource contains no data.");
                return(true);
            }

            //
            // Load Blam resource definition
            //

            Console.Write("Loading Blam render_geometry resource definition...");

            var definitionEntry = BlamCache.ResourceGestalt.TagResources[edModeDefinition.Geometry.ZoneAssetHandle.Index];

            var resourceDefinition = new RenderGeometryApiResourceDefinition
            {
                VertexBuffers = new List <TagStructureReference <VertexBufferDefinition> >(),
                IndexBuffers  = new List <TagStructureReference <IndexBufferDefinition> >()
            };

            using (var definitionStream = new MemoryStream(BlamCache.ResourceGestalt.FixupInformation))
                using (var definitionReader = new EndianReader(definitionStream, EndianFormat.BigEndian))
                {
                    var dataContext = new DataSerializationContext(definitionReader, null, CacheResourceAddressType.Definition);

                    definitionReader.SeekTo(definitionEntry.FixupInformationOffset + (definitionEntry.FixupInformationLength - 24));

                    var vertexBufferCount = definitionReader.ReadInt32();
                    definitionReader.Skip(8);
                    var indexBufferCount = definitionReader.ReadInt32();

                    definitionReader.SeekTo(definitionEntry.FixupInformationOffset);

                    for (var i = 0; i < vertexBufferCount; i++)
                    {
                        resourceDefinition.VertexBuffers.Add(new TagStructureReference <VertexBufferDefinition>
                        {
                            Definition = new VertexBufferDefinition
                            {
                                Count      = definitionReader.ReadInt32(),
                                Format     = (VertexBufferFormat)definitionReader.ReadInt16(),
                                VertexSize = definitionReader.ReadInt16(),
                                Data       = new TagData
                                {
                                    Size     = definitionReader.ReadInt32(),
                                    Unused4  = definitionReader.ReadInt32(),
                                    Unused8  = definitionReader.ReadInt32(),
                                    Address  = new CacheResourceAddress(CacheResourceAddressType.Memory, definitionReader.ReadInt32()),
                                    Unused10 = definitionReader.ReadInt32()
                                }
                            }
                        });
                    }

                    definitionReader.Skip(vertexBufferCount * 12);

                    for (var i = 0; i < indexBufferCount; i++)
                    {
                        resourceDefinition.IndexBuffers.Add(new TagStructureReference <IndexBufferDefinition>
                        {
                            Definition = new IndexBufferDefinition
                            {
                                Format = (IndexBufferFormat)definitionReader.ReadInt32(),
                                Data   = new TagData
                                {
                                    Size     = definitionReader.ReadInt32(),
                                    Unused4  = definitionReader.ReadInt32(),
                                    Unused8  = definitionReader.ReadInt32(),
                                    Address  = new CacheResourceAddress(CacheResourceAddressType.Memory, definitionReader.ReadInt32()),
                                    Unused10 = definitionReader.ReadInt32()
                                }
                            }
                        });
                    }
                }

            Console.WriteLine("done.");

            //
            // Convert Blam resource data
            //

            using (var edResourceStream = new MemoryStream())
            {
                //
                // Convert Blam render_geometry_api_resource_definition
                //

                using (var blamResourceStream = new MemoryStream(resourceData))
                {
                    //
                    // Convert Blam vertex buffers
                    //

                    Console.Write("Converting vertex buffers...");

                    var previousVertexBufferCount = -1;

                    for (var i = 0; i < resourceDefinition.VertexBuffers.Count; i++)
                    {
                        if (!variantVertexBuffers.Contains(i))
                        {
                            continue;
                        }

                        blamResourceStream.Position = definitionEntry.ResourceFixups[i].Offset;
                        if (i > 0)
                        {
                            previousVertexBufferCount = resourceDefinition.VertexBuffers[i - 1].Definition.Count;
                        }
                        GeometryConverter.ConvertVertexBuffer(resourceDefinition, blamResourceStream, edResourceStream, i, previousVertexBufferCount);
                    }

                    Console.WriteLine("done.");

                    //
                    // Convert Blam index buffers
                    //

                    Console.Write("Converting index buffers...");

                    for (var i = 0; i < resourceDefinition.IndexBuffers.Count; i++)
                    {
                        if (!variantIndexBuffers.Contains(i))
                        {
                            continue;
                        }

                        blamResourceStream.Position = definitionEntry.ResourceFixups[resourceDefinition.VertexBuffers.Count * 2 + i].Offset;
                        GeometryConverter.ConvertIndexBuffer(resourceDefinition, blamResourceStream, edResourceStream, i);
                    }

                    Console.WriteLine("done.");
                }

                resourceDefinition.VertexBuffers = resourceDefinition.VertexBuffers.Where(i => variantVertexBuffers.Contains(resourceDefinition.VertexBuffers.IndexOf(i))).ToList();
                resourceDefinition.IndexBuffers  = resourceDefinition.IndexBuffers.Where(i => variantIndexBuffers.Contains(resourceDefinition.IndexBuffers.IndexOf(i))).ToList();

                //
                // Finalize the new ElDorado geometry resource
                //

                Console.Write("Writing resource data...");

                edModeDefinition.Geometry.Resource = new PageableResource
                {
                    Page     = new RawPage(),
                    Resource = new TagResourceGen3
                    {
                        ResourceType             = TagResourceTypeGen3.RenderGeometry,
                        ResourceFixups           = new List <TagResourceGen3.ResourceFixup>(),
                        ResourceDefinitionFixups = new List <TagResourceGen3.ResourceDefinitionFixup>(),
                        Unknown2 = 1
                    }
                };

                edResourceStream.Position = 0;

                var resourceContext = new ResourceSerializationContext(CacheContext, edModeDefinition.Geometry.Resource);
                CacheContext.Serializer.Serialize(resourceContext, resourceDefinition);
                edModeDefinition.Geometry.Resource.ChangeLocation(ResourceLocation.ResourcesB);
                CacheContext.AddResource(edModeDefinition.Geometry.Resource, edResourceStream);

                Console.WriteLine("done.");
            }

            edModeDefinition.Name = CacheContext.GetStringId(variantName);

            if (edModeTag == null)
            {
                for (var i = 0; i < CacheContext.TagCache.Index.Count; i++)
                {
                    if (CacheContext.TagCache.Index[i] == null)
                    {
                        CacheContext.TagCache.Index[i] = edModeTag = new CachedTagInstance(i, TagGroup.Instances[new Tag("mode")]);
                        break;
                    }
                }

                if (edModeTag == null)
                {
                    edModeTag = CacheContext.TagCache.AllocateTag(TagGroup.Instances[new Tag("mode")]);
                }
            }

            //
            // Create a new armor model tag
            //

            Model             edHlmtDefinition = null;
            CachedTagInstance edHlmtTag        = null;

            if (isScenery)
            {
                Console.Write($"Verifying {blamTagName}.model...");

                CacheFile.IndexItem blamHlmtTag = null;

                foreach (var tag in BlamCache.IndexItems)
                {
                    if ((tag.GroupTag == "hlmt") && (tag.Name == blamTagName))
                    {
                        blamHlmtTag = tag;
                        break;
                    }
                }

                if (blamHlmtTag == null)
                {
                    Console.WriteLine($"ERROR: Blam tag does not exist: {blamTagName}.model");
                    return(true);
                }

                Console.WriteLine("done.");

                blamContext      = new CacheSerializationContext(ref BlamCache, blamHlmtTag);
                edHlmtDefinition = (Model)ConvertData(null, BlamCache.Deserializer.Deserialize <Model>(blamContext), false);

                edHlmtDefinition.RenderModel        = edModeTag;
                edHlmtDefinition.ReduceToL1SuperLow = 36.38004f;
                edHlmtDefinition.ReduceToL2Low      = 27.28503f;
                edHlmtDefinition.Variants           = new List <Model.Variant>();
                edHlmtDefinition.Materials          = new List <Model.Material>();
                edHlmtDefinition.NewDamageInfo      = new List <Model.GlobalDamageInfoBlock>();
                edHlmtDefinition.Targets            = new List <Model.Target>();

                var collisionRegions = new List <Model.CollisionRegion>();

                foreach (var collisionRegion in edHlmtDefinition.CollisionRegions)
                {
                    var found = false;

                    foreach (var variantRegion in variantRegions)
                    {
                        if (collisionRegion.Name == variantRegion.Name)
                        {
                            found = true;
                            break;
                        }
                    }

                    if (!found)
                    {
                        continue;
                    }

                    found = false;

                    foreach (var permutation in collisionRegion.Permutations)
                    {
                        if (permutation.Name == CacheContext.GetStringId(variantName))
                        {
                            found = true;
                            break;
                        }
                    }

                    if (found)
                    {
                        collisionRegions.Add(collisionRegion);
                    }
                }

                foreach (var collisionRegion in collisionRegions)
                {
                    Model.CollisionRegion.Permutation permutation = null;

                    foreach (var collisionPermutation in collisionRegion.Permutations)
                    {
                        if (collisionPermutation.Name == CacheContext.GetStringId(variantName))
                        {
                            permutation = collisionPermutation;
                            break;
                        }
                    }

                    if (permutation == null)
                    {
                        throw new KeyNotFoundException();
                    }

                    collisionRegion.Permutations = new List <Model.CollisionRegion.Permutation> {
                        permutation
                    };
                }

                edHlmtDefinition.CollisionRegions = collisionRegions;

                for (var i = 0; i < CacheContext.TagCache.Index.Count; i++)
                {
                    if (CacheContext.TagCache.Index[i] == null)
                    {
                        CacheContext.TagCache.Index[i] = edHlmtTag = new CachedTagInstance(i, TagGroup.Instances[new Tag("hlmt")]);
                        break;
                    }
                }

                if (edHlmtTag == null)
                {
                    edHlmtTag = CacheContext.TagCache.AllocateTag(TagGroup.Instances[new Tag("hlmt")]);
                }
            }

            //
            // Create a new armor scenery tag
            //

            Scenery           edScenDefinition = null;
            CachedTagInstance edScenTag        = null;

            if (isScenery)
            {
                edScenDefinition = new Scenery
                {
                    ObjectType = new GameObjectType
                    {
                        Halo2       = GameObjectTypeHalo2.Scenery,
                        Halo3Retail = GameObjectTypeHalo3Retail.Scenery,
                        Halo3ODST   = GameObjectTypeHalo3ODST.Scenery,
                        HaloOnline  = GameObjectTypeHaloOnline.Scenery
                    },
                    BoundingRadius    = 0.44f,
                    BoundingOffset    = new RealPoint3d(-0.02f, 0.0f, 0.0f),
                    AccelerationScale = 1.2f,
                    SweetenerSize     = GameObject.SweetenerSizeValue.Medium,
                    Model             = edHlmtTag,
                    ChangeColors      = new List <GameObject.ChangeColor>
                    {
                        new GameObject.ChangeColor(),
                        new GameObject.ChangeColor(),
                        new GameObject.ChangeColor(),
                        new GameObject.ChangeColor(),
                        new GameObject.ChangeColor()
                    },
                    NodeMaps = new List <GameObject.NodeMap>()
                };

                for (sbyte i = 0; i < 51; i++)
                {
                    edScenDefinition.NodeMaps.Add(new GameObject.NodeMap {
                        TargetNode = i
                    });
                }

                for (var i = 0; i < CacheContext.TagCache.Index.Count; i++)
                {
                    if (CacheContext.TagCache.Index[i] == null)
                    {
                        CacheContext.TagCache.Index[i] = edScenTag = new CachedTagInstance(i, TagGroup.Instances[new Tag("scen")]);
                        break;
                    }
                }

                if (edScenTag == null)
                {
                    edScenTag = CacheContext.TagCache.AllocateTag(TagGroup.Instances[new Tag("scen")]);
                }
            }

            //
            // Serialize new ElDorado tag definitions
            //

            using (var cacheStream = CacheContext.OpenTagCacheReadWrite())
            {
                CacheContext.Serialize(cacheStream, edModeTag, edModeDefinition);
                edModeTag.Name = isScenery ?
                                 (unitName == "spartan" ?
                                  $@"objects\characters\masterchief\mp_masterchief\armor\{variantName}" :
                                  $@"objects\characters\elite\mp_elite\armor\{variantName}") :
                                 (unitName == "spartan" ?
                                  @"objects\characters\masterchief\mp_masterchief\mp_masterchief" :
                                  @"objects\characters\elite\mp_elite\mp_elite");

                if (isScenery)
                {
                    CacheContext.Serialize(cacheStream, edHlmtTag, edHlmtDefinition);
                    CacheContext.Serialize(cacheStream, edScenTag, edScenDefinition);
                    edScenTag.Name = unitName == "spartan" ?
                                     $@"objects\characters\masterchief\mp_masterchief\armor\{variantName}" :
                                     $@"objects\characters\elite\mp_elite\armor\{variantName}";
                }
            }

            return(true);
        }
Пример #4
0
        public override object Execute(List <string> args)
        {
            if (args.Count != 0)
            {
                return(false);
            }

            ResourcesB = CacheContext.GetResourceCache(ResourceLocation.ResourcesB);
            Resources  = CacheContext.GetResourceCache(ResourceLocation.Resources);

            var tags = new Dictionary <int, CachedTagInstance>();
            var relocatedResources = new Dictionary <int, PageableResource>();

            using (var tagsStream = CacheContext.OpenTagCacheReadWrite())
                using (var sourceStream = CacheContext.OpenResourceCacheRead(ResourceLocation.ResourcesB))
                    using (var destStream = CacheContext.OpenResourceCacheReadWrite(ResourceLocation.Resources))
                    {
                        for (var i = 0; i < CacheContext.TagCache.Index.Count; i++)
                        {
                            if (tags.ContainsKey(i))
                            {
                                continue;
                            }

                            var tag = tags[i] = CacheContext.GetTag(i);

                            if (tag == null || tag.ResourcePointerOffsets.Count == 0)
                            {
                                continue;
                            }

                            var isB = false;

                            using (var dataStream = new MemoryStream(CacheContext.TagCache.ExtractTagRaw(tagsStream, tag)))
                                using (var reader = new EndianReader(dataStream))
                                {
                                    var dataContext = new DataSerializationContext(reader, null, CacheResourceAddressType.Resource);

                                    foreach (var resourcePointerOffset in tag.ResourcePointerOffsets)
                                    {
                                        reader.BaseStream.Position = resourcePointerOffset;
                                        var resourcePointer = reader.ReadUInt32();

                                        reader.BaseStream.Position = tag.PointerToOffset(resourcePointer);
                                        var resource = CacheContext.Deserializer.Deserialize <PageableResource>(dataContext);

                                        if (resource.Page.Index == -1)
                                        {
                                            continue;
                                        }

                                        if (resource.GetLocation(out var location) && location == ResourceLocation.ResourcesB)
                                        {
                                            isB = true;
                                            break;
                                        }
                                    }
                                }

                            if (!isB)
                            {
                                continue;
                            }

                            var tagDefinition = CacheContext.Deserialize(tagsStream, tag);

                            tagDefinition = ConvertData(tagsStream, sourceStream, destStream, tagDefinition);

                            CacheContext.Serialize(tagsStream, tag, tagDefinition);
                        }
                    }

            return(true);
        }
Пример #5
0
        private void ConvertShaderCortana(ShaderCortana shaderCortana, Stream cacheStream, Dictionary <ResourceLocation, Stream> resourceStreams)
        {
            var render_method_option_indices = shaderCortana.RenderMethodDefinitionOptionIndices.Select(c => (int)c.OptionIndex).ToList();

            //CachedTagInstance newCortanaShaderInstance = CacheContext.TagCache.AllocateTag(TagGroup.Instances[groupTag]);
            //var ho_cortana_shader = (ShaderCortana)Activator.CreateInstance(typeof(ShaderCortana));

            var rmdf_instance = shaderCortana.BaseRenderMethod;
            var rmdf          = CacheContext.Deserialize <RenderMethodDefinition>(new TagSerializationContext(cacheStream, CacheContext, rmdf_instance));

            //var shader_instance = CacheContext.GetTag<Shader>(@"shaders\invalid");
            //var shader = CacheContext.Deserialize<Shader>(new TagSerializationContext(cacheStream, CacheContext, shader_instance));

            //ho_cortana_shader.ImportData = shader.ImportData;
            //ho_cortana_shader.ShaderProperties = shader.ShaderProperties;

            var shader_properties = shaderCortana.ShaderProperties[0];

            shader_properties.ShaderMaps          = new List <RenderMethod.ShaderProperty.ShaderMap>();
            shader_properties.Arguments           = new List <RenderMethod.ShaderProperty.Argument>();
            shader_properties.Unknown             = new List <RenderMethod.ShaderProperty.UnknownBlock1>();
            shader_properties.DrawModes           = new List <RenderMethodTemplate.DrawMode>();
            shader_properties.Unknown3            = new List <RenderMethod.ShaderProperty.UnknownBlock3>();
            shader_properties.ArgumentMappings    = new List <RenderMethod.ShaderProperty.ArgumentMapping>();
            shader_properties.AnimationProperties = new List <RenderMethod.AnimationPropertiesBlock>();

            List <RenderMethodOption.OptionBlock> templateOptions = new List <RenderMethodOption.OptionBlock>();

            for (int i = 0; i < rmdf.Methods.Count; i++)
            {
                var method = rmdf.Methods[i];
                int selected_option_index = render_method_option_indices.Count > i ? render_method_option_indices[i] : 0;
                var selected_option       = method.ShaderOptions[selected_option_index];

                var rmop_instance = selected_option.Option;
                if (rmop_instance != null)
                {
                    var rmop = CacheContext.Deserialize <RenderMethodOption>(new TagSerializationContext(cacheStream, CacheContext, rmop_instance));

                    templateOptions.AddRange(rmop.Options);
                }
            }

            RenderMethodTemplate rmt2 = null;

            if (shader_properties.Template == null)
            {
                GenerateCortanaRMT2Tag(
                    render_method_option_indices,
                    cacheStream,
                    resourceStreams,
                    out CachedTagInstance rmt2Instance,
                    out RenderMethodTemplate newRMT2);

                shader_properties.Template = rmt2Instance;
                rmt2 = newRMT2;
            }
            else
            {
                rmt2 = CacheContext.Deserialize <RenderMethodTemplate>(new TagSerializationContext(cacheStream, CacheContext, shader_properties.Template));
            }
            //shader_properties.DrawModes = rmt2.DrawModes;

            var shaderFunctions       = new List <RenderMethod.AnimationPropertiesBlock>();
            var shaderVectorArguments = new RenderMethod.ShaderProperty.Argument[rmt2.VectorArguments.Count];

            var shaderSamplerArguments = new RenderMethod.ShaderProperty.ShaderMap[rmt2.SamplerArguments.Count];

            for (int rmt2SamplerIndex = 0; rmt2SamplerIndex < rmt2.SamplerArguments.Count; rmt2SamplerIndex++)
            {
                var rmt2SamplerArgument = rmt2.SamplerArguments[rmt2SamplerIndex];
                var name     = rmt2SamplerArgument.Name;
                var name_str = CacheContext.GetString(name);
                var shaderSamplerArgument = new RenderMethod.ShaderProperty.ShaderMap();
                {
                    foreach (var importData in shaderCortana.ImportData)
                    {
                        if (importData.Type != RenderMethodOption.OptionBlock.OptionDataType.Sampler)
                        {
                            continue;
                        }
                        if (importData.Name.Index != name.Index)
                        {
                            continue;
                        }

                        if (importData.Bitmap != null)
                        {
                            shaderSamplerArgument.Bitmap = importData.Bitmap;
                            goto datafound;
                        }
                    }

                    foreach (var deafult_option in templateOptions)
                    {
                        if (deafult_option.Type != RenderMethodOption.OptionBlock.OptionDataType.Sampler)
                        {
                            continue;
                        }
                        if (deafult_option.Name.Index != name.Index)
                        {
                            continue;
                        }

                        shaderSamplerArgument.Bitmap = deafult_option.Bitmap;

                        goto datafound;
                    }

                    shaderSamplerArguments[rmt2SamplerIndex] = shaderSamplerArgument;

datafound:
                    if (shaderSamplerArgument.Bitmap == null)
                    {
                        Console.WriteLine($"WARNING: RMCT Conversion couldn't find a shader map for {name_str}");
                        shaderSamplerArgument.Bitmap = CacheContext.GetTag <Bitmap>(@"shaders\default_bitmaps\bitmaps\gray_50_percent");
                    }
                    shaderSamplerArguments[rmt2SamplerIndex] = shaderSamplerArgument;
                }

                {
                    int xform_index = GetExistingXFormArgumentIndex(name, rmt2.VectorArguments);
                    if (xform_index == -1)
                    {
                        Console.WriteLine($"WARNING: RMCT Conversion couldn't find a shader xform argument for {name_str}. Defaulting to 0");
                        xform_index = 0;
                    }
                    else
                    {
                        var shaderVectorArgument = ProcessArgument(rmt2SamplerArgument, shaderFunctions, templateOptions, shaderCortana);
                        shaderVectorArguments[xform_index] = shaderVectorArgument;
                    }
                    shaderSamplerArgument.XFormArgumentIndex = (sbyte)xform_index;
                }
            }
            shader_properties.ShaderMaps = shaderSamplerArguments.ToList();

            for (int rmt2ArgumentIndex = 0; rmt2ArgumentIndex < rmt2.VectorArguments.Count; rmt2ArgumentIndex++)
            {
                if (shaderVectorArguments[rmt2ArgumentIndex] != null)
                {
                    continue;
                }
                var vectorArgument = rmt2.VectorArguments[rmt2ArgumentIndex];

                var shaderArgument = ProcessArgument(vectorArgument, shaderFunctions, templateOptions, shaderCortana);
                shaderVectorArguments[rmt2ArgumentIndex] = shaderArgument;
            }
            shader_properties.Arguments           = shaderVectorArguments.ToList();
            shader_properties.AnimationProperties = shaderFunctions;

            if (shaderCortana.Material.Index == 0)
            {
                if (CacheContext.StringIdCache.Contains("default_material"))
                {
                    shaderCortana.Material = CacheContext.StringIdCache.GetStringId("default_material");
                }
            }

            //shader_cortana.Material = shader.Material;

            //ho_cortana_shader.BaseRenderMethod = shader.BaseRenderMethod;
            //newCortanaShaderInstance.Name = blamTag.Name;
            //CacheContext.Serialize(new TagSerializationContext(cacheStream, CacheContext, newCortanaShaderInstance), ho_cortana_shader);
            //CacheContext.SaveTagNames();
        }
Пример #6
0
        public override object Execute(List <string> args)
        {
            bool iscluster = false;

            if (args.Count > 0 && args[0] == "cluster")
            {
                iscluster = true;
            }

            using (var stream = CacheContext.OpenCacheReadWrite())
            {
                for (var sbspindex = 0; sbspindex < Scnr.StructureBsps.Count; sbspindex++)
                {
                    var sbsp = (ScenarioStructureBsp)CacheContext.Deserialize(stream, Scnr.StructureBsps[sbspindex].StructureBsp);

                    var converter = new GeometryToObjectConverter((GameCacheHaloOnlineBase)CacheContext, stream, CacheContext, stream, Scnr, sbspindex);

                    var converted = new HashSet <short>();

                    var loopcounter = iscluster ? sbsp.Clusters.Count : sbsp.InstancedGeometryInstances.Count;

                    for (int geometryIndex = 0; geometryIndex < loopcounter; geometryIndex++)
                    {
                        var meshindex = iscluster ? sbsp.Clusters[geometryIndex].MeshIndex : sbsp.InstancedGeometryInstances[geometryIndex].MeshIndex;
                        if (converted.Contains(meshindex))
                        {
                            continue;
                        }
                        converted.Add(meshindex);
                        //strip digits from the end of the instancedgeometry name
                        //string instancedgeoname = CacheContext.StringTable.GetString(InstancedGeometryBlock.Name);
                        //var digits = new[] { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9' };
                        //var instancedgeoname = tempname.TrimEnd(digits);

                        //string NewName = $"objects\\reforge\\instanced_geometry\\{currentmeshindex}";

                        var objectTag = converter.ConvertGeometry(geometryIndex, null, iscluster);

                        //if sbsp resource is null this tag will return null, and we skip to the next bsp
                        if (objectTag == null)
                        {
                            break;
                        }

                        var instanceName = $"geometry_{geometryIndex:000}";
                        Console.WriteLine($"Converting geometry '{instanceName}'...");

                        //add new object to forge globals
                        CachedTag forgeglobal = CacheContext.GetTag <ForgeGlobalsDefinition>(@"multiplayer\forge_globals");
                        var       tmpforg     = (ForgeGlobalsDefinition)CacheContext.Deserialize(stream, forgeglobal);
                        tmpforg.Palette.Add(new ForgeGlobalsDefinition.PaletteItem
                        {
                            Name             = Path.GetFileName(objectTag.Name),
                            Type             = ForgeGlobalsDefinition.PaletteItemType.Structure,
                            CategoryIndex    = 64,
                            DescriptionIndex = -1,
                            MaxAllowed       = 0,
                            Object           = objectTag
                        });
                        CacheContext.Serialize(stream, forgeglobal, tmpforg);
                        CacheContext.SaveStrings();
                    }
                }

                if (CacheContext is GameCacheHaloOnlineBase hoCache)
                {
                    hoCache.SaveTagNames();
                }
            }

            Console.WriteLine("Done!");

            return(true);
        }
        private RenderMethod ConvertRenderMethod(Stream cacheStream, Dictionary <ResourceLocation, Stream> resourceStreams, RenderMethod finalRm, string blamTagName)
        {
            // Verify that the ShaderMatcher is ready to use
            if (!Matcher.IsInitialized())
            {
                Matcher.Init(cacheStream, CacheContext, BlamCache);
            }

            // Set flags
            Matcher.SetMS30Flag(cacheStream, FlagIsSet(PortingFlags.Ms30));

            // finalRm.ShaderProperties[0].ShaderMaps are all ported bitmaps
            // finalRm.BaseRenderMethod is a H3 tag
            // finalRm.ShaderProperties[0].Template is a H3 tag

            // TODO hardcode shader values such as argument changes for specific shaders
            var bmMaps = new List <string>();
            var bmArgs = new List <string>();
            var edMaps = new List <string>();
            var edArgs = new List <string>();

            // Reset rmt2 preset
            var pRmt2 = 0;

            // Make a template of ShaderProperty, with the correct bitmaps and arguments counts.
            var newShaderProperty = new RenderMethod.ShaderProperty
            {
                ShaderMaps = new List <RenderMethod.ShaderProperty.ShaderMap>(),
                Arguments  = new List <RenderMethod.ShaderProperty.Argument>()
            };

            // Get a simple list of bitmaps and arguments names
            var bmRmt2Instance = BlamCache.IndexItems.Find(x => x.ID == finalRm.ShaderProperties[0].Template.Index);
            var blamContext    = new CacheSerializationContext(ref BlamCache, bmRmt2Instance);
            var bmRmt2         = BlamCache.Deserializer.Deserialize <RenderMethodTemplate>(blamContext);

            // Get a simple list of H3 bitmaps and arguments names
            foreach (var a in bmRmt2.SamplerArguments)
            {
                bmMaps.Add(BlamCache.Strings.GetItemByID(a.Name.Index));
            }
            foreach (var a in bmRmt2.VectorArguments)
            {
                bmArgs.Add(BlamCache.Strings.GetItemByID(a.Name.Index));
            }

            // Find a HO equivalent rmt2
            var edRmt2Instance = Matcher.FixRmt2Reference(cacheStream, blamTagName, bmRmt2Instance, bmRmt2, bmMaps, bmArgs);

            if (edRmt2Instance == null)
            {
                return(CacheContext.Deserialize <Shader>(cacheStream, CacheContext.GetTag <Shader>(@"shaders\invalid")));
            }

            var edRmt2Tagname = edRmt2Instance.Name ?? $"0x{edRmt2Instance.Index:X4}";

            // pRmsh pRmt2 now potentially have a new value
            if (pRmt2 != 0)
            {
                if (CacheContext.TagCache.Index.Contains(pRmt2))
                {
                    var a = CacheContext.GetTag(pRmt2);
                    if (a != null)
                    {
                        edRmt2Instance = a;
                    }
                }
            }

            var edRmt2 = CacheContext.Deserialize <RenderMethodTemplate>(cacheStream, edRmt2Instance);

            foreach (var a in edRmt2.SamplerArguments)
            {
                edMaps.Add(CacheContext.StringIdCache.GetString(a.Name));
            }
            foreach (var a in edRmt2.VectorArguments)
            {
                edArgs.Add(CacheContext.StringIdCache.GetString(a.Name));
            }

            // The bitmaps are default textures.
            // Arguments are probably default values. I took the values that appeared the most frequently, assuming they are the default value.
            foreach (var a in edMaps)
            {
                var newBitmap = Matcher.GetDefaultBitmapTag(a);

                if (!CacheContext.TagCache.Index.Contains(pRmt2))
                {
                    newBitmap = @"shaders\default_bitmaps\bitmaps\default_detail"; // would only happen for removed shaders
                }
                CachedTagInstance bitmap = null;

                try
                {
                    bitmap = CacheContext.GetTag <Bitmap>(newBitmap);
                }
                catch
                {
                    bitmap = ConvertTag(cacheStream, resourceStreams, ParseLegacyTag($"{newBitmap}.bitm")[0]);
                }

                newShaderProperty.ShaderMaps.Add(
                    new RenderMethod.ShaderProperty.ShaderMap
                {
                    Bitmap = bitmap
                });
            }

            foreach (var a in edArgs)
            {
                newShaderProperty.Arguments.Add(Matcher.DefaultArgumentsValues(a));
            }

            // Reorder blam bitmaps to match the HO rmt2 order
            // Reorder blam arguments to match the HO rmt2 order
            foreach (var eM in edMaps)
            {
                foreach (var bM in bmMaps)
                {
                    if (eM == bM)
                    {
                        newShaderProperty.ShaderMaps[edMaps.IndexOf(eM)] = finalRm.ShaderProperties[0].ShaderMaps[bmMaps.IndexOf(bM)];
                    }
                }
            }

            foreach (var eA in edArgs)
            {
                foreach (var bA in bmArgs)
                {
                    if (eA == bA)
                    {
                        newShaderProperty.Arguments[edArgs.IndexOf(eA)] = finalRm.ShaderProperties[0].Arguments[bmArgs.IndexOf(bA)];
                    }
                }
            }

            // Remove some tagblocks
            // finalRm.Unknown = new List<RenderMethod.UnknownBlock>(); // hopefully not used; this gives rmt2's name. They correspond to the first tagblocks in rmdf, they tell what the shader does
            finalRm.ImportData = new List <RenderMethod.ImportDatum>(); // most likely not used
            finalRm.ShaderProperties[0].Template   = edRmt2Instance;
            finalRm.ShaderProperties[0].ShaderMaps = newShaderProperty.ShaderMaps;
            finalRm.ShaderProperties[0].Arguments  = newShaderProperty.Arguments;

            Matcher.FixRmdfTagRef(finalRm);

            FixAnimationProperties(cacheStream, resourceStreams, BlamCache, CacheContext, finalRm, edRmt2, bmRmt2, blamTagName);

            // Fix any null bitmaps, caused by bitm port failure
            foreach (var a in finalRm.ShaderProperties[0].ShaderMaps)
            {
                if (a.Bitmap != null)
                {
                    continue;
                }

                var defaultBitmap = Matcher.GetDefaultBitmapTag(edMaps[finalRm.ShaderProperties[0].ShaderMaps.IndexOf(a)]);

                try
                {
                    a.Bitmap = CacheContext.GetTag <Bitmap>(defaultBitmap);
                }
                catch
                {
                    a.Bitmap = ConvertTag(cacheStream, resourceStreams, ParseLegacyTag($"{defaultBitmap}.bitm")[0]);
                }
            }

            if (Matcher.RmhgUnknownTemplates.Contains(edRmt2Instance.Name))
            {
                if (finalRm.ShaderProperties[0].Unknown.Count == 0)
                {
                    finalRm.ShaderProperties[0].Unknown = new List <RenderMethod.ShaderProperty.UnknownBlock1>
                    {
                        new RenderMethod.ShaderProperty.UnknownBlock1
                        {
                            Unknown = 1
                        }
                    }
                }
            }
            ;

            switch (blamTagName)
            {
            case @"levels\dlc\chillout\shaders\chillout_flood_godrays" when finalRm is ShaderHalogram:
            {
                // Fixup bitmaps
                for (var i = 0; i < edRmt2.SamplerArguments.Count; i++)
                {
                    if (CacheContext.GetString(edRmt2.SamplerArguments[i].Name) == "overlay_map")
                    {
                        finalRm.ShaderProperties[0].ShaderMaps[i].Bitmap = ConvertTag(cacheStream, resourceStreams, ParseLegacyTag(@"levels\dlc\chillout\bitmaps\chillout_flood_godrays.bitmap")[0]);
                        break;
                    }
                }

                // Fixup arguments
                for (var i = 0; i < edRmt2.VectorArguments.Count; i++)
                {
                    var templateArg = edRmt2.VectorArguments[i];

                    switch (CacheContext.GetString(templateArg.Name))
                    {
                    case "overlay_map":
                        finalRm.ShaderProperties[0].Arguments[i].Values = new float[] { 1f, 1f, 0f, 0f };
                        break;

                    case "overlay_tint":
                        finalRm.ShaderProperties[0].Arguments[i].Values = new float[] { 0.3764706f, 0.7254902f, 0.9215687f, 1f };
                        break;

                    case "overlay_intensity":
                        finalRm.ShaderProperties[0].Arguments[i].Values = new float[] { 1.25f, 1.25f, 1.25f, 1.25f };
                        break;
                    }
                }
                break;
            }

            case @"levels\dlc\chillout\shaders\chillout_invis_godrays" when finalRm is ShaderHalogram:
            {
                // Fixup bitmaps
                for (var i = 0; i < edRmt2.SamplerArguments.Count; i++)
                {
                    if (CacheContext.GetString(edRmt2.SamplerArguments[i].Name) == "overlay_map")
                    {
                        finalRm.ShaderProperties[0].ShaderMaps[i].Bitmap = ConvertTag(cacheStream, resourceStreams, ParseLegacyTag(@"levels\dlc\chillout\bitmaps\chillout_invis_godrays.bitmap")[0]);
                        break;
                    }
                }

                // Fixup arguments
                for (var i = 0; i < edRmt2.VectorArguments.Count; i++)
                {
                    var templateArg = edRmt2.VectorArguments[i];

                    switch (CacheContext.GetString(templateArg.Name))
                    {
                    case "overlay_map":
                        finalRm.ShaderProperties[0].Arguments[i].Values = new float[] { 1f, 1f, 0f, 0f };
                        break;

                    case "overlay_tint":
                        finalRm.ShaderProperties[0].Arguments[i].Values = new float[] { 0.3058824f, 0.7098039f, 0.937255f, 1f };
                        break;

                    case "overlay_intensity":
                        finalRm.ShaderProperties[0].Arguments[i].Values = new float[] { 1f, 1f, 1f, 1f };
                        break;
                    }
                }
                break;
            }

            case @"levels\solo\020_base\lights\light_volume_hatlight" when finalRm is ShaderHalogram:
            {
                // Fixup bitmaps
                for (var i = 0; i < edRmt2.SamplerArguments.Count; i++)
                {
                    if (CacheContext.GetString(edRmt2.SamplerArguments[i].Name) == "overlay_map")
                    {
                        finalRm.ShaderProperties[0].ShaderMaps[i].Bitmap = ConvertTag(cacheStream, resourceStreams, ParseLegacyTag(@"levels\solo\020_base\bitmaps\light_volume_hatlight.bitmap")[0]);
                        break;
                    }
                }

                // Fixup arguments
                for (var i = 0; i < edRmt2.VectorArguments.Count; i++)
                {
                    var templateArg = edRmt2.VectorArguments[i];

                    switch (CacheContext.GetString(templateArg.Name))
                    {
                    case "overlay_map":
                        finalRm.ShaderProperties[0].Arguments[i].Values = new float[] { 2f, 1f, 0f, 0f };
                        break;

                    case "overlay_tint":
                        finalRm.ShaderProperties[0].Arguments[i].Values = new float[] { 0.9960785f, 1f, 0.8039216f, 1f };
                        break;

                    case "overlay_intensity":
                        finalRm.ShaderProperties[0].Arguments[i].Values = new float[] { 1f, 1f, 1f, 1f };
                        break;
                    }
                }
                break;
            }

            case @"objects\vehicles\ghost\shaders\ghost_dash_zcam" when finalRm is ShaderHalogram:
            case @"objects\weapons\rifle\sniper_rifle\shaders\scope_alpha" when finalRm is ShaderHalogram:
                finalRm.InputVariable = TagTool.Tags.TagMapping.VariableTypeValue.ParticleRandom1;
                finalRm.RangeVariable = TagTool.Tags.TagMapping.VariableTypeValue.ParticleAge;
                break;

            case @"levels\dlc\armory\shaders\concrete_floor_smooth" when finalRm is Shader:
            {
                // Fixup bitmaps
                for (var i = 0; i < edRmt2.SamplerArguments.Count; i++)
                {
                    if (CacheContext.GetString(edRmt2.SamplerArguments[i].Name) == "bump_map")
                    {
                        finalRm.ShaderProperties[0].ShaderMaps[i].Bitmap = ConvertTag(cacheStream, resourceStreams, ParseLegacyTag(@"levels\dlc\armory\bitmaps\concrete_floor_bump.bitmap")[0]);
                        break;
                    }
                }
                break;
            }

            case @"levels\dlc\sidewinder\shaders\side_tree_branch_snow" when finalRm is Shader:
                for (var i = 0; i < edRmt2.VectorArguments.Count; i++)
                {
                    var templateArg = edRmt2.VectorArguments[i];

                    if (CacheContext.GetString(templateArg.Name) == "env_tint_color")
                    {
                        finalRm.ShaderProperties[0].Arguments[i].Values = new float[] { 0f, 0f, 0f, 0f };
                        break;
                    }
                }
                break;

            case @"levels\multi\isolation\sky\shaders\skydome" when finalRm is Shader:
                for (var i = 0; i < edRmt2.VectorArguments.Count; i++)
                {
                    var templateArg = edRmt2.VectorArguments[i];

                    if (CacheContext.GetString(templateArg.Name) == "albedo_color")
                    {
                        finalRm.ShaderProperties[0].Arguments[i].Values = new float[] { 0.447059f, 0.376471f, 0.898039f, 1.0f };
                        break;
                    }
                }
                break;

            case @"levels\multi\snowbound\shaders\cov_grey_icy" when finalRm is Shader:
            {
                // Fixup bitmaps
                for (var i = 0; i < edRmt2.SamplerArguments.Count; i++)
                {
                    switch (CacheContext.GetString(edRmt2.SamplerArguments[i].Name))
                    {
                    case "base_map":
                        try
                        {
                            finalRm.ShaderProperties[0].ShaderMaps[i].Bitmap = ConvertTag(cacheStream, resourceStreams, ParseLegacyTag(@"levels\multi\snowbound\bitmaps\for_metal_greytech_dif.bitmap")[0]);
                        }
                        catch { }
                        break;

                    case "detail_map":
                        try
                        {
                            finalRm.ShaderProperties[0].ShaderMaps[i].Bitmap = ConvertTag(cacheStream, resourceStreams, ParseLegacyTag(@"levels\multi\snowbound\bitmaps\for_metal_greytech_icy.bitmap")[0]);
                        }
                        catch { }
                        break;

                    case "bump_map":
                        try
                        {
                            finalRm.ShaderProperties[0].ShaderMaps[i].Bitmap = ConvertTag(cacheStream, resourceStreams, ParseLegacyTag(@"levels\multi\snowbound\bitmaps\for_metal_greytech_platebump.bitmap")[0]);
                        }
                        catch { }
                        break;

                    case "bump_detail_map":
                        try
                        {
                            finalRm.ShaderProperties[0].ShaderMaps[i].Bitmap = ConvertTag(cacheStream, resourceStreams, ParseLegacyTag(@"levels\multi\snowbound\bitmaps\for_metal_greytech_bump.bitmap")[0]);
                        }
                        catch { }
                        break;
                    }
                }

                // Fixup arguments
                for (var i = 0; i < edRmt2.VectorArguments.Count; i++)
                {
                    var templateArg = edRmt2.VectorArguments[i];

                    switch (CacheContext.GetString(templateArg.Name))
                    {
                    case "base_map":
                        finalRm.ShaderProperties[0].Arguments[i].Values = new float[] { 1f, 1f, 0f, 0f };
                        break;

                    case "detail_map":
                        finalRm.ShaderProperties[0].Arguments[i].Values = new float[] { 1.5f, 1.5f, 0f, 0f };
                        break;

                    case "albedo_color":
                        finalRm.ShaderProperties[0].Arguments[i].Values = new float[] { 0.554902f, 0.5588236f, 0.5921569f, 1f };
                        break;

                    case "bump_map":
                        finalRm.ShaderProperties[0].Arguments[i].Values = new float[] { 1f, 1f, 0f, 0f };
                        break;

                    case "bump_detail_map":
                        finalRm.ShaderProperties[0].Arguments[i].Values = new float[] { 2f, 2f, 0f, 0f };
                        break;

                    case "diffuse_coefficient":
                        finalRm.ShaderProperties[0].Arguments[i].Values = new float[] { 0.4f, 0.4f, 0.4f, 0.4f };
                        break;

                    case "specular_coefficient":
                        finalRm.ShaderProperties[0].Arguments[i].Values = new float[] { 1f, 1f, 1f, 1f };
                        break;

                    case "roughness":
                        finalRm.ShaderProperties[0].Arguments[i].Values = new float[] { 0.2f, 0.2f, 0.2f, 0.2f };
                        break;

                    case "analytical_specular_contribution":
                        finalRm.ShaderProperties[0].Arguments[i].Values = new float[] { 0.2f, 0.2f, 0.2f, 0.2f };
                        break;

                    case "area_specular_contribution":
                        finalRm.ShaderProperties[0].Arguments[i].Values = new float[] { 0.1f, 0.1f, 0.1f, 0.1f };
                        break;

                    case "environment_map_specular_contribution":
                        finalRm.ShaderProperties[0].Arguments[i].Values = new float[] { 0.15f, 0.15f, 0.15f, 0.15f };
                        break;

                    case "specular_tint":
                        finalRm.ShaderProperties[0].Arguments[i].Values = new float[] { 0.8431373f, 0.8470589f, 0.8117648f, 1f };
                        break;
                    }
                }
                break;
            }

            case @"levels\multi\snowbound\shaders\rock_cliffs" when finalRm is Shader:
            case @"levels\multi\snowbound\shaders\rock_rocky" when finalRm is Shader:
            case @"levels\multi\snowbound\shaders\rock_rocky_icy" when finalRm is Shader:
            {
                // Fixup bitmaps
                for (var i = 0; i < edRmt2.SamplerArguments.Count; i++)
                {
                    switch (CacheContext.GetString(edRmt2.SamplerArguments[i].Name))
                    {
                    case "base_map":
                        try
                        {
                            finalRm.ShaderProperties[0].ShaderMaps[i].Bitmap = ConvertTag(cacheStream, resourceStreams, ParseLegacyTag(@"levels\multi\snowbound\bitmaps\rock_horiz.bitmap")[0]);
                        }
                        catch { }
                        break;

                    case "detail_map":
                        try
                        {
                            finalRm.ShaderProperties[0].ShaderMaps[i].Bitmap = ConvertTag(cacheStream, resourceStreams, ParseLegacyTag(@"levels\multi\snowbound\bitmaps\rock_granite_detail.bitmap")[0]);
                        }
                        catch { }
                        break;

                    case "detail_map2":
                        try
                        {
                            switch (blamTagName)
                            {
                            case @"levels\multi\snowbound\shaders\rock_rocky_icy":
                                finalRm.ShaderProperties[0].ShaderMaps[i].Bitmap = ConvertTag(cacheStream, resourceStreams, ParseLegacyTag(@"levels\multi\snowbound\bitmaps\rock_icy_blend.bitmap")[0]);
                                break;

                            default:
                                finalRm.ShaderProperties[0].ShaderMaps[i].Bitmap = ConvertTag(cacheStream, resourceStreams, ParseLegacyTag(@"levels\multi\snowbound\bitmaps\rock_cliff_dif.bitmap")[0]);
                                break;
                            }
                        }
                        catch { }
                        break;

                    case "bump_map":
                        try
                        {
                            finalRm.ShaderProperties[0].ShaderMaps[i].Bitmap = ConvertTag(cacheStream, resourceStreams, ParseLegacyTag(@"levels\multi\snowbound\bitmaps\rock_horiz_bump.bitmap")[0]);
                        }
                        catch { }
                        break;

                    case "bump_detail_map":
                        try
                        {
                            finalRm.ShaderProperties[0].ShaderMaps[i].Bitmap = ConvertTag(cacheStream, resourceStreams, ParseLegacyTag(@"levels\multi\snowbound\bitmaps\rock_granite_bump.bitmap")[0]);
                        }
                        catch { }
                        break;

                    case "height_map":
                        try
                        {
                            finalRm.ShaderProperties[0].ShaderMaps[i].Bitmap = ConvertTag(cacheStream, resourceStreams, ParseLegacyTag(@"levels\multi\snowbound\bitmaps\rock_horiz_parallax.bitmap")[0]);
                        }
                        catch { }
                        break;

                    case "environment_map":
                        try
                        {
                            finalRm.ShaderProperties[0].ShaderMaps[i].Bitmap = ConvertTag(cacheStream, resourceStreams, ParseLegacyTag(@"shaders\default_bitmaps\bitmaps\color_white.bitmap")[0]);
                        }
                        catch { }
                        break;
                    }
                }

                // Fixup arguments
                for (var i = 0; i < edRmt2.VectorArguments.Count; i++)
                {
                    var templateArg = edRmt2.VectorArguments[i];

                    switch (CacheContext.GetString(templateArg.Name))
                    {
                    case "base_map":
                        switch (blamTagName)
                        {
                        case @"levels\multi\snowbound\shaders\rock_cliffs":
                            finalRm.ShaderProperties[0].Arguments[i].Values = new float[] { 16f, 2f, 0f, 0.5f };
                            break;
                        }
                        break;

                    case "detail_map":
                        switch (blamTagName)
                        {
                        case @"levels\multi\snowbound\shaders\rock_cliffs":
                        case @"levels\multi\snowbound\shaders\rock_rocky":
                            finalRm.ShaderProperties[0].Arguments[i].Values = new float[] { 320f, 20f, 0f, 0f };
                            break;
                        }
                        break;

                    case "detail_map2":
                        switch (blamTagName)
                        {
                        case @"levels\multi\snowbound\shaders\rock_cliffs":
                            finalRm.ShaderProperties[0].Arguments[i].Values = new float[] { 1f, 1f, 0f, 0f };
                            break;
                        }
                        break;

                    case "bump_detail_map":
                        switch (blamTagName)
                        {
                        case @"levels\multi\snowbound\shaders\rock_cliffs":
                        case @"levels\multi\snowbound\shaders\rock_rocky":
                            finalRm.ShaderProperties[0].Arguments[i].Values = new float[] { 320f, 20f, 0f, 0f };
                            break;
                        }
                        break;

                    case "diffuse_coefficient":
                        switch (blamTagName)
                        {
                        case @"levels\multi\snowbound\shaders\rock_rocky_icy":
                            finalRm.ShaderProperties[0].Arguments[i].Values = new float[] { 1.2f, 1.2f, 1.2f, 1.2f };
                            break;
                        }
                        break;
                    }
                }
                break;
            }

            case @"levels\multi\snowbound\shaders\cov_metalplates_icy" when finalRm is Shader:
                // Fixup bitmaps
                for (var i = 0; i < edRmt2.SamplerArguments.Count; i++)
                {
                    switch (CacheContext.GetString(edRmt2.SamplerArguments[i].Name))
                    {
                    case "detail_map":
                        try
                        {
                            finalRm.ShaderProperties[0].ShaderMaps[i].Bitmap = CacheContext.GetTag <Bitmap>(@"levels\multi\snowbound\bitmaps\for_metal_greytech_icy4");
                        }
                        catch { }
                        break;

                    case "detail_map2":
                        try
                        {
                            finalRm.ShaderProperties[0].ShaderMaps[i].Bitmap = CacheContext.GetTag <Bitmap>(@"levels\multi\snowbound\bitmaps\for_metal_greytech_icy3");
                        }
                        catch { }
                        break;
                    }
                }
                break;

            case @"levels\multi\snowbound\shaders\invis_col_glass" when finalRm is Shader:
                // Fixup arguments
                for (var i = 0; i < edRmt2.VectorArguments.Count; i++)
                {
                    var templateArg = edRmt2.VectorArguments[i];

                    switch (CacheContext.GetString(templateArg.Name))
                    {
                    case "albedo_color":
                        finalRm.ShaderProperties[0].Arguments[i].Values = new float[] { 0f, 0f, 0f, 0f };
                        break;
                    }
                }
                break;
            }

            return(finalRm);
        }
Пример #8
0
        private ChudGlobalsDefinition ConvertChudGlobalsDefinition(Stream cacheStream, Stream blamCacheStream, Dictionary <ResourceLocation, Stream> resourceStreams, ChudGlobalsDefinition H3Definition)
        {
            for (int hudGlobalsIndex = 0; hudGlobalsIndex < H3Definition.HudGlobals.Count; hudGlobalsIndex++)
            {
                var H3globs = H3Definition.HudGlobals[hudGlobalsIndex];

                //Color Conversion
                H3globs.HUDDisabled                = ConvertColor(H3globs.HUDDisabled);
                H3globs.HUDPrimary                 = ConvertColor(H3globs.HUDPrimary);
                H3globs.HUDForeground              = ConvertColor(H3globs.HUDForeground);
                H3globs.HUDWarning                 = ConvertColor(H3globs.HUDWarning);
                H3globs.NeutralReticule            = ConvertColor(H3globs.NeutralReticule);
                H3globs.HostileReticule            = ConvertColor(H3globs.HostileReticule);
                H3globs.FriendlyReticule           = ConvertColor(H3globs.FriendlyReticule);
                H3globs.GlobalDynamic7_UnknownBlip = ConvertColor(H3globs.GlobalDynamic7_UnknownBlip);
                H3globs.NeutralBlip                = ConvertColor(H3globs.NeutralBlip);
                H3globs.HostileBlip                = ConvertColor(H3globs.HostileBlip);
                H3globs.FriendlyPlayerBlip         = ConvertColor(H3globs.FriendlyPlayerBlip);
                H3globs.FriendlyAIBlip             = ConvertColor(H3globs.FriendlyAIBlip);
                H3globs.GlobalDynamic12            = ConvertColor(H3globs.GlobalDynamic12);
                H3globs.WaypointBlip               = ConvertColor(H3globs.WaypointBlip);
                H3globs.DistantWaypointBlip        = ConvertColor(H3globs.DistantWaypointBlip);
                H3globs.FriendlyWaypoint           = ConvertColor(H3globs.FriendlyWaypoint);
                H3globs.GlobalDynamic16            = ConvertColor(H3globs.GlobalDynamic16);
                H3globs.GlobalDynamic17            = ConvertColor(H3globs.GlobalDynamic17);
                H3globs.GlobalDynamic18            = ConvertColor(H3globs.GlobalDynamic18);
                H3globs.GlobalDynamic19            = ConvertColor(H3globs.GlobalDynamic19);
                H3globs.GlobalDynamic20            = ConvertColor(H3globs.GlobalDynamic20);
                H3globs.GlobalDynamic21            = ConvertColor(H3globs.GlobalDynamic21);
                H3globs.GlobalDynamic22            = ConvertColor(H3globs.GlobalDynamic22);
                H3globs.GlobalDynamic23            = ConvertColor(H3globs.GlobalDynamic23);
                H3globs.GlobalDynamic24            = ConvertColor(H3globs.GlobalDynamic24);
                H3globs.GlobalDynamic25            = ConvertColor(H3globs.GlobalDynamic25);
                H3globs.GlobalDynamic26            = ConvertColor(H3globs.GlobalDynamic26);
                H3globs.GlobalDynamic27            = ConvertColor(H3globs.GlobalDynamic27);


                //fixups
                H3globs.GrenadeScematicsSpacing = 1.5f * H3globs.GrenadeScematicsSpacing;

                for (int hudAttributesIndex = 0; hudAttributesIndex < H3Definition.HudGlobals[hudGlobalsIndex].HudAttributes.Count; hudAttributesIndex++)
                {
                    var H3att = H3Definition.HudGlobals[hudGlobalsIndex].HudAttributes[hudAttributesIndex];

                    if (BlamCache.Version <= CacheVersion.Halo3Retail)
                    {
                        H3att.HorizontalScale = 1.0f;
                        H3att.VerticalScale   = 1.0f;
                    }

                    //more fixups
                    H3att.ResolutionWidth           = (uint)(H3att.ResolutionWidth * 1.5f);
                    H3att.ResolutionHeight          = (uint)(H3att.ResolutionHeight * 1.5f);
                    H3att.MotionSensorOffset.X     *= 1.5f;
                    H3att.MotionSensorOffset.Y     *= 1.5f;
                    H3att.MotionSensorRadius       *= 1.5f;
                    H3att.MotionSensorScale        *= 1.5f;
                    H3att.StateLeftRightOffset_HO.Y = H3att.StateLeftRightOffsetY_H3;
                    H3att.StateScale_HO             = H3att.StateScale;
                    H3att.NotificationOffsetY_HO    = H3att.NotificationOffsetY_H3;
                    H3att.NotificationOffsetX_HO    = H3att.NotificationOffsetX_H3;
                    H3att.NotificationScale        *= 1.5f;
                    H3att.NotificationLineSpacing  *= 1.5f;

                    if (BlamCache.Version == CacheVersion.Halo3ODST)
                    {
                        H3att.WarpAngle  = Angle.FromDegrees(4.5f);
                        H3att.WarpAmount = 0.1f;
                        H3att.StateLeftRightOffset_HO.Y = 0.2f; // 0.2 due to odsts 0.87 hud scale
                    }
                }


                for (int hudSoundsIndex = 0; hudSoundsIndex < H3Definition.HudGlobals[hudGlobalsIndex].HudSounds.Count; hudSoundsIndex++)
                {
                    var H3snd = H3Definition.HudGlobals[hudGlobalsIndex].HudSounds[hudSoundsIndex];

                    if (BlamCache.Version == CacheVersion.Halo3Retail)
                    {
                        H3snd.LatchedTo = GetEquivalentFlags(H3snd.LatchedTo, H3snd.LatchedTo_H3);

                        H3snd.Bipeds = new List <ChudGlobalsDefinition.HudGlobal.HudSound.BipedData>();

                        if (H3snd.SpartanSound != null)
                        {
                            var spartanBiped = new ChudGlobalsDefinition.HudGlobal.HudSound.BipedData();
                            spartanBiped.BipedType_HO = ChudGlobalsDefinition.HudGlobal.HudSound.BipedData.BipedTypeValue_HO.Spartan;
                            spartanBiped.Sound        = (CachedTag)ConvertData(cacheStream, blamCacheStream, resourceStreams, H3snd.SpartanSound, null, H3snd.SpartanSound.Name);
                            H3snd.Bipeds.Add(spartanBiped);
                        }
                        if (H3snd.EliteSound != null)
                        {
                            var eliteBiped = new ChudGlobalsDefinition.HudGlobal.HudSound.BipedData();
                            eliteBiped.BipedType_HO = ChudGlobalsDefinition.HudGlobal.HudSound.BipedData.BipedTypeValue_HO.Elite;
                            eliteBiped.Sound        = (CachedTag)ConvertData(cacheStream, blamCacheStream, resourceStreams, H3snd.EliteSound, null, H3snd.EliteSound.Name);
                            H3snd.Bipeds.Add(eliteBiped);
                        }
                    }

                    else if (BlamCache.Version == CacheVersion.Halo3ODST)
                    {
                        for (int bipedIndex = 0; bipedIndex < H3snd.Bipeds.Count; bipedIndex++)
                        {
                            if (H3snd.Bipeds[bipedIndex].BipedType_ODST == ChudGlobalsDefinition.HudGlobal.HudSound.BipedData.BipedTypeValue_ODST.Rookie ||
                                H3snd.Bipeds[bipedIndex].BipedType_ODST == ChudGlobalsDefinition.HudGlobal.HudSound.BipedData.BipedTypeValue_ODST.Any)
                            {
                                H3snd.Bipeds[bipedIndex].BipedType_HO = ChudGlobalsDefinition.HudGlobal.HudSound.BipedData.BipedTypeValue_HO.Spartan;
                            }
                            else
                            {
                                H3snd.Bipeds.RemoveAt(bipedIndex);
                                //indexes are shifted left by one because of this removal
                                bipedIndex -= 1;
                            }
                        }
                    }
                }
            }

            //additional values
            if (BlamCache.Version <= CacheVersion.Halo3Retail)
            {
                H3Definition.ShieldMinorThreshold    = 1.0f;
                H3Definition.ShieldMajorThreshold    = 0.5f;
                H3Definition.ShieldCriticalThreshold = 0.25f;
                H3Definition.HealthMinorThreshold    = 0.9f;
                H3Definition.HealthMajorThreshold    = 0.75f;
                H3Definition.HealthCriticalThreshold = 0.5f;
            }

            //prevent crash when porting from odst
            if (BlamCache.Version == CacheVersion.Halo3ODST)
            {
                try
                {
                    H3Definition.MotionSensorBlip = CacheContext.GetTag <Bitmap>(@"ui\chud\bitmaps\sensor_blips");
                }
                catch
                {
                    Console.WriteLine("WARNING: Motion sensor bitmap 'ui\\chud\\bitmaps\\sensor_blips' not found.");
                }
            }

            //metagame values
            H3Definition.CampaignMedalScale   = 1.5f;
            H3Definition.CampaignMedalSpacing = 60.0f;

            //upscale blip bitmap sizes
            H3Definition.LargeSensorBlipScale  *= 1.5f;
            H3Definition.MediumSensorBlipScale *= 1.5f;
            H3Definition.SmallSensorBlipScale  *= 1.5f;
            H3Definition.SensorBlipGlowRadius  *= 1.5f;

            //prevent crash?
            H3Definition.AchievementDisplayTime = 3.0f;

            return(H3Definition);
        }