Пример #1
0
        public override object Execute(List <string> args)
        {
            if (args.Count != 1 || !CacheContext.TryGetTag(args[0], out var tag))
            {
                return(false);
            }

            var oldContext = ContextStack.Context;

            TagInstance = tag;

            using (var stream = CacheContext.OpenTagCacheRead())
                TagDefinition = CacheContext.Deserialize(stream, TagInstance);

            ContextStack.Push(EditTagContextFactory.Create(ContextStack, CacheContext, TagInstance, TagDefinition));

            var groupName = CacheContext.GetString(TagInstance.Group.Name);
            var tagName   = TagInstance?.Name ?? $"0x{TagInstance.Index:X4}";

            Console.WriteLine($"Tag {tagName}.{groupName} has been opened for editing.");
            Console.WriteLine("New commands are now available. Enter \"help\" to view them.");
            Console.WriteLine("Use \"exit\" to return to {0}.", oldContext.Name);

            return(true);
        }
Пример #2
0
        private Dialogue ConvertDialogue(Stream cacheStream, Dialogue dialogue)
        {
            if (BlamSoundGestalt == null)
            {
                BlamSoundGestalt = PortingContextFactory.LoadSoundGestalt(CacheContext, ref BlamCache);
            }

            CachedTagInstance edAdlg = null;
            AiDialogueGlobals adlg   = null;

            foreach (var tag in CacheContext.TagCache.Index.FindAllInGroup("adlg"))
            {
                edAdlg = tag;
                break;
            }

            adlg = CacheContext.Deserialize <AiDialogueGlobals>(cacheStream, edAdlg);

            //Create empty udlg vocalization block and fill it with empty blocks matching adlg

            List <Dialogue.Vocalization> newVocalization = new List <Dialogue.Vocalization>();

            foreach (var vocalization in adlg.Vocalizations)
            {
                Dialogue.Vocalization block = new Dialogue.Vocalization
                {
                    Sound   = null,
                    Flags   = 0,
                    Unknown = 0,
                    Name    = vocalization.Name,
                };
                newVocalization.Add(block);
            }

            //Match the tags with the proper stringId

            for (int i = 0; i < 304; i++)
            {
                var vocalization = newVocalization[i];
                for (int j = 0; j < dialogue.Vocalizations.Count; j++)
                {
                    var vocalizationH3 = dialogue.Vocalizations[j];
                    if (CacheContext.StringIdCache.GetString(vocalization.Name).Equals(CacheContext.StringIdCache.GetString(vocalizationH3.Name)))
                    {
                        vocalization.Flags   = vocalizationH3.Flags;
                        vocalization.Unknown = vocalizationH3.Unknown;
                        vocalization.Sound   = vocalizationH3.Sound;
                        break;
                    }
                }
            }

            dialogue.Vocalizations = newVocalization;

            return(dialogue);
        }
        private void MergeMultilingualUnicodeStringList(Stream cacheStream, Dictionary <ResourceLocation, Stream> resourceStreams, CachedTagInstance edTag, CacheFile.IndexItem h3Tag)
        {
            var edDef = CacheContext.Deserialize <MultilingualUnicodeStringList>(cacheStream, edTag);

            var h3Def = BlamCache.Deserializer.Deserialize <MultilingualUnicodeStringList>(
                new CacheSerializationContext(ref BlamCache, h3Tag));

            ConvertMultilingualUnicodeStringList(cacheStream, resourceStreams, h3Def);

            var mergedStringCount = 0;

            for (var i = 0; i < h3Def.Strings.Count; i++)
            {
                var found = false;

                for (var j = 0; j < edDef.Strings.Count; j++)
                {
                    if (h3Def.Strings[i].StringID == edDef.Strings[j].StringID)
                    {
                        found = true;
                        break;
                    }
                }

                if (!found)
                {
                    var localizedStr = new LocalizedString
                    {
                        StringID    = h3Def.Strings[i].StringID,
                        StringIDStr = h3Def.Strings[i].StringIDStr
                    };

                    edDef.Strings.Add(localizedStr);

                    for (var x = 0; x < 12; x++)
                    {
                        edDef.SetString(
                            localizedStr,
                            (GameLanguage)x,
                            h3Def.GetString(
                                h3Def.Strings[i],
                                (GameLanguage)x));
                    }

                    mergedStringCount++;
                }
            }

            if (mergedStringCount > 0)
            {
                Console.WriteLine($"Merged {mergedStringCount} localized strings.");
                CacheContext.Serialize(cacheStream, edTag, edDef);
            }
        }
