Decompiled source of Poorilla v1.0.0

Poorilla.dll

Decompiled a month ago
using System;
using System.Collections.Generic;
using System.Reflection;
using System.Runtime.CompilerServices;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using HarmonyLib;
using Jotunn.Configs;
using Jotunn.Entities;
using Jotunn.Managers;
using Jotunn.Utils;
using UnityEngine;
using UnityEngine.Rendering;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: AssemblyVersion("0.0.0.0")]
namespace Poorilla;

[BepInDependency(/*Could not decode attribute arguments.*/)]
[NetworkCompatibility(/*Could not decode attribute arguments.*/)]
[BepInPlugin("com.poorilla.mod", "Poorilla", "1.0.0")]
public class PoorillaPlugin : BaseUnityPlugin
{
	private class AttackInfo
	{
		public SharedData Shared;

		public DamageTypes Damages;

		public DamageTypes DamagesPerLevel;
	}

	private class CreatureInfo
	{
		public Humanoid Humanoid;

		public float Speed;

		public float WalkSpeed;

		public float RunSpeed;

		public ConfigEntry<float> Health;

		public ConfigEntry<float> Damage;

		public readonly List<AttackInfo> Attacks = new List<AttackInfo>();
	}

	internal class Palette
	{
		public readonly string Name;

		public readonly Color Dark;

		public readonly Color Mid;

		public readonly Color Light;

		public readonly Color Caked;

		public readonly Color Wet;

		public static readonly Palette Mud = new Palette("mud", new Color(0.12f, 0.08f, 0.045f), new Color(0.34f, 0.24f, 0.13f), new Color(0.52f, 0.4f, 0.26f), new Color(0.5f, 0.44f, 0.34f), new Color(0.08f, 0.055f, 0.03f));

		public static readonly Palette Egg = new Palette("egg", new Color(0.2f, 0.14f, 0.08f), new Color(0.55f, 0.44f, 0.3f), new Color(0.8f, 0.7f, 0.52f), new Color(0.4f, 0.28f, 0.16f), new Color(0.14f, 0.09f, 0.05f));

		public static readonly Palette Stink = new Palette("stink", new Color(0.1f, 0.11f, 0.03f), new Color(0.36f, 0.4f, 0.12f), new Color(0.66f, 0.72f, 0.3f), new Color(0.48f, 0.4f, 0.2f), new Color(0.12f, 0.09f, 0.04f));

		public Palette(string name, Color dark, Color mid, Color light, Color caked, Color wet)
		{
			//IL_000e: Unknown result type (might be due to invalid IL or missing references)
			//IL_000f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0015: Unknown result type (might be due to invalid IL or missing references)
			//IL_0016: Unknown result type (might be due to invalid IL or missing references)
			//IL_001c: Unknown result type (might be due to invalid IL or missing references)
			//IL_001e: 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_0026: Unknown result type (might be due to invalid IL or missing references)
			//IL_002c: Unknown result type (might be due to invalid IL or missing references)
			//IL_002e: Unknown result type (might be due to invalid IL or missing references)
			Name = name;
			Dark = dark;
			Mid = mid;
			Light = light;
			Caked = caked;
			Wet = wet;
		}
	}

	public const string PluginGuid = "com.poorilla.mod";

	public const string PluginName = "Poorilla";

	public const string PluginVersion = "1.0.0";

	public const string AdultName = "Poorilla";

	public const string BabyName = "PoorillaBaby";

	public const string HideName = "PoorillaHide";

	public const string EggName = "PoorillaEgg";

	public const string CapeName = "CapeOfStank";

	public const string MudName = "PoorillaMud";

	public const string NestName = "PoorillaNest";

	public const string MudStinkName = "SE_PoorillaStinky";

	public const string CapeStinkName = "SE_CapeOfStank";

	public const string StinkZdoKey = "poorilla_stinky";

	public const string MudSpawnZdoKey = "poorilla_mud_spawn";

	private const float DaySeconds = 1800f;

	internal static PoorillaPlugin Instance;

	internal static ManualLogSource Log;

	internal static bool HasGraphics;

	internal static GameObject MudPrefab;

	internal static SE_Stats MudStinkSE;

	internal static SE_Stats CapeStinkSE;

	public static ConfigEntry<float> Scale;

	public static ConfigEntry<float> Health;

	public static ConfigEntry<float> DamageMultiplier;

	public static ConfigEntry<float> SpeedMultiplier;

	public static ConfigEntry<bool> MudSlap;

	public static ConfigEntry<bool> KeepLogAttacks;

	public static ConfigEntry<bool> SpawnEnabled;

	public static ConfigEntry<float> SpawnChance;

	public static ConfigEntry<float> SpawnInterval;

	public static ConfigEntry<int> MaxSpawned;

	public static ConfigEntry<int> MaxGroupSize;

	public static ConfigEntry<int> MaxLevel;

	public static ConfigEntry<bool> NestEnabled;

	public static ConfigEntry<int> NestQuantity;

	public static ConfigEntry<float> NestMinDistance;

	public static ConfigEntry<float> HatchDays;

	public static ConfigEntry<bool> RequireRoof;

	public static ConfigEntry<bool> EggTeleportable;

	public static ConfigEntry<float> EggWeight;

	public static ConfigEntry<float> BabyScale;

	public static ConfigEntry<float> BabyHealth;

	public static ConfigEntry<float> BabyDamage;

	public static ConfigEntry<bool> MudEnabled;

	public static ConfigEntry<float> MudIntervalMin;

	public static ConfigEntry<float> MudIntervalMax;

	public static ConfigEntry<float> MudLifetime;

	public static ConfigEntry<float> StinkDuration;

	public static ConfigEntry<float> StaminaRegenPenalty;

	public static ConfigEntry<float> AttractRange;

	public static ConfigEntry<float> CapeSpeedBonus;

	public static ConfigEntry<bool> StinkCloud;

	private readonly List<CreatureInfo> creatures = new List<CreatureInfo>();

	private readonly Dictionary<string, Material> recolored = new Dictionary<string, Material>();

	private Material bodyMaterial;

	private GameObject prefabHolder;

	private GameObject adultPrefab;

	private GameObject babyPrefab;

	private GameObject hidePrefab;

	private GameObject eggPrefab;

	private GameObject capePrefab;

	private float stinkBroadcastTimer;

	private void Awake()
	{
		//IL_0011: Unknown result type (might be due to invalid IL or missing references)
		//IL_0017: Invalid comparison between Unknown and I4
		//IL_002c: Unknown result type (might be due to invalid IL or missing references)
		Instance = this;
		Log = ((BaseUnityPlugin)this).Logger;
		HasGraphics = (int)SystemInfo.graphicsDeviceType != 4;
		BindConfig();
		new Harmony("com.poorilla.mod").PatchAll(typeof(PoorillaPlugin).Assembly);
		CreatureManager.OnVanillaCreaturesAvailable += OnVanillaCreaturesAvailable;
		ZoneManager.OnVanillaLocationsAvailable += AddNest;
		SynchronizationManager.OnConfigurationSynchronized += delegate
		{
			ApplyStats();
		};
		((BaseUnityPlugin)this).Config.SettingChanged += delegate
		{
			ApplyStats();
		};
	}

	private ConfigEntry<T> Bind<T>(string section, string key, T value, string description)
	{
		//IL_0015: Unknown result type (might be due to invalid IL or missing references)
		//IL_001b: Expected O, but got Unknown
		//IL_0025: Unknown result type (might be due to invalid IL or missing references)
		//IL_002f: Expected O, but got Unknown
		ConfigFile config = ((BaseUnityPlugin)this).Config;
		object[] array = new object[1];
		ConfigurationManagerAttributes val = new ConfigurationManagerAttributes();
		val.IsAdminOnly = true;
		array[0] = val;
		return config.Bind<T>(section, key, value, new ConfigDescription(description, (AcceptableValueBase)null, array));
	}

