using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Globalization;
using System.IO;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Serialization;
using System.Runtime.Serialization.Json;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using BepInEx;
using BepInEx.Bootstrap;
using BepInEx.Configuration;
using HarmonyLib;
using UnityEngine;
using ValheimHDTerrain.Logging;
[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[assembly: AssemblyTitle("FindObjectTexture")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("FindObjectTexture")]
[assembly: AssemblyCopyright("Copyright © 2021")]
[assembly: AssemblyTrademark("")]
[assembly: ComVisible(false)]
[assembly: Guid("26565f84-978a-4666-88ca-4465f43cb131")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: TargetFramework(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.0.0.0")]
[module: UnverifiableCode]
namespace ValheimHDTerrain
{
internal class Config
{
private ConfigFile cf = new ConfigFile(Mod.ConfigFile, true);
public ConfigEntry<bool> EnableExtendedDebug;
public ConfigEntry<bool> DeveloperMode;
public ConfigEntry<KeyCode> ReloadTextureKey;
public ConfigEntry<KeyCode> ReloadShaderKey;
public ConfigEntry<float> GrassDrawDistance;
public ConfigEntry<float> GrassAmountModifier;
public ConfigEntry<float> WaterCausticsEnabled;
public Config()
{
//IL_0007: Unknown result type (might be due to invalid IL or missing references)
//IL_0011: Expected O, but got Unknown
EnableExtendedDebug = cf.Bind<bool>("Mod", "EnableExtendedDebug", false, "Enable Extended Debug Information");
DeveloperMode = cf.Bind<bool>("Mod", "EnableDeveloperMode", false, "Enable Developer Mode");
ReloadTextureKey = cf.Bind<KeyCode>("Keybinds", "ReloadTexturesKey", (KeyCode)287, "Key to hot reload textures");
ReloadShaderKey = cf.Bind<KeyCode>("Keybinds", "ReloadShaderKey", (KeyCode)289, "Key to reload shader");
GrassDrawDistance = cf.Bind<float>("Clutter", "GrassDrawDistance", 40f, "Grass Draw Distance");
GrassAmountModifier = cf.Bind<float>("Clutter", "GrassAmountModifier", 1f, "Modifier for grass amount");
WaterCausticsEnabled = cf.Bind<float>("Shader Effects", "WaterCausticsEnabled", 1f, "Enable/Disable Water Caustics");
}
}
internal class HarmonyPatches
{
[HarmonyPatch(typeof(Terminal), "InitTerminal")]
private class Terminal_InitTerminal
{
private static void Postfix()
{
Mod.AddConsoleCommands();
}
}
[HarmonyPatch(typeof(Player), "Update")]
private class Player_Update
{
private static void Prefix()
{
//IL_000b: Unknown result type (might be due to invalid IL or missing references)
//IL_0051: Unknown result type (might be due to invalid IL or missing references)
if (Input.GetKeyDown(Mod.Config.ReloadShaderKey.Value) && Mod.Config.DeveloperMode.Value)
{
bLog.Log("Reloading Shader");
Mod.LoadShader();
Mod.ApplyShader();
}
if (!Input.GetKeyDown(Mod.Config.ReloadTextureKey.Value) || !Mod.Config.DeveloperMode.Value)
{
return;
}
Mod.CreateTerrainArrays();
Mod.LoadAdditionalTextures();
foreach (Heightmap allHeightmap in Heightmap.GetAllHeightmaps())
{
if ((Object)(object)allHeightmap.m_materialInstance != (Object)null)
{
bLog.Log("Replacing heightmap shader");
if (!allHeightmap.m_isDistantLod)
{
allHeightmap.m_materialInstance.SetTexture("_DiffuseArrayTex", (Texture)(object)Mod.DiffuseArray);
allHeightmap.m_materialInstance.SetTexture("_NormalArrayTex", (Texture)(object)Mod.NormalArray);
allHeightmap.m_materialInstance.SetTexture("_WaterCaustics", (Texture)(object)Mod.WaterCaustics);
}
else if (allHeightmap.m_isDistantLod)
{
allHeightmap.m_materialInstance.SetTexture("_DiffuseArrayTex", (Texture)(object)Mod.DiffuseArrayLod);
allHeightmap.m_materialInstance.SetTexture("_NormalArrayTex", (Texture)(object)Mod.NormalArrayLod);
}
}
}
}
}
[HarmonyPatch(typeof(Heightmap), "Awake")]
private class HeightMap_Awake
{
private static void Prefix(Heightmap __instance)
{
if ((Object)(object)Mod.TerrainShader != (Object)null && Mod.UseShader)
{
bLog.Log($"Is Distant Lod: {__instance.m_isDistantLod}");
if ((Object)(object)__instance.m_material != (Object)null)
{
bLog.Log("Replacing Terrain Shader");
__instance.m_material.shader = Mod.TerrainShader;
}
else
{
bLog.Log("heightmap does not have material");
}
}
else
{
bLog.Log("Terrain shader is null, will not replace.");
}
}
}
[HarmonyPatch(typeof(Heightmap), "Initialize")]
private class Heightmap_Initialize
{
private static void Postfix(Heightmap __instance)
{
if (Mod.ReplaceTextures)
{
if (!__instance.m_isDistantLod)
{
__instance.m_material.SetTexture("_DiffuseArrayTex", (Texture)(object)Mod.DiffuseArray);
__instance.m_material.SetTexture("_NormalArrayTex", (Texture)(object)Mod.NormalArray);
__instance.m_material.SetTexture("_WaterCaustics", (Texture)(object)Mod.WaterCaustics);
}
else if (__instance.m_isDistantLod)
{
__instance.m_material.SetTexture("_DiffuseArrayTex", (Texture)(object)Mod.DiffuseArrayLod);
__instance.m_material.SetTexture("_NormalArrayTex", (Texture)(object)Mod.NormalArrayLod);
}
}
}
}
[HarmonyPatch(typeof(Heightmap), "RebuildCollisionMesh")]
private class Heightmap_RebuildCollisionMesh
{
private static bool Prefix(Heightmap __instance)
{
//IL_0013: Unknown result type (might be due to invalid IL or missing references)
//IL_001d: Expected O, but got Unknown
//IL_0066: Unknown result type (might be due to invalid IL or missing references)
if ((Object)(object)__instance.m_collisionMesh == (Object)null)
{
__instance.m_collisionMesh = new Mesh();
((Object)__instance.m_collisionMesh).name = "___Heightmap m_collisionMesh";
}
int num = __instance.m_width + 1;
Heightmap.s_tempVertices.Clear();
Heightmap.s_tempIndices.Clear();
for (int i = 0; i < num; i++)
{
for (int j = 0; j < num; j++)
{
Heightmap.s_tempVertices.Add(__instance.CalcVertex(j, i));
if (i != 0 && j != 0)
{
Heightmap.s_tempIndices.Add(num * (i - 1) + j - 1);
Heightmap.s_tempIndices.Add(num * i + j - 1);
Heightmap.s_tempIndices.Add(num * (i - 1) + j);
Heightmap.s_tempIndices.Add(num * i + j - 1);
Heightmap.s_tempIndices.Add(num * i + j);
Heightmap.s_tempIndices.Add(num * (i - 1) + j);
}
}
}
__instance.m_collisionMesh.SetVertices(Heightmap.s_tempVertices);
__instance.m_collisionMesh.SetIndices(Heightmap.s_tempIndices.ToArray(), (MeshTopology)0, 0);
if (Object.op_Implicit((Object)(object)__instance.m_collider))
{
__instance.m_collider.sharedMesh = __instance.m_collisionMesh;
}
return false;
}
}
[HarmonyPatch(typeof(ClutterSystem), "Awake")]
private class ClutterSystem_AwakePatch
{
[HarmonyPostfix]
[HarmonyPriority(0)]
private static void Postfix(ClutterSystem __instance)
{
if (Mod.TweaksInstalled)
{
return;
}
for (int i = 0; i < __instance.m_clutter.Count; i++)
{
if (__instance.m_clutter[i].m_instanced)
{
__instance.m_clutter[i].m_prefab.GetComponent<InstanceRenderer>().m_useLod = false;
__instance.m_clutter[i].m_prefab.GetComponent<InstanceRenderer>().m_useXZLodDistance = false;
}
}
__instance.m_distance = Mod.Config.GrassDrawDistance.Value;
__instance.m_amountScale = Mod.Config.GrassAmountModifier.Value;
}
}
[HarmonyPatch(typeof(ClutterSystem), "LateUpdate")]
private class ClutterSysten_LateUpdatePatch
{
[HarmonyPrefix]
private static void Prefix(ClutterSystem __instance)
{
if (!Mod.TweaksInstalled)
{
__instance.m_distance = Mod.Config.GrassDrawDistance.Value;
if (Mod.ForceUpdateClutter)
{
__instance.m_amountScale = Mod.Config.GrassAmountModifier.Value;
Mod.ForceUpdateClutter = false;
__instance.ClearAll();
bLog.Log("Rebuilding Grass");
}
}
}
}
private Harmony harmony = new Harmony("Badgers.ValheimHDTerrain");
public HarmonyPatches()
{
//IL_0006: Unknown result type (might be due to invalid IL or missing references)
//IL_0010: Expected O, but got Unknown
harmony.PatchAll();
}
}
[DataContract]
internal class TerrainConfig
{
[DataMember]
public float cliffLowThreshold = 0.8f;
[DataMember]
public float cliffHighThreshold = 0.9f;
[DataMember]
public float rockLowThreshold = 0.7f;
[DataMember]
public float rockHighThreshold = 0.86f;
[DataMember]
public float cliffLowThresholdForest = 0.7f;
[DataMember]
public float cliffHighThresholdForest = 0.95f;
[DataMember]
public float rockLowThresholdForest = 0.65f;
[DataMember]
public float rockHighThresholdForest = 0.8f;
[DataMember]
public float cliffLowThresholdMountain = 0.6f;
[DataMember]
public float cliffHighThresholdMountain = 0.8f;
[DataMember]
public float rockLowThresholdMountain = 0.4f;
[DataMember]
public float rockHighThresholdMountain = 0.6f;
[DataMember]
public float cliffLowThresholdPlains = 0.7f;
[DataMember]
public float cliffHighThresholdPlains = 1f;
[DataMember]
public float rockLowThresholdPlains = 0.55f;
[DataMember]
public float rockHighThresholdPlains = 0.7f;
[DataMember]
public int tilingAmount = 8;
public static TerrainConfig Load(string Path)
{
//IL_001a: Unknown result type (might be due to invalid IL or missing references)
//IL_0020: Expected O, but got Unknown
TerrainConfig result = new TerrainConfig();
using (FileStream fileStream = new FileStream(Path, FileMode.Open))
{
DataContractJsonSerializer val = new DataContractJsonSerializer(typeof(TerrainConfig));
result = (TerrainConfig)((XmlObjectSerializer)val).ReadObject((Stream)fileStream);
}
return result;
}
public void Save(string FileName)
{
//IL_0015: Unknown result type (might be due to invalid IL or missing references)
//IL_001b: Expected O, but got Unknown
using FileStream fileStream = new FileStream(FileName, FileMode.Create, FileAccess.Write);
DataContractJsonSerializer val = new DataContractJsonSerializer(typeof(TerrainConfig));
((XmlObjectSerializer)val).WriteObject((Stream)fileStream, (object)this);
}
}
[BepInPlugin("Badgers.ValheimHDTerrain", "ValheimHDTerrain", "0.1.0")]
[BepInProcess("valheim.exe")]
[BepInDependency(/*Could not decode attribute arguments.*/)]
public class HDTerrain : BaseUnityPlugin
{
private HarmonyPatches DefaultPatches;
private void Awake()
{
DefaultPatches = new HarmonyPatches();
if (HasConflictingMods())
{
Mod.TweaksInstalled = true;
}
Mod.Init();
}
private bool HasConflictingMods()
{
foreach (KeyValuePair<string, PluginInfo> pluginInfo in Chainloader.PluginInfos)
{
if (pluginInfo.Value.Metadata.GUID == "Badgers.ValheimTweaksLite")
{
bLog.Log("Valheim Tweaks mod is loaded, clutter changes will not be enabled.", extendedlog: true);
return true;
}
}
return false;
}
}
internal static class Mod
{
[Serializable]
[CompilerGenerated]
private sealed class <>c
{
public static readonly <>c <>9 = new <>c();
public static ConsoleEvent <>9__33_0;
public static ConsoleEvent <>9__33_1;
public static ConsoleEvent <>9__33_2;
public static ConsoleEvent <>9__33_3;
public static ConsoleEvent <>9__33_4;
public static ConsoleEvent <>9__33_5;
public static ConsoleEvent <>9__33_6;
public static ConsoleEvent <>9__33_7;
public static ConsoleEvent <>9__33_8;
internal void <AddConsoleCommands>b__33_0(ConsoleEventArgs args)
{
if (args.Length == 2)
{
string text = args[1].ToString();
string text2 = text.ToLower();
string text3 = text2;
if (!(text3 == "enabled"))
{
if (text3 == "disabled")
{
Config.WaterCausticsEnabled.Value = 0f;
Shader.SetGlobalFloat("_WaterCausticsEnabled", Config.WaterCausticsEnabled.Value);
}
}
else
{
Config.WaterCausticsEnabled.Value = 1f;
Shader.SetGlobalFloat("_WaterCausticsEnabled", Config.WaterCausticsEnabled.Value);
}
}
else
{
MonoBehaviour.print((object)"Not enough arguments to set water caustics");
}
}
internal void <AddConsoleCommands>b__33_1(ConsoleEventArgs args)
{
if (args.Length == 2)
{
Config.GrassDrawDistance.Value = float.Parse(args[1], CultureInfo.InvariantCulture);
}
else
{
MonoBehaviour.print((object)"Not enough arguments to set grass draw distance");
}
}
internal void <AddConsoleCommands>b__33_2(ConsoleEventArgs args)
{
if (args.Length == 2)
{
Config.GrassAmountModifier.Value = float.Parse(args[1], CultureInfo.InvariantCulture);
ForceUpdateClutter = true;
}
else
{
MonoBehaviour.print((object)"Not enough arguments to set grass amount");
}
}
internal void <AddConsoleCommands>b__33_3(ConsoleEventArgs args)
{
if (args.Length == 3)
{
switch (Convert.ToString(args[1]))
{
case "meadows":
TerrainConfig.rockLowThreshold = float.Parse(args[2], CultureInfo.InvariantCulture);
Shader.SetGlobalFloat("_RockLowThreshold", TerrainConfig.rockLowThreshold);
break;
case "forest":
TerrainConfig.rockLowThresholdForest = float.Parse(args[2], CultureInfo.InvariantCulture);
Shader.SetGlobalFloat("_RockLowThresholdForest", TerrainConfig.rockLowThresholdForest);
break;
case "mountains":
TerrainConfig.rockLowThresholdMountain = float.Parse(args[2], CultureInfo.InvariantCulture);
Shader.SetGlobalFloat("_RockLowThresholdMountain", TerrainConfig.rockLowThresholdMountain);
break;
case "plains":
TerrainConfig.rockLowThresholdPlains = float.Parse(args[2], CultureInfo.InvariantCulture);
Shader.SetGlobalFloat("_RockLowThresholdPlains", TerrainConfig.rockLowThresholdPlains);
break;
}
}
else
{
MonoBehaviour.print((object)"Not enough arguments to set threshold");
}
}
internal void <AddConsoleCommands>b__33_4(ConsoleEventArgs args)
{
if (args.Length == 3)
{
switch (Convert.ToString(args[1]))
{
case "meadows":
TerrainConfig.rockHighThreshold = float.Parse(args[2], CultureInfo.InvariantCulture);
Shader.SetGlobalFloat("_RockHighThreshold", TerrainConfig.rockHighThreshold);
break;
case "forest":
TerrainConfig.rockHighThresholdForest = float.Parse(args[2], CultureInfo.InvariantCulture);
Shader.SetGlobalFloat("_RockHighThresholdForest", TerrainConfig.rockHighThresholdForest);
break;
case "mountains":
TerrainConfig.rockHighThresholdMountain = float.Parse(args[2], CultureInfo.InvariantCulture);
Shader.SetGlobalFloat("_RockHighThresholdMountain", TerrainConfig.rockHighThresholdMountain);
break;
case "plains":
TerrainConfig.rockHighThresholdPlains = float.Parse(args[2], CultureInfo.InvariantCulture);
Shader.SetGlobalFloat("_RockHighThresholdPlains", TerrainConfig.rockHighThresholdPlains);
break;
}
}
else
{
MonoBehaviour.print((object)"Not enough arguments to set threshold");
}
}
internal void <AddConsoleCommands>b__33_5(ConsoleEventArgs args)
{
if (args.Length == 3)
{
switch (Convert.ToString(args[1]))
{
case "meadows":
TerrainConfig.cliffLowThreshold = float.Parse(args[2], CultureInfo.InvariantCulture);
Shader.SetGlobalFloat("_CliffLowThreshold", TerrainConfig.cliffLowThreshold);
break;
case "forest":
TerrainConfig.cliffLowThresholdForest = float.Parse(args[2], CultureInfo.InvariantCulture);
Shader.SetGlobalFloat("_CliffLowThresholdForest", TerrainConfig.cliffLowThresholdForest);
break;
case "mountains":
TerrainConfig.cliffLowThresholdMountain = float.Parse(args[2], CultureInfo.InvariantCulture);
Shader.SetGlobalFloat("_CliffLowThresholdMountain", TerrainConfig.cliffLowThresholdMountain);
break;
case "plains":
TerrainConfig.cliffLowThresholdPlains = float.Parse(args[2], CultureInfo.InvariantCulture);
Shader.SetGlobalFloat("_CliffLowThresholdPlains", TerrainConfig.cliffLowThresholdPlains);
break;
}
}
else
{
MonoBehaviour.print((object)"Not enough arguments to set threshold");
}
}
internal void <AddConsoleCommands>b__33_6(ConsoleEventArgs args)
{
if (args.Length == 3)
{
switch (Convert.ToString(args[1]))
{
case "meadows":
TerrainConfig.cliffHighThreshold = float.Parse(args[2], CultureInfo.InvariantCulture);
Shader.SetGlobalFloat("_CliffHighThreshold", TerrainConfig.cliffHighThreshold);
break;
case "forest":
TerrainConfig.cliffHighThresholdForest = float.Parse(args[2], CultureInfo.InvariantCulture);
Shader.SetGlobalFloat("_CliffHighThresholdForest", TerrainConfig.cliffHighThresholdForest);
break;
case "mountains":
TerrainConfig.cliffHighThresholdMountain = float.Parse(args[2], CultureInfo.InvariantCulture);
Shader.SetGlobalFloat("_CliffHighThresholdMountain", TerrainConfig.cliffHighThresholdMountain);
break;
case "plains":
TerrainConfig.cliffHighThresholdPlains = float.Parse(args[2], CultureInfo.InvariantCulture);
Shader.SetGlobalFloat("_CliffHighThresholdPlains", TerrainConfig.cliffHighThresholdPlains);
break;
}
}
else
{
MonoBehaviour.print((object)"Not enough arguments to set threshold");
}
}
internal void <AddConsoleCommands>b__33_7(ConsoleEventArgs args)
{
if (args.Length == 1)
{
TerrainConfig.Save(TerrainConfigFile);
}
else
{
MonoBehaviour.print((object)"Not enough arguments to set threshold");
}
}
internal void <AddConsoleCommands>b__33_8(ConsoleEventArgs args)
{
if (args.Length == 2)
{
TerrainConfig.tilingAmount = int.Parse(args[1]);
Shader.SetGlobalFloat("_TileAmount", (float)TerrainConfig.tilingAmount);
}
else
{
MonoBehaviour.print((object)"Not enough arguments to set threshold");
}
}
}
public static string ConfigPath = Paths.ConfigPath;
public static string PluginPath = Paths.PluginPath;
public static string ConfigFile = Path.Combine(ConfigPath, "ValheimHDTerrain.cfg");
public static string DataPath = Path.Combine(PluginPath, "HDTerrainData");
public static string TerrainTiles = Path.Combine(DataPath, "Terrain");
public static string TerrainTilesLod = Path.Combine(DataPath, "TerrainLod");
public static string AssetBundleFile = Path.Combine(DataPath, "hdterrain");
public static string TerrainConfigFile = Path.Combine(DataPath, "TerrainConfig.json");
public static Config Config = new Config();
public static bool isMaterialChanged = false;
public static Shader TerrainShader;
public static bool IsOriginalShaderSaved = false;
public static bool UseShader = true;
public static bool ReplaceTextures = true;
private static bool consoleCommandsAdded = false;
public static Texture2DArray DiffuseArray = null;
public static Texture2DArray NormalArray = null;
public static Texture2DArray DiffuseArrayLod = null;
public static Texture2DArray NormalArrayLod = null;
public static Texture2D WaterCaustics = null;
public static TerrainConfig TerrainConfig = null;
public static bool ForceUpdateClutter = false;
public static bool TweaksInstalled = false;
private static int ArraySize = 17;
public static void Init()
{
LoadConfig();
LoadShader();
LoadAdditionalTextures();
CreateTerrainArrays();
}
private static void LoadConfig()
{
if (File.Exists(TerrainConfigFile))
{
bLog.Log("Loading Terrain Config", extendedlog: true);
TerrainConfig = TerrainConfig.Load(TerrainConfigFile);
}
else
{
bLog.Log("Creating Default Config", extendedlog: true);
TerrainConfig = new TerrainConfig();
}
}
public static void LoadAdditionalTextures()
{
WaterCaustics = LoadTexture(Path.Combine(TerrainTiles, "WaterCaustics.png"), linear: false, mipMaps: true);
WaterCaustics.Apply();
}
public static void CreateTerrainArrays()
{
bLog.Log("Creating HD Terrain texture arrays");
for (int i = 0; i < ArraySize; i++)
{
Texture2D val = LoadTexture(Path.Combine(TerrainTiles, $"terraintile{i}.png"), linear: false, mipMaps: true);
Texture2D val2 = LoadTexture(Path.Combine(TerrainTiles, $"terraintilen{i}.png"), linear: true, mipMaps: true);
Texture2D val3 = null;
Texture2D val4 = null;
if (i <= 15)
{
val3 = LoadTexture(Path.Combine(TerrainTilesLod, $"terraintile{i}.png"), linear: false, mipMaps: false);
val4 = LoadTexture(Path.Combine(TerrainTilesLod, $"terraintilen{i}.png"), linear: true, mipMaps: false);
}
if (i == 0)
{
bLog.Log($"Creating diffuse terrain array with image size {((Texture)val).width}x{((Texture)val).height}", extendedlog: true);
bLog.Log($"Creating normal terrain array with image size {((Texture)val2).width}x{((Texture)val2).height}", extendedlog: true);
bLog.Log($"Creating diffuse terrain lod array with image size {((Texture)val3).width}x{((Texture)val3).height}", extendedlog: true);
bLog.Log($"Creating normal terrain lod array with image size {((Texture)val4).width}x{((Texture)val4).height}", extendedlog: true);
DiffuseArray = CreateTextureArray(((Texture)val).width, ArraySize, linear: false, mipMaps: true);
NormalArray = CreateTextureArray(((Texture)val2).width, ArraySize, linear: true, mipMaps: true);
DiffuseArrayLod = CreateTextureArray(((Texture)val3).width, ArraySize, linear: false, mipMaps: false);
NormalArrayLod = CreateTextureArray(((Texture)val4).width, ArraySize, linear: true, mipMaps: false);
}
if ((Object)(object)DiffuseArray != (Object)null && (Object)(object)NormalArray != (Object)null)
{
for (int j = 0; j < ((Texture)val).mipmapCount; j++)
{
bLog.Log($"Adding diffuse tile {i} mipmap level {j} image to diffuse terrain array", extendedlog: true);
Graphics.CopyTexture((Texture)(object)val, 0, j, (Texture)(object)DiffuseArray, i, j);
bLog.Log($"Adding normal tile {i} mipmap level {j} image to normal terrain array", extendedlog: true);
Graphics.CopyTexture((Texture)(object)val2, 0, j, (Texture)(object)NormalArray, i, j);
if (j == 0 && (Object)(object)val3 != (Object)null && (Object)(object)val4 != (Object)null)
{
bLog.Log($"Adding terrain lod tile {i} to terrain lod array", extendedlog: true);
Graphics.CopyTexture((Texture)(object)val3, 0, 0, (Texture)(object)DiffuseArrayLod, i, 0);
bLog.Log($"Adding normal lod tile {i} to normal lod array", extendedlog: true);
Graphics.CopyTexture((Texture)(object)val4, 0, 0, (Texture)(object)NormalArrayLod, i, 0);
}
}
Object.DestroyImmediate((Object)(object)val);
Object.DestroyImmediate((Object)(object)val2);
Object.DestroyImmediate((Object)(object)val3);
Object.DestroyImmediate((Object)(object)val4);
continue;
}
bLog.Log("Problem creating terrain arrays, HD Terrain will be disabled", extendedlog: true);
Object.DestroyImmediate((Object)(object)val);
Object.DestroyImmediate((Object)(object)val2);
Object.DestroyImmediate((Object)(object)val3);
Object.DestroyImmediate((Object)(object)val4);
ReplaceTextures = false;
return;
}
Graphics.CopyTexture((Texture)(object)DiffuseArrayLod, 4, (Texture)(object)DiffuseArrayLod, 2);
DiffuseArray.Apply(false, true);
NormalArray.Apply(false, true);
DiffuseArrayLod.Apply(false, true);
NormalArrayLod.Apply(false, true);
}
private static Texture2D LoadTexture(string path, bool linear, bool mipMaps)
{
//IL_001d: Unknown result type (might be due to invalid IL or missing references)
//IL_0023: Expected O, but got Unknown
bLog.Log("Loading texture " + Path.GetFileName(path), extendedlog: true);
Texture2D val = new Texture2D(4, 4, (TextureFormat)5, mipMaps, linear);
((Texture)val).filterMode = (FilterMode)2;
((Texture)val).anisoLevel = 16;
ImageConversion.LoadImage(val, File.ReadAllBytes(path));
val.Compress(true);
return val;
}
private static Texture2DArray CreateTextureArray(int imagesize, int arraySize, bool linear, bool mipMaps)
{
//IL_0008: Unknown result type (might be due to invalid IL or missing references)
//IL_000e: Expected O, but got Unknown
Texture2DArray val = new Texture2DArray(imagesize, imagesize, arraySize, (TextureFormat)12, mipMaps, linear);
((Texture)val).wrapMode = (TextureWrapMode)0;
((Texture)val).filterMode = (FilterMode)2;
((Texture)val).anisoLevel = 16;
return val;
}
public static void LoadShader()
{
if (UseShader)
{
AssetBundle val = AssetBundle.LoadFromFile(AssetBundleFile);
TerrainShader = val.LoadAsset<Shader>("HDTerrain");
val.Unload(false);
if ((Object)(object)TerrainShader != (Object)null)
{
bLog.Log("Loaded Terrain Shader", extendedlog: true);
}
UpdateTerrainShaderValues();
}
}
public static void UpdateTerrainShaderValues()
{
Shader.SetGlobalFloat("_RockLowThreshold", TerrainConfig.rockLowThreshold);
Shader.SetGlobalFloat("_RockHighThreshold", TerrainConfig.rockHighThreshold);
Shader.SetGlobalFloat("_CliffLowThreshold", TerrainConfig.cliffLowThreshold);
Shader.SetGlobalFloat("_CliffHighThreshold", TerrainConfig.cliffHighThreshold);
Shader.SetGlobalFloat("_RockLowThresholdForest", TerrainConfig.rockLowThresholdForest);
Shader.SetGlobalFloat("_RockHighThresholdForest", TerrainConfig.rockHighThresholdForest);
Shader.SetGlobalFloat("_CliffLowThresholdForest", TerrainConfig.cliffLowThresholdForest);
Shader.SetGlobalFloat("_CliffHighThresholdForest", TerrainConfig.cliffHighThresholdForest);
Shader.SetGlobalFloat("_RockLowThresholdMountain", TerrainConfig.rockLowThresholdMountain);
Shader.SetGlobalFloat("_RockHighThresholdMountain", TerrainConfig.rockHighThresholdMountain);
Shader.SetGlobalFloat("_CliffLowThresholdMountain", TerrainConfig.cliffLowThresholdMountain);
Shader.SetGlobalFloat("_CliffHighThresholdMountain", TerrainConfig.cliffHighThresholdMountain);
Shader.SetGlobalFloat("_RockLowThresholdPlains", TerrainConfig.rockLowThresholdPlains);
Shader.SetGlobalFloat("_RockHighThresholdPlains", TerrainConfig.rockHighThresholdPlains);
Shader.SetGlobalFloat("_CliffLowThresholdPlains", TerrainConfig.cliffLowThresholdPlains);
Shader.SetGlobalFloat("_CliffHighThresholdPlains", TerrainConfig.cliffHighThresholdPlains);
Shader.SetGlobalFloat("_TileAmount", (float)TerrainConfig.tilingAmount);
Shader.SetGlobalFloat("_WaterCausticsEnabled", Config.WaterCausticsEnabled.Value);
}
public static void ApplyShader()
{
foreach (Heightmap allHeightmap in Heightmap.GetAllHeightmaps())
{
if (!allHeightmap.IsDistantLod && (Object)(object)allHeightmap.m_materialInstance != (Object)null)
{
bLog.Log("Replacing heightmap shader");
allHeightmap.m_materialInstance.shader = TerrainShader;
allHeightmap.Regenerate();
}
}
}
public static void AddConsoleCommands()
{
//IL_0033: Unknown result type (might be due to invalid IL or missing references)
//IL_001f: Unknown result type (might be due to invalid IL or missing references)
//IL_0024: Unknown result type (might be due to invalid IL or missing references)
//IL_002a: Expected O, but got Unknown
//IL_0078: Unknown result type (might be due to invalid IL or missing references)
//IL_0064: Unknown result type (might be due to invalid IL or missing references)
//IL_0069: Unknown result type (might be due to invalid IL or missing references)
//IL_006f: Expected O, but got Unknown
//IL_00b0: Unknown result type (might be due to invalid IL or missing references)
//IL_009c: Unknown result type (might be due to invalid IL or missing references)
//IL_00a1: Unknown result type (might be due to invalid IL or missing references)
//IL_00a7: Expected O, but got Unknown
//IL_0116: Unknown result type (might be due to invalid IL or missing references)
//IL_0102: Unknown result type (might be due to invalid IL or missing references)
//IL_0107: Unknown result type (might be due to invalid IL or missing references)
//IL_010d: Expected O, but got Unknown
//IL_014e: Unknown result type (might be due to invalid IL or missing references)
//IL_013a: Unknown result type (might be due to invalid IL or missing references)
//IL_013f: Unknown result type (might be due to invalid IL or missing references)
//IL_0145: Expected O, but got Unknown
//IL_0186: Unknown result type (might be due to invalid IL or missing references)
//IL_0172: Unknown result type (might be due to invalid IL or missing references)
//IL_0177: Unknown result type (might be due to invalid IL or missing references)
//IL_017d: Expected O, but got Unknown
//IL_01be: Unknown result type (might be due to invalid IL or missing references)
//IL_01aa: Unknown result type (might be due to invalid IL or missing references)
//IL_01af: Unknown result type (might be due to invalid IL or missing references)
//IL_01b5: Expected O, but got Unknown
//IL_01f6: Unknown result type (might be due to invalid IL or missing references)
//IL_01e2: Unknown result type (might be due to invalid IL or missing references)
//IL_01e7: Unknown result type (might be due to invalid IL or missing references)
//IL_01ed: Expected O, but got Unknown
//IL_022e: Unknown result type (might be due to invalid IL or missing references)
//IL_021a: Unknown result type (might be due to invalid IL or missing references)
//IL_021f: Unknown result type (might be due to invalid IL or missing references)
//IL_0225: Expected O, but got Unknown
object obj = <>c.<>9__33_0;
if (obj == null)
{
ConsoleEvent val = delegate(ConsoleEventArgs args)
{
if (args.Length == 2)
{
string text = args[1].ToString();
string text2 = text.ToLower();
string text3 = text2;
if (!(text3 == "enabled"))
{
if (text3 == "disabled")
{
Config.WaterCausticsEnabled.Value = 0f;
Shader.SetGlobalFloat("_WaterCausticsEnabled", Config.WaterCausticsEnabled.Value);
}
}
else
{
Config.WaterCausticsEnabled.Value = 1f;
Shader.SetGlobalFloat("_WaterCausticsEnabled", Config.WaterCausticsEnabled.Value);
}
}
else
{
MonoBehaviour.print((object)"Not enough arguments to set water caustics");
}
};
<>c.<>9__33_0 = val;
obj = (object)val;
}
new ConsoleCommand("watercaustics", "Enable / Disable water caustics", (ConsoleEvent)obj, false, false, false, false, false, (ConsoleOptionsFetcher)null, false, false, false);
if (!TweaksInstalled)
{
object obj2 = <>c.<>9__33_1;
if (obj2 == null)
{
ConsoleEvent val2 = delegate(ConsoleEventArgs args)
{
if (args.Length == 2)
{
Config.GrassDrawDistance.Value = float.Parse(args[1], CultureInfo.InvariantCulture);
}
else
{
MonoBehaviour.print((object)"Not enough arguments to set grass draw distance");
}
};
<>c.<>9__33_1 = val2;
obj2 = (object)val2;
}
new ConsoleCommand("grassdrawdistance", "Set grass draw distance", (ConsoleEvent)obj2, false, false, false, false, false, (ConsoleOptionsFetcher)null, false, false, false);
object obj3 = <>c.<>9__33_2;
if (obj3 == null)
{
ConsoleEvent val3 = delegate(ConsoleEventArgs args)
{
if (args.Length == 2)
{
Config.GrassAmountModifier.Value = float.Parse(args[1], CultureInfo.InvariantCulture);
ForceUpdateClutter = true;
}
else
{
MonoBehaviour.print((object)"Not enough arguments to set grass amount");
}
};
<>c.<>9__33_2 = val3;
obj3 = (object)val3;
}
new ConsoleCommand("grassamount", "Set grass amount", (ConsoleEvent)obj3, false, false, false, false, false, (ConsoleOptionsFetcher)null, false, false, false);
}
if (consoleCommandsAdded || !Config.DeveloperMode.Value)
{
return;
}
bLog.Log("Adding console commands");
object obj4 = <>c.<>9__33_3;
if (obj4 == null)
{
ConsoleEvent val4 = delegate(ConsoleEventArgs args)
{
if (args.Length == 3)
{
switch (Convert.ToString(args[1]))
{
case "meadows":
TerrainConfig.rockLowThreshold = float.Parse(args[2], CultureInfo.InvariantCulture);
Shader.SetGlobalFloat("_RockLowThreshold", TerrainConfig.rockLowThreshold);
break;
case "forest":
TerrainConfig.rockLowThresholdForest = float.Parse(args[2], CultureInfo.InvariantCulture);
Shader.SetGlobalFloat("_RockLowThresholdForest", TerrainConfig.rockLowThresholdForest);
break;
case "mountains":
TerrainConfig.rockLowThresholdMountain = float.Parse(args[2], CultureInfo.InvariantCulture);
Shader.SetGlobalFloat("_RockLowThresholdMountain", TerrainConfig.rockLowThresholdMountain);
break;
case "plains":
TerrainConfig.rockLowThresholdPlains = float.Parse(args[2], CultureInfo.InvariantCulture);
Shader.SetGlobalFloat("_RockLowThresholdPlains", TerrainConfig.rockLowThresholdPlains);
break;
}
}
else
{
MonoBehaviour.print((object)"Not enough arguments to set threshold");
}
};
<>c.<>9__33_3 = val4;
obj4 = (object)val4;
}
new ConsoleCommand("setrocklow", "Set low transition threshold for rock", (ConsoleEvent)obj4, false, false, false, false, false, (ConsoleOptionsFetcher)null, false, false, false);
object obj5 = <>c.<>9__33_4;
if (obj5 == null)
{
ConsoleEvent val5 = delegate(ConsoleEventArgs args)
{
if (args.Length == 3)
{
switch (Convert.ToString(args[1]))
{
case "meadows":
TerrainConfig.rockHighThreshold = float.Parse(args[2], CultureInfo.InvariantCulture);
Shader.SetGlobalFloat("_RockHighThreshold", TerrainConfig.rockHighThreshold);
break;
case "forest":
TerrainConfig.rockHighThresholdForest = float.Parse(args[2], CultureInfo.InvariantCulture);
Shader.SetGlobalFloat("_RockHighThresholdForest", TerrainConfig.rockHighThresholdForest);
break;
case "mountains":
TerrainConfig.rockHighThresholdMountain = float.Parse(args[2], CultureInfo.InvariantCulture);
Shader.SetGlobalFloat("_RockHighThresholdMountain", TerrainConfig.rockHighThresholdMountain);
break;
case "plains":
TerrainConfig.rockHighThresholdPlains = float.Parse(args[2], CultureInfo.InvariantCulture);
Shader.SetGlobalFloat("_RockHighThresholdPlains", TerrainConfig.rockHighThresholdPlains);
break;
}
}
else
{
MonoBehaviour.print((object)"Not enough arguments to set threshold");
}
};
<>c.<>9__33_4 = val5;
obj5 = (object)val5;
}
new ConsoleCommand("setrockhigh", "Set high transition threshold for rock", (ConsoleEvent)obj5, false, false, false, false, false, (ConsoleOptionsFetcher)null, false, false, false);
object obj6 = <>c.<>9__33_5;
if (obj6 == null)
{
ConsoleEvent val6 = delegate(ConsoleEventArgs args)
{
if (args.Length == 3)
{
switch (Convert.ToString(args[1]))
{
case "meadows":
TerrainConfig.cliffLowThreshold = float.Parse(args[2], CultureInfo.InvariantCulture);
Shader.SetGlobalFloat("_CliffLowThreshold", TerrainConfig.cliffLowThreshold);
break;
case "forest":
TerrainConfig.cliffLowThresholdForest = float.Parse(args[2], CultureInfo.InvariantCulture);
Shader.SetGlobalFloat("_CliffLowThresholdForest", TerrainConfig.cliffLowThresholdForest);
break;
case "mountains":
TerrainConfig.cliffLowThresholdMountain = float.Parse(args[2], CultureInfo.InvariantCulture);
Shader.SetGlobalFloat("_CliffLowThresholdMountain", TerrainConfig.cliffLowThresholdMountain);
break;
case "plains":
TerrainConfig.cliffLowThresholdPlains = float.Parse(args[2], CultureInfo.InvariantCulture);
Shader.SetGlobalFloat("_CliffLowThresholdPlains", TerrainConfig.cliffLowThresholdPlains);
break;
}
}
else
{
MonoBehaviour.print((object)"Not enough arguments to set threshold");
}
};
<>c.<>9__33_5 = val6;
obj6 = (object)val6;
}
new ConsoleCommand("setclifflow", "Set low transition threshold for cliff", (ConsoleEvent)obj6, false, false, false, false, false, (ConsoleOptionsFetcher)null, false, false, false);
object obj7 = <>c.<>9__33_6;
if (obj7 == null)
{
ConsoleEvent val7 = delegate(ConsoleEventArgs args)
{
if (args.Length == 3)
{
switch (Convert.ToString(args[1]))
{
case "meadows":
TerrainConfig.cliffHighThreshold = float.Parse(args[2], CultureInfo.InvariantCulture);
Shader.SetGlobalFloat("_CliffHighThreshold", TerrainConfig.cliffHighThreshold);
break;
case "forest":
TerrainConfig.cliffHighThresholdForest = float.Parse(args[2], CultureInfo.InvariantCulture);
Shader.SetGlobalFloat("_CliffHighThresholdForest", TerrainConfig.cliffHighThresholdForest);
break;
case "mountains":
TerrainConfig.cliffHighThresholdMountain = float.Parse(args[2], CultureInfo.InvariantCulture);
Shader.SetGlobalFloat("_CliffHighThresholdMountain", TerrainConfig.cliffHighThresholdMountain);
break;
case "plains":
TerrainConfig.cliffHighThresholdPlains = float.Parse(args[2], CultureInfo.InvariantCulture);
Shader.SetGlobalFloat("_CliffHighThresholdPlains", TerrainConfig.cliffHighThresholdPlains);
break;
}
}
else
{
MonoBehaviour.print((object)"Not enough arguments to set threshold");
}
};
<>c.<>9__33_6 = val7;
obj7 = (object)val7;
}
new ConsoleCommand("setcliffhigh", "Set high transition threshold for cliff", (ConsoleEvent)obj7, false, false, false, false, false, (ConsoleOptionsFetcher)null, false, false, false);
object obj8 = <>c.<>9__33_7;
if (obj8 == null)
{
ConsoleEvent val8 = delegate(ConsoleEventArgs args)
{
if (args.Length == 1)
{
TerrainConfig.Save(TerrainConfigFile);
}
else
{
MonoBehaviour.print((object)"Not enough arguments to set threshold");
}
};
<>c.<>9__33_7 = val8;
obj8 = (object)val8;
}
new ConsoleCommand("saveterrainconfig", "Save the current terrain config", (ConsoleEvent)obj8, false, false, false, false, false, (ConsoleOptionsFetcher)null, false, false, false);
object obj9 = <>c.<>9__33_8;
if (obj9 == null)
{
ConsoleEvent val9 = delegate(ConsoleEventArgs args)
{
if (args.Length == 2)
{
TerrainConfig.tilingAmount = int.Parse(args[1]);
Shader.SetGlobalFloat("_TileAmount", (float)TerrainConfig.tilingAmount);
}
else
{
MonoBehaviour.print((object)"Not enough arguments to set threshold");
}
};
<>c.<>9__33_8 = val9;
obj9 = (object)val9;
}
new ConsoleCommand("settilingamount", "Set amount of times each texture tiles in a terrain chunk", (ConsoleEvent)obj9, false, false, false, false, false, (ConsoleOptionsFetcher)null, false, false, false);
}
}
}
namespace ValheimHDTerrain.Logging
{
internal class bLog
{
private static bool extendedDebugEnabled = false;
private static string logLabel = "HD Terrain";
public static void Log(string LogMessage, bool extendedlog = false)
{
if (extendedlog || extendedDebugEnabled)
{
Debug.Log((object)(logLabel + ": " + LogMessage));
}
}
}
}