Пример #4
0
        private Character ConvertCharacter(Stream cacheStream, Character character)
        {
            if (character.Style == null && character.ParentCharacter != null)
            {
                var parent = CacheContext.Deserialize <Character>(cacheStream, character.ParentCharacter);

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

            var shaderMaps = new Dictionary <StringId, CachedTagInstance>();

            foreach (var property in Definition.ShaderProperties)
            {
                RenderMethodTemplate template = null;

                using (var cacheStream = CacheContext.OpenTagCacheRead())
                    template = CacheContext.Deserialize <RenderMethodTemplate>(cacheStream, property.Template);

                for (var i = 0; i < template.SamplerArguments.Count; i++)
                {
                    var mapTemplate = template.SamplerArguments[i];

                    Console.Write(string.Format("Please enter the {0} index: ", CacheContext.GetString(mapTemplate.Name)));

                    if (!CacheContext.TryGetTag(Console.ReadLine(), out var shaderMap))
                    {
                        Console.WriteLine($"ERROR: Invalid bitmap name, setting to null.");
                        shaderMaps[mapTemplate.Name] = null;
                    }

                    property.ShaderMaps[i].Bitmap = shaderMaps[mapTemplate.Name];
                }
            }

            foreach (var import in Definition.ImportData)
            {
                if (shaderMaps.ContainsKey(import.Name))
                {
                    import.Bitmap = shaderMaps[import.Name];
                }
            }

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

            Console.WriteLine("Done!");

            return(true);
        }
Пример #6
0
        public override object Execute(List <string> args)
        {
            foreach (var property in Definition.ShaderProperties)
            {
                RenderMethodTemplate template = null;

                using (var cacheStream = CacheContext.OpenTagCacheRead())
                    template = CacheContext.Deserialize <RenderMethodTemplate>(cacheStream, property.Template);

                for (var i = 0; i < template.VectorArguments.Count; i++)
                {
                    Console.WriteLine("");

                    var argumentName  = CacheContext.GetString(template.VectorArguments[i].Name);
                    var argumentValue = new RealQuaternion(property.Arguments[i].Values);

                    Console.WriteLine(string.Format("{0}:", argumentName));

                    if (argumentName.EndsWith("_map"))
                    {
                        Console.WriteLine(string.Format("\tX Scale: {0}", argumentValue.I));
                        Console.WriteLine(string.Format("\tY Scale: {0}", argumentValue.J));
                        Console.WriteLine(string.Format("\tX Offset: {0}", argumentValue.K));
                        Console.WriteLine(string.Format("\tY Offset: {0}", argumentValue.W));
                    }
                    else
                    {
                        Console.WriteLine(string.Format("\tX: {0}", argumentValue.I));
                        Console.WriteLine(string.Format("\tY: {0}", argumentValue.J));
                        Console.WriteLine(string.Format("\tZ: {0}", argumentValue.K));
                        Console.WriteLine(string.Format("\tW: {0}", argumentValue.W));
                    }
                }
            }

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

            foreach (var property in Definition.ShaderProperties)
            {
                RenderMethodTemplate template = null;

                using (var cacheStream = CacheContext.OpenTagCacheRead())
                    template = CacheContext.Deserialize <RenderMethodTemplate>(cacheStream, property.Template);

                for (var i = 0; i < template.SamplerArguments.Count; i++)
                {
                    var mapTemplate = template.SamplerArguments[i];

                    Console.WriteLine($"Bitmap {i} ({CacheContext.GetString(mapTemplate.Name)}): {property.ShaderMaps[i].Bitmap.Group.Tag} 0x{property.ShaderMaps[i].Bitmap.Index:X4}");
                }
            }

            return(true);
        }
Пример #8
0
        private void MergeCharacter(Stream cacheStream, Stream blamCacheStream, Dictionary <ResourceLocation, Stream> resourceStreams, CachedTag edTag, CachedTag h3Tag)
        {
            var edDef = CacheContext.Deserialize <Character>(cacheStream, edTag);
            var h3Def = BlamCache.Deserialize <Character>(blamCacheStream, h3Tag);

            var merged = false;

            if (edDef.WeaponsProperties.Count == h3Def.WeaponsProperties.Count)
            {
                for (var i = 0; i < edDef.WeaponsProperties.Count; i++)
                {
                    if (edDef.WeaponsProperties[i].Weapon != null || h3Def.WeaponsProperties[i].Weapon == null)
                    {
                        continue;
                    }

                    edDef.WeaponsProperties[i].Weapon = ConvertTag(cacheStream, blamCacheStream, resourceStreams, h3Def.WeaponsProperties[i].Weapon);

                    merged = true;
                }
            }

            if (edDef.VehicleProperties.Count == h3Def.VehicleProperties.Count)
            {
                for (var i = 0; i < edDef.VehicleProperties.Count; i++)
                {
                    if (edDef.VehicleProperties[i].Unit != null || h3Def.VehicleProperties[i].Unit == null)
                    {
                        continue;
                    }

                    edDef.VehicleProperties[i].Unit = ConvertTag(cacheStream, blamCacheStream, resourceStreams, h3Def.VehicleProperties[i].Unit);

                    merged = true;
                }
            }

            if (edDef.EquipmentProperties.Count == h3Def.EquipmentProperties.Count)
            {
                for (var i = 0; i < edDef.EquipmentProperties.Count; i++)
                {
                    if (edDef.EquipmentProperties[i].Equipment != null || h3Def.EquipmentProperties[i].Equipment == null)
                    {
                        continue;
                    }

                    edDef.EquipmentProperties[i].Equipment = ConvertTag(cacheStream, blamCacheStream, resourceStreams, h3Def.EquipmentProperties[i].Equipment);

                    merged = true;
                }
            }

            if (edDef.FiringPatternProperties.Count == h3Def.FiringPatternProperties.Count)
            {
                for (var i = 0; i < edDef.FiringPatternProperties.Count; i++)
                {
                    if (edDef.FiringPatternProperties[i].Weapon != null || h3Def.FiringPatternProperties[i].Weapon == null)
                    {
                        continue;
                    }

                    edDef.FiringPatternProperties[i].Weapon = ConvertTag(cacheStream, blamCacheStream, resourceStreams, h3Def.FiringPatternProperties[i].Weapon);

                    merged = true;
                }
            }

            if (edDef.ActAttachments.Count == h3Def.ActAttachments.Count)
            {
                for (var i = 0; i < edDef.ActAttachments.Count; i++)
                {
                    if (edDef.ActAttachments[i].Crate != null || h3Def.ActAttachments[i].Crate == null)
                    {
                        continue;
                    }

                    edDef.ActAttachments[i].Crate = ConvertTag(cacheStream, blamCacheStream, resourceStreams, h3Def.ActAttachments[i].Crate);

                    merged = true;
                }
            }

            if (merged)
            {
                CacheContext.Serialize(cacheStream, edTag, edDef);
            }
        }
Пример #9
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);
        }
Пример #10
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();
        }
