private void MergeMultilingualUnicodeStringList(Stream cacheStream, Stream blamCacheStream, Dictionary <ResourceLocation, Stream> resourceStreams, CachedTag edTag, CachedTag h3Tag) { MultilingualUnicodeStringList h3Def = BlamCache.Deserialize <MultilingualUnicodeStringList>(blamCacheStream, h3Tag); var edDef = CacheContext.Deserialize <MultilingualUnicodeStringList>(cacheStream, edTag); ConvertMultilingualUnicodeStringList(cacheStream, blamCacheStream, 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); } }
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); } }
private RenderMethod FixAnimationProperties(Stream cacheStream, Stream blamCacheStream, Dictionary <ResourceLocation, Stream> resourceStreams, GameCache blamCache, GameCacheHaloOnlineBase CacheContext, RenderMethod finalRm, RenderMethodTemplate edRmt2, RenderMethodTemplate bmRmt2, string blamTagName) { // finalRm is a H3 rendermethod with ported bitmaps, if (finalRm.ShaderProperties[0].Functions.Count == 0) { return(finalRm); } foreach (var properties in finalRm.ShaderProperties[0].Functions) { properties.InputName = ConvertStringId(properties.InputName); properties.RangeName = ConvertStringId(properties.RangeName); ConvertTagFunction(properties.Function); } var pixlTag = CacheContext.Deserialize(cacheStream, edRmt2.PixelShader); var edPixl = (PixelShader)pixlTag; var bmPixl = BlamCache.Deserialize <PixelShader>(blamCacheStream, bmRmt2.PixelShader); // Make a collection of drawmodes and their DrawModeItem's // DrawModeItem are has info about all registers modified by functions for each drawmode. var bmPixlParameters = new Dictionary <int, List <ArgumentMapping> >(); // key is shader index // pixl side // For each drawmode, find its shader, and get all that shader's parameter. // Each parameter has a registerIndex, a registerType, and a registerName. // We'll use this to know which function acts on what shader and which registers var RegistersList = new Dictionary <int, string>(); foreach (var a in finalRm.ShaderProperties[0].Parameters) { if (!RegistersList.ContainsKey(a.RegisterIndex)) { RegistersList.Add(a.RegisterIndex, ""); } } var DrawModeIndex = -1; foreach (var a in bmPixl.DrawModes) { DrawModeIndex++; bmPixlParameters.Add(DrawModeIndex, new List <ArgumentMapping>()); if (a.Count == 0) { continue; } foreach (var b in bmPixl.Shaders[a.Offset].XboxParameters) { var ParameterName = BlamCache.StringTable.GetString(b.ParameterName); bmPixlParameters[DrawModeIndex].Add(new ArgumentMapping { ShaderIndex = a.Offset, ParameterName = ParameterName, RegisterIndex = b.RegisterIndex, RegisterType = b.RegisterType }); } } // rm side var bmDrawmodesFunctions = new Dictionary <int, Unknown3Tagblock>(); // key is shader index DrawModeIndex = -1; foreach (var a in finalRm.ShaderProperties[0].EntryPoints) { DrawModeIndex++; // These are not modes. This is an indireciton table of packed 10_6 shorts // from RMT2 ShaderDrawmodes to RegisterOffsets // register_offset = ShaderDrawmodes[current_drawmode].Offset var drawmodeRegisterOffset = (int)a.Offset; var drawmodeRegisterCount = (int)a.Count; var ArgumentMappingsIndexSampler = (byte)finalRm.ShaderProperties[0].ParameterTables[drawmodeRegisterOffset].Texture.Offset; var ArgumentMappingsCountSampler = finalRm.ShaderProperties[0].ParameterTables[drawmodeRegisterOffset].Texture.Count; var ArgumentMappingsIndexUnknown = (byte)finalRm.ShaderProperties[0].ParameterTables[drawmodeRegisterOffset].RealVertex.Offset; var ArgumentMappingsCountUnknown = finalRm.ShaderProperties[0].ParameterTables[drawmodeRegisterOffset].RealVertex.Count; var ArgumentMappingsIndexVector = (byte)finalRm.ShaderProperties[0].ParameterTables[drawmodeRegisterOffset].RealPixel.Offset; var ArgumentMappingsCountVector = finalRm.ShaderProperties[0].ParameterTables[drawmodeRegisterOffset].RealPixel.Count; var ArgumentMappings = new List <ArgumentMapping>(); for (int j = 0; j < ArgumentMappingsCountSampler; j++) { ArgumentMappings.Add(new ArgumentMapping { RegisterIndex = finalRm.ShaderProperties[0].Parameters[ArgumentMappingsIndexSampler + j].RegisterIndex, ArgumentIndex = finalRm.ShaderProperties[0].Parameters[ArgumentMappingsIndexSampler + j].SourceIndex, // i don't think i can use it to match stuf ArgumentMappingsTagblockIndex = ArgumentMappingsIndexSampler + j, RegisterType = TagTool.Shaders.ShaderParameter.RType.Sampler, ShaderIndex = drawmodeRegisterOffset, // WARNING i think drawmodes in rm aren't the same as in pixl, because rm drawmodes can point to a global shader . // say rm.drawmodes[17]'s value is 13, pixl.drawmodes[17] would typically be 12 }); } for (int j = 0; j < ArgumentMappingsCountUnknown; j++) { ArgumentMappings.Add(new ArgumentMapping { RegisterIndex = finalRm.ShaderProperties[0].Parameters[ArgumentMappingsIndexUnknown + j].RegisterIndex, ArgumentIndex = finalRm.ShaderProperties[0].Parameters[ArgumentMappingsIndexUnknown + j].SourceIndex, ArgumentMappingsTagblockIndex = ArgumentMappingsIndexUnknown + j, RegisterType = TagTool.Shaders.ShaderParameter.RType.Vector, ShaderIndex = drawmodeRegisterOffset, // it's something else, uses a global shader or some shit, one water shader pointed to a vtsh in rasg, but not in H3, maybe coincidence // yeah guaranteed rmdf's glvs or rasg shaders }); } for (int j = 0; j < ArgumentMappingsCountVector; j++) { ArgumentMappings.Add(new ArgumentMapping { RegisterIndex = finalRm.ShaderProperties[0].Parameters[ArgumentMappingsIndexVector + j].RegisterIndex, ArgumentIndex = finalRm.ShaderProperties[0].Parameters[ArgumentMappingsIndexVector + j].SourceIndex, ArgumentMappingsTagblockIndex = ArgumentMappingsIndexVector + j, RegisterType = TagTool.Shaders.ShaderParameter.RType.Vector, ShaderIndex = drawmodeRegisterOffset, }); } bmDrawmodesFunctions.Add(DrawModeIndex, new Unknown3Tagblock { Unknown3Index = drawmodeRegisterOffset, // not shader index for rm and rmt2 Unknown3Count = drawmodeRegisterCount, // should always be 4 for enabled drawmodes ArgumentMappingsIndexSampler = ArgumentMappingsIndexSampler, ArgumentMappingsCountSampler = ArgumentMappingsCountSampler, ArgumentMappingsIndexUnknown = ArgumentMappingsIndexUnknown, // no clue what it's used for, global shaders? i know one of the drawmodes will use one or more shaders from glvs, no idea if always or based on something ArgumentMappingsCountUnknown = ArgumentMappingsCountUnknown, ArgumentMappingsIndexVector = ArgumentMappingsIndexVector, ArgumentMappingsCountVector = ArgumentMappingsCountVector, ArgumentMappings = ArgumentMappings }); } DrawModeIndex = -1; foreach (var a in bmDrawmodesFunctions) { DrawModeIndex++; if (a.Value.Unknown3Count == 0) { continue; } foreach (var b in a.Value.ArgumentMappings) { foreach (var c in bmPixlParameters[a.Key]) { if (b.RegisterIndex == c.RegisterIndex && b.RegisterType == c.RegisterType) { b.ParameterName = c.ParameterName; break; } } } } // // Now that we know which register is what for each drawmode, find its halo online equivalent register indexes based on register name. // // This is where it gets tricky because drawmodes count changed in HO. foreach (var a in bmDrawmodesFunctions) { if (a.Value.Unknown3Count == 0) { continue; } foreach (var b in a.Value.ArgumentMappings) { foreach (var c in edPixl.Shaders[edPixl.DrawModes[a.Key].Offset].PCParameters) { var ParameterName = CacheContext.StringTable.GetString(c.ParameterName); if (ParameterName == b.ParameterName && b.RegisterType == c.RegisterType) { if (RegistersList[b.RegisterIndex] == "") { RegistersList[b.RegisterIndex] = $"{c.RegisterIndex}"; } else { RegistersList[b.RegisterIndex] = $"{RegistersList[b.RegisterIndex]},{c.RegisterIndex}"; } b.EDRegisterIndex = c.RegisterIndex; } } } } // DEBUG draw registers // DEBUG check for invalid registers foreach (var a in bmDrawmodesFunctions) { if (a.Value.Unknown3Count == 0) { continue; } foreach (var b in a.Value.ArgumentMappings) { finalRm.ShaderProperties[0].Parameters[b.ArgumentMappingsTagblockIndex].RegisterIndex = (short)b.EDRegisterIndex; } } // one final check // Gather all register indexes from pixl tag. Then check against all the converted register indexes. // It should detect registers that are invalid and would crash, but it does not verify if the register is valid. var validEDRegisters = new List <int>(); foreach (var a in edPixl.Shaders) { foreach (var b in a.PCParameters) { if (!validEDRegisters.Contains(b.RegisterIndex)) { validEDRegisters.Add(b.RegisterIndex); } } } foreach (var a in finalRm.ShaderProperties[0].Parameters) { if (!validEDRegisters.Contains((a.RegisterIndex))) { // Display a warning // Console.WriteLine($"INVALID REGISTERS IN TAG {blamTagName}!"); finalRm.ShaderProperties[0].EntryPoints = new List <RenderMethodTemplate.PackedInteger_10_6>(); finalRm.ShaderProperties[0].ParameterTables = new List <ParameterTable>(); finalRm.ShaderProperties[0].Parameters = new List <ParameterMapping>(); finalRm.ShaderProperties[0].Functions = new List <ShaderFunction>(); foreach (var map in finalRm.ShaderProperties[0].TextureConstants) { map.Functions.Integer = 0; } return(finalRm); } } return(finalRm); }
private RenderMethod ConvertRenderMethod(Stream cacheStream, Stream blamCacheStream, 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 bmRealConstants = new List <string>(); var bmIntConstants = new List <string>(); var bmBoolConstants = new List <string>(); var edMaps = new List <string>(); var edRealConstants = new List <string>(); var edIntConstants = new List <string>(); var edBoolConstants = 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 { TextureConstants = new List <RenderMethod.ShaderProperty.TextureConstant>(), RealConstants = new List <RenderMethod.ShaderProperty.RealConstant>(), IntegerConstants = new List <uint>() }; // Get a simple list of bitmaps and arguments names var bmRmt2Instance = finalRm.ShaderProperties[0].Template; var bmRmt2 = BlamCache.Deserialize <RenderMethodTemplate>(blamCacheStream, bmRmt2Instance); // Get a simple list of H3 bitmaps and arguments names foreach (var a in bmRmt2.TextureParameterNames) { bmMaps.Add(BlamCache.StringTable.GetString(a.Name)); } foreach (var a in bmRmt2.RealParameterNames) { bmRealConstants.Add(BlamCache.StringTable.GetString(a.Name)); } foreach (var a in bmRmt2.IntegerParameterNames) { bmIntConstants.Add(BlamCache.StringTable.GetString(a.Name)); } foreach (var a in bmRmt2.BooleanParameterNames) { bmBoolConstants.Add(BlamCache.StringTable.GetString(a.Name)); } // Find a HO equivalent rmt2 var edRmt2Instance = Matcher.FixRmt2Reference(cacheStream, blamTagName, bmRmt2Instance, bmRmt2, bmMaps, bmRealConstants); if (edRmt2Instance == null) { throw new Exception($"Failed to find HO rmt2 for this RenderMethod instance"); } var edRmt2Tagname = edRmt2Instance.Name ?? $"0x{edRmt2Instance.Index:X4}"; // pRmsh pRmt2 now potentially have a new value if (pRmt2 != 0) { if (pRmt2 < CacheContext.TagCache.Count && pRmt2 >= 0) { var a = CacheContext.TagCache.GetTag(pRmt2); if (a != null) { edRmt2Instance = a; } } } var edRmt2 = CacheContext.Deserialize <RenderMethodTemplate>(cacheStream, edRmt2Instance); // fixup for no use_material_texture vector arg in ms23 //for (int index = 0; index < edRmt2.BooleanArguments.Count; index++) //{ // if (CacheContext.StringTable.GetString(edRmt2.BooleanArguments[index].Name) == "use_material_texture") // { // finalRm.ShaderProperties[0].BooleanArguments = (ushort)(index + 1); // break; // } //} foreach (var a in edRmt2.TextureParameterNames) { edMaps.Add(CacheContext.StringTable.GetString(a.Name)); } foreach (var a in edRmt2.RealParameterNames) { edRealConstants.Add(CacheContext.StringTable.GetString(a.Name)); } foreach (var a in edRmt2.IntegerParameterNames) { edIntConstants.Add(CacheContext.StringTable.GetString(a.Name)); } foreach (var a in edRmt2.BooleanParameterNames) { edBoolConstants.Add(CacheContext.StringTable.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 (pRmt2 >= CacheContext.TagCache.Count || pRmt2 < 0) { newBitmap = @"shaders\default_bitmaps\bitmaps\default_detail"; // would only happen for removed shaders } CachedTag bitmap = null; try { bitmap = CacheContext.GetTag <Bitmap>(newBitmap); } catch { bitmap = ConvertTag(cacheStream, blamCacheStream, resourceStreams, ParseLegacyTag($"{newBitmap}.bitm")[0]); } newShaderProperty.TextureConstants.Add( new RenderMethod.ShaderProperty.TextureConstant { Bitmap = bitmap }); } foreach (var a in edRealConstants) { newShaderProperty.RealConstants.Add(Matcher.DefaultArgumentsValues(a)); } foreach (var a in edIntConstants) { newShaderProperty.IntegerConstants.Add(Matcher.DefaultIntegerArgumentsValues(a)); } // Reorder blam bitmaps to match the HO rmt2 order // Reorder blam real constants to match the HO rmt2 order // Reorder blam int constants to match the HO rmt2 order // Reorder blam bool constants to match the HO rmt2 order foreach (var eM in edMaps) { foreach (var bM in bmMaps) { if (eM == bM) { newShaderProperty.TextureConstants[edMaps.IndexOf(eM)] = finalRm.ShaderProperties[0].TextureConstants[bmMaps.IndexOf(bM)]; } } } foreach (var eA in edRealConstants) { foreach (var bA in bmRealConstants) { if (eA == bA) { newShaderProperty.RealConstants[edRealConstants.IndexOf(eA)] = finalRm.ShaderProperties[0].RealConstants[bmRealConstants.IndexOf(bA)]; } } } foreach (var eA in edIntConstants) { foreach (var bA in bmIntConstants) { if (eA == bA) { newShaderProperty.IntegerConstants[edIntConstants.IndexOf(eA)] = finalRm.ShaderProperties[0].IntegerConstants[bmIntConstants.IndexOf(bA)]; } } } foreach (var eA in edBoolConstants) { foreach (var bA in bmBoolConstants) { if (eA == bA) { if ((newShaderProperty.BooleanConstants & (1u << bmBoolConstants.IndexOf(bA))) != 0) { newShaderProperty.BooleanConstants &= ~(1u << bmBoolConstants.IndexOf(bA)); newShaderProperty.BooleanConstants |= (1u << edBoolConstants.IndexOf(eA)); } } } } // 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].TextureConstants = newShaderProperty.TextureConstants; finalRm.ShaderProperties[0].RealConstants = newShaderProperty.RealConstants; finalRm.ShaderProperties[0].IntegerConstants = newShaderProperty.IntegerConstants; finalRm.ShaderProperties[0].BooleanConstants = newShaderProperty.BooleanConstants; // fixup runtime queryable properties for (int i = 0; i < finalRm.ShaderProperties[0].QueryableProperties.Length; i++) { if (finalRm.ShaderProperties[0].QueryableProperties[i] == -1) { continue; } switch (i) { case 0: case 1: case 2: case 3: case 5: finalRm.ShaderProperties[0].QueryableProperties[i] = (short)edMaps.IndexOf(bmMaps[finalRm.ShaderProperties[0].QueryableProperties[i]]); break; case 4: finalRm.ShaderProperties[0].QueryableProperties[i] = (short)edRealConstants.IndexOf(bmRealConstants[finalRm.ShaderProperties[0].QueryableProperties[i]]); break; default: finalRm.ShaderProperties[0].QueryableProperties[i] = -1; break; } } // fixup xform arguments; foreach (var tex in finalRm.ShaderProperties[0].TextureConstants) { if (tex.XFormArgumentIndex != -1) { tex.XFormArgumentIndex = (sbyte)edRealConstants.IndexOf(bmRealConstants[tex.XFormArgumentIndex]); } } Matcher.FixRmdfTagRef(finalRm); FixAnimationProperties(cacheStream, blamCacheStream, resourceStreams, BlamCache, CacheContext, finalRm, edRmt2, bmRmt2, blamTagName); // Fix any null bitmaps, caused by bitm port failure foreach (var a in finalRm.ShaderProperties[0].TextureConstants) { if (a.Bitmap != null) { continue; } var defaultBitmap = Matcher.GetDefaultBitmapTag(edMaps[finalRm.ShaderProperties[0].TextureConstants.IndexOf(a)]); try { a.Bitmap = CacheContext.GetTag <Bitmap>(defaultBitmap); } catch { a.Bitmap = ConvertTag(cacheStream, blamCacheStream, resourceStreams, ParseLegacyTag($"{defaultBitmap}.bitm")[0]); } } switch (blamTagName) { case @"levels\dlc\chillout\shaders\chillout_flood_godrays" when finalRm is ShaderHalogram: { // Fixup bitmaps for (var i = 0; i < edRmt2.TextureParameterNames.Count; i++) { if (CacheContext.StringTable.GetString(edRmt2.TextureParameterNames[i].Name) == "overlay_map") { finalRm.ShaderProperties[0].TextureConstants[i].Bitmap = ConvertTag(cacheStream, blamCacheStream, resourceStreams, ParseLegacyTag(@"levels\dlc\chillout\bitmaps\chillout_flood_godrays.bitmap")[0]); break; } } // Fixup arguments for (var i = 0; i < edRmt2.RealParameterNames.Count; i++) { var templateArg = edRmt2.RealParameterNames[i]; switch (CacheContext.StringTable.GetString(templateArg.Name)) { case "overlay_map": finalRm.ShaderProperties[0].RealConstants[i].Values = new float[] { 1f, 1f, 0f, 0f }; break; case "overlay_tint": finalRm.ShaderProperties[0].RealConstants[i].Values = new float[] { 0.3764706f, 0.7254902f, 0.9215687f, 1f }; break; case "overlay_intensity": finalRm.ShaderProperties[0].RealConstants[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.TextureParameterNames.Count; i++) { if (CacheContext.StringTable.GetString(edRmt2.TextureParameterNames[i].Name) == "overlay_map") { finalRm.ShaderProperties[0].TextureConstants[i].Bitmap = ConvertTag(cacheStream, blamCacheStream, resourceStreams, ParseLegacyTag(@"levels\dlc\chillout\bitmaps\chillout_invis_godrays.bitmap")[0]); break; } } // Fixup arguments for (var i = 0; i < edRmt2.RealParameterNames.Count; i++) { var templateArg = edRmt2.RealParameterNames[i]; switch (CacheContext.StringTable.GetString(templateArg.Name)) { case "overlay_map": finalRm.ShaderProperties[0].RealConstants[i].Values = new float[] { 1f, 1f, 0f, 0f }; break; case "overlay_tint": finalRm.ShaderProperties[0].RealConstants[i].Values = new float[] { 0.3058824f, 0.7098039f, 0.937255f, 1f }; break; case "overlay_intensity": finalRm.ShaderProperties[0].RealConstants[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.TextureParameterNames.Count; i++) { if (CacheContext.StringTable.GetString(edRmt2.TextureParameterNames[i].Name) == "overlay_map") { finalRm.ShaderProperties[0].TextureConstants[i].Bitmap = ConvertTag(cacheStream, blamCacheStream, resourceStreams, ParseLegacyTag(@"levels\solo\020_base\bitmaps\light_volume_hatlight.bitmap")[0]); break; } } // Fixup arguments for (var i = 0; i < edRmt2.RealParameterNames.Count; i++) { var templateArg = edRmt2.RealParameterNames[i]; switch (CacheContext.StringTable.GetString(templateArg.Name)) { case "overlay_map": finalRm.ShaderProperties[0].RealConstants[i].Values = new float[] { 2f, 1f, 0f, 0f }; break; case "overlay_tint": finalRm.ShaderProperties[0].RealConstants[i].Values = new float[] { 0.9960785f, 1f, 0.8039216f, 1f }; break; case "overlay_intensity": finalRm.ShaderProperties[0].RealConstants[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.TextureParameterNames.Count; i++) { if (CacheContext.StringTable.GetString(edRmt2.TextureParameterNames[i].Name) == "bump_map") { finalRm.ShaderProperties[0].TextureConstants[i].Bitmap = ConvertTag(cacheStream, blamCacheStream, 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.RealParameterNames.Count; i++) { var templateArg = edRmt2.RealParameterNames[i]; if (CacheContext.StringTable.GetString(templateArg.Name) == "env_tint_color") { finalRm.ShaderProperties[0].RealConstants[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.RealParameterNames.Count; i++) { var templateArg = edRmt2.RealParameterNames[i]; if (CacheContext.StringTable.GetString(templateArg.Name) == "albedo_color") { finalRm.ShaderProperties[0].RealConstants[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.TextureParameterNames.Count; i++) { switch (CacheContext.StringTable.GetString(edRmt2.TextureParameterNames[i].Name)) { case "base_map": try { finalRm.ShaderProperties[0].TextureConstants[i].Bitmap = ConvertTag(cacheStream, blamCacheStream, resourceStreams, ParseLegacyTag(@"levels\multi\snowbound\bitmaps\for_metal_greytech_dif.bitmap")[0]); } catch { } break; case "detail_map": try { finalRm.ShaderProperties[0].TextureConstants[i].Bitmap = ConvertTag(cacheStream, blamCacheStream, resourceStreams, ParseLegacyTag(@"levels\multi\snowbound\bitmaps\for_metal_greytech_icy.bitmap")[0]); } catch { } break; case "bump_map": try { finalRm.ShaderProperties[0].TextureConstants[i].Bitmap = ConvertTag(cacheStream, blamCacheStream, resourceStreams, ParseLegacyTag(@"levels\multi\snowbound\bitmaps\for_metal_greytech_platebump.bitmap")[0]); } catch { } break; case "bump_detail_map": try { finalRm.ShaderProperties[0].TextureConstants[i].Bitmap = ConvertTag(cacheStream, blamCacheStream, resourceStreams, ParseLegacyTag(@"levels\multi\snowbound\bitmaps\for_metal_greytech_bump.bitmap")[0]); } catch { } break; } } // Fixup arguments for (var i = 0; i < edRmt2.RealParameterNames.Count; i++) { var templateArg = edRmt2.RealParameterNames[i]; switch (CacheContext.StringTable.GetString(templateArg.Name)) { case "base_map": finalRm.ShaderProperties[0].RealConstants[i].Values = new float[] { 1f, 1f, 0f, 0f }; break; case "detail_map": finalRm.ShaderProperties[0].RealConstants[i].Values = new float[] { 1.5f, 1.5f, 0f, 0f }; break; case "albedo_color": finalRm.ShaderProperties[0].RealConstants[i].Values = new float[] { 0.554902f, 0.5588236f, 0.5921569f, 1f }; break; case "bump_map": finalRm.ShaderProperties[0].RealConstants[i].Values = new float[] { 1f, 1f, 0f, 0f }; break; case "bump_detail_map": finalRm.ShaderProperties[0].RealConstants[i].Values = new float[] { 2f, 2f, 0f, 0f }; break; case "diffuse_coefficient": finalRm.ShaderProperties[0].RealConstants[i].Values = new float[] { 0.4f, 0.4f, 0.4f, 0.4f }; break; case "specular_coefficient": finalRm.ShaderProperties[0].RealConstants[i].Values = new float[] { 1f, 1f, 1f, 1f }; break; case "roughness": finalRm.ShaderProperties[0].RealConstants[i].Values = new float[] { 0.2f, 0.2f, 0.2f, 0.2f }; break; case "analytical_specular_contribution": finalRm.ShaderProperties[0].RealConstants[i].Values = new float[] { 0.2f, 0.2f, 0.2f, 0.2f }; break; case "area_specular_contribution": finalRm.ShaderProperties[0].RealConstants[i].Values = new float[] { 0.1f, 0.1f, 0.1f, 0.1f }; break; case "environment_map_specular_contribution": finalRm.ShaderProperties[0].RealConstants[i].Values = new float[] { 0.15f, 0.15f, 0.15f, 0.15f }; break; case "specular_tint": finalRm.ShaderProperties[0].RealConstants[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.TextureParameterNames.Count; i++) { switch (CacheContext.StringTable.GetString(edRmt2.TextureParameterNames[i].Name)) { case "base_map": try { finalRm.ShaderProperties[0].TextureConstants[i].Bitmap = ConvertTag(cacheStream, blamCacheStream, resourceStreams, ParseLegacyTag(@"levels\multi\snowbound\bitmaps\rock_horiz.bitmap")[0]); } catch { } break; case "detail_map": try { finalRm.ShaderProperties[0].TextureConstants[i].Bitmap = ConvertTag(cacheStream, blamCacheStream, 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].TextureConstants[i].Bitmap = ConvertTag(cacheStream, blamCacheStream, resourceStreams, ParseLegacyTag(@"levels\multi\snowbound\bitmaps\rock_icy_blend.bitmap")[0]); break; default: finalRm.ShaderProperties[0].TextureConstants[i].Bitmap = ConvertTag(cacheStream, blamCacheStream, resourceStreams, ParseLegacyTag(@"levels\multi\snowbound\bitmaps\rock_cliff_dif.bitmap")[0]); break; } } catch { } break; case "bump_map": try { finalRm.ShaderProperties[0].TextureConstants[i].Bitmap = ConvertTag(cacheStream, blamCacheStream, resourceStreams, ParseLegacyTag(@"levels\multi\snowbound\bitmaps\rock_horiz_bump.bitmap")[0]); } catch { } break; case "bump_detail_map": try { finalRm.ShaderProperties[0].TextureConstants[i].Bitmap = ConvertTag(cacheStream, blamCacheStream, resourceStreams, ParseLegacyTag(@"levels\multi\snowbound\bitmaps\rock_granite_bump.bitmap")[0]); } catch { } break; case "height_map": try { finalRm.ShaderProperties[0].TextureConstants[i].Bitmap = ConvertTag(cacheStream, blamCacheStream, resourceStreams, ParseLegacyTag(@"levels\multi\snowbound\bitmaps\rock_horiz_parallax.bitmap")[0]); } catch { } break; case "environment_map": try { finalRm.ShaderProperties[0].TextureConstants[i].Bitmap = ConvertTag(cacheStream, blamCacheStream, resourceStreams, ParseLegacyTag(@"shaders\default_bitmaps\bitmaps\color_white.bitmap")[0]); } catch { } break; } } // Fixup arguments for (var i = 0; i < edRmt2.RealParameterNames.Count; i++) { var templateArg = edRmt2.RealParameterNames[i]; switch (CacheContext.StringTable.GetString(templateArg.Name)) { case "base_map": switch (blamTagName) { case @"levels\multi\snowbound\shaders\rock_cliffs": finalRm.ShaderProperties[0].RealConstants[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].RealConstants[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].RealConstants[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].RealConstants[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].RealConstants[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.TextureParameterNames.Count; i++) { switch (CacheContext.StringTable.GetString(edRmt2.TextureParameterNames[i].Name)) { case "detail_map": try { finalRm.ShaderProperties[0].TextureConstants[i].Bitmap = CacheContext.GetTag <Bitmap>(@"levels\multi\snowbound\bitmaps\for_metal_greytech_icy4"); } catch { } break; case "detail_map2": try { finalRm.ShaderProperties[0].TextureConstants[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.RealParameterNames.Count; i++) { var templateArg = edRmt2.RealParameterNames[i]; switch (CacheContext.StringTable.GetString(templateArg.Name)) { case "albedo_color": finalRm.ShaderProperties[0].RealConstants[i].Values = new float[] { 0f, 0f, 0f, 0f }; break; } } break; } return(finalRm); }
private void MergeMultiplayerGlobals(Stream cacheStream, Stream blamCacheStream, Dictionary <ResourceLocation, Stream> resourceStreams, CachedTag edTag, CachedTag h3Tag) { var edDef = CacheContext.Deserialize <MultiplayerGlobals>(cacheStream, edTag); var h3Def = BlamCache.Deserialize <MultiplayerGlobals>(blamCacheStream, 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.StringTable.GetString(h3Event.DisplayString); for (var j = 0; j < edDef.Runtime[0].GeneralEvents.Count; j++) { var edEvent = edDef.Runtime[0].GeneralEvents[j]; var edString = CacheContext.StringTable.GetString(edEvent.DisplayString); if (edString == h3String) { MergeMultiplayerEvent(cacheStream, blamCacheStream, 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.StringTable.GetString(h3Event.DisplayString); for (var j = 0; j < edDef.Runtime[0].FlavorEvents.Count; j++) { var edEvent = edDef.Runtime[0].FlavorEvents[j]; var edString = CacheContext.StringTable.GetString(edEvent.DisplayString); if (edString == h3String) { MergeMultiplayerEvent(cacheStream, blamCacheStream, 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.StringTable.GetString(h3Event.DisplayString); for (var j = 0; j < edDef.Runtime[0].SlayerEvents.Count; j++) { var edEvent = edDef.Runtime[0].SlayerEvents[j]; var edString = CacheContext.StringTable.GetString(edEvent.DisplayString); if (edString == h3String) { MergeMultiplayerEvent(cacheStream, blamCacheStream, 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.StringTable.GetString(h3Event.DisplayString); for (var j = 0; j < edDef.Runtime[0].CtfEvents.Count; j++) { var edEvent = edDef.Runtime[0].CtfEvents[j]; var edString = CacheContext.StringTable.GetString(edEvent.DisplayString); if (edString == h3String) { MergeMultiplayerEvent(cacheStream, blamCacheStream, 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.StringTable.GetString(h3Event.DisplayString); for (var j = 0; j < edDef.Runtime[0].OddballEvents.Count; j++) { var edEvent = edDef.Runtime[0].OddballEvents[j]; var edString = CacheContext.StringTable.GetString(edEvent.DisplayString); if (edString == h3String) { MergeMultiplayerEvent(cacheStream, blamCacheStream, 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.StringTable.GetString(h3Event.DisplayString); for (var j = 0; j < edDef.Runtime[0].KingOfTheHillEvents.Count; j++) { var edEvent = edDef.Runtime[0].KingOfTheHillEvents[j]; var edString = CacheContext.StringTable.GetString(edEvent.DisplayString); if (edString == h3String) { MergeMultiplayerEvent(cacheStream, blamCacheStream, 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.StringTable.GetString(h3Event.DisplayString); for (var j = 0; j < edDef.Runtime[0].VipEvents.Count; j++) { var edEvent = edDef.Runtime[0].VipEvents[j]; var edString = CacheContext.StringTable.GetString(edEvent.DisplayString); if (edString == h3String) { MergeMultiplayerEvent(cacheStream, blamCacheStream, 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.StringTable.GetString(h3Event.DisplayString); for (var j = 0; j < edDef.Runtime[0].JuggernautEvents.Count; j++) { var edEvent = edDef.Runtime[0].JuggernautEvents[j]; var edString = CacheContext.StringTable.GetString(edEvent.DisplayString); if (edString == h3String) { MergeMultiplayerEvent(cacheStream, blamCacheStream, 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.StringTable.GetString(h3Event.DisplayString); for (var j = 0; j < edDef.Runtime[0].TerritoriesEvents.Count; j++) { var edEvent = edDef.Runtime[0].TerritoriesEvents[j]; var edString = CacheContext.StringTable.GetString(edEvent.DisplayString); if (edString == h3String) { MergeMultiplayerEvent(cacheStream, blamCacheStream, 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.StringTable.GetString(h3Event.DisplayString); for (var j = 0; j < edDef.Runtime[0].AssaultEvents.Count; j++) { var edEvent = edDef.Runtime[0].AssaultEvents[j]; var edString = CacheContext.StringTable.GetString(edEvent.DisplayString); if (edString == h3String) { MergeMultiplayerEvent(cacheStream, blamCacheStream, 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.StringTable.GetString(h3Event.DisplayString); for (var j = 0; j < edDef.Runtime[0].InfectionEvents.Count; j++) { var edEvent = edDef.Runtime[0].InfectionEvents[j]; var edString = CacheContext.StringTable.GetString(edEvent.DisplayString); if (edString == h3String) { MergeMultiplayerEvent(cacheStream, blamCacheStream, resourceStreams, edEvent, h3Event); } } } CacheContext.Serialize(cacheStream, edTag, edDef); }