	private void BindConfig()
	{
		Scale = Bind("Poorilla", "Scale", 0.6f, "Size relative to a Troll. (Restart required; server and clients should match.)");
		Health = Bind("Poorilla", "Health", 300f, "Base health (Troll is 600).");
		DamageMultiplier = Bind("Poorilla", "DamageMultiplier", 0.45f, "Attack damage relative to a Troll's.");
		SpeedMultiplier = Bind("Poorilla", "SpeedMultiplier", 1.25f, "Movement speed relative to a Troll's (also used by Mini Poorillas).");
		MudSlap = Bind("Poorilla", "MudSlap", value: true, "Poorilla hits make you Wet. (Restart required; server and clients should match.)");
		KeepLogAttacks = Bind("Poorilla", "KeepLogAttacks", value: false, "Keep the Troll's log swings. (Restart required; server and clients should match.)");
		SpawnEnabled = Bind("Spawning", "Enabled", value: true, "Poorillas spawn naturally in the Black Forest. (Restart required; server and clients should match.)");
		SpawnChance = Bind("Spawning", "SpawnChance", 25f, "Percent chance per spawn check. (Restart required; server and clients should match.)");
		SpawnInterval = Bind("Spawning", "SpawnInterval", 400f, "Seconds between spawn checks. (Restart required; server and clients should match.)");
		MaxSpawned = Bind("Spawning", "MaxSpawned", 2, "Max Poorillas alive near a player at once. (Restart required; server and clients should match.)");
		MaxGroupSize = Bind("Spawning", "MaxGroupSize", 2, "Poorillas show up in troops of up to this many. (Restart required; server and clients should match.)");
		MaxLevel = Bind("Spawning", "MaxLevel", 3, "Highest spawn level (3 = two stars). (Restart required; server and clients should match.)");
		NestEnabled = Bind("Nest", "Enabled", value: true, "Generate Poorilla Nests in the Black Forest (only in unexplored areas). (Restart required; server and clients should match.)");
		NestQuantity = Bind("Nest", "Quantity", 40, "How many nests the world generator tries to place. (Restart required; server and clients should match.)");
		NestMinDistance = Bind("Nest", "MinDistanceFromSimilar", 500f, "Minimum meters between nests. (Restart required; server and clients should match.)");
		HatchDays = Bind("Egg", "HatchDays", 2f, "In-game days (30 real minutes each) an egg must stay warm to hatch.");
		RequireRoof = Bind("Egg", "RequireRoof", value: false, "Eggs also need to be under a roof to incubate.");
		EggTeleportable = Bind("Egg", "Teleportable", value: false, "Allow Poorilla Eggs through portals.");
		EggWeight = Bind("Egg", "Weight", 50f, "Weight of a Poorilla Egg.");
		BabyScale = Bind("MiniPoorilla", "Scale", 0.3f, "Size relative to a Troll. (Restart required; server and clients should match.)");
		BabyHealth = Bind("MiniPoorilla", "Health", 200f, "Base health.");
		BabyDamage = Bind("MiniPoorilla", "DamageMultiplier", 0.25f, "Attack damage relative to a Troll's.");
		MudEnabled = Bind("Mud", "Enabled", value: true, "Mini Poorillas leave mud puddles behind.");
		MudIntervalMin = Bind("Mud", "IntervalMin", 90f, "Minimum seconds between puddles.");
		MudIntervalMax = Bind("Mud", "IntervalMax", 240f, "Maximum seconds between puddles.");
		MudLifetime = Bind("Mud", "Lifetime", 600f, "Seconds before a puddle dries up and disappears.");
		StinkDuration = Bind("Stink", "Duration", 60f, "Seconds of Stinky after stepping in mud.");
		StaminaRegenPenalty = Bind("Stink", "StaminaRegenPenalty", 0.1f, "Stamina regen reduction while Stinky (0.1 = -10%).");
		AttractRange = Bind("Stink", "AttractRange", 60f, "Meters wild Poorillas can smell a Stinky player from.");
		CapeSpeedBonus = Bind("Stink", "CapeSpeedBonus", 0.25f, "Cape of Stank movement speed bonus (0.25 = +25%).");
		StinkCloud = Bind("Stink", "StinkCloud", value: true, "Show a green stink cloud while Stinky. (Restart required; server and clients should match.)");
	}

	private void OnVanillaCreaturesAvailable()
	{
		//IL_0017: Unknown result type (might be due to invalid IL or missing references)
		//IL_0021: Expected O, but got Unknown
		CreatureManager.OnVanillaCreaturesAvailable -= OnVanillaCreaturesAvailable;
		prefabHolder = new GameObject("PoorillaPrefabs");
		prefabHolder.SetActive(false);
		Object.DontDestroyOnLoad((Object)(object)prefabHolder);
		Step("stinky status effects", CreateStatusEffects);
		Step("items", CreateItems);
		Step("Mini Poorilla", delegate
		{
			babyPrefab = CreateCreature("PoorillaBaby", "Mini Poorilla", BabyScale.Value, BabyHealth, BabyDamage, wetOnHit: false, baby: true);
		});
		Step("Poorilla", delegate
		{
			adultPrefab = CreateCreature("Poorilla", "Poorilla", Scale.Value, Health, DamageMultiplier, MudSlap.Value, baby: false);
		});
		Step("Poorilla Egg hatching", SetupEgg);
		Step("mud puddles", CreateMudPrefab);
		Step("Cape of Stank recipe", CreateCapeRecipe);
		ApplyStats();
		Log.LogInfo((object)"Poorillas have entered the Black Forest.");
	}

	private static void Step(string what, Action action)
	{
		try
		{
			action();
		}
		catch (Exception ex)
		{
			Log.LogError((object)("Failed to set up " + what + ": " + ex));
		}
	}

	private void CreateStatusEffects()
	{
		//IL_008d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0097: Expected O, but got Unknown
		//IL_00a3: Unknown result type (might be due to invalid IL or missing references)
		//IL_00ad: Expected O, but got Unknown
		StatusEffect prefab = Cache.GetPrefab<StatusEffect>("Wet");
		StatusEffect prefab2 = Cache.GetPrefab<StatusEffect>("Poison");
		Sprite icon = null;
		if (HasGraphics && (Object)(object)prefab != (Object)null && (Object)(object)prefab.m_icon != (Object)null)
		{
			icon = RecolorSprite(prefab.m_icon, Palette.Stink);
		}
		MudStinkSE = MakeStinkEffect("SE_PoorillaStinky", icon, prefab2, "You stepped in Poorilla mud. You stink!");
		CapeStinkSE = MakeStinkEffect("SE_CapeOfStank", icon, prefab2, "");
		((StatusEffect)CapeStinkSE).m_tooltip = "The Cape of Stank reeks. Poorillas nearby can smell you coming.";
		ItemManager.Instance.AddStatusEffect(new CustomStatusEffect((StatusEffect)(object)MudStinkSE, false));
		ItemManager.Instance.AddStatusEffect(new CustomStatusEffect((StatusEffect)(object)CapeStinkSE, false));
	}

	private static SE_Stats MakeStinkEffect(string internalName, Sprite icon, StatusEffect poison, string message)
	{
		//IL_002c: 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_0068: Expected O, but got Unknown
		//IL_0069: Unknown result type (might be due to invalid IL or missing references)
		//IL_0073: Expected O, but got Unknown
		//IL_0069: Unknown result type (might be due to invalid IL or missing references)
		//IL_0073: Expected O, but got Unknown
		SE_Stats val = ScriptableObject.CreateInstance<SE_Stats>();
		((Object)val).name = internalName;
		((StatusEffect)val).m_name = "Stinky";
		((StatusEffect)val).m_tooltip = "Something smells awful. Probably you. Poorillas nearby can smell you.";
		((StatusEffect)val).m_icon = icon;
		((StatusEffect)val).m_startMessageType = (MessageType)1;
		((StatusEffect)val).m_startMessage = message;
		((StatusEffect)val).m_startEffects = (EffectList)((StinkCloud.Value && (Object)(object)poison != (Object)null && poison.m_startEffects != null) ? ((object)poison.m_startEffects) : ((object)new EffectList()));
		((StatusEffect)val).m_stopEffects = new EffectList();
		return val;
	}