Пример #11
0
        public override object Execute(List <string> args)
        {
            if (args.Count != 3)
            {
                return(false);
            }

            var variantName   = args[0];
            var fileType      = args[1].ToLower();
            var modelFileName = args[2];

            switch (fileType)
            {
            case "obj":
            case "amf":
            case "dae":
                break;

            default:
                throw new NotImplementedException(fileType);
            }

            //
            // Find the variant to extract
            //

            if (Definition.RenderModel == null)
            {
                Console.WriteLine("The model does not have a render model associated with it.");
                return(true);
            }


            var modelVariant = Definition.Variants.FirstOrDefault(v => (CacheContext.GetString(v.Name) ?? v.Name.ToString()) == variantName);

            if (modelVariant == null && Definition.Variants.Count > 0 && fileType != "dae")
            {
                Console.WriteLine("Unable to find variant \"{0}\"", variantName);
                Console.WriteLine("Use \"listvariants\" to list available variants.");
                return(true);
            }

            //
            // Deserialize the render model tag
            //

            RenderModel renderModel;

            using (var cacheStream = CacheContext.TagCacheFile.OpenRead())
            {
                renderModel = CacheContext.Deserialize <RenderModel>(cacheStream, Definition.RenderModel);
            }

            if (renderModel.Geometry.Resource == null)
            {
                Console.WriteLine("Render model does not have a resource associated with it");
                return(true);
            }

            //
            // Deserialize the resource definition
            //

            var resourceContext    = new ResourceSerializationContext(CacheContext, renderModel.Geometry.Resource);
            var resourceDefinition = CacheContext.Deserialize <RenderGeometryApiResourceDefinition>(resourceContext);

            using (var resourceStream = new MemoryStream())
            {
                //
                // Extract the resource data
                //

                CacheContext.ExtractResource(renderModel.Geometry.Resource, resourceStream);

                var modelFile = new FileInfo(modelFileName);

                if (!modelFile.Directory.Exists)
                {
                    modelFile.Directory.Create();
                }

                switch (fileType)
                {
                case "obj":
                    ExtractObj(modelFile, renderModel, modelVariant, resourceDefinition, resourceStream);
                    break;

                case "amf":
                    ExtractAmf(modelFile, renderModel, modelVariant, resourceDefinition, resourceStream);
                    break;

                case "dae":
                    ModelExtractor extractor = new ModelExtractor(CacheContext, renderModel);
                    extractor.ExtractRenderModel();
                    extractor.ExportCollada(modelFile);
                    break;

                default:
                    throw new NotImplementedException(fileType);
                }
            }

            Console.WriteLine("Done!");

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

            var directory = args[0];

            if (!Directory.Exists(directory))
            {
                Console.Write("Destination directory does not exist. Create it? [y/n] ");
                var answer = Console.ReadLine().ToLower();

                if (answer.Length == 0 || !(answer.StartsWith("y") || answer.StartsWith("n")))
                {
                    return(false);
                }

                if (answer.StartsWith("y"))
                {
                    Directory.CreateDirectory(directory);
                }
                else
                {
                    return(false);
                }
            }

            using (var cacheStream = CacheContext.TagCacheFile.OpenRead())
            {
                foreach (var shader in Definition.Materials)
                {
                    var renderMethod = (RenderMethod)CacheContext.Deserialize(cacheStream, shader.RenderMethod);

                    foreach (var property in renderMethod.ShaderProperties)
                    {
                        var template = CacheContext.Deserialize <RenderMethodTemplate>(cacheStream, property.Template);

                        for (var i = 0; i < template.SamplerArguments.Count; i++)
                        {
                            var mapTemplate = template.SamplerArguments[i];

                            var extractor = new BitmapDdsExtractor(CacheContext);

                            var bitmap    = CacheContext.Deserialize <Bitmap>(cacheStream, property.ShaderMaps[i].Bitmap);
                            var ddsOutDir = directory;

                            if (bitmap.Images.Count > 1)
                            {
                                ddsOutDir = Path.Combine(directory, property.ShaderMaps[i].Bitmap.Index.ToString("X8"));
                                Directory.CreateDirectory(ddsOutDir);
                            }

                            for (var j = 0; j < bitmap.Images.Count; j++)
                            {
                                var outPath = Path.Combine(ddsOutDir, CacheContext.GetString(mapTemplate.Name) + "_" + property.ShaderMaps[i].Bitmap.Index.ToString("X4")) + ".dds";

                                using (var outStream = File.Open(outPath, FileMode.Create, FileAccess.Write))
                                    extractor.ExtractDds(bitmap, j, outStream);

                                Console.WriteLine($"Bitmap {i} ({CacheContext.GetString(mapTemplate.Name)}): {property.ShaderMaps[i].Bitmap.Group.Tag} 0x{property.ShaderMaps[i].Bitmap.Index:X4} extracted to '{outPath}'");
                            }
                        }
                    }
                }
            }

            return(true);
        }
        public override object Execute(List <string> args)
        {
            if (args.Count != 0)
            {
                return(false);
            }

            if (Definition.CollisionBspResource == null)
            {
                Console.WriteLine("ERROR: Collision geometry does not have a resource associated with it.");
                return(true);
            }

            var resourceDefinition = CacheContext.Deserialize <StructureBspTagResources>(Definition.CollisionBspResource);

            using (var resourceStream = new MemoryStream())
            {
                CacheContext.ExtractResource(Definition.CollisionBspResource, resourceStream);

                using (var reader = new EndianReader(resourceStream))
                {
                    foreach (var cbsp in resourceDefinition.CollisionBsps)
                    {
                        reader.BaseStream.Position = cbsp.Bsp3dNodes.Address.Offset;
                        for (var i = 0; i < cbsp.Bsp3dNodes.Count; i++)
                        {
                            var element = CacheContext.Deserializer.DeserializeValue(reader, null, null, typeof(CollisionGeometry.Bsp3dNode));
                            cbsp.Bsp3dNodes.Add((CollisionGeometry.Bsp3dNode)element);
                        }

                        reader.BaseStream.Position = cbsp.Planes.Address.Offset;
                        for (var i = 0; i < cbsp.Planes.Count; i++)
                        {
                            var element = CacheContext.Deserializer.DeserializeValue(reader, null, null, typeof(CollisionGeometry.Plane));
                            cbsp.Planes.Add((CollisionGeometry.Plane)element);
                        }

                        reader.BaseStream.Position = cbsp.Leaves.Address.Offset;
                        for (var i = 0; i < cbsp.Leaves.Count; i++)
                        {
                            var element = CacheContext.Deserializer.DeserializeValue(reader, null, null, typeof(CollisionGeometry.Leaf));
                            cbsp.Leaves.Add((CollisionGeometry.Leaf)element);
                        }

                        reader.BaseStream.Position = cbsp.Bsp2dReferences.Address.Offset;
                        for (var i = 0; i < cbsp.Bsp2dReferences.Count; i++)
                        {
                            var element = CacheContext.Deserializer.DeserializeValue(reader, null, null, typeof(CollisionGeometry.Bsp2dReference));
                            cbsp.Bsp2dReferences.Add((CollisionGeometry.Bsp2dReference)element);
                        }

                        reader.BaseStream.Position = cbsp.Bsp2dNodes.Address.Offset;
                        for (var i = 0; i < cbsp.Bsp2dNodes.Count; i++)
                        {
                            var element = CacheContext.Deserializer.DeserializeValue(reader, null, null, typeof(CollisionGeometry.Bsp2dNode));
                            cbsp.Bsp2dNodes.Add((CollisionGeometry.Bsp2dNode)element);
                        }

                        reader.BaseStream.Position = cbsp.Surfaces.Address.Offset;
                        for (var i = 0; i < cbsp.Surfaces.Count; i++)
                        {
                            var element = CacheContext.Deserializer.DeserializeValue(reader, null, null, typeof(CollisionGeometry.Surface));
                            cbsp.Surfaces.Add((CollisionGeometry.Surface)element);
                        }

                        reader.BaseStream.Position = cbsp.Edges.Address.Offset;
                        for (var i = 0; i < cbsp.Edges.Count; i++)
                        {
                            var element = CacheContext.Deserializer.DeserializeValue(reader, null, null, typeof(CollisionGeometry.Edge));
                            cbsp.Edges.Add((CollisionGeometry.Edge)element);
                        }

                        reader.BaseStream.Position = cbsp.Vertices.Address.Offset;
                        for (var i = 0; i < cbsp.Vertices.Count; i++)
                        {
                            var element = CacheContext.Deserializer.DeserializeValue(reader, null, null, typeof(CollisionGeometry.Vertex));
                            cbsp.Vertices.Add((CollisionGeometry.Vertex)element);
                        }
                    }

                    foreach (var cbsp in resourceDefinition.LargeCollisionBsps)
                    {
                        reader.BaseStream.Position = cbsp.Bsp3dNodes.Address.Offset;
                        for (var i = 0; i < cbsp.Bsp3dNodes.Count; i++)
                        {
                            var element = CacheContext.Deserializer.DeserializeValue(reader, null, null, typeof(StructureBspTagResources.LargeCollisionBspBlock.Bsp3dNode));
                            cbsp.Bsp3dNodes.Add((StructureBspTagResources.LargeCollisionBspBlock.Bsp3dNode)element);
                        }

                        reader.BaseStream.Position = cbsp.Planes.Address.Offset;
                        for (var i = 0; i < cbsp.Planes.Count; i++)
                        {
                            var element = CacheContext.Deserializer.DeserializeValue(reader, null, null, typeof(CollisionGeometry.Plane));
                            cbsp.Planes.Add((CollisionGeometry.Plane)element);
                        }

                        reader.BaseStream.Position = cbsp.Leaves.Address.Offset;
                        for (var i = 0; i < cbsp.Leaves.Count; i++)
                        {
                            var element = CacheContext.Deserializer.DeserializeValue(reader, null, null, typeof(CollisionGeometry.Leaf));
                            cbsp.Leaves.Add((CollisionGeometry.Leaf)element);
                        }

                        reader.BaseStream.Position = cbsp.Bsp2dReferences.Address.Offset;
                        for (var i = 0; i < cbsp.Bsp2dReferences.Count; i++)
                        {
                            var element = CacheContext.Deserializer.DeserializeValue(reader, null, null, typeof(StructureBspTagResources.LargeCollisionBspBlock.Bsp2dReference));
                            cbsp.Bsp2dReferences.Add((StructureBspTagResources.LargeCollisionBspBlock.Bsp2dReference)element);
                        }

                        reader.BaseStream.Position = cbsp.Bsp2dNodes.Address.Offset;
                        for (var i = 0; i < cbsp.Bsp2dNodes.Count; i++)
                        {
                            var element = CacheContext.Deserializer.DeserializeValue(reader, null, null, typeof(StructureBspTagResources.LargeCollisionBspBlock.Bsp2dNode));
                            cbsp.Bsp2dNodes.Add((StructureBspTagResources.LargeCollisionBspBlock.Bsp2dNode)element);
                        }

                        reader.BaseStream.Position = cbsp.Surfaces.Address.Offset;
                        for (var i = 0; i < cbsp.Surfaces.Count; i++)
                        {
                            var element = CacheContext.Deserializer.DeserializeValue(reader, null, null, typeof(StructureBspTagResources.LargeCollisionBspBlock.Surface));
                            cbsp.Surfaces.Add((StructureBspTagResources.LargeCollisionBspBlock.Surface)element);
                        }

                        reader.BaseStream.Position = cbsp.Edges.Address.Offset;
                        for (var i = 0; i < cbsp.Edges.Count; i++)
                        {
                            var element = CacheContext.Deserializer.DeserializeValue(reader, null, null, typeof(StructureBspTagResources.LargeCollisionBspBlock.Edge));
                            cbsp.Edges.Add((StructureBspTagResources.LargeCollisionBspBlock.Edge)element);
                        }

                        reader.BaseStream.Position = cbsp.Vertices.Address.Offset;
                        for (var i = 0; i < cbsp.Vertices.Count; i++)
                        {
                            var element = CacheContext.Deserializer.DeserializeValue(reader, null, null, typeof(StructureBspTagResources.LargeCollisionBspBlock.Vertex));
                            cbsp.Vertices.Add((StructureBspTagResources.LargeCollisionBspBlock.Vertex)element);
                        }
                    }

                    foreach (var instance in resourceDefinition.InstancedGeometry)
                    {
                        reader.BaseStream.Position = instance.CollisionInfo.Bsp3dNodes.Address.Offset;
                        for (var i = 0; i < instance.CollisionInfo.Bsp3dNodes.Count; i++)
                        {
                            var element = CacheContext.Deserializer.DeserializeValue(reader, null, null, typeof(CollisionGeometry.Bsp3dNode));
                            instance.CollisionInfo.Bsp3dNodes.Add((CollisionGeometry.Bsp3dNode)element);
                        }

                        reader.BaseStream.Position = instance.CollisionInfo.Planes.Address.Offset;
                        for (var i = 0; i < instance.CollisionInfo.Planes.Count; i++)
                        {
                            var element = CacheContext.Deserializer.DeserializeValue(reader, null, null, typeof(CollisionGeometry.Plane));
                            instance.CollisionInfo.Planes.Add((CollisionGeometry.Plane)element);
                        }

                        reader.BaseStream.Position = instance.CollisionInfo.Leaves.Address.Offset;
                        for (var i = 0; i < instance.CollisionInfo.Leaves.Count; i++)
                        {
                            var element = CacheContext.Deserializer.DeserializeValue(reader, null, null, typeof(CollisionGeometry.Leaf));
                            instance.CollisionInfo.Leaves.Add((CollisionGeometry.Leaf)element);
                        }

                        reader.BaseStream.Position = instance.CollisionInfo.Bsp2dReferences.Address.Offset;
                        for (var i = 0; i < instance.CollisionInfo.Bsp2dReferences.Count; i++)
                        {
                            var element = CacheContext.Deserializer.DeserializeValue(reader, null, null, typeof(CollisionGeometry.Bsp2dReference));
                            instance.CollisionInfo.Bsp2dReferences.Add((CollisionGeometry.Bsp2dReference)element);
                        }

                        reader.BaseStream.Position = instance.CollisionInfo.Bsp2dNodes.Address.Offset;
                        for (var i = 0; i < instance.CollisionInfo.Bsp2dNodes.Count; i++)
                        {
                            var element = CacheContext.Deserializer.DeserializeValue(reader, null, null, typeof(CollisionGeometry.Bsp2dNode));
                            instance.CollisionInfo.Bsp2dNodes.Add((CollisionGeometry.Bsp2dNode)element);
                        }

                        reader.BaseStream.Position = instance.CollisionInfo.Surfaces.Address.Offset;
                        for (var i = 0; i < instance.CollisionInfo.Surfaces.Count; i++)
                        {
                            var element = CacheContext.Deserializer.DeserializeValue(reader, null, null, typeof(CollisionGeometry.Surface));
                            instance.CollisionInfo.Surfaces.Add((CollisionGeometry.Surface)element);
                        }

                        reader.BaseStream.Position = instance.CollisionInfo.Edges.Address.Offset;
                        for (var i = 0; i < instance.CollisionInfo.Edges.Count; i++)
                        {
                            var element = CacheContext.Deserializer.DeserializeValue(reader, null, null, typeof(CollisionGeometry.Edge));
                            instance.CollisionInfo.Edges.Add((CollisionGeometry.Edge)element);
                        }

                        reader.BaseStream.Position = instance.CollisionInfo.Vertices.Address.Offset;
                        for (var i = 0; i < instance.CollisionInfo.Vertices.Count; i++)
                        {
                            var element = CacheContext.Deserializer.DeserializeValue(reader, null, null, typeof(CollisionGeometry.Vertex));
                            instance.CollisionInfo.Vertices.Add((CollisionGeometry.Vertex)element);
                        }

                        foreach (var cbsp in instance.CollisionGeometries)
                        {
                            reader.BaseStream.Position = cbsp.Bsp3dNodes.Address.Offset;
                            for (var i = 0; i < cbsp.Bsp3dNodes.Count; i++)
                            {
                                var element = CacheContext.Deserializer.DeserializeValue(reader, null, null, typeof(CollisionGeometry.Bsp3dNode));
                                cbsp.Bsp3dNodes.Add((CollisionGeometry.Bsp3dNode)element);
                            }

                            reader.BaseStream.Position = cbsp.Planes.Address.Offset;
                            for (var i = 0; i < cbsp.Planes.Count; i++)
                            {
                                var element = CacheContext.Deserializer.DeserializeValue(reader, null, null, typeof(CollisionGeometry.Plane));
                                cbsp.Planes.Add((CollisionGeometry.Plane)element);
                            }

                            reader.BaseStream.Position = cbsp.Leaves.Address.Offset;
                            for (var i = 0; i < cbsp.Leaves.Count; i++)
                            {
                                var element = CacheContext.Deserializer.DeserializeValue(reader, null, null, typeof(CollisionGeometry.Leaf));
                                cbsp.Leaves.Add((CollisionGeometry.Leaf)element);
                            }

                            reader.BaseStream.Position = cbsp.Bsp2dReferences.Address.Offset;
                            for (var i = 0; i < cbsp.Bsp2dReferences.Count; i++)
                            {
                                var element = CacheContext.Deserializer.DeserializeValue(reader, null, null, typeof(CollisionGeometry.Bsp2dReference));
                                cbsp.Bsp2dReferences.Add((CollisionGeometry.Bsp2dReference)element);
                            }

                            reader.BaseStream.Position = cbsp.Bsp2dNodes.Address.Offset;
                            for (var i = 0; i < cbsp.Bsp2dNodes.Count; i++)
                            {
                                var element = CacheContext.Deserializer.DeserializeValue(reader, null, null, typeof(CollisionGeometry.Bsp2dNode));
                                cbsp.Bsp2dNodes.Add((CollisionGeometry.Bsp2dNode)element);
                            }

                            reader.BaseStream.Position = cbsp.Surfaces.Address.Offset;
                            for (var i = 0; i < cbsp.Surfaces.Count; i++)
                            {
                                var element = CacheContext.Deserializer.DeserializeValue(reader, null, null, typeof(CollisionGeometry.Surface));
                                cbsp.Surfaces.Add((CollisionGeometry.Surface)element);
                            }

                            reader.BaseStream.Position = cbsp.Edges.Address.Offset;
                            for (var i = 0; i < cbsp.Edges.Count; i++)
                            {
                                var element = CacheContext.Deserializer.DeserializeValue(reader, null, null, typeof(CollisionGeometry.Edge));
                                cbsp.Edges.Add((CollisionGeometry.Edge)element);
                            }

                            reader.BaseStream.Position = cbsp.Vertices.Address.Offset;
                            for (var i = 0; i < cbsp.Vertices.Count; i++)
                            {
                                var element = CacheContext.Deserializer.DeserializeValue(reader, null, null, typeof(CollisionGeometry.Vertex));
                                cbsp.Vertices.Add((CollisionGeometry.Vertex)element);
                            }
                        }

                        for (var i = 0; i < instance.Unknown1.Count; i++)
                        {
                            var element = CacheContext.Deserializer.DeserializeValue(reader, null, null, typeof(StructureBspTagResources.InstancedGeometryBlock.Unknown1Block));
                            instance.Unknown1.Add((StructureBspTagResources.InstancedGeometryBlock.Unknown1Block)element);
                        }

                        for (var i = 0; i < instance.Unknown2.Count; i++)
                        {
                            var element = CacheContext.Deserializer.DeserializeValue(reader, null, null, typeof(StructureBspTagResources.InstancedGeometryBlock.Unknown2Block));
                            instance.Unknown2.Add((StructureBspTagResources.InstancedGeometryBlock.Unknown2Block)element);
                        }

                        for (var i = 0; i < instance.Unknown3.Count; i++)
                        {
                            var element = CacheContext.Deserializer.DeserializeValue(reader, null, null, typeof(StructureBspTagResources.InstancedGeometryBlock.Unknown3Block));
                            instance.Unknown3.Add((StructureBspTagResources.InstancedGeometryBlock.Unknown3Block)element);
                        }

                        foreach (var collision in instance.BspPhysics)
                        {
                            for (var i = 0; i < collision.Data.Count; i++)
                            {
                                var element = CacheContext.Deserializer.DeserializeValue(reader, null, null, typeof(byte));
                                collision.Data.Add(new StructureBspTagResources.CollisionBspPhysicsBlock.Datum {
                                    Value = (byte)element
                                });
                            }
                        }
                    }
                }
            }

            Definition.TagResources = new List <ScenarioStructureBsp.TagResourcesBlock>
            {
                new ScenarioStructureBsp.TagResourcesBlock
                {
                    CollisionBsps = resourceDefinition.CollisionBsps.Select(
                        x => new CollisionGeometry
                    {
                        Bsp3dNodes      = x.Bsp3dNodes.Elements,
                        Planes          = x.Planes.Elements,
                        Leaves          = x.Leaves.Elements,
                        Bsp2dReferences = x.Bsp2dReferences.Elements,
                        Bsp2dNodes      = x.Bsp2dNodes.Elements,
                        Surfaces        = x.Surfaces.Elements,
                        Edges           = x.Edges.Elements,
                        Vertices        = x.Vertices.Elements
                    }).ToList(),

                    LargeCollisionBsps = resourceDefinition.LargeCollisionBsps.Select(
                        x => new ScenarioStructureBsp.TagResourcesBlock.LargeCollisionBspBlock
                    {
                        Bsp3dNodes      = x.Bsp3dNodes.Elements,
                        Planes          = x.Planes.Elements,
                        Leaves          = x.Leaves.Elements,
                        Bsp2dReferences = x.Bsp2dReferences.Elements,
                        Bsp2dNodes      = x.Bsp2dNodes.Elements,
                        Surfaces        = x.Surfaces.Elements,
                        Edges           = x.Edges.Elements,
                        Vertices        = x.Vertices.Elements
                    }).ToList(),

                    InstancedGeometry = resourceDefinition.InstancedGeometry.Select(
                        x => new ScenarioStructureBsp.TagResourcesBlock.InstancedGeometryBlock
                    {
                        Checksum             = x.Checksum,
                        BoundingSphereOffset = x.BoundingSphereOffset,
                        BoundingSphereRadius = x.BoundingSphereRadius,

                        CollisionInfo = new CollisionGeometry
                        {
                            Bsp3dNodes      = x.CollisionInfo.Bsp3dNodes.Elements,
                            Planes          = x.CollisionInfo.Planes.Elements,
                            Leaves          = x.CollisionInfo.Leaves.Elements,
                            Bsp2dReferences = x.CollisionInfo.Bsp2dReferences.Elements,
                            Bsp2dNodes      = x.CollisionInfo.Bsp2dNodes.Elements,
                            Surfaces        = x.CollisionInfo.Surfaces.Elements,
                            Edges           = x.CollisionInfo.Edges.Elements,
                            Vertices        = x.CollisionInfo.Vertices.Elements
                        },

                        CollisionGeometries = x.CollisionGeometries.Select(
                            y => new CollisionGeometry
                        {
                            Bsp3dNodes      = y.Bsp3dNodes.Elements,
                            Planes          = y.Planes.Elements,
                            Leaves          = y.Leaves.Elements,
                            Bsp2dReferences = y.Bsp2dReferences.Elements,
                            Bsp2dNodes      = y.Bsp2dNodes.Elements,
                            Surfaces        = y.Surfaces.Elements,
                            Edges           = y.Edges.Elements,
                            Vertices        = y.Vertices.Elements
                        }).ToList(),

                        BspPhysics = x.BspPhysics.Select(
                            y => new ScenarioStructureBsp.TagResourcesBlock.CollisionBspPhysicsBlock
                        {
                            Unused1              = y.Unused1,
                            Size                 = y.Size,
                            Count                = y.Count,
                            Address              = y.Address,
                            Unused2              = y.Unused2,
                            Offset               = y.Offset,
                            Unused3              = y.Unused3,
                            DataSize             = y.DataSize,
                            DataCapacityAndFlags = y.DataCapacityAndFlags,
                            DataBuildType        = y.DataBuildType,
                            Unused4              = y.Unused4,
                            Unused5              = y.Unused5,
                            Data                 = y.Data.Elements,
                            MoppBuildType        = y.MoppBuildType,
                            Unused6              = y.Unused6,
                            Unused7              = y.Unused7
                        }).ToList(),

                        Unknown1         = x.Unknown1.Elements,
                        Unknown2         = x.Unknown2.Elements,
                        Unknown3         = x.Unknown3.Elements,
                        MeshIndex        = x.MeshIndex,
                        CompressionIndex = x.CompressionIndex,
                        Unknown4         = x.Unknown4,
                        Unknown5         = x.Unknown5.Elements,
                        Unknown6         = x.Unknown6
                    }).ToList(),

                    HavokData = resourceDefinition.HavokData
                }
            };

            return(true);
        }
