D:\ValheimDev\Dumps\Old\assembly_valheim\Projectile.cs D:\ValheimDev\Dumps\Latest\assembly_valheim\Projectile.cs
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using UnityEngine; using UnityEngine;
   
public class Projectile : MonoBehaviour, IProjectile public class Projectile : MonoBehaviour, IProjectile
{ {
    private void Awake()     private void Awake()
    {     {
        this.m_nview = base.GetComponent<ZNetView>();         this.m_nview = base.GetComponent<ZNetView>();
        if (Projectile.s_rayMaskSolids == 0)         if (Projectile.s_rayMaskSolids == 0)
        {         {
            Projectile.s_rayMaskSolids = LayerMask.GetMask(new string[]             Projectile.s_rayMaskSolids = LayerMask.GetMask(new string[]
            {             {
                "Default", "static_solid", "Default_small", "piece", "piece_nonsolid", "terrain", "character", "character_net", "character_ghost", "hitbox",                 "Default", "static_solid", "Default_small", "piece", "piece_nonsolid", "terrain", "character", "character_net", "character_ghost", "hitbox",
                "character_noenv", "vehicle"                  "character_noenv", "vehicle" 
            });             });
        }         }
        if (!string.IsNullOrEmpty(this.m_statusEffect))         if (!string.IsNullOrEmpty(this.m_statusEffect))
        {         {
            this.m_statusEffectHash = this.m_statusEffect.GetStableHashCode();             this.m_statusEffectHash = this.m_statusEffect.GetStableHashCode();
        }         }
        this.m_nview.Register("RPC_OnHit", new Action<long>(this.RPC_OnHit));         this.m_nview.Register("RPC_OnHit", new Action<long>(this.RPC_OnHit));
        this.m_nview.Register<ZDOID>("RPC_Attach", new Action<long, ZDOID>(this.RPC_Attach));         this.m_nview.Register<ZDOID>("RPC_Attach", new Action<long, ZDOID>(this.RPC_Attach));
.          this.UpdateVisual();
    }     }
   
    public string GetTooltipString(int itemQuality)     public string GetTooltipString(int itemQuality)
    {     {
        return "";         return "";
    }     }
   
    private void FixedUpdate()     private void FixedUpdate()
    {     {
        if (!this.m_nview.IsValid())         if (!this.m_nview.IsValid())
        {         {
            return;             return;
        }         }
        this.UpdateRotation(Time.fixedDeltaTime);         this.UpdateRotation(Time.fixedDeltaTime);
        if (!this.m_nview.IsOwner())         if (!this.m_nview.IsOwner())
        {         {
            return;             return;
        }         }
        if (!this.m_didHit)         if (!this.m_didHit)
        {         {
            Vector3 vector = base.transform.position;             Vector3 vector = base.transform.position;
            if (this.m_haveStartPoint)             if (this.m_haveStartPoint)
            {             {
                vector = this.m_startPoint;                 vector = this.m_startPoint;
            }             }
.            this.m_vel += Vector3.down * this.m_gravity * Time.fixedDeltaTime;             this.m_vel += Vector3.down * (this.m_gravity * Time.fixedDeltaTime);
              float num = Mathf.Pow(this.m_vel.magnitude, 2f) * this.m_drag * Time.fixedDeltaTime; 
              this.m_vel += num * -this.m_vel.normalized; 
            base.transform.position += this.m_vel * Time.fixedDeltaTime;             base.transform.position += this.m_vel * Time.fixedDeltaTime;
            if (this.m_rotateVisual == 0f)             if (this.m_rotateVisual == 0f)
            {             {
                base.transform.rotation = Quaternion.LookRotation(this.m_vel);                 base.transform.rotation = Quaternion.LookRotation(this.m_vel);
            }             }
            if (this.m_canHitWater)             if (this.m_canHitWater)
            {             {
                float liquidLevel = Floating.GetLiquidLevel(base.transform.position, 1f, LiquidType.All);                 float liquidLevel = Floating.GetLiquidLevel(base.transform.position, 1f, LiquidType.All);
                if (base.transform.position.y < liquidLevel)                 if (base.transform.position.y < liquidLevel)
                {                 {
.                    this.OnHit(null, base.transform.position, true);                     this.OnHit(null, base.transform.position, true, Vector3.up);
                }                 }
            }             }
.              this.m_didBounce = false;
            if (!this.m_didHit)             if (!this.m_didHit)
            {             {
                Vector3 vector2 = base.transform.position - vector;                 Vector3 vector2 = base.transform.position - vector;
                if (!this.m_haveStartPoint)                 if (!this.m_haveStartPoint)
                {                 {
.                    vector -= vector2.normalized * vector2.magnitude * 0.5f;                     vector -= vector2.normalized * (vector2.magnitude * 0.5f);
                }                 }
                RaycastHit[] array;                 RaycastHit[] array;
                if (this.m_rayRadius == 0f)                 if (this.m_rayRadius == 0f)
                {                 {
                    array = Physics.RaycastAll(vector, vector2.normalized, vector2.magnitude * 1.5f, Projectile.s_rayMaskSolids);                     array = Physics.RaycastAll(vector, vector2.normalized, vector2.magnitude * 1.5f, Projectile.s_rayMaskSolids);
                }                 }
                else                 else
                {                 {
                    array = Physics.SphereCastAll(vector, this.m_rayRadius, vector2.normalized, vector2.magnitude, Projectile.s_rayMaskSolids);                     array = Physics.SphereCastAll(vector, this.m_rayRadius, vector2.normalized, vector2.magnitude, Projectile.s_rayMaskSolids);
                }                 }
                Debug.DrawLine(vector, base.transform.position, (array.Length != 0) ? Color.red : Color.yellow, 5f);                 Debug.DrawLine(vector, base.transform.position, (array.Length != 0) ? Color.red : Color.yellow, 5f);
                if (array.Length != 0)                 if (array.Length != 0)
                {                 {
                    Array.Sort<RaycastHit>(array, (RaycastHit x, RaycastHit y) => x.distance.CompareTo(y.distance));                     Array.Sort<RaycastHit>(array, (RaycastHit x, RaycastHit y) => x.distance.CompareTo(y.distance));
                    foreach (RaycastHit raycastHit in array)                     foreach (RaycastHit raycastHit in array)
                    {                     {
                        Vector3 vector3 = ((raycastHit.distance == 0f) ? vector : raycastHit.point);                         Vector3 vector3 = ((raycastHit.distance == 0f) ? vector : raycastHit.point);
.                        this.OnHit(raycastHit.collider, vector3, false);                         this.OnHit(raycastHit.collider, vector3, false, raycastHit.normal);
                        if (this.m_didHit)                         if (this.m_didHit || this.m_didBounce)
                        {                         {
                            break;                             break;
                        }                         }
                    }                     }
                }                 }
            }             }
            if (this.m_haveStartPoint)             if (this.m_haveStartPoint)
            {             {
                this.m_haveStartPoint = false;                 this.m_haveStartPoint = false;
            }             }
        }         }
        if (this.m_ttl > 0f)         if (this.m_ttl > 0f)
        {         {
            this.m_ttl -= Time.fixedDeltaTime;             this.m_ttl -= Time.fixedDeltaTime;
            if (this.m_ttl <= 0f)             if (this.m_ttl <= 0f)
            {             {
.                  if (this.m_spawnOnTtl)
                  {
                      this.SpawnOnHit(null, null, -this.m_vel.normalized);
                  }
                ZNetScene.instance.Destroy(base.gameObject);                 ZNetScene.instance.Destroy(base.gameObject);
            }             }
        }         }
.          ShieldGenerator.CheckProjectile(this);
      }
   
      private void Update()
      {
          this.UpdateVisual();
    }     }
   
    private void LateUpdate()     private void LateUpdate()
    {     {
        if (this.m_attachParent)         if (this.m_attachParent)
        {         {
            Vector3 vector = this.m_attachParent.transform.position - this.m_attachParentOffset;             Vector3 vector = this.m_attachParent.transform.position - this.m_attachParentOffset;
            Quaternion quaternion = this.m_attachParent.transform.rotation * this.m_attachParentOffsetRot;             Quaternion quaternion = this.m_attachParent.transform.rotation * this.m_attachParentOffsetRot;
            base.transform.position = Utils.RotatePointAroundPivot(vector, this.m_attachParent.transform.position, quaternion);             base.transform.position = Utils.RotatePointAroundPivot(vector, this.m_attachParent.transform.position, quaternion);
            base.transform.localRotation = quaternion;             base.transform.localRotation = quaternion;
        }         }
    }     }
   
.      private void UpdateVisual()
      {
          if (!this.m_canChangeVisuals || this.m_nview == null)
          {
              return;
          }
          if (!this.m_nview.IsValid())
          {
              return;
          }
          string text;
          if (this.m_changedVisual || !this.m_nview.GetZDO().GetString(ZDOVars.s_visual, out text))
          {
              return;
          }
          ZLog.Log("Visual prefab is " + text);
          GameObject itemPrefab = ObjectDB.instance.GetItemPrefab(text);
          if (itemPrefab.GetComponent<ItemDrop>() == null)
          {
              return;
          }
          GameObject gameObject = ItemStand.GetAttachPrefab(itemPrefab);
          if (gameObject == null)
          {
              return;
          }
          gameObject = ItemStand.GetAttachGameObject(gameObject);
          this.m_visual.gameObject.SetActive(false);
          this.m_visual = UnityEngine.Object.Instantiate<GameObject>(gameObject, base.transform);
          this.m_visual.transform.localPosition = Vector3.zero;
          this.m_changedVisual = true;
      }
   
    public Vector3 GetVelocity()     public Vector3 GetVelocity()
    {     {
        if (!this.m_nview.IsValid() || !this.m_nview.IsOwner())         if (!this.m_nview.IsValid() || !this.m_nview.IsOwner())
        {         {
            return Vector3.zero;             return Vector3.zero;
        }         }
        if (this.m_didHit)         if (this.m_didHit)
        {         {
            return Vector3.zero;             return Vector3.zero;
        }         }
        return this.m_vel;         return this.m_vel;
    }     }
   
    private void UpdateRotation(float dt)     private void UpdateRotation(float dt)
    {     {
.        if ((double)this.m_rotateVisual == 0.0 || this.m_visual == null)          if (this.m_visual == null || ((double)this.m_rotateVisual == 0.0 && (double)this.m_rotateVisualY == 0.0 && (double)this.m_rotateVisualZ == 0.0)) 
        {         {
            return;             return;
        }         }
.        this.m_visual.transform.Rotate(new Vector3(this.m_rotateVisual * dt, 0f, 0f));         this.m_visual.transform.Rotate(new Vector3(this.m_rotateVisual * dt, this.m_rotateVisualY * dt, this.m_rotateVisualZ * dt));
    }     }
   
    public void Setup(Character owner, Vector3 velocity, float hitNoise, HitData hitData, ItemDrop.ItemData item, ItemDrop.ItemData ammo)     public void Setup(Character owner, Vector3 velocity, float hitNoise, HitData hitData, ItemDrop.ItemData item, ItemDrop.ItemData ammo)
    {     {
        this.m_owner = owner;         this.m_owner = owner;
        this.m_vel = velocity;         this.m_vel = velocity;
        this.m_ammo = ammo;         this.m_ammo = ammo;
.          this.m_weapon = item;
        if (hitNoise >= 0f)         if (hitNoise >= 0f)
        {         {
            this.m_hitNoise = hitNoise;             this.m_hitNoise = hitNoise;
        }         }
        if (hitData != null)         if (hitData != null)
        {         {
.              this.m_originalHitData = hitData;
            this.m_damage = hitData.m_damage;             this.m_damage = hitData.m_damage;
            this.m_blockable = hitData.m_blockable;             this.m_blockable = hitData.m_blockable;
            this.m_dodgeable = hitData.m_dodgeable;             this.m_dodgeable = hitData.m_dodgeable;
            this.m_attackForce = hitData.m_pushForce;             this.m_attackForce = hitData.m_pushForce;
            this.m_backstabBonus = hitData.m_backstabBonus;             this.m_backstabBonus = hitData.m_backstabBonus;
.              this.m_healthReturn = hitData.m_healthReturn;
            if (this.m_statusEffectHash != hitData.m_statusEffectHash)             if (this.m_statusEffectHash != hitData.m_statusEffectHash)
            {             {
                this.m_statusEffectHash = hitData.m_statusEffectHash;                 this.m_statusEffectHash = hitData.m_statusEffectHash;
                this.m_statusEffect = "";                 this.m_statusEffect = "";
            }             }
            this.m_skill = hitData.m_skill;             this.m_skill = hitData.m_skill;
            this.m_raiseSkillAmount = hitData.m_skillRaiseAmount;             this.m_raiseSkillAmount = hitData.m_skillRaiseAmount;
        }         }
.          if (this.m_spawnOnHit != null && this.m_onlySpawnedProjectilesDealDamage)
          {
              this.m_damage.Modify(0f);
          }
        if (this.m_respawnItemOnHit)         if (this.m_respawnItemOnHit)
        {         {
            this.m_spawnItem = item;             this.m_spawnItem = item;
        }         }
        if (this.m_doOwnerRaytest && owner)         if (this.m_doOwnerRaytest && owner)
        {         {
            this.m_startPoint = owner.GetCenterPoint();             this.m_startPoint = owner.GetCenterPoint();
            this.m_startPoint.y = base.transform.position.y;             this.m_startPoint.y = base.transform.position.y;
            this.m_haveStartPoint = true;             this.m_haveStartPoint = true;
        }         }
.          else
          {
              this.m_startPoint = base.transform.position;
          }
        LineConnect component = base.GetComponent<LineConnect>();         LineConnect component = base.GetComponent<LineConnect>();
.        if (component)         if (component && owner)
        {         {
            component.SetPeer(owner.GetZDOID());             component.SetPeer(owner.GetZDOID());
        }         }
.          this.m_hasLeftShields = !ShieldGenerator.IsInsideShield(base.transform.position);
    }     }
   
    private void DoAOE(Vector3 hitPoint, ref bool hitCharacter, ref bool didDamage)     private void DoAOE(Vector3 hitPoint, ref bool hitCharacter, ref bool didDamage)
    {     {
        Collider[] array = Physics.OverlapSphere(hitPoint, this.m_aoe, Projectile.s_rayMaskSolids, QueryTriggerInteraction.UseGlobal);         Collider[] array = Physics.OverlapSphere(hitPoint, this.m_aoe, Projectile.s_rayMaskSolids, QueryTriggerInteraction.UseGlobal);
        HashSet<GameObject> hashSet = new HashSet<GameObject>();         HashSet<GameObject> hashSet = new HashSet<GameObject>();
        foreach (Collider collider in array)         foreach (Collider collider in array)
        {         {
            GameObject gameObject = Projectile.FindHitObject(collider);             GameObject gameObject = Projectile.FindHitObject(collider);
            IDestructible component = gameObject.GetComponent<IDestructible>();             IDestructible component = gameObject.GetComponent<IDestructible>();
            if (component != null && !hashSet.Contains(gameObject))             if (component != null && !hashSet.Contains(gameObject))
            {             {
                hashSet.Add(gameObject);                 hashSet.Add(gameObject);
                if (this.IsValidTarget(component))                 if (this.IsValidTarget(component))
                {                 {
                    if (component is Character)                     if (component is Character)
                    {                     {
                        hitCharacter = true;                         hitCharacter = true;
                    }                     }
                    Vector3 vector = collider.ClosestPointOnBounds(hitPoint);                     Vector3 vector = collider.ClosestPointOnBounds(hitPoint);
                    Vector3 vector2 = ((Vector3.Distance(vector, hitPoint) > 0.1f) ? (vector - hitPoint) : this.m_vel);                     Vector3 vector2 = ((Vector3.Distance(vector, hitPoint) > 0.1f) ? (vector - hitPoint) : this.m_vel);
                    vector2.y = 0f;                     vector2.y = 0f;
                    vector2.Normalize();                     vector2.Normalize();
                    HitData hitData = new HitData();                     HitData hitData = new HitData();
                    hitData.m_hitCollider = collider;                     hitData.m_hitCollider = collider;
                    hitData.m_damage = this.m_damage;                     hitData.m_damage = this.m_damage;
                    hitData.m_pushForce = this.m_attackForce;                     hitData.m_pushForce = this.m_attackForce;
                    hitData.m_backstabBonus = this.m_backstabBonus;                     hitData.m_backstabBonus = this.m_backstabBonus;
                    hitData.m_ranged = true;                     hitData.m_ranged = true;
                    hitData.m_point = vector;                     hitData.m_point = vector;
                    hitData.m_dir = vector2.normalized;                     hitData.m_dir = vector2.normalized;
                    hitData.m_statusEffectHash = this.m_statusEffectHash;                     hitData.m_statusEffectHash = this.m_statusEffectHash;
.                    hitData.m_skillLevel = ((this.m_owner != null) ? this.m_owner.GetSkillLevel(this.m_skill) : 0f);                     hitData.m_skillLevel = (this.m_owner ? this.m_owner.GetSkillLevel(this.m_skill) : 1f);
                    hitData.m_dodgeable = this.m_dodgeable;                     hitData.m_dodgeable = this.m_dodgeable;
                    hitData.m_blockable = this.m_blockable;                     hitData.m_blockable = this.m_blockable;
                    hitData.m_skill = this.m_skill;                     hitData.m_skill = this.m_skill;
                    hitData.m_skillRaiseAmount = this.m_raiseSkillAmount;                     hitData.m_skillRaiseAmount = this.m_raiseSkillAmount;
                    hitData.SetAttacker(this.m_owner);                     hitData.SetAttacker(this.m_owner);
                    hitData.m_hitType = ((hitData.GetAttacker() is Player) ? HitData.HitType.PlayerHit : HitData.HitType.EnemyHit);                     hitData.m_hitType = ((hitData.GetAttacker() is Player) ? HitData.HitType.PlayerHit : HitData.HitType.EnemyHit);
.                      hitData.m_healthReturn = this.m_healthReturn;
                    component.Damage(hitData);                     component.Damage(hitData);
                    didDamage = true;                     didDamage = true;
                }                 }
            }             }
        }         }
    }     }
   
    private bool IsValidTarget(IDestructible destr)     private bool IsValidTarget(IDestructible destr)
    {     {
        Character character = destr as Character;         Character character = destr as Character;
        if (character)         if (character)
        {         {
            if (character == this.m_owner)             if (character == this.m_owner)
            {             {
                return false;                 return false;
            }             }
            if (this.m_owner != null)             if (this.m_owner != null)
            {             {
                bool flag = BaseAI.IsEnemy(this.m_owner, character) || (character.GetBaseAI() && character.GetBaseAI().IsAggravatable() && this.m_owner.IsPlayer());                 bool flag = BaseAI.IsEnemy(this.m_owner, character) || (character.GetBaseAI() && character.GetBaseAI().IsAggravatable() && this.m_owner.IsPlayer());
                if (!this.m_owner.IsPlayer() && !flag)                 if (!this.m_owner.IsPlayer() && !flag)
                {                 {
                    return false;                     return false;
                }                 }
                if (this.m_owner.IsPlayer() && !this.m_owner.IsPVPEnabled() && !flag)                 if (this.m_owner.IsPlayer() && !this.m_owner.IsPVPEnabled() && !flag)
                {                 {
                    return false;                     return false;
                }                 }
            }             }
            if (this.m_dodgeable && character.IsDodgeInvincible())             if (this.m_dodgeable && character.IsDodgeInvincible())
            {             {
                return false;                 return false;
            }             }
        }         }
        return true;         return true;
    }     }
   
.    private void OnHit(Collider collider, Vector3 hitPoint, bool water)     public void OnHit(Collider collider, Vector3 hitPoint, bool water, Vector3 normal)
    {     {
        GameObject gameObject = (collider ? Projectile.FindHitObject(collider) : null);         GameObject gameObject = (collider ? Projectile.FindHitObject(collider) : null);
        bool flag = false;         bool flag = false;
        bool flag2 = false;         bool flag2 = false;
.          bool flag3 = this.m_bounce && normal != Vector3.zero;
          if (water)
          {
              flag3 = flag3 && this.m_bounceOnWater;
          }
        IDestructible destructible = (gameObject ? gameObject.GetComponent<IDestructible>() : null);         IDestructible destructible = (gameObject ? gameObject.GetComponent<IDestructible>() : null);
        if (destructible != null)         if (destructible != null)
        {         {
            flag2 = destructible is Character;             flag2 = destructible is Character;
.              flag3 = flag3 && !flag2;
            if (!this.IsValidTarget(destructible))             if (!this.IsValidTarget(destructible))
            {             {
                return;                 return;
            }             }
        }         }
.          if (flag3 && this.m_bounceCount < this.m_maxBounces && this.m_vel.magnitude > this.m_minBounceVel)
          {
              Vector3 normalized = this.m_vel.normalized;
              if (this.m_bounceRoughness > 0f)
              {
                  Vector3 vector = UnityEngine.Random.onUnitSphere;
                  float num = Vector3.Dot(normal, vector);
                  vector *= Mathf.Sign(num);
                  normal = Vector3.Lerp(normal, vector, this.m_bounceRoughness).normalized;
              }
              this.m_vel = Vector3.Reflect(normalized, normal) * (this.m_vel.magnitude * this.m_bouncePower);
              this.m_bounceCount++;
              this.m_didBounce = true;
              return;
          }
        if (this.m_aoe > 0f)         if (this.m_aoe > 0f)
        {         {
            this.DoAOE(hitPoint, ref flag2, ref flag);             this.DoAOE(hitPoint, ref flag2, ref flag);
        }         }
        else if (destructible != null)         else if (destructible != null)
        {         {
            HitData hitData = new HitData();             HitData hitData = new HitData();
            hitData.m_hitCollider = collider;             hitData.m_hitCollider = collider;
            hitData.m_damage = this.m_damage;             hitData.m_damage = this.m_damage;
            hitData.m_pushForce = this.m_attackForce;             hitData.m_pushForce = this.m_attackForce;
            hitData.m_backstabBonus = this.m_backstabBonus;             hitData.m_backstabBonus = this.m_backstabBonus;
            hitData.m_point = hitPoint;             hitData.m_point = hitPoint;
            hitData.m_dir = base.transform.forward;             hitData.m_dir = base.transform.forward;
            hitData.m_statusEffectHash = this.m_statusEffectHash;             hitData.m_statusEffectHash = this.m_statusEffectHash;
            hitData.m_dodgeable = this.m_dodgeable;             hitData.m_dodgeable = this.m_dodgeable;
            hitData.m_blockable = this.m_blockable;             hitData.m_blockable = this.m_blockable;
            hitData.m_ranged = true;             hitData.m_ranged = true;
            hitData.m_skill = this.m_skill;             hitData.m_skill = this.m_skill;
            hitData.m_skillRaiseAmount = this.m_raiseSkillAmount;             hitData.m_skillRaiseAmount = this.m_raiseSkillAmount;
            hitData.SetAttacker(this.m_owner);             hitData.SetAttacker(this.m_owner);
            hitData.m_hitType = ((hitData.GetAttacker() is Player) ? HitData.HitType.PlayerHit : HitData.HitType.EnemyHit);             hitData.m_hitType = ((hitData.GetAttacker() is Player) ? HitData.HitType.PlayerHit : HitData.HitType.EnemyHit);
.              hitData.m_healthReturn = this.m_healthReturn;
            destructible.Damage(hitData);             destructible.Damage(hitData);
.              if (this.m_healthReturn > 0f && this.m_owner)
              {
                  this.m_owner.Heal(this.m_healthReturn, true);
              }
            flag = true;             flag = true;
        }         }
        if (water)         if (water)
        {         {
            this.m_hitWaterEffects.Create(hitPoint, Quaternion.identity, null, 1f, -1);             this.m_hitWaterEffects.Create(hitPoint, Quaternion.identity, null, 1f, -1);
        }         }
        else         else
        {         {
            this.m_hitEffects.Create(hitPoint, Quaternion.identity, null, 1f, -1);             this.m_hitEffects.Create(hitPoint, Quaternion.identity, null, 1f, -1);
        }         }
        if (this.m_spawnOnHit != null || this.m_spawnItem != null || this.m_randomSpawnOnHit.Count > 0)         if (this.m_spawnOnHit != null || this.m_spawnItem != null || this.m_randomSpawnOnHit.Count > 0)
        {         {
.            this.SpawnOnHit(gameObject, collider);             this.SpawnOnHit(gameObject, collider, normal);
          } 
          OnProjectileHit onHit = this.m_onHit; 
          if (onHit != null) 
          { 
              onHit(collider, hitPoint, water); 
        }         }
        if (this.m_hitNoise > 0f)         if (this.m_hitNoise > 0f)
        {         {
            BaseAI.DoProjectileHitNoise(base.transform.position, this.m_hitNoise, this.m_owner);             BaseAI.DoProjectileHitNoise(base.transform.position, this.m_hitNoise, this.m_owner);
        }         }
        if (flag && this.m_owner != null && flag2)         if (flag && this.m_owner != null && flag2)
        {         {
            this.m_owner.RaiseSkill(this.m_skill, this.m_raiseSkillAmount);             this.m_owner.RaiseSkill(this.m_skill, this.m_raiseSkillAmount);
        }         }
        this.m_didHit = true;         this.m_didHit = true;
        base.transform.position = hitPoint;         base.transform.position = hitPoint;
        this.m_nview.InvokeRPC("RPC_OnHit", Array.Empty<object>());         this.m_nview.InvokeRPC("RPC_OnHit", Array.Empty<object>());
        this.m_ttl = this.m_stayTTL;         this.m_ttl = this.m_stayTTL;
        if (collider && collider.attachedRigidbody != null)         if (collider && collider.attachedRigidbody != null)
        {         {
            ZNetView componentInParent = collider.gameObject.GetComponentInParent<ZNetView>();             ZNetView componentInParent = collider.gameObject.GetComponentInParent<ZNetView>();
            if (componentInParent && (this.m_attachToClosestBone || this.m_attachToRigidBody))             if (componentInParent && (this.m_attachToClosestBone || this.m_attachToRigidBody))
            {             {
                this.m_nview.InvokeRPC("RPC_Attach", new object[] { componentInParent.GetZDO().m_uid });                 this.m_nview.InvokeRPC("RPC_Attach", new object[] { componentInParent.GetZDO().m_uid });
                return;                 return;
            }             }
            if (!this.m_stayAfterHitDynamic)             if (!this.m_stayAfterHitDynamic)
            {             {
                ZNetScene.instance.Destroy(base.gameObject);                 ZNetScene.instance.Destroy(base.gameObject);
                return;                 return;
            }             }
        }         }
        else if (!this.m_stayAfterHitStatic)         else if (!this.m_stayAfterHitStatic)
        {         {
            ZNetScene.instance.Destroy(base.gameObject);             ZNetScene.instance.Destroy(base.gameObject);
        }         }
    }     }
   
    private void RPC_OnHit(long sender)     private void RPC_OnHit(long sender)
    {     {
        if (this.m_hideOnHit)         if (this.m_hideOnHit)
        {         {
            this.m_hideOnHit.SetActive(false);             this.m_hideOnHit.SetActive(false);
        }         }
        if (this.m_stopEmittersOnHit)         if (this.m_stopEmittersOnHit)
        {         {
            ParticleSystem[] componentsInChildren = base.GetComponentsInChildren<ParticleSystem>();             ParticleSystem[] componentsInChildren = base.GetComponentsInChildren<ParticleSystem>();
            for (int i = 0; i < componentsInChildren.Length; i++)             for (int i = 0; i < componentsInChildren.Length; i++)
            {             {
                componentsInChildren[i].emission.enabled = false;                 componentsInChildren[i].emission.enabled = false;
            }             }
        }         }
    }     }
   
    private void RPC_Attach(long sender, ZDOID parent)     private void RPC_Attach(long sender, ZDOID parent)
    {     {
        this.m_attachParent = ZNetScene.instance.FindInstance(parent);         this.m_attachParent = ZNetScene.instance.FindInstance(parent);
        if (this.m_attachParent)         if (this.m_attachParent)
        {         {
            if (this.m_attachToClosestBone)             if (this.m_attachToClosestBone)
            {             {
                float dist = float.MaxValue;                 float dist = float.MaxValue;
                Animator componentInChildren = this.m_attachParent.gameObject.GetComponentInChildren<Animator>();                 Animator componentInChildren = this.m_attachParent.gameObject.GetComponentInChildren<Animator>();
                if (componentInChildren != null)                 if (componentInChildren != null)
                {                 {
                    Utils.IterateHierarchy(componentInChildren.gameObject, delegate(GameObject obj)                     Utils.IterateHierarchy(componentInChildren.gameObject, delegate(GameObject obj)
                    {                     {
                        float num = Vector3.Distance(this.transform.position, obj.transform.position);                         float num = Vector3.Distance(this.transform.position, obj.transform.position);
                        if (num < dist)                         if (num < dist)
                        {                         {
                            dist = num;                             dist = num;
                            this.m_attachParent = obj;                             this.m_attachParent = obj;
                        }                         }
                    }, false);                     }, false);
                }                 }
            }             }
            base.transform.position += base.transform.forward * this.m_attachPenetration;             base.transform.position += base.transform.forward * this.m_attachPenetration;
            base.transform.position += (this.m_attachParent.transform.position - base.transform.position) * this.m_attachBoneNearify;             base.transform.position += (this.m_attachParent.transform.position - base.transform.position) * this.m_attachBoneNearify;
            this.m_attachParentOffset = this.m_attachParent.transform.position - base.transform.position;             this.m_attachParentOffset = this.m_attachParent.transform.position - base.transform.position;
            this.m_attachParentOffsetRot = Quaternion.Inverse(this.m_attachParent.transform.localRotation * base.transform.localRotation);             this.m_attachParentOffsetRot = Quaternion.Inverse(this.m_attachParent.transform.localRotation * base.transform.localRotation);
        }         }
    }     }
   
.    private void SpawnOnHit(GameObject go, Collider collider)     private void SpawnOnHit(GameObject go, Collider collider, Vector3 normal)
    {     {
        if (this.m_groundHitOnly && go.GetComponent<Heightmap>() == null)         if (this.m_groundHitOnly && go.GetComponent<Heightmap>() == null)
        {         {
            return;             return;
        }         }
        if (this.m_staticHitOnly)         if (this.m_staticHitOnly)
        {         {
            if (collider && collider.attachedRigidbody != null)             if (collider && collider.attachedRigidbody != null)
            {             {
                return;                 return;
            }             }
            if (go && go.GetComponent<IDestructible>() != null)             if (go && go.GetComponent<IDestructible>() != null)
            {             {
                return;                 return;
            }             }
        }         }
.        if (this.m_spawnOnHitChance < 1f && UnityEngine.Random.value > this.m_spawnOnHitChance)         Vector3 vector = base.transform.position + base.transform.TransformDirection(this.m_spawnOffset); 
          Quaternion quaternion = Quaternion.identity; 
          if (this.m_copyProjectileRotation)
        {         {
.            return;             quaternion = base.transform.rotation;
        }         }
.        Vector3 vector = base.transform.position + base.transform.TransformDirection(this.m_spawnOffset);  
        Quaternion quaternion = base.transform.rotation;  
        if (this.m_spawnRandomRotation)         if (this.m_spawnRandomRotation)
        {         {
            quaternion = Quaternion.Euler(0f, (float)UnityEngine.Random.Range(0, 360), 0f);             quaternion = Quaternion.Euler(0f, (float)UnityEngine.Random.Range(0, 360), 0f);
        }         }
        if (this.m_spawnFacingRotation)         if (this.m_spawnFacingRotation)
        {         {
            quaternion = Quaternion.Euler(0f, base.transform.rotation.eulerAngles.y, 0f);             quaternion = Quaternion.Euler(0f, base.transform.rotation.eulerAngles.y, 0f);
        }         }
.        if (this.m_spawnOnHit != null)          if (this.m_spawnOnHit != null && (this.m_spawnOnHitChance >= 1f || UnityEngine.Random.value < this.m_spawnOnHitChance)) 
        {         {
.            IProjectile component = UnityEngine.Object.Instantiate<GameObject>(this.m_spawnOnHit, vector, quaternion).GetComponent<IProjectile>();              for (int i = 0; i < this.m_spawnCount; i++)
            if (component != null)  
            {             {
.                component.Setup(this.m_owner, this.m_vel, this.m_hitNoise, null, null, this.m_ammo);                 GameObject gameObject = UnityEngine.Object.Instantiate<GameObject>(this.m_spawnOnHit, vector, quaternion);
                  Vector3 vector2 = this.m_vel.normalized; 
                  Vector3 vector3 = UnityEngine.Random.onUnitSphere; 
                  if (this.m_spawnProjectileHemisphereDir) 
                  { 
                      vector3 *= Mathf.Sign(Vector3.Dot(normal, vector3)); 
                  } 
                  vector2 = Vector3.Lerp(vector2, vector3, this.m_spawnProjectileRandomDir).normalized; 
                  float num = this.m_vel.magnitude; 
                  if (this.m_spawnProjectileNewVelocity) 
                  { 
                      num = UnityEngine.Random.Range(this.m_spawnProjectileMinVel, this.m_spawnProjectileMaxVel); 
                  } 
                  IProjectile componentInChildren = gameObject.GetComponentInChildren<IProjectile>(); 
                  if (componentInChildren != null) 
                  { 
                      gameObject.transform.position += normal * 0.25f; 
                      HitData hitData = null; 
                      if (this.m_projectilesInheritHitData) 
                      { 
                          hitData = this.m_originalHitData; 
                          if (this.m_divideDamageBetweenProjectiles) 
                          { 
                              hitData.m_damage.Modify(1f / (float)this.m_spawnCount); 
                          } 
                      } 
                      componentInChildren.Setup(this.m_owner, vector2 * num, this.m_hitNoise, hitData, this.m_weapon, this.m_ammo); 
                  } 
            }             }
        }         }
        if (this.m_spawnItem != null)         if (this.m_spawnItem != null)
        {         {
            ItemDrop.DropItem(this.m_spawnItem, 0, vector, base.transform.rotation);             ItemDrop.DropItem(this.m_spawnItem, 0, vector, base.transform.rotation);
        }         }
.        if (this.m_randomSpawnOnHit.Count > 0)          if (this.m_randomSpawnOnHit.Count > 0 && (!this.m_randomSpawnSkipLava || !ZoneSystem.instance.IsLava(base.transform.position, false))) 
        {         {
.            GameObject gameObject = this.m_randomSpawnOnHit[UnityEngine.Random.Range(0, this.m_randomSpawnOnHit.Count)];              for (int j = 0; j < this.m_randomSpawnOnHitCount; j++)
            if (gameObject)  
            {             {
.                IProjectile component2 = UnityEngine.Object.Instantiate<GameObject>(gameObject, vector, quaternion).GetComponent<IProjectile>();                 GameObject gameObject2 = this.m_randomSpawnOnHit[UnityEngine.Random.Range(0, this.m_randomSpawnOnHit.Count)];
                if (component2 != null)                 if (gameObject2)
                {                 {
.                    component2.Setup(this.m_owner, this.m_vel, this.m_hitNoise, null, null, this.m_ammo);                     IProjectile component = UnityEngine.Object.Instantiate<GameObject>(gameObject2, vector, quaternion).GetComponent<IProjectile>(); 
                      if (component != null) 
                      { 
                          component.Setup(this.m_owner, this.m_vel, this.m_hitNoise, null, null, this.m_ammo);
                      } 
                }                 }
            }             }
        }         }
        this.m_spawnOnHitEffects.Create(vector, Quaternion.identity, null, 1f, -1);         this.m_spawnOnHitEffects.Create(vector, Quaternion.identity, null, 1f, -1);
    }     }
   
    public static GameObject FindHitObject(Collider collider)     public static GameObject FindHitObject(Collider collider)
    {     {
        IDestructible componentInParent = collider.gameObject.GetComponentInParent<IDestructible>();         IDestructible componentInParent = collider.gameObject.GetComponentInParent<IDestructible>();
        if (componentInParent != null)         if (componentInParent != null)
        {         {
            return (componentInParent as MonoBehaviour).gameObject;             return (componentInParent as MonoBehaviour).gameObject;
        }         }
        if (collider.attachedRigidbody)         if (collider.attachedRigidbody)
        {         {
            return collider.attachedRigidbody.gameObject;             return collider.attachedRigidbody.gameObject;
        }         }
        return collider.gameObject;         return collider.gameObject;
    }     }
   
.      public bool HasBeenOutsideShields
      {
          get
          {
              return this.m_hasLeftShields;
          }
      }
   
      public void TriggerShieldsLeftFlag()
      {
          this.m_hasLeftShields = true;
      }
   
    public HitData.DamageTypes m_damage;     public HitData.DamageTypes m_damage;
   
    public float m_aoe;     public float m_aoe;
   
    public bool m_dodgeable;     public bool m_dodgeable;
   
    public bool m_blockable;     public bool m_blockable;
   
    public float m_attackForce;     public float m_attackForce;
   
    public float m_backstabBonus = 4f;     public float m_backstabBonus = 4f;
   
    public string m_statusEffect = "";     public string m_statusEffect = "";
   
    private int m_statusEffectHash;     private int m_statusEffectHash;
   
.      public float m_healthReturn;
   
    public bool m_canHitWater;     public bool m_canHitWater;
   
    public float m_ttl = 4f;     public float m_ttl = 4f;
   
    public float m_gravity;     public float m_gravity;
   
.      public float m_drag;
   
    public float m_rayRadius;     public float m_rayRadius;
   
    public float m_hitNoise = 50f;     public float m_hitNoise = 50f;
   
    public bool m_doOwnerRaytest;     public bool m_doOwnerRaytest;
   
    public bool m_stayAfterHitStatic;     public bool m_stayAfterHitStatic;
   
    public bool m_stayAfterHitDynamic;     public bool m_stayAfterHitDynamic;
   
    public float m_stayTTL = 1f;     public float m_stayTTL = 1f;
   
    public bool m_attachToRigidBody;     public bool m_attachToRigidBody;
   
    public bool m_attachToClosestBone;     public bool m_attachToClosestBone;
   
    public float m_attachPenetration;     public float m_attachPenetration;
   
    public float m_attachBoneNearify = 0.25f;     public float m_attachBoneNearify = 0.25f;
   
    public GameObject m_hideOnHit;     public GameObject m_hideOnHit;
   
    public bool m_stopEmittersOnHit = true;     public bool m_stopEmittersOnHit = true;
   
    public EffectList m_hitEffects = new EffectList();     public EffectList m_hitEffects = new EffectList();
   
    public EffectList m_hitWaterEffects = new EffectList();     public EffectList m_hitWaterEffects = new EffectList();
   
.      [Header("Bounce")]
      public bool m_bounce;
   
      public bool m_bounceOnWater;
   
      [Range(0f, 1f)]
      public float m_bouncePower = 0.85f;
   
      [Range(0f, 1f)]
      public float m_bounceRoughness = 0.3f;
   
      [Min(1f)]
      public int m_maxBounces = 99;
   
      [Min(0.01f)]
      public float m_minBounceVel = 0.25f;
   
    [Header("Spawn on hit")]     [Header("Spawn on hit")]
    public bool m_respawnItemOnHit;     public bool m_respawnItemOnHit;
   
.      public bool m_spawnOnTtl;
   
    public GameObject m_spawnOnHit;     public GameObject m_spawnOnHit;
   
    [Range(0f, 1f)]     [Range(0f, 1f)]
    public float m_spawnOnHitChance = 1f;     public float m_spawnOnHitChance = 1f;
   
.      public int m_spawnCount = 1;
   
    public List<GameObject> m_randomSpawnOnHit = new List<GameObject>();     public List<GameObject> m_randomSpawnOnHit = new List<GameObject>();
   
.      public int m_randomSpawnOnHitCount = 1;
   
      public bool m_randomSpawnSkipLava;
   
    public bool m_showBreakMessage;     public bool m_showBreakMessage;
   
    public bool m_staticHitOnly;     public bool m_staticHitOnly;
   
    public bool m_groundHitOnly;     public bool m_groundHitOnly;
   
    public Vector3 m_spawnOffset = Vector3.zero;     public Vector3 m_spawnOffset = Vector3.zero;
   
.      public bool m_copyProjectileRotation = true;
   
    public bool m_spawnRandomRotation;     public bool m_spawnRandomRotation;
   
    public bool m_spawnFacingRotation;     public bool m_spawnFacingRotation;
   
    public EffectList m_spawnOnHitEffects = new EffectList();     public EffectList m_spawnOnHitEffects = new EffectList();
   
.      public OnProjectileHit m_onHit;
   
      [Header("Projectile Spawning")]
      public bool m_spawnProjectileNewVelocity;
   
      public float m_spawnProjectileMinVel = 1f;
   
      public float m_spawnProjectileMaxVel = 5f;
   
      [Range(0f, 1f)]
      public float m_spawnProjectileRandomDir;
   
      public bool m_spawnProjectileHemisphereDir;
   
      public bool m_projectilesInheritHitData;
   
      public bool m_onlySpawnedProjectilesDealDamage;
   
      public bool m_divideDamageBetweenProjectiles;
   
    [Header("Rotate projectile")]     [Header("Rotate projectile")]
    public float m_rotateVisual;     public float m_rotateVisual;
   
.      public float m_rotateVisualY;
   
      public float m_rotateVisualZ;
   
    public GameObject m_visual;     public GameObject m_visual;
   
.      public bool m_canChangeVisuals;
   
    private ZNetView m_nview;     private ZNetView m_nview;
   
    private GameObject m_attachParent;     private GameObject m_attachParent;
   
    private Vector3 m_attachParentOffset;     private Vector3 m_attachParentOffset;
   
    private Quaternion m_attachParentOffsetRot;     private Quaternion m_attachParentOffsetRot;
   
.      private bool m_hasLeftShields = true;
   
    private Vector3 m_vel = Vector3.zero;     private Vector3 m_vel = Vector3.zero;
   
    private Character m_owner;     private Character m_owner;
   
    private Skills.SkillType m_skill;     private Skills.SkillType m_skill;
   
    private float m_raiseSkillAmount = 1f;     private float m_raiseSkillAmount = 1f;
   
.      private ItemDrop.ItemData m_weapon;
   
    private ItemDrop.ItemData m_ammo;     private ItemDrop.ItemData m_ammo;
   
.    private ItemDrop.ItemData m_spawnItem;     [NonSerialized] 
      public ItemDrop.ItemData m_spawnItem;
   
      private HitData m_originalHitData; 
   
    private bool m_didHit;     private bool m_didHit;
   
.    private Vector3 m_startPoint;     private int m_bounceCount; 
   
      private bool m_didBounce; 
   
      private bool m_changedVisual; 
   
      [HideInInspector] 
      public Vector3 m_startPoint;
   
    private bool m_haveStartPoint;     private bool m_haveStartPoint;
   
    private static int s_rayMaskSolids;     private static int s_rayMaskSolids;
} }