Please disclose if any significant portion of your mod was created 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 Gunworks v0.1.0
plugins/Gunworks/Gunworks.dll
Decompiled 15 hours ago
The result has been truncated due to the large size, download it to view full contents!
using System; using System.Collections.Generic; using System.Diagnostics; using System.IO; using System.Linq; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using System.Security; using System.Security.Permissions; using System.Text; using BepInEx; using BepInEx.Configuration; using BepInEx.Logging; using HarmonyLib; using Microsoft.CodeAnalysis; using TMPro; using UnityEngine; using UnityEngine.Audio; using UnityEngine.EventSystems; using UnityEngine.Events; using UnityEngine.Rendering; using UnityEngine.UI; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: IgnoresAccessChecksTo("assembly_valheim")] [assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("0.0.0.0")] [module: UnverifiableCode] [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 Gunworks { internal sealed class Ammo { public const string GiveRpc = "gw_give"; private readonly IModHost host; private readonly float scale; private Recipe recipe; public AmmoSpec Spec { get; } public GameObject Item { get; private set; } public string ItemName => Spec.Name; public Ammo(IModHost host, AmmoSpec spec, float scale) { this.host = host; this.scale = scale; Spec = spec; } public GameObject Ensure(IEnumerable<GameObject> vanilla, Transform holder, Dictionary<string, Material> materials) { //IL_010b: Unknown result type (might be due to invalid IL or missing references) //IL_0110: Unknown result type (might be due to invalid IL or missing references) //IL_011c: Unknown result type (might be due to invalid IL or missing references) //IL_012e: 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_013f: Unknown result type (might be due to invalid IL or missing references) //IL_0149: Unknown result type (might be due to invalid IL or missing references) //IL_018d: Unknown result type (might be due to invalid IL or missing references) //IL_0192: Unknown result type (might be due to invalid IL or missing references) //IL_0196: Unknown result type (might be due to invalid IL or missing references) //IL_01a1: Unknown result type (might be due to invalid IL or missing references) //IL_01b1: Unknown result type (might be due to invalid IL or missing references) //IL_01b6: Unknown result type (might be due to invalid IL or missing references) //IL_01ba: Unknown result type (might be due to invalid IL or missing references) //IL_01c5: Unknown result type (might be due to invalid IL or missing references) //IL_01ff: Unknown result type (might be due to invalid IL or missing references) //IL_0206: Expected O, but got Unknown //IL_022d: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)Item != (Object)null) { return Item; } GameObject val = vanilla.FirstOrDefault((Func<GameObject, bool>)((GameObject go) => (Object)(object)go != (Object)null && ((Object)go).name == Spec.Look)); if ((Object)(object)val == (Object)null) { return null; } GameObject val2 = Object.Instantiate<GameObject>(val, holder, false); ((Object)val2).name = Spec.Prefab; LODGroup[] componentsInChildren = val2.GetComponentsInChildren<LODGroup>(true); for (int num = 0; num < componentsInChildren.Length; num++) { Object.DestroyImmediate((Object)(object)componentsInChildren[num]); } Renderer[] componentsInChildren2 = val2.GetComponentsInChildren<Renderer>(true); foreach (Renderer val3 in componentsInChildren2) { Object.DestroyImmediate((Object)(((Object)(object)((Component)val3).gameObject == (Object)(object)val2) ? ((object)val3) : ((object)((Component)val3).gameObject))); } Collider[] componentsInChildren3 = val2.GetComponentsInChildren<Collider>(true); for (int num = 0; num < componentsInChildren3.Length; num++) { Object.DestroyImmediate((Object)(object)componentsInChildren3[num]); } Model model = Files.Mesh(host, Spec.Model); GameObject val4 = new GameObject("look") { layer = val2.layer }; val4.transform.SetParent(val2.transform, false); val4.transform.localScale = Vector3.one * scale; val4.AddComponent<MeshFilter>().sharedMesh = model.mesh; ((Renderer)val4.AddComponent<MeshRenderer>()).sharedMaterials = model.slots.Select((string slot) => materials[slot]).ToArray(); BoxCollider obj = val2.AddComponent<BoxCollider>(); Bounds bounds = model.mesh.bounds; obj.center = ((Bounds)(ref bounds)).center * scale; bounds = model.mesh.bounds; obj.size = ((Bounds)(ref bounds)).size * scale; ItemDrop component = val2.GetComponent<ItemDrop>(); SharedData val5 = (SharedData)AccessTools.Method(typeof(object), "MemberwiseClone", (Type[])null, (Type[])null).Invoke(component.m_itemData.m_shared, null); val5.m_name = Spec.Name; val5.m_description = Spec.Description; val5.m_itemType = (ItemType)1; val5.m_weight = Spec.Weight; val5.m_maxStackSize = Spec.MaxStack; val5.m_teleportable = true; val5.m_icons = (Sprite[])(object)new Sprite[1] { Files.Icon(host, Spec.Icon) }; component.m_itemData.m_shared = val5; component.m_itemData.m_stack = 1; Item = val2; Renew(val5); return val2; } private void Renew(SharedData shared) { Player localPlayer = Player.m_localPlayer; if ((Object)(object)localPlayer == (Object)null) { return; } foreach (ItemData item in from i in ((Humanoid)localPlayer).GetInventory().GetAllItems() where i.m_shared.m_name == shared.m_name select i) { item.m_shared = shared; item.m_dropPrefab = Item; } } public void Register(ObjectDB db, CraftingStation station) { if ((Object)(object)Item == (Object)null) { return; } if (!db.m_items.Contains(Item)) { db.m_items.RemoveAll((GameObject go) => (Object)(object)go != (Object)null && ((Object)go).name == ((Object)Item).name); db.m_items.Add(Item); db.UpdateRegisters(); } if ((Object)(object)recipe == (Object)null) { recipe = ScriptableObject.CreateInstance<Recipe>(); ((Object)recipe).name = "Recipe_" + Spec.Prefab; recipe.m_item = Item.GetComponent<ItemDrop>(); recipe.m_amount = 1; } recipe.m_craftingStation = station; recipe.m_resources = Guns.Costs(host, db, Spec.Cost(), Spec.Name, recover: false); if (!db.m_recipes.Contains(recipe)) { db.m_recipes.Add(recipe); } } public void Unload() { ObjectDB instance = ObjectDB.instance; if ((Object)(object)instance != (Object)null) { if ((Object)(object)Item != (Object)null && instance.m_items.Remove(Item)) { instance.UpdateRegisters(); } if ((Object)(object)recipe != (Object)null) { instance.m_recipes.Remove(recipe); } } Item = null; recipe = null; } public static void RegisterGive() { if (ZRoutedRpc.instance != null) { Guns.UnregisterRpc("gw_give"); ZRoutedRpc.instance.Register<string, int>("gw_give", (Action<long, string, int>)OnGive); } } private static void OnGive(long sender, string prefab, int count) { Player localPlayer = Player.m_localPlayer; GameObject val = (((Object)(object)ObjectDB.instance != (Object)null) ? ObjectDB.instance.GetItemPrefab(prefab) : null); if (!((Object)(object)localPlayer == (Object)null) && !((Object)(object)val == (Object)null)) { bool flag = ((Humanoid)localPlayer).GetInventory().AddItem(val, count); string name = val.GetComponent<ItemDrop>().m_itemData.m_shared.m_name; ((Character)localPlayer).Message((MessageType)2, flag ? $"{count} {name}" : ("No room for " + name), 0, (Sprite)null, false); Guns.Log.LogInfo((object)string.Format("gunworks gave {0} {1}, {2}", count, prefab, flag ? "in the inventory" : "no room")); } } } public sealed class GunBuilder { private readonly Dictionary<string, Material> materials; private readonly GameObject smelter; public Transform Swivel; public Transform Barrel; public Transform Muzzle; public Transform Seat; public Transform Grips; public Light Flash; public Light Glow; public ParticleSystem Steam; public IModHost Host { get; } public MountedGun Gun { get; } public Transform Root { get; } internal GunBuilder(IModHost host, MountedGun gun, Transform root, Dictionary<string, Material> materials, GameObject smelter) { Host = host; Gun = gun; Root = root; this.materials = materials; this.smelter = smelter; } public Transform Part(Transform parent, string model, Vector3 at, Quaternion rotation) { //IL_000e: Unknown result type (might be due to invalid IL or missing references) //IL_0013: 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_0031: Unknown result type (might be due to invalid IL or missing references) //IL_0037: Unknown result type (might be due to invalid IL or missing references) //IL_003d: Unknown result type (might be due to invalid IL or missing references) //IL_0043: Unknown result type (might be due to invalid IL or missing references) //IL_004a: 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_0060: Unknown result type (might be due to invalid IL or missing references) //IL_006a: Unknown result type (might be due to invalid IL or missing references) //IL_007b: Unknown result type (might be due to invalid IL or missing references) Model model2 = Files.Mesh(Host, model); GameObject val = new GameObject(model) { layer = ((Component)parent).gameObject.layer }; val.transform.SetParent(parent, false); val.transform.localPosition = at; val.transform.localRotation = rotation; val.transform.localScale = Vector3.one * Gun.Scale; val.AddComponent<MeshFilter>().sharedMesh = model2.mesh; ((Renderer)val.AddComponent<MeshRenderer>()).sharedMaterials = model2.slots.Select((string slot) => materials[slot]).ToArray(); return val.transform; } public Transform Inner(Transform parent, string model, Vector3 at, Quaternion rotation) { //IL_0003: Unknown result type (might be due to invalid IL or missing references) //IL_0004: Unknown result type (might be due to invalid IL or missing references) //IL_000c: Unknown result type (might be due to invalid IL or missing references) Transform obj = Part(parent, model, at, rotation); obj.localScale = Vector3.one; return obj; } public Transform Point(Transform parent, string name, Vector3 at) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_0013: Unknown result type (might be due to invalid IL or missing references) //IL_0019: Unknown result type (might be due to invalid IL or missing references) GameObject val = new GameObject(name); val.transform.SetParent(parent, false); val.transform.localPosition = at; return val.transform; } public GameObject Solid(Transform parent, Vector3 center, Vector3 size, Quaternion rotation) { //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_0013: Unknown result type (might be due to invalid IL or missing references) GameObject obj = Box(parent, "collider", center, size); obj.transform.localRotation = rotation; obj.AddComponent<Inert>(); return obj; } public void Handle(Transform parent, Vector3 center, Vector3 size) { //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Unknown result type (might be due to invalid IL or missing references) Box(parent, "handle", center, size).AddComponent<Handle>(); } public void GripsAt(Transform parent, Vector3 center, Vector3 size) { //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Unknown result type (might be due to invalid IL or missing references) GameObject val = Box(parent, "grips", center, size); val.AddComponent<Grips>(); Grips = val.transform; } public void SlotAt(Transform parent, Vector3 center, Vector3 size) { //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Unknown result type (might be due to invalid IL or missing references) Box(parent, "slot", center, size).AddComponent<Slot>(); } public Light Lamp(Transform at, Color color, float range, float intensity) { //IL_0013: Unknown result type (might be due to invalid IL or missing references) Light obj = ((Component)at).gameObject.AddComponent<Light>(); obj.type = (LightType)2; obj.color = color; obj.range = range; obj.intensity = intensity; obj.shadows = (LightShadows)0; ((Behaviour)obj).enabled = false; return obj; } public ParticleSystem SteamAt(Transform at) { //IL_008a: 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_00b1: Unknown result type (might be due to invalid IL or missing references) //IL_00b6: Unknown result type (might be due to invalid IL or missing references) //IL_00cd: 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_00ed: 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_00fa: Unknown result type (might be due to invalid IL or missing references) ParticleSystem val = (((Object)(object)smelter != (Object)null) ? ((IEnumerable<ParticleSystem>)smelter.GetComponentsInChildren<ParticleSystem>(true)).FirstOrDefault((Func<ParticleSystem, bool>)((ParticleSystem p) => ((Object)p).name.ToLowerInvariant().Contains("smoke"))) : null); if ((Object)(object)val == (Object)null) { Host.Log.LogWarning((object)("the smoke of the smelter was not found, " + Gun.Name + " has no steam")); return null; } GameObject obj = Object.Instantiate<GameObject>(((Component)val).gameObject, at, false); obj.transform.localPosition = Vector3.zero; obj.transform.localRotation = Quaternion.identity; obj.SetActive(true); ParticleSystem component = obj.GetComponent<ParticleSystem>(); MainModule main = component.main; ((MainModule)(ref main)).startColor = MinMaxGradient.op_Implicit(new Color(0.95f, 0.95f, 0.95f, 0.7f)); ((MainModule)(ref main)).loop = true; ((MainModule)(ref main)).playOnAwake = true; EmissionModule emission = component.emission; ((EmissionModule)(ref emission)).rateOverTime = MinMaxCurve.op_Implicit(0f); return component; } public AudioClip Sound(string name) { return Files.Sound(Host, name); } public AudioSource Speaker(AudioClip clip, float maxDistance) { return Guns.Speaker(((Component)Root).gameObject, clip, maxDistance); } public Transform FromPrefab(GameObject model) { GameObject copy = Object.Instantiate<GameObject>(model, Root, false); ((Object)copy).name = ((Object)model).name; Swivel = Find("swivel") ?? Swivel; Barrel = Find("barrel") ?? Barrel; Muzzle = Find("muzzle") ?? Muzzle; Seat = Find("seat") ?? Seat; Transform val = Find("grips"); Transform val2 = Find("slot"); Transform val3 = Find("handle"); Collider[] componentsInChildren = copy.GetComponentsInChildren<Collider>(true); for (int i = 0; i < componentsInChildren.Length; i++) { Transform transform = ((Component)componentsInChildren[i]).transform; if ((Object)(object)transform == (Object)(object)val) { ((Component)transform).gameObject.AddComponent<Grips>(); Grips = transform; } else if ((Object)(object)transform == (Object)(object)val2) { ((Component)transform).gameObject.AddComponent<Slot>(); } else if ((Object)(object)transform == (Object)(object)val3) { ((Component)transform).gameObject.AddComponent<Handle>(); } else { ((Component)transform).gameObject.AddComponent<Inert>(); } } return copy.transform; Transform Find(string name) { return ((IEnumerable<Transform>)copy.GetComponentsInChildren<Transform>(true)).FirstOrDefault((Func<Transform, bool>)((Transform t) => ((Object)t).name.ToLowerInvariant() == name)); } } private static GameObject Box(Transform parent, string name, Vector3 center, Vector3 size) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_0017: 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: Unknown result type (might be due to invalid IL or missing references) //IL_0030: Unknown result type (might be due to invalid IL or missing references) //IL_0036: Unknown result type (might be due to invalid IL or missing references) //IL_003d: Expected O, but got Unknown GameObject val = new GameObject(name) { layer = ((Component)parent).gameObject.layer }; val.transform.SetParent(parent, false); val.transform.localPosition = center; val.AddComponent<BoxCollider>().size = size; return val; } } public sealed class SyncedConfig { private abstract class Entry { public abstract void Write(ZPackage pkg); public abstract void Read(ZPackage pkg); public abstract string Show(); } private sealed class Entry<T> : Entry { public ConfigEntry<T> local; public T server; public SyncedConfig owner; public Func<T, T> clamp; public T Value => clamp(owner.fromServer ? server : local.Value); public override void Write(ZPackage pkg) { object obj = Value; if (!(obj is float num)) { if (obj is bool flag) { pkg.Write(flag); } else { pkg.Write((string)obj); } } else { pkg.Write(num); } } public override void Read(ZPackage pkg) { object obj = ((typeof(T) == typeof(float)) ? ((object)pkg.ReadSingle()) : ((typeof(T) == typeof(bool)) ? ((object)pkg.ReadBool()) : pkg.ReadString())); server = (T)obj; } public override string Show() { return $"{((ConfigEntryBase)local).Definition.Key} {Value}"; } } private static readonly List<SyncedConfig> all = new List<SyncedConfig>(); private readonly IModHost host; private readonly ConfigFile file; private readonly string ask; private readonly string answer; private readonly List<Entry> entries = new List<Entry>(); private bool fromServer; public event Action Received; public SyncedConfig(IModHost host, string fileName, string keys) { //IL_0025: Unknown result type (might be due to invalid IL or missing references) //IL_002f: Expected O, but got Unknown this.host = host; file = new ConfigFile(Path.Combine(Paths.ConfigPath, fileName), true); ask = keys + "_settings_ask"; answer = keys + "_settings"; all.Add(this); } public void Start() { if (ZRoutedRpc.instance != null && (Object)(object)ZNet.instance != (Object)null) { Register(ZRoutedRpc.instance); } } public Func<float> Float(string section, string key, float value, string description, float min, float max) { return Add(section, key, value, description, (float v) => Mathf.Clamp(v, min, max)); } public Func<bool> Bool(string section, string key, bool value, string description) { return Add(section, key, value, description, (bool v) => v); } public Func<string> Text(string section, string key, string value, string description) { return Add(section, key, value, description, (string v) => v); } private Func<T> Add<T>(string section, string key, T value, string description, Func<T, T> clamp) { Entry<T> entry = new Entry<T> { local = file.Bind<T>(section, key, value, description), owner = this, clamp = clamp }; entries.Add(entry); return () => entry.Value; } internal static void RegisterAll(ZRoutedRpc rpc) { foreach (SyncedConfig item in all) { item.Register(rpc); } } internal static void UnregisterAll() { foreach (SyncedConfig item in all) { Guns.UnregisterRpc(item.ask, item.answer); } all.Clear(); } private void Register(ZRoutedRpc rpc) { Guns.UnregisterRpc(ask, answer); rpc.Register(ask, (Action<long>)OnAsk); rpc.Register<ZPackage>(answer, (Action<long, ZPackage>)OnAnswer); fromServer = false; if (!ZNet.instance.IsServer()) { rpc.InvokeRoutedRPC(rpc.GetServerPeerID(), ask, Array.Empty<object>()); } } private void OnAsk(long sender) { //IL_000d: Unknown result type (might be due to invalid IL or missing references) //IL_0013: Expected O, but got Unknown if (!ZNet.instance.IsServer()) { return; } ZPackage val = new ZPackage(); foreach (Entry entry in entries) { entry.Write(val); } ZRoutedRpc.instance.InvokeRoutedRPC(sender, answer, new object[1] { val }); } private void OnAnswer(long sender, ZPackage pkg) { foreach (Entry entry in entries) { entry.Read(pkg); } fromServer = true; host.Log.LogInfo((object)(host.Name + " settings from the server: " + string.Join(", ", entries.ConvertAll((Entry e) => e.Show())))); this.Received?.Invoke(); } } internal static class Damage { private const int AnyTier = 100; public static bool Hits(Player gunner, Collider collider) { Character componentInParent = ((Component)collider).GetComponentInParent<Character>(); if ((Object)(object)componentInParent == (Object)null) { return true; } if ((Object)(object)componentInParent == (Object)(object)gunner || componentInParent.IsDead()) { return false; } if (!BaseAI.IsEnemy((Character)(object)gunner, componentInParent) && (!((Object)(object)componentInParent.GetBaseAI() != (Object)null) || !componentInParent.GetBaseAI().IsAggravatable())) { return ((Character)gunner).IsPVPEnabled(); } return true; } public static void Strike(Player gunner, Collider collider, Vector3 point, Vector3 dir, RoundSpec spec) { //IL_0038: Unknown result type (might be due to invalid IL or missing references) //IL_003e: Expected O, but got Unknown //IL_0026: Unknown result type (might be due to invalid IL or missing references) //IL_008b: 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_0092: 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) IDestructible componentInParent = ((Component)collider).GetComponentInParent<IDestructible>(); if (componentInParent == null) { if ((Object)(object)((Component)collider).GetComponent<Heightmap>() != (Object)null && Random.value < spec.DentChance) { Guns.Dent(point, gunner); } } else if (Breaks(gunner, collider)) { HitData val = new HitData(); if (componentInParent is Character) { val.m_damage.m_pierce = spec.Damage(); } else { val.m_damage.m_damage = spec.Damage(); val.m_toolTier = 100; val.m_itemWorldLevel = (byte)Game.m_worldLevel; } val.m_point = point; val.m_dir = dir; val.m_pushForce = spec.PushForce; val.m_ranged = true; val.m_dodgeable = false; val.m_blockable = true; val.m_hitCollider = collider; val.SetAttacker((Character)(object)gunner); componentInParent.Damage(val); } } private static bool Breaks(Player gunner, Collider collider) { Piece componentInParent = ((Component)collider).GetComponentInParent<Piece>(); if ((Object)(object)componentInParent == (Object)null || Guns.BreakAllBuildings() || ((Character)gunner).IsPVPEnabled()) { return true; } long creator = componentInParent.GetCreator(); if (creator != 0L) { return creator == gunner.GetPlayerID(); } return true; } } public class Feed : MonoBehaviour { private ZNetView m_nview; private FeedSpec m_spec; private Ammo m_ammo; private string m_roundsKey; private string m_loadRpc; public FeedSpec Spec => m_spec; public int Loaded { get { if (m_spec == null || !m_nview.IsValid()) { return 0; } return m_nview.GetZDO().GetInt(m_roundsKey, 0); } } private void Awake() { m_nview = ((Component)this).GetComponentInParent<ZNetView>(); Guns.Entry entry = Guns.Find(((Component)this).GetComponent<Gun>()?.m_prefab); if (!((Object)(object)m_nview == (Object)null) && m_nview.GetZDO() != null && entry != null) { m_spec = entry.gun.Feed; m_ammo = entry.ammo; m_roundsKey = entry.gun.Keys + "_rounds"; m_loadRpc = entry.gun.Keys + "_load"; m_nview.Register<int>(m_loadRpc, (Action<long, int>)OnLoad); } } public bool Holds(ItemData item) { if ((Object)(object)m_ammo?.Item != (Object)null) { return item.m_shared.m_name == m_ammo.ItemName; } return false; } public bool Load(Humanoid user, Gun gun) { if (m_spec == null || !m_nview.IsValid() || (Object)(object)m_ammo?.Item == (Object)null) { return false; } Inventory inventory = user.GetInventory(); if (inventory.CountItems(m_ammo.ItemName, -1, true) == 0) { ((Character)user).Message((MessageType)2, "You have no " + m_ammo.ItemName, 0, (Sprite)null, false); return false; } if (Loaded + m_spec.RoundsPerItem > m_spec.Most) { ((Character)user).Message((MessageType)2, $"The gun holds {m_spec.Most} rounds", 0, (Sprite)null, false); return false; } inventory.RemoveItem(m_ammo.ItemName, 1, -1, true); m_nview.InvokeRPC(m_loadRpc, new object[1] { m_spec.RoundsPerItem }); m_nview.InvokeRPC(ZNetView.Everybody, gun.LoadShowRpc, Array.Empty<object>()); ((Character)user).Message((MessageType)2, $"A {m_spec.Noun} of {m_spec.RoundsPerItem} rounds is in", 0, (Sprite)null, false); return true; } public void Spend(int rounds) { if (m_spec != null && rounds > 0) { ZDO zDO = m_nview.GetZDO(); zDO.Set(m_roundsKey, Mathf.Max(0, zDO.GetInt(m_roundsKey, 0) - rounds)); } } private void OnLoad(long sender, int rounds) { if (m_nview.IsOwner()) { ZDO zDO = m_nview.GetZDO(); zDO.Set(m_roundsKey, Mathf.Min(m_spec.Most, zDO.GetInt(m_roundsKey, 0) + rounds)); } } } public sealed class Model { public Mesh mesh; public string[] slots; public List<Box> boxes; } public sealed class Box { public Vector3 center; public Vector3 size; public Quaternion rotation; } public static class Files { private static readonly Dictionary<string, Model> models = new Dictionary<string, Model>(); private static readonly Dictionary<string, AssetBundle> bundles = new Dictionary<string, AssetBundle>(); public static Model Mesh(IModHost host, string name) { //IL_00d9: Unknown result type (might be due to invalid IL or missing references) //IL_00e6: Unknown result type (might be due to invalid IL or missing references) //IL_00fe: 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_0173: Unknown result type (might be due to invalid IL or missing references) //IL_0176: Unknown result type (might be due to invalid IL or missing references) //IL_017b: 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_0183: 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) //IL_0195: Unknown result type (might be due to invalid IL or missing references) //IL_0197: Unknown result type (might be due to invalid IL or missing references) //IL_019d: Unknown result type (might be due to invalid IL or missing references) //IL_019f: Unknown result type (might be due to invalid IL or missing references) //IL_01a5: Unknown result type (might be due to invalid IL or missing references) //IL_01a7: Unknown result type (might be due to invalid IL or missing references) //IL_01a9: Unknown result type (might be due to invalid IL or missing references) //IL_01ae: Unknown result type (might be due to invalid IL or missing references) //IL_01c4: Unknown result type (might be due to invalid IL or missing references) //IL_01c9: Unknown result type (might be due to invalid IL or missing references) //IL_01dc: Expected O, but got Unknown //IL_0210: Unknown result type (might be due to invalid IL or missing references) string key = host.Name + "/" + name; if (models.TryGetValue(key, out var value)) { return value; } using BinaryReader binaryReader = new BinaryReader(new MemoryStream(host.ReadAsset("meshes/" + name + ".bfm"))); if (Encoding.ASCII.GetString(binaryReader.ReadBytes(4)) != "BFM5") { throw new InvalidDataException(name + " is not a mesh file"); } int num = binaryReader.ReadInt32(); List<Vector3> list = new List<Vector3>(); List<Vector3> list2 = new List<Vector3>(); List<Vector2> list3 = new List<Vector2>(); List<int[]> list4 = new List<int[]>(); string[] array = new string[num]; for (int i = 0; i < num; i++) { array[i] = Encoding.UTF8.GetString(binaryReader.ReadBytes(binaryReader.ReadInt32())); int count = list.Count; int num2 = binaryReader.ReadInt32(); for (int j = 0; j < num2; j++) { list.Add(Vector(binaryReader)); list2.Add(Vector(binaryReader)); list3.Add(new Vector2(binaryReader.ReadSingle(), binaryReader.ReadSingle())); } int[] array2 = new int[binaryReader.ReadInt32()]; for (int k = 0; k < array2.Length; k++) { array2[k] = count + binaryReader.ReadInt32(); } list4.Add(array2); } List<Box> list5 = new List<Box>(); int num3 = binaryReader.ReadInt32(); for (int l = 0; l < num3; l++) { Vector3 center = Vector(binaryReader); Vector3 size = Vector(binaryReader); Vector3 val = Vector(binaryReader); Vector3 val2 = Vector(binaryReader); list5.Add(new Box { center = center, size = size, rotation = Quaternion.LookRotation(val, val2) }); } Mesh val3 = new Mesh { name = "gw_" + name }; if (list.Count > 65535) { val3.indexFormat = (IndexFormat)1; } val3.SetVertices(list); val3.SetNormals(list2); val3.SetUVs(0, list3); val3.SetColors(Enumerable.Repeat<Color>(Color.white, list.Count).ToList()); val3.subMeshCount = num; for (int m = 0; m < num; m++) { val3.SetTriangles(list4[m], m); } val3.RecalculateBounds(); val3.RecalculateTangents(); value = new Model { mesh = val3, slots = array, boxes = list5 }; models[key] = value; return value; } private static Vector3 Vector(BinaryReader reader) { //IL_0012: Unknown result type (might be due to invalid IL or missing references) return new Vector3(reader.ReadSingle(), reader.ReadSingle(), reader.ReadSingle()); } public static Sprite Icon(IModHost host, string name) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0008: Expected O, but got Unknown //IL_003e: Unknown result type (might be due to invalid IL or missing references) //IL_004d: Unknown result type (might be due to invalid IL or missing references) Texture2D val = new Texture2D(2, 2); ImageConversion.LoadImage(val, host.ReadAsset("icons/" + name + ".png")); return Sprite.Create(val, new Rect(0f, 0f, (float)((Texture)val).width, (float)((Texture)val).height), new Vector2(0.5f, 0.5f)); } public static AudioClip Sound(IModHost host, string name) { byte[] array = host.ReadAsset("sounds/" + name + ".wav"); if (Encoding.ASCII.GetString(array, 0, 4) != "RIFF" || Encoding.ASCII.GetString(array, 8, 4) != "WAVE") { throw new FormatException(name + ".wav is not a WAV file"); } int num = 1; int num2 = 44100; int num3; for (int i = 12; i + 8 <= array.Length; i += 8 + num3 + (num3 & 1)) { string text = Encoding.ASCII.GetString(array, i, 4); num3 = BitConverter.ToInt32(array, i + 4); if (text == "fmt ") { num = BitConverter.ToInt16(array, i + 10); num2 = BitConverter.ToInt32(array, i + 12); if (BitConverter.ToInt16(array, i + 22) != 16) { throw new FormatException(name + ".wav is not 16 bit"); } } else if (text == "data") { int num4 = Math.Min(num3, array.Length - i - 8) / 2; float[] array2 = new float[num4]; for (int j = 0; j < num4; j++) { array2[j] = (float)BitConverter.ToInt16(array, i + 8 + j * 2) / 32768f; } AudioClip obj = AudioClip.Create(host.Name + " " + name, num4 / num, num, num2, false); obj.SetData(array2, 0); return obj; } } throw new FormatException(name + ".wav has no data"); } public static GameObject Bundle(IModHost host, string file, string asset) { string key = host.Name + "/" + file; if (!bundles.TryGetValue(key, out var value)) { value = AssetBundle.LoadFromMemory(host.ReadAsset(file)); if ((Object)(object)value == (Object)null) { throw new InvalidDataException(file + " is not an asset bundle of this Unity version"); } bundles[key] = value; } GameObject val = value.LoadAsset<GameObject>(asset); if ((Object)(object)val == (Object)null) { throw new InvalidDataException(file + " has no prefab " + asset + ", it has " + string.Join(", ", value.GetAllAssetNames())); } return val; } public static void Clear() { models.Clear(); foreach (AssetBundle value in bundles.Values) { value.Unload(true); } bundles.Clear(); } } internal sealed class Flight { private sealed class Round { public LineRenderer line; public LineRenderer core; public Light light; public Vector3 at; public Vector3 velocity; public float flown; public Player gunner; public bool active; } private const int MostRounds = 48; private readonly Transform gun; private readonly RoundSpec spec; private readonly float range; private readonly Material tracer; private readonly Material core; private readonly List<Round> rounds = new List<Round>(); public Flight(Transform gun, RoundSpec spec, float range, Material tracer, Material core) { this.gun = gun; this.spec = spec; this.range = range; this.tracer = tracer; this.core = core; } public void Launch(Vector3 from, Vector3 dir, Player gunner) { //IL_000c: Unknown result type (might be due to invalid IL or missing references) //IL_000d: 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_0025: Unknown result type (might be due to invalid IL or missing references) //IL_002a: Unknown result type (might be due to invalid IL or missing references) Round round = Free(); if (round != null) { round.at = from; round.velocity = ((Vector3)(ref dir)).normalized * spec.Speed; round.flown = 0f; round.gunner = gunner; round.active = true; Show(round, on: true); Draw(round); } } public void Fly(float dt) { //IL_003d: Unknown result type (might be due to invalid IL or missing references) //IL_0043: Unknown result type (might be due to invalid IL or missing references) //IL_0048: Unknown result type (might be due to invalid IL or missing references) //IL_004b: 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_0060: Unknown result type (might be due to invalid IL or missing references) //IL_0066: Unknown result type (might be due to invalid IL or missing references) //IL_006b: Unknown result type (might be due to invalid IL or missing references) //IL_0070: Unknown result type (might be due to invalid IL or missing references) //IL_0077: 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_009f: Unknown result type (might be due to invalid IL or missing references) //IL_00a0: Unknown result type (might be due to invalid IL or missing references) //IL_00a5: Unknown result type (might be due to invalid IL or missing references) //IL_0084: Unknown result type (might be due to invalid IL or missing references) //IL_0089: Unknown result type (might be due to invalid IL or missing references) //IL_0090: Unknown result type (might be due to invalid IL or missing references) foreach (Round item in rounds.Where((Round r) => r.active)) { Vector3 val = item.velocity * dt; item.velocity += Vector3.down * spec.Gravity * dt; if (Cast(item, val, out var found)) { item.at = ((RaycastHit)(ref found)).point; Land(item, found); continue; } item.at += val; item.flown += ((Vector3)(ref val)).magnitude; if (item.flown >= range) { Stop(item); } else { Draw(item); } } } private bool Cast(Round round, Vector3 step, out RaycastHit found) { //IL_0036: Unknown result type (might be due to invalid IL or missing references) //IL_003b: Unknown result type (might be due to invalid IL or missing references) //IL_003d: Unknown result type (might be due to invalid IL or missing references) //IL_007a: Unknown result type (might be due to invalid IL or missing references) //IL_007f: Unknown result type (might be due to invalid IL or missing references) //IL_00f9: Unknown result type (might be due to invalid IL or missing references) //IL_00d9: 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) float magnitude = ((Vector3)(ref step)).magnitude; object obj; if (!((Object)(object)round.gunner != (Object)null)) { Player localPlayer = Player.m_localPlayer; obj = ((localPlayer != null) ? ((Component)localPlayer).transform : null); } else { obj = ((Component)round.gunner).transform; } Transform val = (Transform)obj; foreach (RaycastHit item in from h in Physics.RaycastAll(round.at, step / magnitude, magnitude, Gun.Mask) orderby ((RaycastHit)(ref h)).distance select h) { RaycastHit current = item; if (!((Component)((RaycastHit)(ref current)).collider).transform.IsChildOf(gun) && (!((Object)(object)val != (Object)null) || !((Component)((RaycastHit)(ref current)).collider).transform.IsChildOf(val)) && (!((Object)(object)round.gunner != (Object)null) || Damage.Hits(round.gunner, ((RaycastHit)(ref current)).collider))) { found = current; return true; } } found = default(RaycastHit); return false; } private void Land(Round round, RaycastHit hit) { //IL_001d: Unknown result type (might be due to invalid IL or missing references) //IL_0028: Unknown result type (might be due to invalid IL or missing references) //IL_0045: Unknown result type (might be due to invalid IL or missing references) //IL_004c: 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) //IL_005f: Unknown result type (might be due to invalid IL or missing references) //IL_0065: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)round.gunner != (Object)null) { Damage.Strike(round.gunner, ((RaycastHit)(ref hit)).collider, ((RaycastHit)(ref hit)).point, ((Vector3)(ref round.velocity)).normalized, spec); } EffectList hitEffects = Guns.HitEffects; if (hitEffects != null) { hitEffects.Create(((RaycastHit)(ref hit)).point, Quaternion.LookRotation(((RaycastHit)(ref hit)).normal), (Transform)null, 1f, -1, default(ZDOID)); } Stop(round); } private void Draw(Round round) { //IL_0015: Unknown result type (might be due to invalid IL or missing references) //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_003f: 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) //IL_0056: Unknown result type (might be due to invalid IL or missing references) //IL_0058: Unknown result type (might be due to invalid IL or missing references) //IL_005d: Unknown result type (might be due to invalid IL or missing references) //IL_006f: 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_0086: Unknown result type (might be due to invalid IL or missing references) //IL_0088: Unknown result type (might be due to invalid IL or missing references) //IL_0092: Unknown result type (might be due to invalid IL or missing references) //IL_0097: Unknown result type (might be due to invalid IL or missing references) //IL_00ad: Unknown result type (might be due to invalid IL or missing references) if (!((Object)(object)round.line == (Object)null)) { Vector3 val = -((Vector3)(ref round.velocity)).normalized; float num = Mathf.Min(round.flown, spec.TracerLength); round.line.SetPosition(0, round.at); round.line.SetPosition(1, round.at + val * num); round.core.SetPosition(0, round.at); round.core.SetPosition(1, round.at + val * num * 0.45f); ((Component)round.light).transform.position = round.at; } } private static void Stop(Round round) { round.active = false; Show(round, on: false); } private static void Show(Round round, bool on) { if ((Object)(object)round.line != (Object)null) { ((Renderer)round.line).enabled = on; ((Renderer)round.core).enabled = on; ((Behaviour)round.light).enabled = on; } } private Round Free() { //IL_0068: Unknown result type (might be due to invalid IL or missing references) //IL_006e: Expected O, but got Unknown //IL_009d: 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_00d4: Expected O, but got Unknown //IL_00f6: Unknown result type (might be due to invalid IL or missing references) Round round = rounds.FirstOrDefault((Round r) => !r.active); if (round != null) { return round; } if (rounds.Count >= 48) { return null; } if ((Object)(object)tracer == (Object)null) { round = new Round(); rounds.Add(round); return round; } GameObject val = new GameObject("round"); val.transform.SetParent(gun, false); LineRenderer line = Streak(val, tracer, spec.TracerWidth); GameObject val2 = new GameObject("core"); val2.transform.SetParent(val.transform, false); LineRenderer val3 = Streak(val2, core ?? tracer, spec.CoreWidth); Light val4 = val.AddComponent<Light>(); val4.type = (LightType)2; val4.color = new Color(1f, 0.5f, 0.15f); val4.range = 5f; val4.intensity = 3f; val4.shadows = (LightShadows)0; ((Behaviour)val4).enabled = false; round = new Round { line = line, core = val3, light = val4 }; rounds.Add(round); return round; } private static LineRenderer Streak(GameObject go, Material material, float width) { //IL_002e: Unknown result type (might be due to invalid IL or missing references) //IL_004d: Unknown result type (might be due to invalid IL or missing references) LineRenderer obj = go.AddComponent<LineRenderer>(); obj.useWorldSpace = true; obj.positionCount = 2; obj.startWidth = width; obj.endWidth = 0f; ((Renderer)obj).material = material; obj.startColor = Color.white; obj.endColor = new Color(1f, 1f, 1f, 0f); obj.numCapVertices = 2; ((Renderer)obj).shadowCastingMode = (ShadowCastingMode)0; ((Renderer)obj).receiveShadows = false; ((Renderer)obj).enabled = false; return obj; } } public class Gun : MonoBehaviour, IDoodadController { [HarmonyPatch(typeof(Player), "SetControls")] private static class TriggerFromAttack { private static void Prefix(Player __instance, ref bool attack, ref bool attackHold, ref bool secondaryAttack, ref bool secondaryAttackHold) { if (!((Object)(object)__instance != (Object)(object)Player.m_localPlayer) && __instance.GetDoodadController() is Gun gun) { gun.SetTrigger((attack | attackHold) || gun.FireHeld); attack = false; attackHold = false; secondaryAttack = false; secondaryAttackHold = false; } } } public static readonly int Mask = LayerMask.GetMask(new string[13] { "Default", "static_solid", "Default_small", "piece", "piece_nonsolid", "terrain", "character", "character_net", "character_ghost", "hitbox", "character_noenv", "vehicle", "tree" }); public string m_prefab; public Transform m_swivel; public Transform m_barrel; public Transform m_muzzle; public Transform m_seat; public Transform m_grips; public Light m_flash; public Light m_glow; public ParticleSystem m_steam; public AudioSource[] m_voices; public AudioSource m_tail; private MountedGun m_spec; private Guns.Entry m_entry; private string m_userKey; private string m_yawKey; private string m_pitchKey; private string m_heatKey; private string m_heatTimeKey; private string m_jamKey; private string m_firingKey; private string m_takeRpc; private string m_grantRpc; private string m_releaseRpc; private string m_stateRpc; private string m_loadShowRpc; private ZNetView m_nview; private Rigidbody m_body; private Feed m_feed; private IGunExtra[] m_extras; private bool m_manned; private bool m_trigger; private Vector3 m_look; private Vector3 m_target; private float m_yaw; private float m_pitch; private float m_shotTimer; private int m_spent; private float m_heat; private double m_heatTime; private double m_jamUntil; private float m_nextSend; private bool m_wasFiring; private float m_flashOff; private int m_voice; private float m_burnMessage; private float m_loadWait; private Hud m_hud; private int m_rounds; private int m_lastSeen; private Flight m_flight; public static Gun Manned { get; private set; } public MountedGun Spec => m_spec; public bool Busy => m_extras.Any((IGunExtra e) => e.Busy); public string LoadShowRpc => m_loadShowRpc; private static double Now { get { if (!((Object)(object)ZNet.instance != (Object)null)) { return Time.time; } return ZNet.instance.GetTimeSeconds(); } } public float Heat { get { if (!m_manned) { return HeatNow(m_nview.GetZDO().GetFloat(m_heatKey, 0f), Seconds(m_heatTimeKey)); } return HeatNow(m_heat, m_heatTime); } } public float JamLeft => (float)((m_manned ? m_jamUntil : Seconds(m_jamKey)) - Now); public bool Infinite => m_spec.Fire.InfiniteAmmo(); public int Rounds { get { if (!Infinite) { if (!m_manned) { return Loaded; } return m_rounds; } return int.MaxValue; } } private int Loaded { get { if (!((Object)(object)m_feed != (Object)null)) { return 0; } return m_feed.Loaded; } } public long User { get { if (!m_nview.IsValid()) { return 0L; } return m_nview.GetZDO().GetLong(m_userKey, 0L); } } private float Interval => 60f / m_spec.Fire.RoundsPerMinute(); internal bool FireHeld { get { if ((Object)(object)m_hud != (Object)null) { return m_hud.FireHeld; } return false; } } private void Awake() { m_nview = ((Component)this).GetComponent<ZNetView>(); m_body = ((Component)this).GetComponent<Rigidbody>(); m_feed = ((Component)this).GetComponentInChildren<Feed>(true); m_extras = ((Component)this).GetComponents<IGunExtra>(); m_entry = Guns.Find(m_prefab); if ((Object)(object)m_nview == (Object)null || m_nview.GetZDO() == null || m_entry == null) { ((Behaviour)this).enabled = false; return; } m_spec = m_entry.gun; string keys = m_spec.Keys; m_userKey = keys + "_user"; m_yawKey = keys + "_yaw"; m_pitchKey = keys + "_pitch"; m_heatKey = keys + "_heat"; m_heatTimeKey = keys + "_heat_time"; m_jamKey = keys + "_jam"; m_firingKey = keys + "_firing"; m_takeRpc = keys + "_take"; m_grantRpc = keys + "_grant"; m_releaseRpc = keys + "_release"; m_stateRpc = keys + "_state"; m_loadShowRpc = keys + "_load_show"; m_flight = new Flight(((Component)this).transform, m_spec.Round, m_spec.Fire.Range, m_entry.tracer, m_entry.core); m_nview.Register<long>(m_takeRpc, (Action<long, long>)OnTake); m_nview.Register<bool>(m_grantRpc, (Action<long, bool>)OnGrant); m_nview.Register<long>(m_releaseRpc, (Action<long, long>)OnRelease); m_nview.Register<ZPackage>(m_stateRpc, (Action<long, ZPackage>)OnState); m_nview.Register(m_loadShowRpc, (Action<long>)OnLoadShow); } private void OnLoadShow(long sender) { IGunExtra[] extras = m_extras; for (int i = 0; i < extras.Length; i++) { extras[i].OnLoadShow(); } } public void LoadFrom(Humanoid user) { m_feed?.Load(user, this); } private void OnDestroy() { if (m_manned && (Object)(object)Player.m_localPlayer != (Object)null) { Player.m_localPlayer.StopDoodadControl(); ((Character)Player.m_localPlayer).AttachStop(); } Leave(); } private float HeatNow(float heat, double since) { HeatSpec heat2 = m_spec.Heat; if (heat2 == null) { return 0f; } float num = (float)(Now - since) - heat2.CoolAfter; return Mathf.Max(0f, heat - Mathf.Max(0f, num) * heat2.CoolPerSecond); } private double Seconds(string key) { return (double)m_nview.GetZDO().GetLong(key, 0L) / 1000.0; } public void Take(Humanoid character) { Player val = (Player)(object)((character is Player) ? character : null); if (!((Object)(object)val == (Object)null) && m_nview.IsValid()) { if (m_manned) { val.StopDoodadControl(); return; } m_nview.InvokeRPC(m_takeRpc, new object[1] { val.GetPlayerID() }); } } private void OnTake(long sender, long playerID) { if (m_nview.IsOwner()) { long user = User; bool flag = user == 0L || user == playerID || (Object)(object)Player.GetPlayer(user) == (Object)null; if (flag) { m_nview.GetZDO().Set(m_userKey, playerID); } m_nview.InvokeRPC(sender, m_grantRpc, new object[1] { flag }); } } private void OnGrant(long sender, bool granted) { //IL_00ef: Unknown result type (might be due to invalid IL or missing references) Player localPlayer = Player.m_localPlayer; if (!((Object)(object)localPlayer == (Object)null)) { if (!granted) { ((Character)localPlayer).Message((MessageType)2, "$msg_inuse", 0, (Sprite)null, false); return; } ZDO zDO = m_nview.GetZDO(); m_heat = zDO.GetFloat(m_heatKey, 0f); m_heatTime = Seconds(m_heatTimeKey); m_jamUntil = Seconds(m_jamKey); m_rounds = Loaded; m_lastSeen = m_rounds; m_yaw = zDO.GetFloat(m_yawKey, 0f); m_pitch = zDO.GetFloat(m_pitchKey, 0f); m_spent = 0; m_manned = true; Manned = this; localPlayer.StartDoodadControl((IDoodadController)(object)this); ((Character)localPlayer).AttachStart(m_seat, ((Component)this).gameObject, true, false, false, "crouching", new Vector3(0f, 0.1f, -0.3f), (Transform)null); m_hud = Hud.Show(this); Guns.Log.LogInfo((object)$"{m_spec.Name} taken, {Rounds} rounds, heat {Heat:0}"); } } private void OnRelease(long sender, long playerID) { if (m_nview.IsOwner() && User == playerID) { m_nview.GetZDO().Set(m_userKey, 0L); m_nview.GetZDO().Set(m_firingKey, false); } } public void OnUseStop(Player player) { if (m_manned) { Send(force: true, firing: false); if (m_nview.IsValid()) { m_nview.InvokeRPC(m_releaseRpc, new object[1] { player.GetPlayerID() }); } ((Character)player).AttachStop(); Leave(); } } private void Leave() { if (m_manned) { AudioSource tail = m_tail; if (tail != null) { tail.Play(); } } m_manned = false; m_trigger = false; if ((Object)(object)Manned == (Object)(object)this) { Manned = null; } if ((Object)(object)m_hud != (Object)null) { Object.Destroy((Object)(object)((Component)m_hud).gameObject); m_hud = null; } } public void ApplyControlls(Vector3 moveDir, Vector3 lookDir, bool run, bool autoRun, bool block) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0002: Unknown result type (might be due to invalid IL or missing references) m_look = lookDir; } public Component GetControlledComponent() { return (Component)(object)m_barrel; } public Vector3 GetPosition() { //IL_0006: Unknown result type (might be due to invalid IL or missing references) return m_grips.position; } public bool IsValid() { if ((Object)(object)this != (Object)null && (Object)(object)m_nview != (Object)null) { return m_nview.IsValid(); } return false; } public void SetTrigger(bool down) { m_trigger = down; } private void Update() { //IL_0189: Unknown result type (might be due to invalid IL or missing references) //IL_0167: Unknown result type (might be due to invalid IL or missing references) if (!m_nview.IsValid()) { return; } if (m_manned) { int loaded = Loaded; if (loaded > m_lastSeen) { m_rounds += loaded - m_lastSeen; } m_lastSeen = loaded; Aim(); Fire(Time.deltaTime); Send(force: false, m_wasFiring); } else { ZDO zDO = m_nview.GetZDO(); float num = m_spec.Traverse.Speed * 2f * Time.deltaTime; m_yaw = Mathf.MoveTowardsAngle(m_yaw, zDO.GetFloat(m_yawKey, 0f), num); m_pitch = Mathf.MoveTowardsAngle(m_pitch, zDO.GetFloat(m_pitchKey, 0f), num); Echo(zDO.GetBool(m_firingKey, false), Time.deltaTime); } m_flight.Fly(Time.deltaTime); bool loaded2 = Loaded > 0 || (m_manned && m_rounds > 0); IGunExtra[] extras = m_extras; for (int i = 0; i < extras.Length; i++) { extras[i].Tick(loaded2); } if ((Object)(object)m_swivel != (Object)null) { m_swivel.localRotation = Quaternion.Euler(0f, m_yaw, 0f); } m_barrel.localRotation = Quaternion.Euler(0f - m_pitch, m_yaw, 0f); ShowHeat(Heat); } private Vector3 Target() { //IL_007d: Unknown result type (might be due to invalid IL or missing references) //IL_0083: Unknown result type (might be due to invalid IL or missing references) //IL_003b: 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) //IL_0046: Unknown result type (might be due to invalid IL or missing references) //IL_0065: Unknown result type (might be due to invalid IL or missing references) //IL_0058: Unknown result type (might be due to invalid IL or missing references) //IL_006b: Unknown result type (might be due to invalid IL or missing references) //IL_0070: Unknown result type (might be due to invalid IL or missing references) //IL_00c0: Unknown result type (might be due to invalid IL or missing references) //IL_00c5: 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_0128: Unknown result type (might be due to invalid IL or missing references) //IL_012e: Unknown result type (might be due to invalid IL or missing references) //IL_0133: Unknown result type (might be due to invalid IL or missing references) //IL_0104: Unknown result type (might be due to invalid IL or missing references) //IL_0109: 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) float range = m_spec.Fire.Range; Transform val = (((Object)(object)GameCamera.instance != (Object)null) ? ((Component)GameCamera.instance).transform : null); if ((Object)(object)val == (Object)null) { return m_muzzle.position + ((m_look == Vector3.zero) ? m_muzzle.forward : ((Vector3)(ref m_look)).normalized) * range; } Player localPlayer = Player.m_localPlayer; foreach (RaycastHit item in from h in Physics.RaycastAll(val.position, val.forward, range, Mask) orderby ((RaycastHit)(ref h)).distance select h) { RaycastHit current = item; if (!((Component)((RaycastHit)(ref current)).collider).transform.IsChildOf(((Component)this).transform) && (!((Object)(object)localPlayer != (Object)null) || !((Component)((RaycastHit)(ref current)).collider).transform.IsChildOf(((Component)localPlayer).transform))) { return ((RaycastHit)(ref current)).point; } } return val.position + val.forward * range; } private void Aim() { //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_002b: Unknown result type (might be due to invalid IL or missing references) //IL_001a: Unknown result type (might be due to invalid IL or missing references) //IL_0030: Unknown result type (might be due to invalid IL or missing references) //IL_0031: Unknown result type (might be due to invalid IL or missing references) //IL_0032: Unknown result type (might be due to invalid IL or missing references) //IL_0053: Unknown result type (might be due to invalid IL or missing references) //IL_0058: Unknown result type (might be due to invalid IL or missing references) //IL_005d: Unknown result type (might be due to invalid IL or missing references) //IL_005e: 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_0097: Unknown result type (might be due to invalid IL or missing references) m_target = Target(); Vector3 val = (((Object)(object)GameCamera.instance != (Object)null) ? ((Component)GameCamera.instance).transform.forward : m_look); if (!(val == Vector3.zero)) { TraverseSpec traverse = m_spec.Traverse; Vector3 val2 = ((Component)this).transform.InverseTransformDirection(((Vector3)(ref val)).normalized); float num = Mathf.Atan2(val2.x, val2.z) * 57.29578f; if (traverse.Side < 180f) { num = Mathf.Clamp(num, 0f - traverse.Side, traverse.Side); } float num2 = Mathf.Clamp(Mathf.Asin(Mathf.Clamp(val2.y, -1f, 1f)) * 57.29578f, 0f - traverse.Down, traverse.Up); m_yaw = Mathf.Repeat(Mathf.MoveTowardsAngle(m_yaw, num, traverse.Speed * Time.deltaTime) + 180f, 360f) - 180f; m_pitch = Mathf.MoveTowards(m_pitch, num2, traverse.Speed * Time.deltaTime); } } private void Fire(float dt) { bool flag = JamLeft > 0f; bool busy = Busy; bool num = m_trigger && Rounds > 0 && !flag && !busy; Player localPlayer = Player.m_localPlayer; if (m_trigger && !flag && !busy && Rounds == 0 && (Object)(object)localPlayer != (Object)null && Time.time > m_loadWait && m_spec.Feed != null) { m_loadWait = Time.time + 2f; ((Character)localPlayer).Message((MessageType)2, m_spec.Feed.EmptyHint, 0, (Sprite)null, false); } if (!num) { m_shotTimer = 0f; if (m_wasFiring) { AudioSource tail = m_tail; if (tail != null) { tail.Play(); } m_wasFiring = false; } } else { if (!m_wasFiring) { m_wasFiring = true; m_shotTimer = Interval; } m_shotTimer += dt; while (m_shotTimer >= Interval && Rounds > 0 && JamLeft <= 0f) { m_shotTimer -= Interval; Shot(localPlayer); } } } private void Shot(Player player) { //IL_006f: Unknown result type (might be due to invalid IL or missing references) //IL_0074: 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_009f: Unknown result type (might be due to invalid IL or missing references) //IL_00a4: Unknown result type (might be due to invalid IL or missing references) //IL_00a9: Unknown result type (might be due to invalid IL or missing references) //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_00b3: Unknown result type (might be due to invalid IL or missing references) //IL_00ba: Unknown result type (might be due to invalid IL or missing references) //IL_00d8: 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_00d9: 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_00f5: Unknown result type (might be due to invalid IL or missing references) //IL_00f7: 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_010a: Unknown result type (might be due to invalid IL or missing references) //IL_010f: Unknown result type (might be due to invalid IL or missing references) if (!Infinite) { m_rounds--; m_spent++; } float num = (m_heat = HeatNow(m_heat, m_heatTime) + 1f); m_heatTime = Now; FireSpec fire = m_spec.Fire; Vector3 val; float num2; if ((Object)(object)m_body != (Object)null) { val = m_body.linearVelocity; if (((Vector3)(ref val)).magnitude > 0.3f) { num2 = fire.MovingSpread; goto IL_0092; } } num2 = fire.Spread; goto IL_0092; IL_0092: float num3 = num2; val = m_target - m_muzzle.position; Vector3 normalized = ((Vector3)(ref val)).normalized; Vector3 val2 = ((Vector3.Angle(normalized, m_muzzle.forward) < 3f) ? normalized : m_muzzle.forward); Vector3 dir = Quaternion.Euler(Random.Range(0f - num3, num3), Random.Range(0f - num3, num3), 0f) * val2; m_flight.Launch(m_muzzle.position, dir, player); Flash(); HeatSpec heat = m_spec.Heat; if (heat == null) { return; } if (num >= heat.BurnFrom) { Burn(player, num, heat); } if (num >= heat.JamAt) { m_jamUntil = Now + (double)heat.JamSeconds; if (player != null) { ((Character)player).Message((MessageType)2, $"The gun jammed from the heat, {heat.JamSeconds:0} s", 0, (Sprite)null, false); } Guns.Log.LogInfo((object)$"{m_spec.Name} jammed at heat {num:0}"); } } private void Burn(Player player, float heat, HeatSpec spec) { if ((Object)(object)player == (Object)null) { return; } float num = 0.02f + 0.13f * Mathf.Clamp01((heat - spec.BurnFrom) / (spec.JamAt - spec.BurnFrom)); if (!(Random.value > num)) { SEMan sEMan = ((Character)player).GetSEMan(); StatusEffect statusEffect = sEMan.GetStatusEffect(SEMan.s_statusEffectBurning); SE_Burning val = (SE_Burning)(((object)((statusEffect is SE_Burning) ? statusEffect : null)) ?? ((object)/*isinst with value type is only supported in some contexts*/)); if ((Object)(object)val != (Object)null && !val.AddFireDamage(4f)) { sEMan.RemoveStatusEffect((StatusEffect)(object)val, false); } if (Time.time > m_burnMessage) { m_burnMessage = Time.time + 3f; ((Character)player).Message((MessageType)2, "The gun is too hot, it burns your hands", 0, (Sprite)null, false); } } } private void Send(bool force, bool firing) { //IL_0022: Unknown result type (might be due to invalid IL or missing references) //IL_0028: Expected O, but got Unknown if (force || !(Time.time < m_nextSend)) { m_nextSend = Time.time + 0.1f; ZPackage val = new ZPackage(); val.Write(m_yaw); val.Write(m_pitch); val.Write(m_spent); val.Write(m_heat); val.Write(m_heatTime); val.Write(m_jamUntil); val.Write(firing); m_nview.InvokeRPC(m_stateRpc, new object[1] { val }); m_spent = 0; } } private void OnState(long sender, ZPackage pkg) { if (m_nview.IsOwner()) { ZDO zDO = m_nview.GetZDO(); zDO.Set(m_yawKey, pkg.ReadSingle()); zDO.Set(m_pitchKey, pkg.ReadSingle()); int rounds = pkg.ReadInt(); m_feed?.Spend(rounds); zDO.Set(m_heatKey, pkg.ReadSingle()); zDO.Set(m_heatTimeKey, (long)(pkg.ReadDouble() * 1000.0)); zDO.Set(m_jamKey, (long)(pkg.ReadDouble() * 1000.0)); zDO.Set(m_firingKey, pkg.ReadBool()); } } private void Echo(bool firing, float dt) { //IL_0088: 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_0098: Unknown result type (might be due to invalid IL or missing references) //IL_009d: 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_00af: Unknown result type (might be due to invalid IL or missing references) if (!firing) { if (m_wasFiring) { AudioSource tail = m_tail; if (tail != null) { tail.Play(); } m_wasFiring = false; } return; } if (!m_wasFiring) { m_wasFiring = true; m_shotTimer = Interval; } m_shotTimer += dt; float spread = m_spec.Fire.Spread; while (m_shotTimer >= Interval) { m_shotTimer -= Interval; Vector3 dir = Quaternion.Euler(Random.Range(0f - spread, spread), Random.Range(0f - spread, spread), 0f) * m_muzzle.forward; m_flight.Launch(m_muzzle.position, dir, null); Flash(); } } private void Flash() { if ((Object)(object)m_flash != (Object)null) { ((Behaviour)m_flash).enabled = true; m_flashOff = Time.time + 0.035f; } if (m_voices != null && m_voices.Length != 0) { AudioSource obj = m_voices[m_voice++ % m_voices.Length]; obj.pitch = Random.Range(0.93f, 1.04f); obj.Play(); } } private void ShowHeat(float heat) { //IL_0058: Unknown result type (might be due to invalid IL or missing references) //IL_005d: Unknown result type (might be due to invalid IL or missing references) //IL_00c5: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)m_flash != (Object)null && ((Behaviour)m_flash).enabled && Time.time > m_flashOff) { ((Behaviour)m_flash).enabled = false; } HeatSpec heat2 = m_spec.Heat; if (heat2 != null) { if ((Object)(object)m_steam != (Object)null) { EmissionModule emission = m_steam.emission; ((EmissionModule)(ref emission)).rateOverTime = MinMaxCurve.op_Implicit((heat < heat2.SteamFrom) ? 0f : ((heat < heat2.BurnFrom) ? Mathf.Lerp(1f, 6f, (heat - heat2.SteamFrom) / (heat2.BurnFrom - heat2.SteamFrom)) : Mathf.Lerp(15f, 40f, (heat - heat2.BurnFrom) / (heat2.JamAt - heat2.BurnFrom)))); } if ((Object)(object)m_glow != (Object)null) { float num = Mathf.Clamp01((heat - heat2.GlowFrom) / (heat2.JamAt - heat2.GlowFrom)); ((Behaviour)m_glow).enabled = num > 0f; m_glow.intensity = num * 2.5f; } } } } public static class Guns { internal sealed class Entry { public IModHost host; public MountedGun gun; public GameObject prefab; public Ammo ammo; public Dictionary<string, Material> looks; public Material tracer; public Material core; } [HarmonyPatch(typeof(ZNetScene), "Awake")] private static class RegisterPrefabs { private static void Prefix(ZNetScene __instance) { FindHitEffects(__instance); foreach (Entry entry in entries) { if (Ensure(entry, __instance.m_prefabs)) { entry.host.AddPrefabs(__instance, Prefabs(entry)); } else { entry.host.Log.LogError((object)("the vanilla materials were not found, " + entry.gun.Name + " is off")); } } } } [HarmonyPatch(typeof(ObjectDB), "Awake")] private static class OnHammer { private static void Postfix(ObjectDB __instance) { AddToHammer(__instance); } } [HarmonyPatch(typeof(ObjectDB), "CopyOtherDB")] private static class OnCopiedHammer { private static void Postfix(ObjectDB __instance) { AddToHammer(__instance); } } [HarmonyPatch(typeof(Game), "Start")] private static class OnGame { private static void Postfix() { Ammo.RegisterGive(); SyncedConfig.RegisterAll(ZRoutedRpc.instance); } } private static readonly List<Entry> entries = new List<Entry>(); private static GameObject holder; private static GameObject dent; internal static ManualLogSource Log; internal static EffectList HitEffects; public static Func<bool> BreakAllBuildings = () => false; public static string Version { get; private set; } public static void Start(IModHost host, Harmony harmony, string version) { Log = host.Log; Version = version; harmony.PatchAll(typeof(Guns).Assembly); SyncedConfig syncedConfig = new SyncedConfig(host, "vladasz.gunworks.cfg", "gw"); BreakAllBuildings = syncedConfig.Bool("Damage", "BreakAllBuildings", value: false, "true: rounds and shells break every building. false: only the buildings of the gunner, and of everyone when the gunner has PvP on."); syncedConfig.Received += Refresh; syncedConfig.Start(); Ammo.RegisterGive(); Log.LogInfo((object)("gunworks " + version + " ready")); } public static void Register(IModHost host, MountedGun gun) { if (entries.Any((Entry e) => e.gun.Prefab == gun.Prefab)) { host.Log.LogError((object)("a gun " + gun.Prefab + " is registered already, " + gun.Name + " is left out")); return; } Entry entry = new Entry { host = host, gun = gun }; entries.Add(entry); if ((Object)(object)ZNetScene.instance != (Object)null) { FindHitEffects(ZNetScene.instance); } if ((Object)(object)ZNetScene.instance != (Object)null && Ensure(entry, ZNetScene.instance.m_prefabs)) { host.AddPrefabs(ZNetScene.instance, Prefabs(entry)); } if ((Object)(object)ObjectDB.instance != (Object)null) { AddToHammer(ObjectDB.instance); } } public static void Stop() { if ((Object)(object)Gun.Manned != (Object)null && (Object)(object)Player.m_localPlayer != (Object)null) { Player.m_localPlayer.StopDoodadControl(); } PieceTable val = Hammer(ObjectDB.instance); Player localPlayer = Player.m_localPlayer; foreach (Entry entry in entries) { if ((Object)(object)val != (Object)null && (Object)(object)entry.prefab != (Object)null) { val.m_pieces.Remove(entry.prefab); } if ((Object)(object)localPlayer != (Object)null && (Object)(object)localPlayer.m_placementGhost != (Object)null && ((Object)localPlayer.m_placementGhost).name.StartsWith(entry.gun.Prefab)) { localPlayer.SetupPlacementGhost(); } entry.ammo?.Unload(); } entries.Clear(); SyncedConfig.UnregisterAll(); UnregisterRpc("gw_give"); if ((Object)(object)holder != (Object)null) { Object.Destroy((Object)(object)holder); holder = null; } TerrainOp val2 = (((Object)(object)dent != (Object)null) ? dent.GetComponent<TerrainOp>() : null); if ((Object)(object)val2 != (Object)null && (Object)(object)ObjectDB.instance != (Object)null && ObjectDB.instance.m_terrainOps.Remove(val2)) { ObjectDB.instance.UpdateRegisters(); } dent = null; HitEffects = null; Files.Clear(); } internal static Entry Find(string prefab) { return entries.FirstOrDefault((Entry e) => e.gun.Prefab == prefab); } public static void UnregisterRpc(params string[] names) { if (ZRoutedRpc.instance != null) { foreach (string text in names) { ZRoutedRpc.instance.m_functions.Remove(StringExtensionMethods.GetStableHashCode(text)); } } } private static IEnumerable<GameObject> Prefabs(Entry entry) { return ((IEnumerable<GameObject>)(object)new GameObject[2] { entry.prefab, entry.ammo?.Item }).Where((GameObject go) => (Object)(object)go != (Object)null); } private static void Refresh() { if ((Object)(object)ObjectDB.instance != (Object)null) { AddToHammer(ObjectDB.instance); } } private static bool Ensure(Entry entry, IEnumerable<GameObject> vanilla) { //IL_00d9: 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_0100: 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_0112: Expected O, but got Unknown //IL_0144: Unknown result type (might be due to invalid IL or missing references) //IL_014e: Expected O, but got Unknown //IL_01d1: Unknown result type (might be due to invalid IL or missing references) //IL_01ec: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)entry.prefab != (Object)null) { return true; } Dictionary<string, GameObject> dictionary = (from go in vanilla where (Object)(object)go != (Object)null group go by ((Object)go).name).ToDictionary((IGrouping<string, GameObject> g) => g.Key, (IGrouping<string, GameObject> g) => g.First()); Dictionary<string, Material> dictionary2 = Looks.Vanilla(dictionary); if (dictionary2 == null) { return false; } foreach (KeyValuePair<string, Color> tint in entry.gun.Tints) { dictionary2[tint.Key] = new Material(dictionary2["iron"]) { name = entry.gun.Prefab + " " + tint.Key, color = tint.Value }; } entry.looks = dictionary2; if ((Object)(object)holder == (Object)null) { holder = new GameObject("GunworksPrefabs"); holder.SetActive(false); Object.DontDestroyOnLoad((Object)(object)holder); } if (entry.gun.Feed?.Item != null) { entry.ammo = new Ammo(entry.host, entry.gun.Feed.Item, entry.gun.Scale); entry.ammo.Ensure(dictionary.Values, holder.transform, dictionary2); } entry.tracer = Looks.Tracer(entry.gun.Round.Glow); entry.core = Looks.Tracer(entry.gun.Round.Core); dictionary.TryGetValue("Cart", out var value); dictionary.TryGetValue("forge", out var value2); dictionary.TryGetValue("smelter", out var value3); entry.prefab = Prefab.Build(entry, holder.transform, value, value2, value3); entry.host.Log.LogInfo((object)(entry.gun.Name + " built: " + entry.gun.Prefab + ", cart sound " + (((Object)(object)value != (Object)null) ? "found" : "missing"))); return true; } private static void FindHitEffects(ZNetScene scene) { if (HitEffects == null) { HitEffects = Looks.BoltHits(scene.m_prefabs.Where((GameObject go) => (Object)(object)go != (Object)null)); } } private static PieceTable Hammer(ObjectDB db) { GameObject val = (((Object)(object)db != (Object)null) ? db.GetItemPrefab("Hammer") : null); if (!((Object)(object)val != (Object)null)) { return null; } return val.GetComponent<ItemDrop>()?.m_itemData.m_shared.m_buildPieces; } private static void AddToHammer(ObjectDB db) { PieceTable val = Hammer(db); if ((Object)(object)val == (Object)null || entries.Count == 0) { return; } EnsureDent(db); foreach (Entry entry in entries) { if (!Ensure(entry, val.m_pieces)) { entry.host.Log.LogError((object)("the vanilla materials were not found, " + entry.gun.Name + " is not buildable")); continue; } Piece component = entry.prefab.GetComponent<Piece>(); component.m_craftingStation = Station(val, entry.gun.Station); if (entry.ammo != null && (Object)(object)entry.ammo.Item == (Object)null && (Object)(object)entry.ammo.Ensure(db.m_items, holder.transform, entry.looks) != (Object)null && (Object)(object)ZNetScene.instance != (Object)null) { entry.host.AddPrefabs(ZNetScene.instance, (IEnumerable<GameObject>)(object)new GameObject[1] { entry.ammo.Item }); } entry.ammo?.Register(db, Station(val, entry.ammo.Spec.Station)); component.m_resources = Costs(entry.host, db, entry.gun.Cost(), entry.gun.Name, recover: true); if (!val.m_pieces.Contains(entry.prefab)) { val.m_pieces.Add(entry.prefab); } entry.host.Log.LogInfo((object)(entry.gun.Name + " on the hammer, station " + (((Object)(object)component.m_craftingStation != (Object)null) ? ((Object)component.m_craftingStation).name : "none"))); } Player localPlayer = Player.m_localPlayer; if (!((Object)(object)localPlayer != (Object)null)) { return; } try { localPlayer.UpdateKnownRecipesList(); localPlayer.UpdateAvailablePiecesList(); } catch (Exception ex) { Log.LogWarning((object)("the game could not look for new pieces, the guns show after the next change of the inventory: " + ex.Message)); } } private static CraftingStation Station(PieceTable table, string name) { return table.m_pieces.Select((GameObject p) => p.GetComponent<CraftingStation>()).FirstOrDefault((Func<CraftingStation, bool>)((CraftingStation s) => (Object)(object)s != (Object)null && ((Object)s).name == name)); } internal static Requirement[] Costs(IModHost host, ObjectDB db, string cost, string what, bool recover) { //IL_00b0: 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_00bd: Unknown result type (might be due to invalid IL or missing references) //IL_00c5: Unknown result type (might be due to invalid IL or missing references) //IL_00d2: Expected O, but got Unknown List<Requirement> list = new List<Requirement>(); string[] array = cost.Split(new char[1] { ',' }, StringSplitOptions.RemoveEmptyEntries); foreach (string text in array) { string[] array2 = text.Split(':'); object obj; if (array2.Length != 2) { obj = null; } else { GameObject itemPrefab = db.GetItemPrefab(array2[0].Trim()); obj = ((itemPrefab != null) ? itemPrefab.GetComponent<ItemDrop>() : null); } ItemDrop val = (ItemDrop)obj; if ((Object)(object)val == (Object)null || !int.TryParse(array2[1].Trim(), out var result) || result <= 0) { host.Log.LogWarning((object)("the cost part " + text + " of " + what + " is not a known item:amount, it is left out")); } else { list.Add(new Requirement { m_resItem = val, m_amount = result, m_recover = recover }); } } return list.ToArray(); } private static void EnsureDent(ObjectDB db) { if ((Object)(object)dent == (Object)null && (Object)(object)holder != (Object)null) { GameObject itemPrefab = db.GetItemPrefab("PickaxeIron"); GameObject val = ((itemPrefab == null) ? null : itemPrefab.GetComponent<ItemDrop>()?.m_itemData.m_shared.m_spawnOnHitTerrain); if ((Object)(object)val == (Object)null) { Log.LogWarning((object)"the dig of the iron pickaxe was not found, the rounds make no dents"); return; } dent = Object.Instantiate<GameObject>(val, holder.transform, false); ((Object)dent).name = "gw_dent"; TerrainOp[] componentsInChildren = dent.GetComponentsInChildren<TerrainOp>(true); for (int i = 0; i < componentsInChildren.Length; i++) { Settings settings = componentsInChildren[i].m_settings; settings.m_raiseDelta *= 0.25f; settings.m_raisePower *= 0.25f; settings.m_raiseRadius *= 0.5f; settings.m_smoothRadius *= 0.5f; settings.m_levelRadius *= 0.5f; settings.m_paintRadius *= 0.5f; } } TerrainOp val2 = (((Object)(object)dent != (Object)null) ? dent.GetComponent<TerrainOp>() : null); if ((Object)(object)val2 != (Object)null && !db.m_terrainOps.Contains(val2)) { db.m_terrainOps.Add(val2); db.UpdateRegisters(); } } internal static void Dent(Vector3 point, Player player) { //IL_000d: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)dent != (Object)null) { Attack.SpawnOnHitTerrain(point, dent, (Character)(object)player, 0f, (ItemData)null, (ItemData)null, false); } } internal static AudioSource Speaker(GameObject root, AudioClip clip, float maxDistance) { AudioSource obj = root.AddComponent<AudioSource>(); obj.clip = clip; obj.playOnAwake = false; obj.spatialBlend = 1f; obj.rolloffMode = (AudioRolloffMode)1; obj.minDistance = 4f; obj.maxDistance = maxDistance; obj.volume = 0.9f; obj.outputAudioMixerGroup = Looks.Mixer; return obj; } } public interface IModHost { string Name { get; } ManualLogSource Log { get; } byte[] ReadAsset(string relative); void AddPrefabs(ZNetScene scene, IEnumerable<GameObject> prefabs); } public sealed class FolderHost : IModHost { private readonly string folder; public string Name { get; } public ManualLogSource Log { get; } public FolderHost(string name, ManualLogSource log, string folder) { Name = name; Log = log; this.folder = folder; } public byte[] ReadAsset(string relative) { string path = Path.Combine(folder, relative.Replace('/', Path.DirectorySeparatorChar)); if (!File.Exists(path)) { path = Path.Combine(folder, Path.GetFileName(path)); } if (!File.Exists(path)) { throw new FileNotFoundException(Name + " has no " + relative + " next to its dll, install the whole mod folder"); } return File.ReadAllBytes(path); } public void AddPrefabs(ZNetScene scene, IEnumerable<GameObject> prefabs) { bool flag = (Object)(object)ZNetScene.instance == (Object)(object)scene; foreach (GameObject prefab in prefabs) { scene.m_prefabs.RemoveAll((GameObject p) => (Object)(object)p != (Object)null && ((Object)p).name == ((Object)prefab).name); scene.m_prefabs.Add(prefab); if (flag) { scene.m_namedPrefabs[StringExtensionMethods.GetStableHashCode(((Object)prefab).name)] = prefab; } } } } public class Hud : MonoBehaviour { private const float BarWidth = 320f; private static readonly Color Cool = new Color(0.75f, 0.75f, 0.75f, 0.9f); private static readonly Color Hot = new Color(1f, 0.55f, 0.1f, 0.95f); private static readonly Color Red = new Color(0.95f, 0.15f, 0.1f, 1f); private static bool touched; private Gun m_gun; private RectTransform m_back; private RectTransform m_fill; private Image m_fillImage; private TMP_Text m_text; private GameObject m_fire; private GameObject m_leave; public bool FireHeld { get; private set; } public static Hud Show(Gun gun) { //IL_0005: Unknown result type (might be due to invalid IL or missing references) //IL_000b: Expected O, but got Unknown //IL_0036: Unknown result type (might be due to invalid IL or missing references) GameObject val = new GameObject("GunworksHud"); Canvas obj = val.AddComponent<Canvas>(); obj.renderMode = (RenderMode)0; obj.sortingOrder = 40; CanvasScaler obj2 = val.AddComponent<CanvasScaler>(); obj2.uiScaleMode = (ScaleMode)1; obj2.referenceResolution = new Vector2(1920f, 1080f); val.AddComponent<GraphicRaycaster>(); Hud hud = val.AddComponent<Hud>(); hud.m_gun = gun; hud.Build(val.transform); return hud; } private void Build(Transform root) { //IL_0022: Unknown result type (might be due to invalid IL or missing references) //IL_0031: Unknown result type (might be due to invalid IL or missing references) //IL_0040: Unknown result type (might be due to invalid IL or missing references) //IL_0059: Unknown result type (might be due to invalid IL or missing references) //IL_007e: Unknown result type (might be due to invalid IL or missing references) //IL_008d: 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_00c0: Unknown result type (might be due to invalid IL or missing references) //IL_00f3: 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_0125: 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_0183: Unknown result type (might be due to invalid IL or missing references) //IL_01ac: Unknown result type (might be due to invalid IL or missing references) //IL_01df: Unknown result type (might be due to invalid IL or missing references) //IL_01ee: Unknown result type (might be due to invalid IL or missing references) //IL_01fd: Unknown result type (might be due to invalid IL or missing references) //IL_0216: Unknown result type (might be due to invalid IL or missing references) //IL_0233: Unknown result type (might be due to invalid IL or missing references) //IL_029f: Unknown result type (might be due to invalid IL or missing references) //IL_02ae: Unknown result type (might be due to invalid IL or missing references) //IL_02bd: Unknown result type (might be due to invalid IL or missing references) //IL_02d6: Unknown result type (might be due to invalid IL or missing references) //IL_02f3: Unknown result type (might be due to invalid IL or missing references) HeatSpec heat = m_gun.Spec.Heat; m_back = Box(root, "heat", new Vector2(0.5f, 0.5f), new Vector2(0f, -90f), new Vector2(326f, 18f), new Color(0f, 0f, 0f, 0.6f)); m_fill = Box((Transform)(object)m_back, "fill", new Vector2(0f, 0.5f), new Vector2(3f, 0f), new Vector2(0f, 12f), Cool); m_fill.pivot = new Vector2(0f, 0.5f); m_fillImage = ((Component)m_fill).GetComponent<Image>(); if (heat != null) { Box((Transform)(object)m_back, "burn mark", new Vector2(0f, 0.5f), new Vector2(3f + 320f * heat.BurnFrom / heat.JamAt, 0f), new Vector2(2f, 18f), new Color(1f, 1f, 1f, 0.7f)); } else { ((Behaviour)((Component)m_back).GetComponent<Image>()).enabled = false; ((Component)m_fill).gameObject.SetActive(false); } m_text = Text((Transform)(object)m_back, "rounds", new Vector2(0f, 22f), 24f); Text((Transform)(object)m_back, "help", new Vector2(0f, -24f), 18f).text = Localization.instance.Localize("[<color=yellow>$KEY_Attack</color>] Fire [<color=yellow>$KEY_Use</color>] Let go"); RectTransform val = Box(root, "fire", new Vector2(1f, 0f), new Vector2(-150f, 150f), new Vector2(190f, 190f), new Color(0.55f, 0.08f, 0.05f, 0.55f)); m_fire = ((Component)val).gameObject; Text((Transform)(object)val, "label", Vector2.zero, 40f).text = "FIRE"; EventTrigger trigger = ((Component)val).gameObject.AddComponent<EventTrigger>(); On(trigger, (EventTriggerType)2, delegate { FireHeld = true; }); On(trigger, (EventTriggerType)3, delegate { FireHeld = false; }); On(trigger, (EventTriggerType)1, delegate { FireHeld = false; }); RectTransform val2 = Box(root, "leave", new Vector2(1f, 0f), new Vector2(-370f, 110f), new Vector2(170f, 90f), new Color(0f, 0f, 0f, 0.55f)); m_leave = ((Component)val2).gameObject; Text((Transform)(object)val2, "label", Vector2.zero, 30f).text = "LEAVE"; On(((Component)val2).gameObject.AddComponent<EventTrigger>(), (EventTriggerType)4, delegate { Player localPlayer = Player.m_localPlayer; if (localPlayer != null) { localPlayer.StopDoodadControl(); } }); Buttons(); } private void Buttons() { touched |= Input.touchCount > 0; if (m_fire.activeSelf != touched) { m_fire.SetActive(touched); m_leave.SetActive(touched); } } private void Update() { //IL_0056: Unknown result type (might be due to invalid IL or missing references) //IL_0096: Unknown result type (might be due to invalid IL or missing references) //IL_009b: 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_006f: Unknown result type (might be due to invalid IL or missing references) //IL_0074: Unknown result type (might be due to invalid IL or missing references) //IL_008f: Unknown result type (might be due to invalid IL or missing references) if (!((Object)(object)m_gun == (Object)null)) { Buttons(); HeatSpec heat = m_gun.Spec.Heat; if (heat != null) { float heat2 = m_gun.Heat; m_fill.sizeDelta = new Vector2(320f * Mathf.Clamp01(heat2 / heat.JamAt), 12f); ((Graphic)m_fillImage).color = ((heat2 < heat.BurnFrom) ? Color.Lerp(Cool, Hot, heat2 / heat.BurnFrom) : Color.Lerp(Hot, Red, (heat2 - heat.BurnFrom) / (heat.JamAt - heat.BurnFrom))); } float jamLeft = m_gun.JamLeft; m_text.text = ((jamLeft > 0f) ? $"Jammed, {Mathf.CeilToInt(jamLeft)} s" : (m_gun.Infinite ? "Infinite rounds" : $"{m_gun.Rounds} rounds")); } } private static RectTransform Box(Transform parent, string name, Vector2 anchor, Vector2 position, Vector2 size, Color color) { //IL_0014: Unknown result type (might be due to invalid IL or missing references) //IL_001a: Expected O, but got Unknown //IL_002d: Unknown result type (might be due to invalid IL or missing references) //IL_0032: Unknown result type (might be due to invalid IL or missing references) //IL_0033: Unknown result type (might be due to invalid IL or missing references) //IL_0039: Unknown result type (might be due to invalid IL or missing references) //IL_003a: Unknown result type (might be due to invalid IL or missing references) //IL_0040: 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) //IL_0047: Unknown result type (might be due to invalid IL or missing references) //IL_0048: Unknown result type (might be due to invalid IL or missing references) //IL_0055: Unknown result type (might be due to invalid IL or missing references) //IL_005d: Expected O, but got Unknown GameObject val = new GameObject(name, new Type[1] { typeof(RectTransform) }); val.transform.SetParent(parent, false); RectTransform val2 = (RectTransform)val.transform; val2.anchorMin = anchor; val2.anchorMax = anchor; val2.anchoredPosition = position; val2.sizeDelta = size; ((Graphic)val.AddComponent<Image>()).color = color; return val2; } private static TMP_Text Text(Transform parent, string name, Vector2 position, float size) { //IL_0014: Unknown result type (might be due to invalid IL or missing references) //IL_0019: Unknown result type (might be due to invalid IL or missing references) //IL_0020: 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_0033: Unknown result type (might be due to invalid IL or missing references) //IL_0038: Unknown result type (might be due to invalid IL or missing references) //IL_0039: Unknown result type (might be due to invalid IL or missing references) //IL_0049: Unknown result type (might be due to invalid IL or missing references) //IL_0053: Unknown result type (might be due to invalid IL or missing references) GameObject val = new GameObject(name, new Type[1] { typeof(RectTransform) }); val.SetActive(false); val.transform.SetParent(parent, false); RectTransform val2 = (RectTransform)val.transform; val2.anchoredPosition = position; val2.sizeDelta = new Vector2(400f, 50f); TextMeshProUGUI val3 = val.AddComponent<TextMeshProUGUI>(); ((TMP_Text)val3).alignment = (TextAlignmentOptions)514; ((TMP_Text)val3).fontSize = size; ((Graphic)val3).raycastTarget = false; TMP_Text val4 = (((Object)(object)MessageHud.instance != (Object)null) ? MessageHud.instance.m_messageText : null); if ((Object)(object)val4 != (Object)null) { ((TMP_Text)val3).font = val4.font; } val.SetActive(true); return (TMP_Text)(object)val3; } private static void On(EventTrigger trigger, EventTriggerType type, Action action) { //IL_000d: Unknown result type (might be due to invalid IL or missing references) //IL_0012: Unknown result type (might be due to invalid IL or missing references) //IL_0013: Unknown result type (might be due to invalid IL or missing references) //IL_0014: Unknown result type (might be due to invalid IL or missing references) //IL_001a: Expected O, but got Unknown Entry val = new Entry { eventID = type }; ((UnityEvent<BaseEventData>)(object)val.callback).AddListener((UnityAction<BaseEventData>)delegate { action(); }); trigger.triggers.Add(val); } } public static class Looks { public const string Wood = "wood"; public const string Iron = "iron"; private static readonly (string slot, string prefab, string material)[] Sources = new(string, string, string)[2] { ("wood", "wood_beam", "woodwall"), ("iron", "woodiron_beam", "Ironbeam_mat") }; internal static AudioMixerGroup Mixer; internal static Dictionary<string, Material> Vanilla(Dictionary<string, GameObject> byName) { Dictionary<string, Material> dictionary = new Dictionary<string, Material>(); (string, string, string)[] sources = Sources; for (int i = 0; i < sources.Length; i++) { (string, string, string) tuple = sources[i]; string item = tuple.Item1; string item2 = tuple.Item2; string material = tuple.Item3; GameObject value; Material val = (byName.TryGetValue(item2, out value) ? value.GetComponentsInChildren<Renderer>(true).SelectMany((Renderer r) => r.sharedMaterials).FirstOrDefault((Func<Material, bool>)((Material m) => (Object)(object)m != (Object)null && ((Object)m).name == material)) : null); if ((Object)(object)val == (Object)null) { return null; } dictionary[item] = Moveable(val, item); } if ((Object)(object)Mixer == (Object)null && byName.TryGetValue("Cart", out var value2)) { Vagon componentInChildren = value2.GetComponentInChildren<Vagon>(true); object mixer; if (componentInChildren == null) { mixer = null; } else { ZSFX? obj = ((IEnumerable<ZSFX>)componentInChildren.m_wheelLoops).FirstOrDefault((Func<ZSFX, bool>)((ZSFX z) => (Object)(object)z != (Object)null)); if (obj == null) { mixer = null; } else { AudioSource component = ((Component)obj).GetComponent<AudioSource>(); mixer = ((component != null) ? component.outputAudioMixerGroup : null); } } Mixer = (AudioMixerGroup)mixer; } return dictionary; } private static Material Moveable(Material source, string slot) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_0018: Expected O, but got Unknown Material val = new Material(source) { name = "gunworks " + slot }; (string, float)[] array = new(string, float)[5] { ("_MoveableObject", 1f), ("_TriplanarLocalPos", 1f), ("_ValueNoise", 0f), ("_ValueNoiseVertex", 0f), ("_RippleDistance", 0f) }; for (int i = 0; i < array.Length; i++) { var (text, num) = array[i]; if (val.HasProperty(text)) { val.SetFloat(text, num); } } return val; } internal static EffectList BoltHits(IEnumerable<GameObject> vanilla) { Projectile[] source = (from go in vanilla select go.GetComponent<Projectile>() into p where (Object)(object)p != (Object)null && p.m_hitEffects != null && p.m_hitEffects.m_effectPrefabs.Length != 0 select p).ToArray(); Projectile val = ((IEnumerable<Projectile>)source).FirstOrDefault((Func<Projectile, bool>)((Projectile p) => ((Object)p).name.Contains("bolt") || ((Object)p).name.Contains("arbalest"))) ?? ((IEnumerable<Projectile>)source).FirstOrDefault((Func<Projectile, bool>)((Projectile p) => ((Object)p).name.Contains("arrow"))); Guns.Log.LogInfo((object)("gunworks hit effects from " + (((Object)(object)val != (Object)null) ? ((Object)val).name : "nothing"))); return val?.m_hitEffects; } internal static Material Tracer(Color color) { //IL_0034: Unknown result type (might be due to invalid IL or missing references) //IL_0039: Unknown result type (might be due to invalid IL or missing references) //IL_0044: Unknown result type (might be due to invalid IL or missing references) //IL_0045: Unknown result type (might be due to invalid IL or missing references) //IL_004c: Expected O, but got Unknown Shader val = Shader.Find("Legacy Shaders/Particles/Additive") ?? Shader.Find("Sprites/Default"); if ((Object)(object)val == (Object)null) { Guns.Log.LogWarning((object)"no shader for the tracers was found, the rounds show no tracers"); return null; } return new Material(val) { name = "gunworks tracer", color = color }; } } public class Grips : MonoBehaviour, Hoverable, Interactable { private Gun m_gun; private void Awake() { m_gun = ((Component)this).GetComponentInParent<Gun>(); } public string GetHoverName() { if (!((Object)(object)m_gun != (Object)null) || m_gun.Spec == null) { return ""; } return m_gun.Spec.Name; } public string GetHoverText() { if ((Object)(object)m_gun == (Object)null || m_gun.Spec == null) { return ""; } string text = (((Object)(object)Gun.Manned == (Object)(object)m_gun) ? "Let go" : "Shoot"); string text2 = (m_gun.Infinite ? "" : $", {m_gun.Rounds} rounds"); return Localization.instance.Localize(m_gun.Spec.Name + text2 + "\n[<color=yellow><b>$KEY_Use</b></color>] " + text); } public bool Interact(Humanoid user, bool hold, bool alt) { if (hold || (Object)(object)m_gun == (Object)null) { return false; } m_gun.Take(user); return true; } public bool UseItem(Humanoid user, ItemData item) { return false; } public float GetHoverOffset() { return 0f; } } public class Handle : MonoBehaviour, Hoverable, Interactable { private Vagon m_vagon; private void Awake() { m_vagon = ((Component)this).GetComponentInParent<Vagon>(); } public string GetHoverName() { if (!((Object)(object)m_vagon != (Object)null)) { return ""; } return m_vagon.m_name; } public string GetHoverText() { if ((Object)(object)m_vagon == (Object)null) { return ""; } string text = (((Object)(object)Player.m_localPlayer != (Object)null && m_vagon.IsAttached((Character)(object)Player.m_localPlayer)) ? "Let go" : "Pull"); return Localization.instance.Localize(m_vagon.m_name + "\n[<color=yellow><b>$KEY_Use</b></color>] " + text); } public bool Interact(Humanoid user, bool hold, bool alt) { if ((Object)(object)m_vagon != (Object)null) { return m_vagon.Interact(user, hold, alt); } return false; } public bool UseItem(Humanoid user, ItemData item) { return false; } public float GetHoverOffset() { return 0f; } } public class Inert : MonoBehaviour, Hoverable, Interactable { public string GetHoverName() { return ""; } public string GetHoverText() { return ""; } public bool Interact(Humanoid user, bool hold, bool alt) { return false; } public bool UseItem(Humanoid user, ItemData item) { return false; } public float GetHoverOffset() { return 0f; } } public class Slot : MonoBehaviour, Hoverable, Interactable { private Gun m_gun; private Feed m_feed;