Пример #14
0
        public override object Execute(List <string> args)
        {
            if (args.Count < 1 || args.Count > 2)
            {
                return(false);
            }

            string palette = "all";

            if (args.Count == 2)
            {
                palette = args[0].ToLower();
                args.RemoveAt(0);
            }

            if (ValidPalettes.Find(i => i == palette) == null)
            {
                Console.WriteLine($"ERROR: invalid forge palette specified: {palette}");
                return(false);
            }

            if (!CacheContext.TryGetTag(args[0], out var destinationTag))
            {
                Console.WriteLine($"ERROR: invalid destination scenario index: {args[0]}");
                return(false);
            }

            Console.Write("Loading destination scenario...");

            Scenario destinationScenario = null;

            using (var cacheStream = CacheContext.OpenTagCacheReadWrite())
                destinationScenario = CacheContext.Deserialize <Scenario>(cacheStream, destinationTag);

            Console.WriteLine("done.");

            Console.Write("Copying specified forge palettes...");

            destinationScenario.SandboxBudget = Definition.SandboxBudget;

            if (palette == "all" || palette == "equipment")
            {
                destinationScenario.SandboxEquipment = Definition.SandboxEquipment;
            }

            if (palette == "all" || palette == "goal_objects")
            {
                destinationScenario.SandboxGoalObjects = Definition.SandboxGoalObjects;
            }

            if (palette == "all" || palette == "scenery")
            {
                destinationScenario.SandboxScenery = Definition.SandboxScenery;
            }

            if (palette == "all" || palette == "spawning")
            {
                destinationScenario.SandboxSpawning = Definition.SandboxSpawning;
            }

            if (palette == "all" || palette == "teleporters")
            {
                destinationScenario.SandboxTeleporters = Definition.SandboxTeleporters;
            }

            if (palette == "all" || palette == "vehicles")
            {
                destinationScenario.SandboxVehicles = Definition.SandboxVehicles;
            }

            if (palette == "all" || palette == "weapons")
            {
                destinationScenario.SandboxWeapons = Definition.SandboxWeapons;
            }

            Console.WriteLine("done.");

            Console.Write("Serializing destination scenario...");

            using (var cacheStream = CacheContext.OpenTagCacheReadWrite())
                CacheContext.Serialize(cacheStream, destinationTag, destinationScenario);

            Console.WriteLine("done.");

            return(true);
        }