	private void CreateItems()
	{
		hidePrefab = CloneItem("PoorillaHide", "TrollHide", "Poorilla Hide", "Thick, matted hide that never quite stops smelling. Used to make the Cape of Stank.", Palette.Mud);
		eggPrefab = CloneItem("PoorillaEgg", "DragonEgg", "Poorilla Egg", "A heavy, mud-caked egg from a Poorilla Nest. Set it down next to a burning fire and keep it warm, and in a couple of days something small and stinky will hatch.", Palette.Egg);
		ItemDrop component = eggPrefab.GetComponent<ItemDrop>();
		component.m_itemData.m_shared.m_maxStackSize = 1;
		component.m_autoPickup = false;
		component.m_autoDestroy = false;
		Light[] componentsInChildren = eggPrefab.GetComponentsInChildren<Light>(true);
		foreach (Light val in componentsInChildren)
		{
			((Behaviour)val).enabled = false;
		}
		ParticleSystem[] componentsInChildren2 = eggPrefab.GetComponentsInChildren<ParticleSystem>(true);
		foreach (ParticleSystem val2 in componentsInChildren2)
		{
			((Component)val2).gameObject.SetActive(false);
		}
		capePrefab = CloneItem("CapeOfStank", "CapeTroll", "Cape of Stank", "Stitched from Poorilla hide. You move like the wind and smell like a bog. Wild Poorillas will come looking for you.", Palette.Mud);
		capePrefab.GetComponent<ItemDrop>().m_itemData.m_shared.m_equipStatusEffect = (StatusEffect)(object)CapeStinkSE;
	}

	private GameObject CloneItem(string name, string baseName, string displayName, string description, Palette palette)
	{
		//IL_00a0: Unknown result type (might be due to invalid IL or missing references)
		//IL_00aa: Expected O, but got Unknown
		GameObject val = PrefabManager.Instance.CreateClonedPrefab(name, baseName);
		if ((Object)(object)val == (Object)null)
		{
			throw new Exception("Vanilla item " + baseName + " not found");
		}
		SharedData shared = val.GetComponent<ItemDrop>().m_itemData.m_shared;
		shared.m_name = displayName;
		shared.m_description = description;
		Recolor(val, palette);
		if (HasGraphics && shared.m_icons != null)
		{
			Sprite[] array = (Sprite[])(object)new Sprite[shared.m_icons.Length];
			for (int i = 0; i < array.Length; i++)
			{
				array[i] = RecolorSprite(shared.m_icons[i], palette);
			}
			shared.m_icons = array;
		}
		ItemManager.Instance.AddItem(new CustomItem(val, false));
		return val;
	}

	private GameObject CreateCreature(string name, string displayName, float scale, ConfigEntry<float> health, ConfigEntry<float> damage, bool wetOnHit, bool baby)
	{
		//IL_0000: Unknown result type (might be due to invalid IL or missing references)
		//IL_0006: Expected O, but got Unknown
		//IL_004b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0051: Expected O, but got Unknown
		//IL_0083: Unknown result type (might be due to invalid IL or missing references)
		//IL_0089: Expected O, but got Unknown
		//IL_00bb: Unknown result type (might be due to invalid IL or missing references)
		//IL_00c2: Expected O, but got Unknown
		//IL_01b4: Unknown result type (might be due to invalid IL or missing references)
		//IL_01bb: Expected O, but got Unknown
		//IL_01cb: 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_010a: Unknown result type (might be due to invalid IL or missing references)
		//IL_0110: Expected O, but got Unknown
		//IL_027b: Unknown result type (might be due to invalid IL or missing references)
		CreatureConfig val = new CreatureConfig();
		val.Name = displayName;
		val.Faction = (Faction)2;
		val.Group = name;
		if (baby)
		{
			val.AddConsumable("Raspberry");
			val.AddConsumable("Blueberries");
			val.AddConsumable("Honey");
		}
		else
		{
			DropConfig val2 = new DropConfig();
			val2.Item = "PoorillaHide";
			val2.Chance = 100f;
			val2.MinAmount = 1;
			val2.MaxAmount = 2;
			val2.LevelMultiplier = true;
			val.AddDropConfig(val2);
			DropConfig val3 = new DropConfig();
			val3.Item = "LeatherScraps";
			val3.Chance = 100f;
			val3.MinAmount = 2;
			val3.MaxAmount = 4;
			val3.LevelMultiplier = true;
			val.AddDropConfig(val3);
			DropConfig val4 = new DropConfig();
			val4.Item = "Coins";
			val4.Chance = 50f;
			val4.MinAmount = 5;
			val4.MaxAmount = 20;
			val4.LevelMultiplier = true;
			val.AddDropConfig(val4);
			if (SpawnEnabled.Value)
			{
				SpawnConfig val5 = new SpawnConfig();
				val5.Name = "Poorilla_BlackForest";
				val5.Biome = (Biome)8;
				val5.SpawnChance = SpawnChance.Value;
				val5.SpawnInterval = SpawnInterval.Value;
				val5.MaxSpawned = MaxSpawned.Value;
				val5.MinGroupSize = 1;
				val5.MaxGroupSize = MaxGroupSize.Value;
				val5.GroupRadius = 6f;
				val5.MinLevel = 1;
				val5.MaxLevel = MaxLevel.Value;
				val5.SpawnAtDay = true;
				val5.SpawnAtNight = true;
				val5.SpawnInForest = true;
				val5.SpawnOutsideForest = true;
				val.AddSpawnConfig(val5);
			}
		}
		CustomCreature val6 = new CustomCreature(name, "Troll", val);
		GameObject prefab = val6.Prefab;
		prefab.transform.localScale = Vector3.one * scale;
		Humanoid component = prefab.GetComponent<Humanoid>();
		CreatureInfo creatureInfo = new CreatureInfo();
		creatureInfo.Humanoid = component;
		creatureInfo.Speed = ((Character)component).m_speed;
		creatureInfo.WalkSpeed = ((Character)component).m_walkSpeed;
		creatureInfo.RunSpeed = ((Character)component).m_runSpeed;
		creatureInfo.Health = health;
		creatureInfo.Damage = damage;
		CreatureInfo creatureInfo2 = creatureInfo;
		((Character)component).m_turnSpeed = ((Character)component).m_turnSpeed * 1.4f;
		((Character)component).m_runTurnSpeed = ((Character)component).m_runTurnSpeed * 1.4f;
		BaseAI component2 = prefab.GetComponent<BaseAI>();
		if ((Object)(object)component2 != (Object)null)
		{
			component2.m_pathAgentType = (AgentType)((scale < 0.45f) ? 1 : 8);
		}
		StatusEffect wet = (wetOnHit ? Cache.GetPrefab<StatusEffect>("Wet") : null);
		component.m_defaultItems = CloneAttacks(name, component.m_defaultItems, scale, wet, creatureInfo2);
		component.m_randomWeapon = CloneAttacks(name, component.m_randomWeapon, scale, wet, creatureInfo2);
		RemoveCameraShakeFootsteps(prefab);
		EffectData[] effectPrefabs = ((Character)component).m_deathEffects.m_effectPrefabs;
		foreach (EffectData val7 in effectPrefabs)
		{
			if (!((Object)(object)val7.m_prefab == (Object)null) && !((Object)(object)val7.m_prefab.GetComponent<Ragdoll>() == (Object)null))
			{
				GameObject val8 = PrefabManager.Instance.CreateClonedPrefab(name + "_ragdoll", val7.m_prefab);
				Recolor(val8, Palette.Mud);
				PrefabManager.Instance.AddPrefab(val8);
				val7.m_prefab = val8;
				val7.m_inheritParentScale = true;
			}
		}
		Recolor(prefab, Palette.Mud);
		if (baby)
		{
			CharacterDrop component3 = prefab.GetComponent<CharacterDrop>();
			if ((Object)(object)component3 != (Object)null)
			{
				component3.m_drops.Clear();
			}
			SetupTameable(prefab);
			prefab.AddComponent<PoorillaMudTrail>();
		}
		else
		{
			prefab.AddComponent<PoorillaSniffer>();
		}
		CreatureManager.Instance.AddCreature(val6);
		creatures.Add(creatureInfo2);
		return prefab;
	}

