using 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;
}
}
}
}