Пример #15
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);
        }
Пример #16
0
        private void MergeCharacter(Stream cacheStream, Dictionary <ResourceLocation, Stream> resourceStreams, CachedTagInstance edTag, CacheFile.IndexItem h3Tag)
        {
            var edDef = CacheContext.Deserialize <Character>(cacheStream, edTag);

            var h3Def = BlamCache.Deserializer.Deserialize <Character>(
                new CacheSerializationContext(ref BlamCache, h3Tag));

            var merged = false;

            if (edDef.WeaponsProperties.Count == h3Def.WeaponsProperties.Count)
            {
                for (var i = 0; i < edDef.WeaponsProperties.Count; i++)
                {
                    if (edDef.WeaponsProperties[i].Weapon != null || h3Def.WeaponsProperties[i].Weapon == null)
                    {
                        continue;
                    }

                    edDef.WeaponsProperties[i].Weapon = ConvertTag(cacheStream, resourceStreams,
                                                                   BlamCache.GetIndexItemFromID(h3Def.WeaponsProperties[i].Weapon.Index));

                    merged = true;
                }
            }

            if (edDef.VehicleProperties.Count == h3Def.VehicleProperties.Count)
            {
                for (var i = 0; i < edDef.VehicleProperties.Count; i++)
                {
                    if (edDef.VehicleProperties[i].Unit != null || h3Def.VehicleProperties[i].Unit == null)
                    {
                        continue;
                    }

                    edDef.VehicleProperties[i].Unit = ConvertTag(cacheStream, resourceStreams,
                                                                 BlamCache.GetIndexItemFromID(h3Def.VehicleProperties[i].Unit.Index));

                    merged = true;
                }
            }

            if (edDef.EquipmentProperties.Count == h3Def.EquipmentProperties.Count)
            {
                for (var i = 0; i < edDef.EquipmentProperties.Count; i++)
                {
                    if (edDef.EquipmentProperties[i].Equipment != null || h3Def.EquipmentProperties[i].Equipment == null)
                    {
                        continue;
                    }

                    edDef.EquipmentProperties[i].Equipment = ConvertTag(cacheStream, resourceStreams,
                                                                        BlamCache.GetIndexItemFromID(h3Def.EquipmentProperties[i].Equipment.Index));

                    merged = true;
                }
            }

            if (merged)
            {
                CacheContext.Serialize(cacheStream, edTag, edDef);
            }
        }