	private GameObject[] CloneAttacks(string owner, GameObject[] source, float scale, StatusEffect wet, CreatureInfo info)
	{
		//IL_0095: Unknown result type (might be due to invalid IL or missing references)
		//IL_009a: Unknown result type (might be due to invalid IL or missing references)
		//IL_00a2: Unknown result type (might be due to invalid IL or missing references)
		//IL_00a7: Unknown result type (might be due to invalid IL or missing references)
		//IL_011d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0127: Expected O, but got Unknown
		if (source == null)
		{
			return null;
		}
		List<GameObject> list = new List<GameObject>();
		foreach (GameObject val in source)
		{
			if (!((Object)(object)val == (Object)null) && (KeepLogAttacks.Value || !((Object)val).name.ToLowerInvariant().Contains("log")))
			{
				GameObject val2 = PrefabManager.Instance.CreateClonedPrefab(owner + "_" + ((Object)val).name, val);
				SharedData shared = val2.GetComponent<ItemDrop>().m_itemData.m_shared;
				info.Attacks.Add(new AttackInfo
				{
					Shared = shared,
					Damages = shared.m_damages,
					DamagesPerLevel = shared.m_damagesPerLevel
				});
				shared.m_attackForce *= 0.6f;
				shared.m_aiAttackRange *= scale;
				shared.m_aiAttackRangeMin *= scale;
				ScaleAttack(shared.m_attack, scale);
				ScaleAttack(shared.m_secondaryAttack, scale);
				if ((Object)(object)wet != (Object)null)
				{
					shared.m_attackStatusEffect = wet;
					shared.m_attackStatusEffectChance = 1f;
				}
				ItemManager.Instance.AddItem(new CustomItem(val2, false));
				list.Add(val2);
			}
		}
		return list.ToArray();
	}

	private static void ScaleAttack(Attack a, float scale)
	{
		if (a != null)
		{
			a.m_attackRange *= scale;
			a.m_attackHeight *= scale;
			a.m_attackHeightChar1 *= scale;
			a.m_attackHeightChar2 *= scale;
			a.m_attackOffset *= scale;
			a.m_attackRayWidth *= scale;
		}
	}

	private static void RemoveCameraShakeFootsteps(GameObject prefab)
	{
		FootStep[] componentsInChildren = prefab.GetComponentsInChildren<FootStep>(true);
		foreach (FootStep val in componentsInChildren)
		{
			foreach (StepEffect effect in val.m_effects)
			{
				if (effect.m_effectPrefabs == null)
				{
					continue;
				}
				List<GameObject> list = new List<GameObject>();
				GameObject[] effectPrefabs = effect.m_effectPrefabs;
				foreach (GameObject val2 in effectPrefabs)
				{
					if ((Object)(object)val2 != (Object)null && (Object)(object)val2.GetComponentInChildren<CamShaker>(true) == (Object)null)
					{
						list.Add(val2);
					}
				}
				effect.m_effectPrefabs = list.ToArray();
			}
		}
	}

	private static void SetupTameable(GameObject prefab)
	{
		GameObject prefab2 = PrefabManager.Instance.GetPrefab("Wolf");
		Tameable val = (((Object)(object)prefab2 != (Object)null) ? prefab2.GetComponent<Tameable>() : null);
		Tameable val2 = prefab.GetComponent<Tameable>();
		if ((Object)(object)val2 == (Object)null)
		{
			val2 = prefab.AddComponent<Tameable>();
		}
		if ((Object)(object)val != (Object)null)
		{
			FieldInfo[] fields = typeof(Tameable).GetFields(BindingFlags.Instance | BindingFlags.Public);
			foreach (FieldInfo fieldInfo in fields)
			{
				fieldInfo.SetValue(val2, fieldInfo.GetValue(val));
			}
		}
		else
		{
			Log.LogWarning((object)"Wolf taming settings not found; Mini Poorilla uses defaults.");
		}
		val2.m_startsTamed = true;
		val2.m_commandable = true;
		val2.m_saddle = null;
		val2.m_saddleItem = null;
		val2.m_randomStartingName = new List<string> { "Mudbutt", "Sir Squelch", "Stinky Pete", "Clod", "Bogsworth", "Little Stank" };
	}

	private void SetupEgg()
	{
		//IL_00ea: Unknown result type (might be due to invalid IL or missing references)
		//IL_00fc: Expected O, but got Unknown
		if (!((Object)(object)eggPrefab == (Object)null) && !((Object)(object)babyPrefab == (Object)null))
		{
			GameObject prefab = PrefabManager.Instance.GetPrefab("ChickenEgg");
			EggGrow val = (((Object)(object)prefab != (Object)null) ? prefab.GetComponent<EggGrow>() : null);
			if ((Object)(object)val == (Object)null)
			{
				Log.LogWarning((object)"ChickenEgg hatching settings not found; Poorilla Egg uses defaults.");
			}
			EggGrow val2 = eggPrefab.GetComponent<EggGrow>();
			if ((Object)(object)val2 == (Object)null)
			{
				val2 = eggPrefab.AddComponent<EggGrow>();
			}
			val2.m_grownPrefab = babyPrefab;
			val2.m_tamed = true;
			val2.m_requireNearbyFire = true;
			val2.m_updateInterval = (((Object)(object)val != (Object)null && val.m_updateInterval > 0f) ? val.m_updateInterval : 5f);
			val2.m_requireCoverPercentige = (((Object)(object)val != (Object)null) ? val.m_requireCoverPercentige : 0.7f);
			val2.m_hatchEffect = (EffectList)(((Object)(object)val != (Object)null && val.m_hatchEffect != null) ? ((object)val.m_hatchEffect) : ((object)new EffectList()));
			val2.m_hoverOffset = (((Object)(object)val != (Object)null) ? val.m_hoverOffset : 0f);
		}
	}

	private void CreateCapeRecipe()
	{
		//IL_008d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0094: Expected O, but got Unknown
		//IL_01a0: Unknown result type (might be due to invalid IL or missing references)
		//IL_01aa: Expected O, but got Unknown
		if ((Object)(object)capePrefab == (Object)null || (Object)(object)hidePrefab == (Object)null)
		{
			return;
		}
		Recipe prefab = Cache.GetPrefab<Recipe>("Recipe_CapeTroll");
		if ((Object)(object)prefab == (Object)null)
		{
			Log.LogWarning((object)"Recipe_CapeTroll not found; Cape of Stank can't be crafted.");
			return;
		}
		ItemDrop component = hidePrefab.GetComponent<ItemDrop>();
		Recipe val = Object.Instantiate<Recipe>(prefab);
		((Object)val).name = "Recipe_CapeOfStank";
		val.m_item = capePrefab.GetComponent<ItemDrop>();
		List<Requirement> list = new List<Requirement>();
		Requirement[] resources = prefab.m_resources;
		foreach (Requirement val2 in resources)
		{
			Requirement val3 = new Requirement();
			val3.m_resItem = (((Object)(object)val2.m_resItem != (Object)null && ((Object)val2.m_resItem).name == "TrollHide") ? component : val2.m_resItem);
			val3.m_amount = val2.m_amount;
			val3.m_amountPerLevel = val2.m_amountPerLevel;
			val3.m_extraAmountOnlyOneIngredient = val2.m_extraAmountOnlyOneIngredient;
			val3.m_upgraderResource = val2.m_upgraderResource;
			val3.m_recover = val2.m_recover;
			list.Add(val3);
			Log.LogInfo((object)("Cape of Stank requires " + val3.m_amount + "x " + (((Object)(object)val3.m_resItem != (Object)null) ? ((Object)val3.m_resItem).name : "?")));
		}
		val.m_resources = list.ToArray();
		ItemManager.Instance.AddRecipe(new CustomRecipe(val, false, false));
	}

