Please disclose if your mod was created primarily using AI tools by adding the 'AI Generated' category. Failing to do so may result in the mod being removed from Thunderstore.
Decompiled source of BiomeCreatureSpeedModifier v1.5.2
BepInEx/plugins/BiomeCreatureSpeedModifier.dll
Decompiled 4 months agousing System; using System.Collections; using System.Collections.Generic; using System.Diagnostics; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using System.Runtime.Versioning; using BepInEx; using BepInEx.Configuration; using UnityEngine; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: AssemblyTitle("ValheimDeerSpeed")] [assembly: AssemblyDescription("")] [assembly: AssemblyConfiguration("")] [assembly: AssemblyCompany("")] [assembly: AssemblyProduct("ValheimDeerSpeed")] [assembly: AssemblyCopyright("Copyright © 2025")] [assembly: AssemblyTrademark("")] [assembly: ComVisible(false)] [assembly: Guid("dcfa2116-3b7e-4cb3-a9d2-88ee2a6a8895")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: TargetFramework(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")] [assembly: AssemblyVersion("1.0.0.0")] [BepInPlugin("ken.valheim.creaturespeed", "Biome Creature Speed Modifier", "1.5.2")] public class CreatureSpeedMod : BaseUnityPlugin { private class CreatureData { public float BaseRun; public float BaseWalk; public float BaseAttackValue; public ConfigEntry<float> MoveSpeed; public ConfigEntry<float> AttackSpeed; } [CompilerGenerated] private sealed class <Initialize>d__3 : IEnumerator<object>, IDisposable, IEnumerator { private int <>1__state; private object <>2__current; public CreatureSpeedMod <>4__this; object IEnumerator<object>.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public <Initialize>d__3(int <>1__state) { this.<>1__state = <>1__state; } [DebuggerHidden] void IDisposable.Dispose() { <>1__state = -2; } private bool MoveNext() { int num = <>1__state; CreatureSpeedMod creatureSpeedMod = <>4__this; switch (num) { default: return false; case 0: <>1__state = -1; break; case 1: <>1__state = -1; break; } if ((Object)(object)ZNetScene.instance == (Object)null || ZNetScene.instance.m_prefabs == null) { <>2__current = null; <>1__state = 1; return true; } creatureSpeedMod.RegisterAllCreatures(); creatureSpeedMod.ApplyAll(); ((BaseUnityPlugin)creatureSpeedMod).Logger.LogInfo((object)$"Creature Speed Modifier loaded ({creatureSpeedMod.creatures.Count} creatures)"); return false; } bool IEnumerator.MoveNext() { //ILSpy generated this explicit interface implementation from .override directive in MoveNext return this.MoveNext(); } [DebuggerHidden] void IEnumerator.Reset() { throw new NotSupportedException(); } } private readonly Dictionary<string, CreatureData> creatures = new Dictionary<string, CreatureData>(); private void Awake() { ((MonoBehaviour)this).StartCoroutine(Initialize()); } [IteratorStateMachine(typeof(<Initialize>d__3))] private IEnumerator Initialize() { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new <Initialize>d__3(0) { <>4__this = this }; } private void RegisterAllCreatures() { //IL_00cd: Unknown result type (might be due to invalid IL or missing references) //IL_00d7: Expected O, but got Unknown //IL_011f: Unknown result type (might be due to invalid IL or missing references) //IL_0129: Expected O, but got Unknown foreach (GameObject prefab in ZNetScene.instance.m_prefabs) { if ((Object)(object)prefab == (Object)null) { continue; } Character component = prefab.GetComponent<Character>(); if ((Object)(object)component == (Object)null || component.IsPlayer()) { continue; } string prefabName = ((Object)prefab).name; if (!creatures.ContainsKey(prefabName)) { string text = (component.m_boss ? "Bosses" : "Creatures"); ConfigEntry<float> val = ((BaseUnityPlugin)this).Config.Bind<float>(text, prefabName + "MoveSpeed", 1f, new ConfigDescription("Movement speed multiplier for " + prefabName, (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.1f, 5f), Array.Empty<object>())); ConfigEntry<float> val2 = ((BaseUnityPlugin)this).Config.Bind<float>(text, prefabName + "AttackSpeed", 1f, new ConfigDescription("Attack speed multiplier for " + prefabName + "\nHigher = more frequent attacks (if supported)", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.1f, 5f), Array.Empty<object>())); CreatureData value = new CreatureData { MoveSpeed = val, AttackSpeed = val2 }; creatures[prefabName] = value; val.SettingChanged += delegate { ApplyCreature(prefabName); }; val2.SettingChanged += delegate { ApplyCreature(prefabName); }; } } } private void ApplyAll() { foreach (string key in creatures.Keys) { ApplyCreature(key); } } private void ApplyCreature(string prefabName) { GameObject prefab = ZNetScene.instance.GetPrefab(prefabName); if ((Object)(object)prefab == (Object)null) { return; } Character component = prefab.GetComponent<Character>(); if (!((Object)(object)component == (Object)null)) { CreatureData creatureData = creatures[prefabName]; if (creatureData.BaseRun == 0f && creatureData.BaseWalk == 0f) { creatureData.BaseRun = component.m_runSpeed; creatureData.BaseWalk = component.m_walkSpeed; } component.m_runSpeed = creatureData.BaseRun * creatureData.MoveSpeed.Value; component.m_walkSpeed = creatureData.BaseWalk * creatureData.MoveSpeed.Value; ApplyAttackSpeed(component, creatureData); } } private void ApplyAttackSpeed(Character character, CreatureData data) { MonoBehaviour component = (MonoBehaviour)(object)((Component)character).GetComponent<MonsterAI>(); if ((Object)(object)component == (Object)null) { return; } string[] array = new string[3] { "m_attackInterval", "m_attackCooldown", "m_attackTimer" }; foreach (string name in array) { FieldInfo field = ((object)component).GetType().GetField(name, BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); if (!(field == null) && !(field.FieldType != typeof(float))) { float baseAttackValue = (float)field.GetValue(component); if (data.BaseAttackValue == 0f) { data.BaseAttackValue = baseAttackValue; } float num = Mathf.Max(0.01f, data.AttackSpeed.Value); field.SetValue(component, data.BaseAttackValue / num); break; } } } }