Пример #17
0
        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);
        }
Пример #18
0
        private void MergeMultiplayerGlobals(Stream cacheStream, Dictionary <ResourceLocation, Stream> resourceStreams, CachedTagInstance edTag, CacheFile.IndexItem h3Tag)
        {
            var edDef = CacheContext.Deserialize <MultiplayerGlobals>(cacheStream, edTag);

            var h3Def = BlamCache.Deserializer.Deserialize <MultiplayerGlobals>(
                new CacheSerializationContext(ref BlamCache, h3Tag));

            if (h3Def.Runtime == null || h3Def.Runtime.Count == 0)
            {
                return;
            }

            for (var i = 0; i < h3Def.Runtime[0].GeneralEvents.Count; i++)
            {
                var h3Event = h3Def.Runtime[0].GeneralEvents[i];

                if (h3Event.DisplayString == StringId.Invalid)
                {
                    continue;
                }

                var h3String = BlamCache.Strings.GetString(h3Event.DisplayString);

                for (var j = 0; j < edDef.Runtime[0].GeneralEvents.Count; j++)
                {
                    var edEvent  = edDef.Runtime[0].GeneralEvents[j];
                    var edString = CacheContext.GetString(edEvent.DisplayString);

                    if (edString == h3String)
                    {
                        MergeMultiplayerEvent(cacheStream, resourceStreams, edEvent, h3Event);
                    }
                }
            }

            for (var i = 0; i < h3Def.Runtime[0].FlavorEvents.Count; i++)
            {
                var h3Event = h3Def.Runtime[0].FlavorEvents[i];

                if (h3Event.DisplayString == StringId.Invalid)
                {
                    continue;
                }

                var h3String = BlamCache.Strings.GetString(h3Event.DisplayString);

                for (var j = 0; j < edDef.Runtime[0].FlavorEvents.Count; j++)
                {
                    var edEvent  = edDef.Runtime[0].FlavorEvents[j];
                    var edString = CacheContext.GetString(edEvent.DisplayString);

                    if (edString == h3String)
                    {
                        MergeMultiplayerEvent(cacheStream, resourceStreams, edEvent, h3Event);
                    }
                }
            }

            for (var i = 0; i < h3Def.Runtime[0].SlayerEvents.Count; i++)
            {
                var h3Event = h3Def.Runtime[0].SlayerEvents[i];

                if (h3Event.DisplayString == StringId.Invalid)
                {
                    continue;
                }

                var h3String = BlamCache.Strings.GetString(h3Event.DisplayString);

                for (var j = 0; j < edDef.Runtime[0].SlayerEvents.Count; j++)
                {
                    var edEvent  = edDef.Runtime[0].SlayerEvents[j];
                    var edString = CacheContext.GetString(edEvent.DisplayString);

                    if (edString == h3String)
                    {
                        MergeMultiplayerEvent(cacheStream, resourceStreams, edEvent, h3Event);
                    }
                }
            }

            for (var i = 0; i < h3Def.Runtime[0].CtfEvents.Count; i++)
            {
                var h3Event = h3Def.Runtime[0].CtfEvents[i];

                if (h3Event.DisplayString == StringId.Invalid)
                {
                    continue;
                }

                var h3String = BlamCache.Strings.GetString(h3Event.DisplayString);

                for (var j = 0; j < edDef.Runtime[0].CtfEvents.Count; j++)
                {
                    var edEvent  = edDef.Runtime[0].CtfEvents[j];
                    var edString = CacheContext.GetString(edEvent.DisplayString);

                    if (edString == h3String)
                    {
                        MergeMultiplayerEvent(cacheStream, resourceStreams, edEvent, h3Event);
                    }
                }
            }

            for (var i = 0; i < h3Def.Runtime[0].OddballEvents.Count; i++)
            {
                var h3Event = h3Def.Runtime[0].OddballEvents[i];

                if (h3Event.DisplayString == StringId.Invalid)
                {
                    continue;
                }

                var h3String = BlamCache.Strings.GetString(h3Event.DisplayString);

                for (var j = 0; j < edDef.Runtime[0].OddballEvents.Count; j++)
                {
                    var edEvent  = edDef.Runtime[0].OddballEvents[j];
                    var edString = CacheContext.GetString(edEvent.DisplayString);

                    if (edString == h3String)
                    {
                        MergeMultiplayerEvent(cacheStream, resourceStreams, edEvent, h3Event);
                    }
                }
            }

            for (var i = 0; i < h3Def.Runtime[0].KingOfTheHillEvents.Count; i++)
            {
                var h3Event = h3Def.Runtime[0].KingOfTheHillEvents[i];

                if (h3Event.DisplayString == StringId.Invalid)
                {
                    continue;
                }

                var h3String = BlamCache.Strings.GetString(h3Event.DisplayString);

                for (var j = 0; j < edDef.Runtime[0].KingOfTheHillEvents.Count; j++)
                {
                    var edEvent  = edDef.Runtime[0].KingOfTheHillEvents[j];
                    var edString = CacheContext.GetString(edEvent.DisplayString);

                    if (edString == h3String)
                    {
                        MergeMultiplayerEvent(cacheStream, resourceStreams, edEvent, h3Event);
                    }
                }
            }

            for (var i = 0; i < h3Def.Runtime[0].VipEvents.Count; i++)
            {
                var h3Event = h3Def.Runtime[0].VipEvents[i];

                if (h3Event.DisplayString == StringId.Invalid)
                {
                    continue;
                }

                var h3String = BlamCache.Strings.GetString(h3Event.DisplayString);

                for (var j = 0; j < edDef.Runtime[0].VipEvents.Count; j++)
                {
                    var edEvent  = edDef.Runtime[0].VipEvents[j];
                    var edString = CacheContext.GetString(edEvent.DisplayString);

                    if (edString == h3String)
                    {
                        MergeMultiplayerEvent(cacheStream, resourceStreams, edEvent, h3Event);
                    }
                }
            }

            for (var i = 0; i < h3Def.Runtime[0].JuggernautEvents.Count; i++)
            {
                var h3Event = h3Def.Runtime[0].JuggernautEvents[i];

                if (h3Event.DisplayString == StringId.Invalid)
                {
                    continue;
                }

                var h3String = BlamCache.Strings.GetString(h3Event.DisplayString);

                for (var j = 0; j < edDef.Runtime[0].JuggernautEvents.Count; j++)
                {
                    var edEvent  = edDef.Runtime[0].JuggernautEvents[j];
                    var edString = CacheContext.GetString(edEvent.DisplayString);

                    if (edString == h3String)
                    {
                        MergeMultiplayerEvent(cacheStream, resourceStreams, edEvent, h3Event);
                    }
                }
            }

            for (var i = 0; i < h3Def.Runtime[0].TerritoriesEvents.Count; i++)
            {
                var h3Event = h3Def.Runtime[0].TerritoriesEvents[i];

                if (h3Event.DisplayString == StringId.Invalid)
                {
                    continue;
                }

                var h3String = BlamCache.Strings.GetString(h3Event.DisplayString);

                for (var j = 0; j < edDef.Runtime[0].TerritoriesEvents.Count; j++)
                {
                    var edEvent  = edDef.Runtime[0].TerritoriesEvents[j];
                    var edString = CacheContext.GetString(edEvent.DisplayString);

                    if (edString == h3String)
                    {
                        MergeMultiplayerEvent(cacheStream, resourceStreams, edEvent, h3Event);
                    }
                }
            }

            for (var i = 0; i < h3Def.Runtime[0].AssaultEvents.Count; i++)
            {
                var h3Event = h3Def.Runtime[0].AssaultEvents[i];

                if (h3Event.DisplayString == StringId.Invalid)
                {
                    continue;
                }

                var h3String = BlamCache.Strings.GetString(h3Event.DisplayString);

                for (var j = 0; j < edDef.Runtime[0].AssaultEvents.Count; j++)
                {
                    var edEvent  = edDef.Runtime[0].AssaultEvents[j];
                    var edString = CacheContext.GetString(edEvent.DisplayString);

                    if (edString == h3String)
                    {
                        MergeMultiplayerEvent(cacheStream, resourceStreams, edEvent, h3Event);
                    }
                }
            }

            for (var i = 0; i < h3Def.Runtime[0].InfectionEvents.Count; i++)
            {
                var h3Event = h3Def.Runtime[0].InfectionEvents[i];

                if (h3Event.DisplayString == StringId.Invalid)
                {
                    continue;
                }

                var h3String = BlamCache.Strings.GetString(h3Event.DisplayString);

                for (var j = 0; j < edDef.Runtime[0].InfectionEvents.Count; j++)
                {
                    var edEvent  = edDef.Runtime[0].InfectionEvents[j];
                    var edString = CacheContext.GetString(edEvent.DisplayString);

                    if (edString == h3String)
                    {
                        MergeMultiplayerEvent(cacheStream, resourceStreams, edEvent, h3Event);
                    }
                }
            }

            CacheContext.Serialize(cacheStream, edTag, edDef);
        }