	private void CreateMudPrefab()
	{
		//IL_0005: Unknown result type (might be due to invalid IL or missing references)
		//IL_000b: Expected O, but got Unknown
		//IL_0065: Unknown result type (might be due to invalid IL or missing references)
		//IL_0079: Unknown result type (might be due to invalid IL or missing references)
		//IL_0094: Unknown result type (might be due to invalid IL or missing references)
		//IL_00a8: Unknown result type (might be due to invalid IL or missing references)
		//IL_00c3: 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)
		//IL_00f2: Unknown result type (might be due to invalid IL or missing references)
		//IL_0106: 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_0135: Unknown result type (might be due to invalid IL or missing references)
		GameObject val = new GameObject("PoorillaMud");
		val.transform.SetParent(prefabHolder.transform, false);
		ZNetView val2 = val.AddComponent<ZNetView>();
		val2.m_persistent = false;
		val.AddComponent<MudPuddle>();
		if (HasGraphics)
		{
			Material val3 = CreateMudMaterial();
			if ((Object)(object)val3 != (Object)null)
			{
				AddMudBlob(val, val3, new Vector3(0f, 0f, 0f), new Vector3(1.1f, 0.05f, 0.8f));
				AddMudBlob(val, val3, new Vector3(0.55f, 0f, 0.3f), new Vector3(0.38f, 0.045f, 0.3f));
				AddMudBlob(val, val3, new Vector3(-0.5f, 0f, -0.3f), new Vector3(0.32f, 0.04f, 0.26f));
				AddMudBlob(val, val3, new Vector3(0.12f, 0f, -0.55f), new Vector3(0.22f, 0.035f, 0.2f));
				AddMudBlob(val, val3, new Vector3(-0.2f, 0.01f, 0.05f), new Vector3(0.45f, 0.06f, 0.35f));
			}
		}
		PrefabManager.Instance.AddPrefab(val);
		MudPrefab = val;
	}

	private static void AddMudBlob(GameObject parent, Material mat, Vector3 pos, Vector3 scale)
	{
		//IL_0035: Unknown result type (might be due to invalid IL or missing references)
		//IL_0041: Unknown result type (might be due to invalid IL or missing references)
		GameObject val = GameObject.CreatePrimitive((PrimitiveType)0);
		Object.DestroyImmediate((Object)(object)val.GetComponent<Collider>());
		((Object)val).name = "mud";
		val.transform.SetParent(parent.transform, false);
		val.transform.localPosition = pos;
		val.transform.localScale = scale;
		MeshRenderer component = val.GetComponent<MeshRenderer>();
		((Renderer)component).sharedMaterial = mat;
		((Renderer)component).shadowCastingMode = (ShadowCastingMode)0;
	}

	private Material CreateMudMaterial()
	{
		//IL_0014: Unknown result type (might be due to invalid IL or missing references)
		//IL_001a: Expected O, but got Unknown
		//IL_0033: Unknown result type (might be due to invalid IL or missing references)
		//IL_0039: Expected O, but got Unknown
		//IL_0045: Unknown result type (might be due to invalid IL or missing references)
		//IL_0050: Unknown result type (might be due to invalid IL or missing references)
		//IL_00a8: Unknown result type (might be due to invalid IL or missing references)
		Material val;
		if ((Object)(object)bodyMaterial != (Object)null)
		{
			val = new Material(bodyMaterial);
		}
		else
		{
			Shader val2 = Shader.Find("Standard");
			if ((Object)(object)val2 == (Object)null)
			{
				return null;
			}
			val = new Material(val2);
		}
		((Object)val).name = "poorilla_mud";
		val.mainTextureScale = Vector2.one;
		val.mainTextureOffset = Vector2.zero;
		if (val.HasProperty("_MainTex"))
		{
			val.SetTexture("_MainTex", (Texture)(object)MakeMudPuddleTexture(128));
		}
		if (val.HasProperty("_BumpMap"))
		{
			val.SetTexture("_BumpMap", (Texture)null);
		}
		if (val.HasProperty("_Color"))
		{
			val.SetColor("_Color", Color.white);
		}
		if (val.HasProperty("_Glossiness"))
		{
			val.SetFloat("_Glossiness", 0.55f);
		}
		if (val.HasProperty("_Metallic"))
		{
			val.SetFloat("_Metallic", 0f);
		}
		return val;
	}

	private void AddNest()
	{
		//IL_00b6: Unknown result type (might be due to invalid IL or missing references)
		//IL_0161: Unknown result type (might be due to invalid IL or missing references)
		//IL_02b4: Unknown result type (might be due to invalid IL or missing references)
		//IL_02ab: Unknown result type (might be due to invalid IL or missing references)
		//IL_02b9: Unknown result type (might be due to invalid IL or missing references)
		//IL_02c3: Unknown result type (might be due to invalid IL or missing references)
		//IL_02c8: Unknown result type (might be due to invalid IL or missing references)
		//IL_02d9: Unknown result type (might be due to invalid IL or missing references)
		//IL_02f4: Unknown result type (might be due to invalid IL or missing references)
		ZoneManager.OnVanillaLocationsAvailable -= AddNest;
		if (!NestEnabled.Value)
		{
			return;
		}
		if ((Object)(object)adultPrefab == (Object)null)
		{
			Log.LogWarning((object)"Poorilla creature missing; skipping Poorilla Nests.");
			return;
		}
		try
		{
			string text = null;
			foreach (ZoneLocation location in ZoneSystem.instance.m_locations)
			{
				if (location != null && !string.IsNullOrEmpty(location.m_prefabName) && location.m_prefabName.IndexOf("TrollCave", StringComparison.OrdinalIgnoreCase) >= 0)
				{
					Log.LogInfo((object)string.Concat("Found Troll cave location ", location.m_prefabName, " (biome ", location.m_biome, ", quantity ", location.m_quantity, ")"));
					if (text == null || location.m_prefabName == "TrollCave02")
					{
						text = location.m_prefabName;
					}
				}
			}
			if (text == null)
			{
				Log.LogWarning((object)"No Troll cave location found; Poorilla Nests disabled.");
				return;
			}
			CustomLocation val = ZoneManager.Instance.CreateClonedLocation("PoorillaNest", text);
			ZoneLocation zoneLocation = val.ZoneLocation;
			if (zoneLocation != null)
			{
				zoneLocation.m_enable = true;
				zoneLocation.m_biome = (Biome)8;
				zoneLocation.m_quantity = NestQuantity.Value;
				zoneLocation.m_minDistanceFromSimilar = NestMinDistance.Value;
				zoneLocation.m_group = "PoorillaNest";
				zoneLocation.m_prioritized = false;
			}
			GameObject prefab = val.Prefab;
			Location component = prefab.GetComponent<Location>();
			if ((Object)(object)component != (Object)null)
			{
				component.m_discoverLabel = "Poorilla Nest";
			}
			Transform val2 = null;
			CreatureSpawner[] componentsInChildren = prefab.GetComponentsInChildren<CreatureSpawner>(true);
			foreach (CreatureSpawner val3 in componentsInChildren)
			{
				if (!((Object)(object)val3.m_creaturePrefab == (Object)null) && ((Object)val3.m_creaturePrefab).name.IndexOf("Troll", StringComparison.OrdinalIgnoreCase) >= 0)
				{
					val3.m_creaturePrefab = adultPrefab;
					if ((Object)(object)val2 == (Object)null)
					{
						val2 = ((Component)val3).transform;
					}
				}
			}
			if ((Object)(object)val2 == (Object)null)
			{
				Container[] componentsInChildren2 = prefab.GetComponentsInChildren<Container>(true);
				int num = 0;
				if (num < componentsInChildren2.Length)
				{
					Container val4 = componentsInChildren2[num];
					val2 = ((Component)val4).transform;
				}
			}
			if ((Object)(object)eggPrefab != (Object)null)
			{
				GameObject val5 = Object.Instantiate<GameObject>(eggPrefab, prefab.transform);
				((Object)val5).name = "PoorillaEgg";
				val5.transform.position = (((Object)(object)val2 != (Object)null) ? val2.position : prefab.transform.position) + Vector3.up * 0.4f;
				val5.transform.rotation = Quaternion.identity;
				Log.LogInfo((object)string.Concat("Poorilla Egg placed in nest at ", val5.transform.localPosition, ((Object)(object)val2 != (Object)null) ? (" near " + ((Object)val2).name) : ""));
			}
			Log.LogInfo((object)("Poorilla Nest registered (based on " + text + ")."));
		}
		catch (Exception ex)
		{
			Log.LogError((object)("Failed to set up Poorilla Nest: " + ex));
		}
	}

