using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Text;
using BepInEx;
using BepInEx.Logging;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using UnityEngine;
[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")]
[assembly: AssemblyCompany("coruscnium")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyDescription("Replaces terrain textures with randomly assigned pride flags")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0.0")]
[assembly: AssemblyProduct("PrideTerrain")]
[assembly: AssemblyTitle("PrideTerrain")]
[assembly: AssemblyVersion("1.0.0.0")]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
[CompilerGenerated]
[Embedded]
internal sealed class EmbeddedAttribute : Attribute
{
}
}
namespace System.Runtime.CompilerServices
{
[CompilerGenerated]
[Embedded]
[AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)]
internal sealed class RefSafetyRulesAttribute : Attribute
{
public readonly int Version;
public RefSafetyRulesAttribute(int P_0)
{
Version = P_0;
}
}
}
namespace PrideTerrain
{
internal static class FlagLibrary
{
private static readonly string[] SupportedExtensions = new string[3] { ".png", ".jpg", ".jpeg" };
private static string[] _paths = new string[0];
private static Texture2D[] _textures = (Texture2D[])(object)new Texture2D[0];
public static int Count => _paths.Length;
private static string FlagFolder
{
get
{
string location = Assembly.GetExecutingAssembly().Location;
if (!string.IsNullOrEmpty(location))
{
return Path.Combine(Path.GetDirectoryName(location), "flags");
}
return null;
}
}
public static void Scan()
{
string flagFolder = FlagFolder;
List<string> list = new List<string>();
try
{
if (Directory.Exists(flagFolder))
{
string[] files = Directory.GetFiles(flagFolder);
foreach (string text in files)
{
if (Array.IndexOf(SupportedExtensions, Path.GetExtension(text).ToLowerInvariant()) >= 0)
{
list.Add(text);
}
}
}
}
catch (Exception ex)
{
Plugin.Logger.LogWarning((object)("Could not read '" + flagFolder + "': " + ex.Message));
}
list.Sort(StringComparer.OrdinalIgnoreCase);
_paths = list.ToArray();
_textures = (Texture2D[])(object)new Texture2D[_paths.Length];
if (_paths.Length == 0)
{
Plugin.Logger.LogWarning((object)("No flag images found in '" + flagFolder + "' — the terrain is left alone."));
}
}
public static int IndexFor(int key)
{
if (_paths.Length == 0)
{
return -1;
}
return (int)((uint)(key * -1640531535) % (uint)_paths.Length);
}
public static string NameAt(int index)
{
if (index >= 0 && index < _paths.Length)
{
return Path.GetFileNameWithoutExtension(_paths[index]);
}
return "?";
}
public static Texture2D Get(int index)
{
if (index < 0 || index >= _paths.Length)
{
return null;
}
Texture2D val = _textures[index];
if ((Object)(object)val != (Object)null)
{
return val;
}
_textures[index] = Load(_paths[index]);
return _textures[index];
}
private static Texture2D Load(string path)
{
//IL_0004: Unknown result type (might be due to invalid IL or missing references)
//IL_000a: Expected O, but got Unknown
try
{
Texture2D val = new Texture2D(2, 2, (TextureFormat)4, true);
if (!ImageConversion.LoadImage(val, File.ReadAllBytes(path)))
{
Plugin.Logger.LogWarning((object)("Could not decode '" + Path.GetFileName(path) + "' as an image."));
Object.Destroy((Object)(object)val);
return null;
}
((Texture)val).wrapMode = (TextureWrapMode)0;
((Texture)val).filterMode = (FilterMode)1;
((Object)val).hideFlags = (HideFlags)61;
((Object)val).name = "PrideTerrain:" + Path.GetFileNameWithoutExtension(path);
return val;
}
catch (Exception ex)
{
Plugin.Logger.LogWarning((object)("Could not load '" + path + "': " + ex.Message));
return null;
}
}
}
[MycoMod(/*Could not decode attribute arguments.*/)]
[BepInPlugin("coruscnium.prideterrain", "PrideTerrain", "1.0.0.0")]
[BepInProcess("Mycopunk.exe")]
public class Plugin : BaseUnityPlugin
{
public const string PluginGUID = "coruscnium.prideterrain";
public const string PluginName = "PrideTerrain";
public const string PluginVersion = "1.0.0.0";
internal static ManualLogSource Logger;
private Harmony _harmony;
private void Awake()
{
//IL_0016: Unknown result type (might be due to invalid IL or missing references)
//IL_0020: Expected O, but got Unknown
Logger = ((BaseUnityPlugin)this).Logger;
FlagLibrary.Scan();
_harmony = new Harmony("coruscnium.prideterrain");
_harmony.PatchAll(Assembly.GetExecutingAssembly());
Logger.LogInfo((object)string.Format("{0} loaded with {1} flag(s).", "PrideTerrain", FlagLibrary.Count));
}
private void OnDestroy()
{
TerrainPainter.ReleaseCreated();
Harmony harmony = _harmony;
if (harmony != null)
{
harmony.UnpatchSelf();
}
}
}
[HarmonyPatch(typeof(TerrainGenerator), "OnTextureBundleLoaded")]
internal static class TerrainTextureBundlePatch
{
[HarmonyPostfix]
private static void Postfix(TerrainGenerator __instance)
{
TerrainPainter.Paint(__instance);
}
}
internal static class TerrainPainter
{
private struct TextureParams
{
public float TintR;
public float TintG;
public float TintB;
public float SpecR;
public float SpecG;
public float SpecB;
public float SpecA;
public float ShadowTint;
public float Smoothness;
public float Tiling;
public float HeightX;
public float HeightY;
public float HeightZ;
public float BlendX;
public float BlendY;
public float BlendZ;
}
private const int LayerSize = 512;
private const byte SpecularAlpha = 0;
private const int ParamSlots = 8;
private static readonly FieldInfo TextureParamBufferField = AccessTools.Field(typeof(TerrainGenerator), "textureParamBuffer");
private static readonly FieldInfo CurrentSeedField = AccessTools.Field(typeof(TerrainGenerator), "currentSeed");
private static readonly MethodInfo GetTextureSetMethod = AccessTools.Method(typeof(TerrainGenerator), "GetTextureSet", (Type[])null, (Type[])null);
private static readonly List<Texture2DArray> Created = new List<Texture2DArray>();
private static bool _loggedPaintError;
public static void Paint(TerrainGenerator generator)
{
try
{
Material val = default(Material);
if ((Object)(object)generator == (Object)null || FlagLibrary.Count == 0 || !generator.HasMaterialInstance(ref val) || (Object)(object)val == (Object)null)
{
return;
}
Texture texture = val.GetTexture("_BaseTextures");
Texture2DArray val2 = (Texture2DArray)(object)((texture is Texture2DArray) ? texture : null);
int num = (((Object)(object)val2 != (Object)null) ? val2.depth : 8);
if (num > 0)
{
uint seed = ((CurrentSeedField != null) ? ((uint)CurrentSeedField.GetValue(null)) : 0u);
string chosen;
Texture2DArray val3 = BuildArray(num, seed, out chosen);
if (!((Object)(object)val3 == (Object)null))
{
val.SetTexture("_BaseTextures", (Texture)(object)val3);
Created.Add(val3);
NeutraliseTints(generator, val);
Plugin.Logger.LogInfo((object)$"[terrain] Repainted {num} layer(s) with: {chosen}");
}
}
}
catch (Exception arg)
{
if (!_loggedPaintError)
{
_loggedPaintError = true;
Plugin.Logger.LogError((object)$"Failed to repaint the terrain: {arg}");
}
}
}
private static Texture2DArray BuildArray(int layers, uint seed, out string chosen)
{
//IL_001a: 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_0026: Unknown result type (might be due to invalid IL or missing references)
//IL_002d: Unknown result type (might be due to invalid IL or missing references)
//IL_0035: Unknown result type (might be due to invalid IL or missing references)
//IL_0041: Expected O, but got Unknown
Random random = new Random((int)seed);
StringBuilder stringBuilder = new StringBuilder();
Texture2DArray val = new Texture2DArray(512, 512, layers, (TextureFormat)4, true)
{
wrapMode = (TextureWrapMode)0,
filterMode = (FilterMode)1,
hideFlags = (HideFlags)61,
name = "PrideTerrain:BaseTextures"
};
for (int i = 0; i < layers; i++)
{
int index = random.Next(FlagLibrary.Count);
Texture2D val2 = FlagLibrary.Get(index);
if ((Object)(object)val2 == (Object)null)
{
Object.Destroy((Object)(object)val);
chosen = null;
return null;
}
if (i > 0)
{
stringBuilder.Append(", ");
}
stringBuilder.Append(FlagLibrary.NameAt(index));
val.SetPixels32(Resample(val2), i);
}
val.Apply(true, true);
chosen = stringBuilder.ToString();
return val;
}
private static Color32[] Resample(Texture2D source)
{
//IL_00bc: Unknown result type (might be due to invalid IL or missing references)
//IL_00c1: Unknown result type (might be due to invalid IL or missing references)
//IL_00cb: Unknown result type (might be due to invalid IL or missing references)
//IL_00d0: Unknown result type (might be due to invalid IL or missing references)
//IL_00da: Unknown result type (might be due to invalid IL or missing references)
//IL_00df: Unknown result type (might be due to invalid IL or missing references)
//IL_00e9: Unknown result type (might be due to invalid IL or missing references)
//IL_00ee: Unknown result type (might be due to invalid IL or missing references)
//IL_00fc: Unknown result type (might be due to invalid IL or missing references)
//IL_0103: Unknown result type (might be due to invalid IL or missing references)
//IL_010a: Unknown result type (might be due to invalid IL or missing references)
//IL_0111: Unknown result type (might be due to invalid IL or missing references)
//IL_0121: Unknown result type (might be due to invalid IL or missing references)
//IL_0128: Unknown result type (might be due to invalid IL or missing references)
//IL_012f: Unknown result type (might be due to invalid IL or missing references)
//IL_0136: Unknown result type (might be due to invalid IL or missing references)
//IL_0146: Unknown result type (might be due to invalid IL or missing references)
//IL_014d: Unknown result type (might be due to invalid IL or missing references)
//IL_0154: Unknown result type (might be due to invalid IL or missing references)
//IL_015b: Unknown result type (might be due to invalid IL or missing references)
//IL_016c: Unknown result type (might be due to invalid IL or missing references)
//IL_0171: Unknown result type (might be due to invalid IL or missing references)
Color32[] pixels = source.GetPixels32();
int width = ((Texture)source).width;
int height = ((Texture)source).height;
Color32[] array = (Color32[])(object)new Color32[262144];
for (int i = 0; i < 512; i++)
{
float num = ((float)i + 0.5f) / 512f * (float)height - 0.5f;
int num2 = Mathf.Clamp(Mathf.FloorToInt(num), 0, height - 1);
int num3 = Mathf.Min(num2 + 1, height - 1);
float fy = Mathf.Clamp01(num - (float)num2);
for (int j = 0; j < 512; j++)
{
float num4 = ((float)j + 0.5f) / 512f * (float)width - 0.5f;
int num5 = Mathf.Clamp(Mathf.FloorToInt(num4), 0, width - 1);
int num6 = Mathf.Min(num5 + 1, width - 1);
float fx = Mathf.Clamp01(num4 - (float)num5);
Color32 val = pixels[num2 * width + num5];
Color32 val2 = pixels[num2 * width + num6];
Color32 val3 = pixels[num3 * width + num5];
Color32 val4 = pixels[num3 * width + num6];
array[i * 512 + j] = new Color32(Lerp2(val.r, val2.r, val3.r, val4.r, fx, fy), Lerp2(val.g, val2.g, val3.g, val4.g, fx, fy), Lerp2(val.b, val2.b, val3.b, val4.b, fx, fy), (byte)0);
}
}
return array;
}
private static byte Lerp2(byte a, byte b, byte c, byte d, float fx, float fy)
{
float num = (float)(int)a + (float)(b - a) * fx;
float num2 = (float)(int)c + (float)(d - c) * fx;
return (byte)Mathf.Clamp(num + (num2 - num) * fy + 0.5f, 0f, 255f);
}
private static void NeutraliseTints(TerrainGenerator generator, Material material)
{
//IL_0051: Unknown result type (might be due to invalid IL or missing references)
//IL_0056: Unknown result type (might be due to invalid IL or missing references)
//IL_005a: Unknown result type (might be due to invalid IL or missing references)
//IL_008c: Unknown result type (might be due to invalid IL or missing references)
//IL_0091: Unknown result type (might be due to invalid IL or missing references)
//IL_0122: Unknown result type (might be due to invalid IL or missing references)
//IL_0124: Unknown result type (might be due to invalid IL or missing references)
//IL_0135: Unknown result type (might be due to invalid IL or missing references)
//IL_0137: Unknown result type (might be due to invalid IL or missing references)
//IL_0148: Unknown result type (might be due to invalid IL or missing references)
//IL_014a: Unknown result type (might be due to invalid IL or missing references)
//IL_015b: Unknown result type (might be due to invalid IL or missing references)
//IL_015d: Unknown result type (might be due to invalid IL or missing references)
//IL_016e: Unknown result type (might be due to invalid IL or missing references)
//IL_017c: Unknown result type (might be due to invalid IL or missing references)
//IL_018a: Unknown result type (might be due to invalid IL or missing references)
//IL_0198: Unknown result type (might be due to invalid IL or missing references)
//IL_019a: Unknown result type (might be due to invalid IL or missing references)
//IL_01ab: Unknown result type (might be due to invalid IL or missing references)
//IL_01ad: Unknown result type (might be due to invalid IL or missing references)
//IL_01be: Unknown result type (might be due to invalid IL or missing references)
//IL_01c0: Unknown result type (might be due to invalid IL or missing references)
//IL_01d1: Unknown result type (might be due to invalid IL or missing references)
//IL_01d3: Unknown result type (might be due to invalid IL or missing references)
//IL_01e4: Unknown result type (might be due to invalid IL or missing references)
//IL_01e6: Unknown result type (might be due to invalid IL or missing references)
//IL_01f7: Unknown result type (might be due to invalid IL or missing references)
//IL_01f9: Unknown result type (might be due to invalid IL or missing references)
//IL_00b3: Unknown result type (might be due to invalid IL or missing references)
//IL_00b5: Unknown result type (might be due to invalid IL or missing references)
//IL_00c4: Unknown result type (might be due to invalid IL or missing references)
//IL_00c6: Unknown result type (might be due to invalid IL or missing references)
//IL_00d5: Unknown result type (might be due to invalid IL or missing references)
//IL_00d7: Unknown result type (might be due to invalid IL or missing references)
if (TextureParamBufferField == null || GetTextureSetMethod == null)
{
return;
}
object? value = TextureParamBufferField.GetValue(generator);
GraphicsBuffer val = (GraphicsBuffer)((value is GraphicsBuffer) ? value : null);
if (val == null || !val.IsValid() || !(GetTextureSetMethod.Invoke(generator, null) is TerrainTextureSet val2))
{
return;
}
TerrainTexture[] textures = val2.Textures;
if (textures == null || textures.Length == 0)
{
return;
}
TextureParams[] array = new TextureParams[8];
StringBuilder stringBuilder = new StringBuilder();
for (int i = 0; i < 8; i++)
{
TerrainTexture val3 = textures[Mathf.Min(i, textures.Length - 1)];
if (i < textures.Length)
{
if (i > 0)
{
stringBuilder.Append(", ");
}
stringBuilder.Append($"{val3.Tint.r:0.00}/{val3.Tint.g:0.00}/{val3.Tint.b:0.00}");
}
array[i] = new TextureParams
{
TintR = 1f,
TintG = 1f,
TintB = 1f,
SpecR = val3.SpecularColor.r,
SpecG = val3.SpecularColor.g,
SpecB = val3.SpecularColor.b,
SpecA = val3.SpecularColor.a,
ShadowTint = val3.ShadowColor,
Smoothness = val3.Smoothness,
Tiling = val3.Tile,
HeightX = val3.HeightAdjust.x,
HeightY = val3.HeightAdjust.y,
HeightZ = val3.HeightAdjust.z,
BlendX = val3.Blending.x,
BlendY = val3.Blending.y,
BlendZ = val3.Blending.z
};
}
val.SetData((Array)array);
material.SetBuffer("_TextureParamBuffer", val);
Plugin.Logger.LogInfo((object)$"[terrain] Tints neutralised. Originals were: {stringBuilder}");
}
public static void ReleaseCreated()
{
foreach (Texture2DArray item in Created)
{
if ((Object)(object)item != (Object)null)
{
Object.Destroy((Object)(object)item);
}
}
Created.Clear();
}
}
}