Пример #19
0
        public override object Execute(List <string> args)
        {
            if (args.Count != 1)
            {
                return(false);
            }

            var directory = args[0];

            if (!Directory.Exists(directory))
            {
                Console.Write("Destination directory does not exist. Create it? [y/n] ");
                var answer = Console.ReadLine().ToLower();

                if (answer.Length == 0 || !(answer.StartsWith("y") || answer.StartsWith("n")))
                {
                    return(false);
                }

                if (answer.StartsWith("y"))
                {
                    Directory.CreateDirectory(directory);
                }
                else
                {
                    return(false);
                }
            }

            //var extractor = new BitmapExtractor(CacheContext);
            var extractor = new BitmapDdsExtractor(CacheContext);

            using (var tagsStream = CacheContext.OpenTagCacheRead())
            {
            #if !DEBUG
                try
                {
            #endif
                var bitmap    = CacheContext.Deserialize <Bitmap>(tagsStream, Tag);
                var ddsOutDir = directory;

                if (bitmap.Images.Count > 1)
                {
                    ddsOutDir = Path.Combine(directory, Tag.Index.ToString("X8"));
                    Directory.CreateDirectory(ddsOutDir);
                }

                for (var i = 0; i < bitmap.Images.Count; i++)
                {
                    var outPath = Path.Combine(ddsOutDir, ((bitmap.Images.Count > 1) ? i.ToString() : Tag.Index.ToString("X8")) + ".dds");

                    using (var outStream = File.Open(outPath, FileMode.Create, FileAccess.Write))
                    {
                        //extractor.ExtractBitmap(bitmap, i, outStream);
                        extractor.ExtractDds(bitmap, i, outStream);
                    }
                }
            #if !DEBUG
            }
            catch (Exception ex)
            {
                Console.WriteLine("ERROR: Failed to extract bitmap: " + ex.Message);
            }
            #endif
            }

            Console.WriteLine("Done!");

            return(true);
        }