	private void ApplyStats()
	{
		//IL_00ad: Unknown result type (might be due to invalid IL or missing references)
		//IL_00b2: 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_00cc: Unknown result type (might be due to invalid IL or missing references)
		//IL_00d2: 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)
		//IL_00f0: Unknown result type (might be due to invalid IL or missing references)
		//IL_00f1: Unknown result type (might be due to invalid IL or missing references)
		foreach (CreatureInfo creature in creatures)
		{
			if ((Object)(object)creature.Humanoid == (Object)null)
			{
				continue;
			}
			((Character)creature.Humanoid).m_health = creature.Health.Value;
			((Character)creature.Humanoid).m_speed = creature.Speed * SpeedMultiplier.Value;
			((Character)creature.Humanoid).m_walkSpeed = creature.WalkSpeed * SpeedMultiplier.Value;
			((Character)creature.Humanoid).m_runSpeed = creature.RunSpeed * SpeedMultiplier.Value;
			foreach (AttackInfo attack in creature.Attacks)
			{
				DamageTypes damages = attack.Damages;
				((DamageTypes)(ref damages)).Modify(creature.Damage.Value);
				attack.Shared.m_damages = damages;
				DamageTypes damagesPerLevel = attack.DamagesPerLevel;
				((DamageTypes)(ref damagesPerLevel)).Modify(creature.Damage.Value);
				attack.Shared.m_damagesPerLevel = damagesPerLevel;
			}
		}
		if ((Object)(object)eggPrefab != (Object)null)
		{
			SharedData shared = eggPrefab.GetComponent<ItemDrop>().m_itemData.m_shared;
			shared.m_teleportable = EggTeleportable.Value;
			shared.m_weight = EggWeight.Value;
			EggGrow component = eggPrefab.GetComponent<EggGrow>();
			if ((Object)(object)component != (Object)null)
			{
				component.m_growTime = Mathf.Max(0.01f, HatchDays.Value) * 1800f;
				component.m_requireUnderRoof = RequireRoof.Value;
			}
		}
		if ((Object)(object)capePrefab != (Object)null)
		{
			capePrefab.GetComponent<ItemDrop>().m_itemData.m_shared.m_movementModifier = CapeSpeedBonus.Value;
		}
		float staminaRegenMultiplier = Mathf.Clamp01(1f - StaminaRegenPenalty.Value);
		if ((Object)(object)MudStinkSE != (Object)null)
		{
			((StatusEffect)MudStinkSE).m_ttl = StinkDuration.Value;
			MudStinkSE.m_staminaRegenMultiplier = staminaRegenMultiplier;
		}
		if ((Object)(object)CapeStinkSE != (Object)null)
		{
			((StatusEffect)CapeStinkSE).m_ttl = 0f;
			CapeStinkSE.m_staminaRegenMultiplier = staminaRegenMultiplier;
		}
	}

	internal static void MakeStinky(Player player)
	{
		if (!((Object)(object)player == (Object)null) && !((Object)(object)MudStinkSE == (Object)null))
		{
			SEMan sEMan = ((Character)player).GetSEMan();
			if (!((Object)(object)CapeStinkSE != (Object)null) || !sEMan.HaveStatusEffect(((StatusEffect)CapeStinkSE).NameHash()))
			{
				sEMan.AddStatusEffect(((StatusEffect)MudStinkSE).NameHash(), true, 0, 0f, (short)0);
			}
		}
	}

	internal static bool IsStinky(Player player)
	{
		SEMan sEMan = ((Character)player).GetSEMan();
		if (!((Object)(object)MudStinkSE != (Object)null) || !sEMan.HaveStatusEffect(((StatusEffect)MudStinkSE).NameHash()))
		{
			if ((Object)(object)CapeStinkSE != (Object)null)
			{
				return sEMan.HaveStatusEffect(((StatusEffect)CapeStinkSE).NameHash());
			}
			return false;
		}
		return true;
	}

	private void Update()
	{
		Player localPlayer = Player.m_localPlayer;
		if ((Object)(object)localPlayer == (Object)null || (Object)(object)ZNet.instance == (Object)null)
		{
			return;
		}
		stinkBroadcastTimer -= Time.deltaTime;
		if (stinkBroadcastTimer > 0f)
		{
			return;
		}
		stinkBroadcastTimer = 2f;
		if (IsStinky(localPlayer))
		{
			ZNetView component = ((Component)localPlayer).GetComponent<ZNetView>();
			if ((Object)(object)component != (Object)null && component.IsValid() && component.IsOwner())
			{
				component.GetZDO().Set("poorilla_stinky", (float)ZNet.instance.GetTimeSeconds());
			}
		}
	}

	internal static string AddHatchProgress(EggGrow egg, string text)
	{
		if ((Object)(object)egg == (Object)null || string.IsNullOrEmpty(text) || (Object)(object)ZNet.instance == (Object)null)
		{
			return text;
		}
		ZNetView component = ((Component)egg).GetComponent<ZNetView>();
		if ((Object)(object)component == (Object)null || !component.IsValid())
		{
			return text;
		}
		float num = component.GetZDO().GetFloat(ZDOVars.s_growStart, 0f);
		string text2;
		if (num > 0f)
		{
			float num2 = Mathf.Clamp01((float)(ZNet.instance.GetTimeSeconds() - (double)num) / Mathf.Max(1f, egg.m_growTime));
			text2 = " <color=orange>" + Mathf.FloorToInt(num2 * 100f) + "% hatched</color>";
		}
		else
		{
			text2 = " <color=#a0a0a0>(keep it next to a fire)</color>";
		}
		int num3 = text.IndexOf('\n');
		if (num3 < 0)
		{
			return text + text2;
		}
		return text.Insert(num3, text2);
	}

	private void Recolor(GameObject root, Palette palette)
	{
		if (!HasGraphics)
		{
			return;
		}
		Renderer[] componentsInChildren = root.GetComponentsInChildren<Renderer>(true);
		foreach (Renderer val in componentsInChildren)
		{
			if (val is ParticleSystemRenderer)
			{
				continue;
			}
			Material[] sharedMaterials = val.sharedMaterials;
			for (int j = 0; j < sharedMaterials.Length; j++)
			{
				if ((Object)(object)sharedMaterials[j] != (Object)null)
				{
					sharedMaterials[j] = GetRecoloredMaterial(sharedMaterials[j], palette);
				}
			}
			val.sharedMaterials = sharedMaterials;
		}
	}

	private Material GetRecoloredMaterial(Material src, Palette palette)
	{
		//IL_002f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0035: Expected O, but got Unknown
		//IL_00ae: 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)
		string key = ((Object)src).GetInstanceID() + "_" + palette.Name;
		if (recolored.TryGetValue(key, out var value))
		{
			return value;
		}
		value = new Material(src);
		((Object)value).name = ((Object)src).name + "_poorilla_" + palette.Name;
		if (value.HasProperty("_MainTex") && (Object)(object)value.GetTexture("_MainTex") != (Object)null)
		{
			Texture2D val = ReadTexture(value.GetTexture("_MainTex"), 2048);
			RecolorPixels(val, palette, mipmaps: true);
			value.SetTexture("_MainTex", (Texture)(object)val);
		}
		if (value.HasProperty("_Color"))
		{
			value.SetColor("_Color", Color.white);
		}
		if (value.HasProperty("_EmissionColor"))
		{
			value.SetColor("_EmissionColor", Color.black);
		}
		if (value.HasProperty("_Glossiness"))
		{
			value.SetFloat("_Glossiness", 0.3f);
		}
		if ((Object)(object)bodyMaterial == (Object)null && palette == Palette.Mud)
		{
			bodyMaterial = value;
		}
		recolored[key] = value;
		return value;
	}

	private static Sprite RecolorSprite(Sprite src, Palette palette)
	{
		//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_0082: Unknown result type (might be due to invalid IL or missing references)
		//IL_0089: Expected O, but got Unknown
		//IL_00a9: Unknown result type (might be due to invalid IL or missing references)
		//IL_00e3: Unknown result type (might be due to invalid IL or missing references)
		//IL_00f2: Unknown result type (might be due to invalid IL or missing references)
		if ((Object)(object)src == (Object)null || (Object)(object)src.texture == (Object)null)
		{
			return src;
		}
		Rect textureRect = src.textureRect;
		int num = Mathf.Max(1, Mathf.RoundToInt(((Rect)(ref textureRect)).width));
		int num2 = Mathf.Max(1, Mathf.RoundToInt(((Rect)(ref textureRect)).height));
		RenderTexture temporary = RenderTexture.GetTemporary(((Texture)src.texture).width, ((Texture)src.texture).height, 0, (RenderTextureFormat)0, (RenderTextureReadWrite)2);
		Graphics.Blit((Texture)(object)src.texture, temporary);
		RenderTexture active = RenderTexture.active;
		RenderTexture.active = temporary;
		Texture2D val = new Texture2D(num, num2, (TextureFormat)4, false);
		val.ReadPixels(new Rect((float)Mathf.RoundToInt(((Rect)(ref textureRect)).x), (float)Mathf.RoundToInt(((Rect)(ref textureRect)).y), (float)num, (float)num2), 0, 0);
		RenderTexture.active = active;
		RenderTexture.ReleaseTemporary(temporary);
		((Texture)val).wrapMode = (TextureWrapMode)1;
		RecolorPixels(val, palette, mipmaps: false);
		Sprite val2 = Sprite.Create(val, new Rect(0f, 0f, (float)num, (float)num2), new Vector2(0.5f, 0.5f), src.pixelsPerUnit);
		((Object)val2).name = ((Object)src).name + "_poorilla";
		return val2;
	}

