Untitled left D:\ValheimDev\Dumps\Latest\assembly_valheim\Catapult.cs
.  using System;
  using System.Collections.Generic;
  using System.Linq;
  using Dynamics;
  using UnityEngine;
  using UnityEngine.Serialization;
   
  public class Catapult : MonoBehaviour
  {
      private void Start()
      {
          this.m_nview = base.GetComponent<ZNetView>();
          this.m_wagon = base.GetComponent<Vagon>();
          this.m_rigidBody = base.GetComponent<Rigidbody>();
          this.m_baseMass = this.m_rigidBody.mass;
          this.m_legRotations = new Vector3[this.m_legs.Count];
          this.m_legRotationQuat = new Quaternion[this.m_legs.Count];
          for (int i = 0; i < this.m_legs.Count; i++)
          {
              Switch @switch = this.m_legs[i];
              @switch.m_onUse = (Switch.Callback)Delegate.Combine(@switch.m_onUse, new Switch.Callback(this.OnLegUse));
              Switch switch2 = this.m_legs[i];
              switch2.m_onHover = (Switch.TooltipCallback)Delegate.Combine(switch2.m_onHover, new Switch.TooltipCallback(this.OnLegHover));
              this.m_legRotations[i] = this.m_legs[i].transform.localEulerAngles;
              this.m_legRotationQuat[i] = this.m_legs[i].transform.localRotation;
          }
          Switch loadPoint = this.m_loadPoint;
          loadPoint.m_onUse = (Switch.Callback)Delegate.Combine(loadPoint.m_onUse, new Switch.Callback(this.OnLoadPointUse));
          Switch loadPoint2 = this.m_loadPoint;
          loadPoint2.m_onHover = (Switch.TooltipCallback)Delegate.Combine(loadPoint2.m_onHover, new Switch.TooltipCallback(this.OnHoverLoadPoint));
          this.m_armRotation = this.m_arm.transform.localRotation.eulerAngles;
          this.m_armDynamics = new FloatDynamics(this.m_armDynamicsSettings, 0f);
          this.m_legDynamics = new FloatDynamics(this.m_legDynamicsSettings, 1f);
          this.m_legAnimationCurveUp = new AnimationCurve();
          for (int j = 0; j < this.m_legAnimationCurve.keys.Length; j++)
          {
              Keyframe keyframe = this.m_legAnimationCurve.keys[j];
              keyframe.value = 1f - keyframe.value;
              this.m_legAnimationCurveUp.AddKey(keyframe);
          }
          if (this.m_nview)
          {
              ZDO zdo = this.m_nview.GetZDO();
              if (zdo != null && zdo.GetBool(ZDOVars.s_locked, false))
              {
                  this.m_lockedLegs = zdo.GetBool(ZDOVars.s_locked, false);
              }
          }
          this.m_nview.Register("RPC_Shoot", new Action<long>(this.RPC_Shoot));
          this.m_nview.Register<bool>("RPC_OnLegUse", new Action<long, bool>(this.RPC_OnLegUse));
          this.m_nview.Register<string>("RPC_SetLoadedVisual", new Action<long, string>(this.RPC_SetLoadedVisual));
          this.m_legAnimTimer = 1f;
          this.m_movingLegs = true;
          this.UpdateLegAnimation(Time.fixedDeltaTime);
          if (Catapult.m_characterMask == 0)
          {
              Catapult.m_characterMask = LayerMask.GetMask(new string[] { "character" });
          }
      }
   
      private void FixedUpdate()
      {
          this.UpdateArmAnimation(Time.fixedDeltaTime);
          this.UpdateLegAnimation(Time.fixedDeltaTime);
      }
   
      private void UpdateArmAnimation(float dt)
      {
          float num = this.m_armAnimTime / this.m_armAnimationTime;
          float num2 = this.m_armDynamics.Update(dt, this.m_armAnimation.Evaluate(num), float.NegativeInfinity, false);
          this.m_arm.transform.localEulerAngles = new Vector3(this.m_armRotation.x + num2 * this.m_armAnimationDegrees, this.m_armRotation.y, this.m_armRotation.z);
          if (this.m_armAnimTime <= 0f)
          {
              return;
          }
          this.m_armAnimTime += dt;
          if (this.m_armAnimTime > this.m_armAnimationTime)
          {
              this.m_armAnimTime = 0f;
              this.m_arm.transform.localEulerAngles = this.m_armRotation;
              this.m_armReturnEffect.Create(this.m_loadPoint.transform.position, this.m_loadPoint.transform.rotation, null, 1f, -1);
              return;
          }
          if (num > this.m_releaseAnimationTime && (this.m_loadedItem != null || this.m_launchCharacters.Count > 0))
          {
              this.Release();
              return;
          }
          if (this.m_preLaunchForce > 0f)
          {
              Vector3 normalized = (this.m_forceVector.transform.position - base.transform.position).normalized;
              foreach (Character character in this.m_launchCharacters)
              {
                  character.ForceJump(normalized * this.m_preLaunchForce, true);
              }
          }
      }
   
      private void UpdateLegAnimation(float dt)
      {
          if (!this.m_nview || !this.m_nview.IsValid())
          {
              return;
          }
          if (this.m_movingLegs)
          {
              this.m_legAnimTimer += Time.deltaTime;
              if (this.m_legAnimTimer >= this.m_legAnimationTime)
              {
                  this.m_movingLegs = false;
                  for (int i = 0; i < this.m_legs.Count; i++)
                  {
                      Vector3 position = this.m_legs[i].transform.GetChild(0).transform.position;
                      if (!this.m_lockedLegs)
                      {
                          this.m_legUpDoneEffect.Create(this.m_legs[i].transform.position, this.m_legs[i].transform.rotation, null, 1f, -1);
                      }
                      else
                      {
                          this.m_legDownDoneEffect.Create(position, Quaternion.identity, null, 1f, -1);
                          this.m_rigidBody.mass = this.m_legDownMass;
                      }
                  }
                  return;
              }
          }
          float num = this.m_legAnimTimer / this.m_legAnimationTime;
          AnimationCurve animationCurve = (this.m_lockedLegs ? this.m_legAnimationCurve : this.m_legAnimationCurveUp);
          float num2 = this.m_legDynamics.Update(dt, animationCurve.Evaluate(num), float.NegativeInfinity, false);
          for (int j = 0; j < this.m_legs.Count; j++)
          {
              Vector3 vector = this.m_legRotations[j];
              vector.z += num2 * this.m_legAnimationDegrees;
              this.m_legs[j].transform.localEulerAngles = vector;
          }
      }
   
      private bool OnLegUse(Switch sw, Humanoid user, ItemDrop.ItemData item)
      {
          if (this.m_movingLegs)
          {
              return false;
          }
          this.m_nview.InvokeRPC(ZNetView.Everybody, "RPC_OnLegUse", new object[] { !this.m_lockedLegs });
          if (!this.m_nview.IsOwner())
          {
              this.m_nview.InvokeRPC("RPC_RequestOwn", Array.Empty<object>());
          }
          return true;
      }
   
      private void RPC_OnLegUse(long sender, bool value)
      {
          this.m_lockedLegs = value;
          if (this.m_nview && this.m_nview.IsOwner())
          {
              this.m_nview.GetZDO().Set(ZDOVars.s_locked, this.m_lockedLegs);
          }
          this.m_legAnimTimer = 0f;
          this.m_movingLegs = true;
          if (this.m_lockedLegs)
          {
              this.m_legDownEffect.Create(base.transform.position, base.transform.rotation, null, 1f, -1);
              return;
          }
          this.m_legUpEffect.Create(base.transform.position, base.transform.rotation, null, 1f, -1);
          this.m_rigidBody.mass = this.m_baseMass;
      }
   
      private string OnLegHover()
      {
          if (this.m_movingLegs)
          {
              return "";
          }
          return Localization.instance.Localize(this.m_lockedLegs ? "[<color=yellow><b>$KEY_Use</b></color>] $piece_catapult_legsup" : "[<color=yellow><b>$KEY_Use</b></color>] $piece_catapult_legsdown");
      }
   
      private bool OnLoadPointUse(Switch sw, Humanoid user, ItemDrop.ItemData item)
      {
          if (this.m_loadedItem != null || item == null || this.m_armAnimTime != 0f)
          {
              user.UseIemBlockkMessage();
              return false;
          }
          if (!this.CanItemBeLoaded(item))
          {
              user.Message(MessageHud.MessageType.Center, "$piece_catapult_wontfit", 0, null);
              user.UseIemBlockkMessage();
              return false;
          }
          this.m_nview.InvokeRPC(ZNetView.Everybody, "RPC_SetLoadedVisual", new object[] { item.m_dropPrefab.name });
          this.m_loadedItem = item;
          this.m_loadStack = Mathf.Min(item.m_stack, this.m_maxLoadStack);
          base.Invoke("Shoot", this.m_shootAfterLoadDelay);
          if (item.m_equipped)
          {
              user.UnequipItem(item, true);
          }
          user.GetInventory().RemoveItem(item, this.m_loadStack);
          if (!this.m_nview.IsOwner())
          {
              this.m_nview.InvokeRPC("RPC_RequestOwn", Array.Empty<object>());
          }
          this.m_loadItemEffect.Create(this.m_loadPoint.transform.position, this.m_loadPoint.transform.rotation, null, 1f, -1);
          return true;
      }
   
      private bool CanItemBeLoaded(ItemDrop.ItemData item)
      {
          return this.m_includeItemsOverride.Any((ItemDrop x) => x.m_itemData.m_shared.m_name == item.m_shared.m_name) || ((!this.m_onlyUseIncludedProjectiles || !(ItemStand.GetAttachPrefab(item.m_dropPrefab) == null)) && (!this.m_defaultIncludeAndListExclude || !this.m_includeExcludeTypesList.Contains(item.m_shared.m_itemType)) && (this.m_defaultIncludeAndListExclude || this.m_includeExcludeTypesList.Contains(item.m_shared.m_itemType)) && !this.m_excludeItemsOverride.Any((ItemDrop x) => x.m_itemData.m_shared.m_name == item.m_shared.m_name));
      }
   
      private void Shoot()
      {
          this.m_nview.InvokeRPC(ZNetView.Everybody, "RPC_Shoot", Array.Empty<object>());
      }
   
      private void RPC_Shoot(long sender)
      {
          this.m_shootStartEffect.Create(this.m_loadPoint.transform.position, this.m_loadPoint.transform.rotation, null, 1f, -1);
          this.m_armAnimTime = 1E-06f;
          this.CollectLaunchCharacters();
      }
   
      private void RPC_SetLoadedVisual(long sender, string name)
      {
          GameObject itemPrefab = ObjectDB.instance.GetItemPrefab(name);
          ItemDrop component = itemPrefab.GetComponent<ItemDrop>();
          if (component != null)
          {
              this.m_loadedItem = component.m_itemData;
          }
          GameObject gameObject = ItemStand.GetAttachPrefab(itemPrefab);
          if (gameObject == null)
          {
              ZLog.LogError("Valid catapult ammo '" + name + "' is missing attach prefab, aborting.");
              return;
          }
          gameObject = ItemStand.GetAttachGameObject(gameObject);
          this.m_visualItem = UnityEngine.Object.Instantiate<GameObject>(gameObject, this.m_loadPoint.transform);
          this.m_visualItem.transform.localPosition = Vector3.zero;
      }
   
      private void Release()
      {
          this.ShootProjectile();
          this.LaunchCharacters();
          this.m_loadedItem = null;
      }
   
      private void ShootProjectile()
      {
          Vector3 vector = this.m_forceVector.transform.position - base.transform.position;
          Vector3 vector2 = vector.normalized;
          this.m_shootReleaseEffect.Create(this.m_loadPoint.transform.position, Quaternion.LookRotation(vector2), null, 1f, -1);
          Projectile projectile = this.m_projectile;
          bool flag = this.m_includeItemsOverride.Any((ItemDrop x) => x.m_itemData.m_shared.m_name == this.m_loadedItem.m_shared.m_name);
          if ((!this.m_onlyUseIncludedProjectiles || (this.m_onlyUseIncludedProjectiles && flag)) && this.m_loadedItem.m_shared.m_attack.m_attackProjectile != null)
          {
              Projectile component = this.m_loadedItem.m_shared.m_attack.m_attackProjectile.GetComponent<Projectile>();
              if (component != null)
              {
                  projectile = component;
              }
          }
          this.m_lastAmmo = this.m_defaultAmmo.m_itemData;
          if (this.m_nview.IsOwner())
          {
              for (int i = 0; i < this.m_loadStack; i++)
              {
                  this.m_lastProjectile = UnityEngine.Object.Instantiate<Projectile>(projectile, this.m_shootPoint.transform.position, this.m_shootPoint.transform.rotation);
                  HitData hitData = new HitData();
                  if (projectile == this.m_projectile)
                  {
                      if (this.m_lastProjectile.m_visual)
                      {
                          this.m_lastProjectile.m_visual.gameObject.SetActive(false);
                      }
                      this.m_lastProjectile.GetComponent<ZNetView>().GetZDO().Set(ZDOVars.s_visual, this.m_loadedItem.m_dropPrefab.name);
                      Collider componentInChildren = this.m_lastProjectile.m_visual.GetComponentInChildren<Collider>();
                      if (componentInChildren != null)
                      {
                          componentInChildren.enabled = false;
                      }
                      if (!this.m_onlyIncludedItemsDealDamage || (this.m_onlyIncludedItemsDealDamage && flag))
                      {
                          hitData.m_toolTier = (short)this.m_lastAmmo.m_shared.m_toolTier;
                          hitData.m_pushForce = this.m_lastAmmo.m_shared.m_attackForce;
                          hitData.m_backstabBonus = this.m_lastAmmo.m_shared.m_backstabBonus;
                          hitData.m_staggerMultiplier = this.m_lastAmmo.m_shared.m_attack.m_staggerMultiplier;
                          hitData.m_damage.Add(this.m_lastAmmo.GetDamage(), 1);
                          hitData.m_statusEffectHash = (this.m_lastAmmo.m_shared.m_attackStatusEffect ? this.m_lastAmmo.m_shared.m_attackStatusEffect.NameHash() : 0);
                          hitData.m_blockable = this.m_lastAmmo.m_shared.m_blockable;
                          hitData.m_dodgeable = this.m_lastAmmo.m_shared.m_dodgeable;
                          hitData.m_skill = this.m_lastAmmo.m_shared.m_skillType;
                          if (this.m_lastAmmo.m_shared.m_attackStatusEffect != null)
                          {
                              hitData.m_statusEffectHash = this.m_lastAmmo.m_shared.m_attackStatusEffect.NameHash();
                          }
                      }
                  }
                  else if (!this.m_onlyIncludedItemsDealDamage || (this.m_onlyIncludedItemsDealDamage && flag))
                  {
                      hitData.m_toolTier = (short)this.m_loadedItem.m_shared.m_toolTier;
                      hitData.m_pushForce = this.m_loadedItem.m_shared.m_attackForce;
                      hitData.m_backstabBonus = this.m_loadedItem.m_shared.m_backstabBonus;
                      hitData.m_damage.Add(this.m_loadedItem.GetDamage(), 1);
                      hitData.m_statusEffectHash = (this.m_loadedItem.m_shared.m_attackStatusEffect ? this.m_loadedItem.m_shared.m_attackStatusEffect.NameHash() : 0);
                      hitData.m_skillLevel = 1f;
                      hitData.m_itemLevel = (short)this.m_loadedItem.m_quality;
                      hitData.m_itemWorldLevel = (byte)this.m_loadedItem.m_worldLevel;
                      hitData.m_blockable = this.m_loadedItem.m_shared.m_blockable;
                      hitData.m_dodgeable = this.m_loadedItem.m_shared.m_dodgeable;
                      hitData.m_skill = this.m_loadedItem.m_shared.m_skillType;
                      hitData.m_hitType = HitData.HitType.Catapult;
                  }
                  if (this.m_lastAmmo.m_shared.m_attack.m_projectileAccuracyMin > 0f || this.m_lastAmmo.m_shared.m_attack.m_projectileAccuracy > 0f)
                  {
                      float num = UnityEngine.Random.Range(this.m_lastAmmo.m_shared.m_attack.m_projectileAccuracyMin, this.m_lastAmmo.m_shared.m_attack.m_projectileAccuracy);
                      Vector3 vector3 = Vector3.Cross(vector2, Vector3.up);
                      Quaternion quaternion = Quaternion.AngleAxis(UnityEngine.Random.Range(-num, num), Vector3.up);
                      vector2 = Quaternion.AngleAxis(UnityEngine.Random.Range(-num, num), vector3) * vector2;
                      vector2 = quaternion * vector2;
                  }
                  Vector3 vector4 = vector * this.m_lastAmmo.m_shared.m_attack.m_projectileVel * UnityEngine.Random.Range(1f, 1f + this.m_shootVelocityVariation);
                  projectile.m_respawnItemOnHit = !flag;
                  this.m_lastProjectile.Setup(null, vector4, this.m_hitNoise, hitData, this.m_loadedItem, this.m_lastAmmo);
                  this.m_lastProjectile.m_rotateVisual = UnityEngine.Random.Range(this.m_randomRotationMin, this.m_randomRotationMax);
                  this.m_lastProjectile.m_rotateVisualY = UnityEngine.Random.Range(this.m_randomRotationMin, this.m_randomRotationMax);
                  this.m_lastProjectile.m_rotateVisualZ = UnityEngine.Random.Range(this.m_randomRotationMin, this.m_randomRotationMax);
              }
          }
          UnityEngine.Object.Destroy(this.m_visualItem);
          this.m_visualItem = null;
      }
   
      private void CollectLaunchCharacters()
      {
          this.m_launchCharacters.Clear();
          int num = Physics.OverlapSphereNonAlloc(this.m_launchCollectArea.transform.position, this.m_launchCollectArea.radius, this.m_colliders, Catapult.m_characterMask);
          for (int i = 0; i < num; i++)
          {
              Character componentInParent = this.m_colliders[i].GetComponentInParent<Character>();
              if (componentInParent != null)
              {
                  ZNetView component = componentInParent.GetComponent<ZNetView>();
                  if (component != null && component.IsOwner())
                  {
                      this.m_launchCharacters.Add(componentInParent);
                      componentInParent.SetTempParent(this.m_arm.transform);
                  }
              }
          }
      }
   
      private void LaunchCharacters()
      {
          foreach (Character character in this.m_launchCharacters)
          {
              character.ReleaseTempParent();
              Vector3 normalized = (this.m_forceVector.transform.position - base.transform.position).normalized;
              character.ForceJump(normalized * this.m_launchForce, true);
              character.StandUpOnNextGround();
          }
          this.m_launchCharacters.Clear();
      }
   
      private string OnHoverLoadPoint()
      {
          return Localization.instance.Localize((this.m_loadedItem == null) ? "[<color=yellow><b>1-8</b></color>] $piece_catapult_placeitem" : "");
      }
   
      [Header("Legs")]
      public List<Switch> m_legs = new List<Switch>();
   
      [FormerlySerializedAs("m_legAnimationDown")]
      public AnimationCurve m_legAnimationCurve;
   
      private AnimationCurve m_legAnimationCurveUp;
   
      public float m_legAnimationDegrees = 90f;
   
      public float m_legAnimationUpMultiplier = 1f;
   
      public float m_legAnimationTime = 5f;
   
      public float m_legDownMass = 500f;
   
      [Header("Shooting")]
      public GameObject m_forceVector;
   
      public GameObject m_arm;
   
      public Switch m_loadPoint;
   
      public Transform m_shootPoint;
   
      public AnimationCurve m_armAnimation;
   
      public float m_armAnimationDegrees = 180f;
   
      public float m_armAnimationTime = 2f;
   
      public float m_releaseAnimationTime;
   
      public float m_shootAfterLoadDelay = 1f;
   
      public Projectile m_projectile;
   
      public ItemDrop m_defaultAmmo;
   
      public int m_maxLoadStack = 1;
   
      public float m_hitNoise = 1f;
   
      public float m_randomRotationMin = 2f;
   
      public float m_randomRotationMax = 10f;
   
      public float m_shootVelocityVariation = 0.1f;
   
      [Header("Dynamics")]
      public DynamicsParameters m_armDynamicsSettings;
   
      private FloatDynamics m_armDynamics;
   
      public DynamicsParameters m_legDynamicsSettings;
   
      private FloatDynamics m_legDynamics;
   
      [Header("Ammo")]
      [global::Tooltip("If checked, will include all except listed types. If unchecked, will exclude all except listed types.")]
      public bool m_defaultIncludeAndListExclude = true;
   
      public bool m_onlyUseIncludedProjectiles = true;
   
      public bool m_onlyIncludedItemsDealDamage = true;
   
      public List<ItemDrop.ItemData.ItemType> m_includeExcludeTypesList = new List<ItemDrop.ItemData.ItemType>();
   
      public List<ItemDrop> m_includeItemsOverride = new List<ItemDrop>();
   
      public List<ItemDrop> m_excludeItemsOverride = new List<ItemDrop>();
   
      [Header("Character Launching")]
      public SphereCollider m_launchCollectArea;
   
      public float m_preLaunchForce = 5f;
   
      public float m_launchForce = 100f;
   
      [Header("Effects")]
      public EffectList m_legDownEffect = new EffectList();
   
      public EffectList m_legDownDoneEffect = new EffectList();
   
      public EffectList m_legUpEffect = new EffectList();
   
      public EffectList m_legUpDoneEffect = new EffectList();
   
      public EffectList m_shootStartEffect = new EffectList();
   
      public EffectList m_shootReleaseEffect = new EffectList();
   
      public EffectList m_armReturnEffect = new EffectList();
   
      public EffectList m_loadItemEffect = new EffectList();
   
      private static int m_characterMask;
   
      private ZNetView m_nview;
   
      private ZNetView m_wagonNview;
   
      private Vagon m_wagon;
   
      private Rigidbody m_rigidBody;
   
      private float m_baseMass;
   
      private ItemDrop.ItemData m_loadedItem;
   
      private int m_loadStack;
   
      private GameObject m_visualItem;
   
      private GameObject m_shotItem;
   
      private bool m_lockedLegs;
   
      private Vector3[] m_legRotations;
   
      private Quaternion[] m_legRotationQuat;
   
      private float m_legAnimTimer;
   
      private bool m_movingLegs;
   
      private Vector3 m_armRotation;
   
      private float m_armAnimTime;
   
      private Projectile m_lastProjectile;
   
      private ItemDrop.ItemData m_lastAmmo;
   
      private Collider[] m_colliders = new Collider[10];
   
      private List<Character> m_launchCharacters = new List<Character>();
  }