Пример #20
0
        public override object Execute(List <string> args)
        {
            if (args.Count < 2 || args.Count > 5)
            {
                return(false);
            }

            var argumentName = args[0];
            var values       = new List <float>();

            while (args.Count > 1)
            {
                if (!float.TryParse(args[1], out var value))
                {
                    throw new FormatException(args[1]);
                }

                values.Add(value);
                args.RemoveAt(1);
            }

            RenderMethodTemplate template = null;
            var properties = Definition.ShaderProperties[0];

            using (var cacheStream = CacheContext.OpenTagCacheRead())
                template = CacheContext.Deserialize <RenderMethodTemplate>(cacheStream, properties.Template);

            var argumentIndex = -1;

            for (var i = 0; i < template.VectorArguments.Count; i++)
            {
                if (CacheContext.GetString(template.VectorArguments[i].Name) == argumentName)
                {
                    argumentIndex = i;
                    break;
                }
            }

            if (argumentIndex < 0 || argumentIndex >= properties.Arguments.Count)
            {
                throw new KeyNotFoundException($"Invalid argument name: {argumentName}");
            }

            var argument = properties.Arguments[argumentIndex];

            for (var i = 0; i < argument.Values.Length; i++)
            {
                if (i < values.Count)
                {
                    argument.Values[i] = values[i];
                }
                else
                {
                    argument.Values[i] = 0.0f;
                }
            }

            var argumentValue = new RealQuaternion(argument.Values);

            Console.WriteLine();
            Console.WriteLine(string.Format("{0}:", argumentName));

            if (argumentName.EndsWith("_map"))
            {
                Console.WriteLine(string.Format("\tX Scale: {0}", argumentValue.I));
                Console.WriteLine(string.Format("\tY Scale: {0}", argumentValue.J));
                Console.WriteLine(string.Format("\tX Offset: {0}", argumentValue.K));
                Console.WriteLine(string.Format("\tY Offset: {0}", argumentValue.W));
            }
            else
            {
                Console.WriteLine(string.Format("\tX: {0}", argumentValue.I));
                Console.WriteLine(string.Format("\tY: {0}", argumentValue.J));
                Console.WriteLine(string.Format("\tZ: {0}", argumentValue.K));
                Console.WriteLine(string.Format("\tW: {0}", argumentValue.W));
            }

            return(true);
        }