	private static Texture2D ReadTexture(Texture src, int maxSize)
	{
		//IL_006d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0074: Expected O, but got Unknown
		//IL_0084: Unknown result type (might be due to invalid IL or missing references)
		float num = Mathf.Min(1f, (float)maxSize / (float)Mathf.Max(src.width, src.height));
		int num2 = Mathf.Max(1, Mathf.RoundToInt((float)src.width * num));
		int num3 = Mathf.Max(1, Mathf.RoundToInt((float)src.height * num));
		RenderTexture temporary = RenderTexture.GetTemporary(num2, num3, 0, (RenderTextureFormat)0, (RenderTextureReadWrite)2);
		Graphics.Blit(src, temporary);
		RenderTexture active = RenderTexture.active;
		RenderTexture.active = temporary;
		Texture2D val = new Texture2D(num2, num3, (TextureFormat)4, true);
		val.ReadPixels(new Rect(0f, 0f, (float)num2, (float)num3), 0, 0);
		RenderTexture.active = active;
		RenderTexture.ReleaseTemporary(temporary);
		((Object)val).name = ((Object)src).name + "_poorilla";
		return val;
	}

	private static void RecolorPixels(Texture2D tex, Palette pal, bool mipmaps)
	{
		//IL_004a: Unknown result type (might be due to invalid IL or missing references)
		//IL_004f: 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_00d1: Unknown result type (might be due to invalid IL or missing references)
		//IL_00de: Unknown result type (might be due to invalid IL or missing references)
		//IL_00aa: Unknown result type (might be due to invalid IL or missing references)
		//IL_00b0: Unknown result type (might be due to invalid IL or missing references)
		//IL_00c3: Unknown result type (might be due to invalid IL or missing references)
		//IL_00e3: Unknown result type (might be due to invalid IL or missing references)
		//IL_014b: Unknown result type (might be due to invalid IL or missing references)
		//IL_014e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0161: Unknown result type (might be due to invalid IL or missing references)
		//IL_0179: Unknown result type (might be due to invalid IL or missing references)
		//IL_017e: Unknown result type (might be due to invalid IL or missing references)
		//IL_01f6: Unknown result type (might be due to invalid IL or missing references)
		//IL_01fb: Unknown result type (might be due to invalid IL or missing references)
		//IL_018b: Unknown result type (might be due to invalid IL or missing references)
		//IL_018e: Unknown result type (might be due to invalid IL or missing references)
		//IL_01a6: 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)
		int width = ((Texture)tex).width;
		int height = ((Texture)tex).height;
		float num = 256f / (float)width;
		float num2 = 256f / (float)height;
		Color32[] pixels = tex.GetPixels32();
		for (int i = 0; i < height; i++)
		{
			for (int j = 0; j < width; j++)
			{
				int num3 = i * width + j;
				Color32 val = pixels[num3];
				float num4 = (0.3f * (float)(int)val.r + 0.59f * (float)(int)val.g + 0.11f * (float)(int)val.b) / 255f;
				num4 = Mathf.Clamp01((num4 - 0.5f) * 1.3f + 0.5f);
				Color val2 = ((num4 < 0.5f) ? Color.Lerp(pal.Dark, pal.Mid, num4 * 2f) : Color.Lerp(pal.Mid, pal.Light, (num4 - 0.5f) * 2f));
				float num5 = Mathf.PerlinNoise((float)j * num * 0.045f + 13.7f, (float)i * num2 * 0.045f + 4.2f) * 0.65f + Mathf.PerlinNoise((float)j * num * 0.18f + 91.1f, (float)i * num2 * 0.18f + 27.9f) * 0.35f;
				if (num5 > 0.58f)
				{
					val2 = Color.Lerp(val2, pal.Caked * (0.7f + num4 * 0.5f), Mathf.Clamp01((num5 - 0.58f) * 5f));
				}
				else if (num5 < 0.34f)
				{
					val2 = Color.Lerp(val2, pal.Wet, Mathf.Clamp01((0.34f - num5) * 4f));
				}
				ref Color32 reference = ref pixels[num3];
				reference = new Color32((byte)(Mathf.Clamp01(val2.r) * 255f), (byte)(Mathf.Clamp01(val2.g) * 255f), (byte)(Mathf.Clamp01(val2.b) * 255f), val.a);
			}
		}
		tex.SetPixels32(pixels);
		tex.Apply(mipmaps);
	}

	private static Texture2D MakeMudPuddleTexture(int size)
	{
		//IL_0004: Unknown result type (might be due to invalid IL or missing references)
		//IL_000a: Expected O, but got Unknown
		//IL_006b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0075: Unknown result type (might be due to invalid IL or missing references)
		//IL_007c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0081: Unknown result type (might be due to invalid IL or missing references)
		//IL_00bd: Unknown result type (might be due to invalid IL or missing references)
		//IL_00bf: 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_008c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0093: Unknown result type (might be due to invalid IL or missing references)
		//IL_00ab: Unknown result type (might be due to invalid IL or missing references)
		//IL_00b0: Unknown result type (might be due to invalid IL or missing references)
		Texture2D val = new Texture2D(size, size, (TextureFormat)4, true);
		Color32[] array = (Color32[])(object)new Color32[size * size];
		for (int i = 0; i < size; i++)
		{
			for (int j = 0; j < size; j++)
			{
				float num = Mathf.PerlinNoise((float)j * 0.08f, (float)i * 0.08f) * 0.6f + Mathf.PerlinNoise((float)j * 0.3f + 50f, (float)i * 0.3f + 20f) * 0.4f;
				Color val2 = Color.Lerp(Palette.Mud.Wet, Palette.Mud.Mid, num);
				if (num > 0.62f)
				{
					val2 = Color.Lerp(val2, Palette.Mud.Light, Mathf.Clamp01((num - 0.62f) * 3f));
				}
				ref Color32 reference = ref array[i * size + j];
				reference = Color32.op_Implicit(val2);
			}
		}
		val.SetPixels32(array);
		val.Apply(true);
		((Object)val).name = "poorilla_mud";
		return val;
	}
}
public class PoorillaSniffer : MonoBehaviour
{
	private static readonly FieldInfo TargetField = AccessTools.Field(typeof(MonsterAI), "m_targetCreature");

	private static readonly FieldInfo SensedField = AccessTools.Field(typeof(MonsterAI), "m_timeSinceSensedTargetCreature");

	private ZNetView nview;

	private MonsterAI ai;

	private Character character;

	private float timer;

	private void Awake()
	{
		nview = ((Component)this).GetComponent<ZNetView>();
		ai = ((Component)this).GetComponent<MonsterAI>();
		character = ((Component)this).GetComponent<Character>();
		timer = Random.Range(1f, 3f);
	}

	private void Update()
	{
		//IL_00f2: Unknown result type (might be due to invalid IL or missing references)
		//IL_00fd: Unknown result type (might be due to invalid IL or missing references)
		timer -= Time.deltaTime;
		if (timer > 0f)
		{
			return;
		}
		timer = 2f;
		if ((Object)(object)nview == (Object)null || !nview.IsValid() || !nview.IsOwner() || (Object)(object)ai == (Object)null || (Object)(object)character == (Object)null || character.IsTamed() || (Object)(object)ZNet.instance == (Object)null || TargetField == null || TargetField.GetValue(ai) != null)
		{
			return;
		}
		double timeSeconds = ZNet.instance.GetTimeSeconds();
		Player val = null;
		float num = PoorillaPlugin.AttractRange.Value;
		foreach (Player allPlayer in Player.GetAllPlayers())
		{
			if ((Object)(object)allPlayer == (Object)null || ((Character)allPlayer).IsDead())
			{
				continue;
			}
			float num2 = Vector3.Distance(((Component)allPlayer).transform.position, ((Component)this).transform.position);
			if (num2 > num)
			{
				continue;
			}
			ZNetView component = ((Component)allPlayer).GetComponent<ZNetView>();
			if (!((Object)(object)component == (Object)null) && component.IsValid())
			{
				float num3 = component.GetZDO().GetFloat("poorilla_stinky", 0f);
				if (num3 > 0f && timeSeconds - (double)num3 < 6.0)
				{
					val = allPlayer;
					num = num2;
				}
			}
		}
		if (!((Object)(object)val == (Object)null))
		{
			TargetField.SetValue(ai, val);
			if (SensedField != null)
			{
				SensedField.SetValue(ai, 0f);
			}
			((BaseAI)ai).Alert();
		}
	}
}
public class PoorillaMudTrail : MonoBehaviour
{
	private static int groundMask;

	private ZNetView nview;

	private Character character;

	private float timer;

	private void Awake()
	{
		nview = ((Component)this).GetComponent<ZNetView>();
		character = ((Component)this).GetComponent<Character>();
		ResetTimer();
		if (groundMask == 0)
		{
			groundMask = LayerMask.GetMask(new string[5] { "Default", "static_solid", "Default_small", "terrain", "piece" });
		}
	}

	private void ResetTimer()
	{
		float num = Mathf.Max(5f, PoorillaPlugin.MudIntervalMin.Value);
		float num2 = Mathf.Max(num, PoorillaPlugin.MudIntervalMax.Value);
		timer = Random.Range(num, num2);
	}

	private void Update()
	{
		//IL_00a5: Unknown result type (might be due to invalid IL or missing references)
		//IL_00aa: 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_00d5: Unknown result type (might be due to invalid IL or missing references)
		//IL_00d6: Unknown result type (might be due to invalid IL or missing references)
		//IL_00db: Unknown result type (might be due to invalid IL or missing references)
		//IL_0106: 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_0111: Unknown result type (might be due to invalid IL or missing references)
		//IL_0116: Unknown result type (might be due to invalid IL or missing references)
		//IL_011b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0134: Unknown result type (might be due to invalid IL or missing references)
		//IL_013b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0140: Unknown result type (might be due to invalid IL or missing references)
		//IL_015e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0163: Unknown result type (might be due to invalid IL or missing references)
		//IL_0168: Unknown result type (might be due to invalid IL or missing references)
		//IL_0170: 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_0181: Unknown result type (might be due to invalid IL or missing references)
		//IL_0186: Unknown result type (might be due to invalid IL or missing references)
		//IL_018b: Unknown result type (might be due to invalid IL or missing references)
		timer -= Time.deltaTime;
		if (timer > 0f)
		{
			return;
		}
		ResetTimer();
		if (!PoorillaPlugin.MudEnabled.Value || (Object)(object)PoorillaPlugin.MudPrefab == (Object)null || (Object)(object)nview == (Object)null || !nview.IsValid() || !nview.IsOwner() || (Object)(object)character == (Object)null || character.IsDead() || !character.IsOnGround() || character.InWater())
		{
			return;
		}
		Vector3 position = ((Component)this).transform.position;
		foreach (MudPuddle item in MudPuddle.Active)
		{
			if ((Object)(object)item != (Object)null)
			{
				Vector3 val = ((Component)item).transform.position - position;
				if (((Vector3)(ref val)).sqrMagnitude < 4f)
				{
					return;
				}
			}
		}
		RaycastHit val2 = default(RaycastHit);
		if (Physics.Raycast(position + Vector3.up * 0.5f, Vector3.down, ref val2, 2f, groundMask))
		{
			Quaternion val3 = Quaternion.FromToRotation(Vector3.up, ((RaycastHit)(ref val2)).normal) * Quaternion.Euler(0f, Random.Range(0f, 360f), 0f);
			Object.Instantiate<GameObject>(PoorillaPlugin.MudPrefab, ((RaycastHit)(ref val2)).point + ((RaycastHit)(ref val2)).normal * 0.02f, val3);
		}
	}
}
public class MudPuddle : MonoBehaviour
{
	public static readonly List<MudPuddle> Active = new List<MudPuddle>();

	private ZNetView nview;

	private Vector3 baseScale;

	private float nextCheck;

	private void Awake()
	{
		//IL_0013: Unknown result type (might be due to invalid IL or missing references)
		//IL_0018: Unknown result type (might be due to invalid IL or missing references)
		nview = ((Component)this).GetComponent<ZNetView>();
		baseScale = ((Component)this).transform.localScale;
	}

	private void OnEnable()
	{
		Active.Add(this);
	}

	private void OnDisable()
	{
		Active.Remove(this);
	}

	private void Update()
	{
		//IL_00e7: Unknown result type (might be due to invalid IL or missing references)
		//IL_00fd: Unknown result type (might be due to invalid IL or missing references)
		//IL_0129: Unknown result type (might be due to invalid IL or missing references)
		//IL_0134: Unknown result type (might be due to invalid IL or missing references)
		//IL_0139: Unknown result type (might be due to invalid IL or missing references)
		//IL_013e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0161: Unknown result type (might be due to invalid IL or missing references)
		//IL_0166: Unknown result type (might be due to invalid IL or missing references)
		//IL_017a: Unknown result type (might be due to invalid IL or missing references)
		if (Time.time < nextCheck)
		{
			return;
		}
		nextCheck = Time.time + 0.5f;
		if ((Object)(object)nview == (Object)null || !nview.IsValid() || (Object)(object)ZNet.instance == (Object)null)
		{
			return;
		}
		ZDO zDO = nview.GetZDO();
		double timeSeconds = ZNet.instance.GetTimeSeconds();
		float num = zDO.GetFloat("poorilla_mud_spawn", 0f);
		if (num <= 0f)
		{
			if (nview.IsOwner())
			{
				zDO.Set("poorilla_mud_spawn", (float)timeSeconds);
			}
			return;
		}
		float num2 = Mathf.Max(10f, PoorillaPlugin.MudLifetime.Value);
		float num3 = (float)(timeSeconds - (double)num);
		if (num3 >= num2)
		{
			if (nview.IsOwner())
			{
				nview.Destroy();
			}
			return;
		}
		float num4 = Mathf.Clamp01((num2 - num3) / (num2 * 0.2f));
		((Component)this).transform.localScale = baseScale * Mathf.Lerp(0.35f, 1f, num4);
		Player localPlayer = Player.m_localPlayer;
		if ((Object)(object)localPlayer == (Object)null || ((Character)localPlayer).IsDead())
		{
			return;
		}
		Vector3 val = ((Component)localPlayer).transform.position - ((Component)this).transform.position;
		if (Mathf.Abs(val.y) < 0.6f)
		{
			Vector2 val2 = new Vector2(val.x, val.z);
			if (((Vector2)(ref val2)).magnitude < 0.75f * ((Component)this).transform.localScale.x)
			{
				PoorillaPlugin.MakeStinky(localPlayer);
			}
		}
	}
}
[HarmonyPatch(typeof(EggGrow), "GetHoverText")]
internal static class EggGrowHoverPatch
{
	internal static bool Inside;

	private static void Prefix()
	{
		Inside = true;
	}

	private static void Postfix(EggGrow __instance, ref string __result)
	{
		__result = PoorillaPlugin.AddHatchProgress(__instance, __result);
	}

	private static void Finalizer()
	{
		Inside = false;
	}
}
[HarmonyPatch(typeof(ItemDrop), "GetHoverText")]
internal static class ItemDropHoverPatch
{
	private static void Postfix(ItemDrop __instance, ref string __result)
	{
		if (!EggGrowHoverPatch.Inside)
		{
			EggGrow component = ((Component)__instance).GetComponent<EggGrow>();
			if ((Object)(object)component != (Object)null)
			{
				__result = component.GetHoverText();
			}
		}
	}
}