private static void CalculatePositionsWeapon(Pawn pawn, ref float weaponAngle,
                                                     CompProperties_WeaponExtensions extensions,
                                                     out Vector3 weaponPosOffset, out bool aiming,
                                                     bool flipped)
        {
            weaponPosOffset = Vector3.zero;
            if (pawn.Rotation == Rot4.West || pawn.Rotation == Rot4.North)
            {
                weaponPosOffset.y = -Offsets.YOffset_Head - Offsets.YOffset_CarriedThing;
            }


            // Use y for the horizontal position. too lazy to add even more vectors
            bool isHorizontal = pawn.Rotation.IsHorizontal;

            aiming = pawn.Aiming();
            Vector3 extOffset;
            Vector3 o = extensions.WeaponPositionOffset;
            Vector3 d = extensions.AimedWeaponPositionOffset;

            if (isHorizontal)
            {
                extOffset = new Vector3(o.y, 0, o.z);
                if (aiming)
                {
                    extOffset += new Vector3(d.y, 0, d.z);
                }
            }
            else
            {
                extOffset = new Vector3(o.x, 0, o.z);
                if (aiming)
                {
                    extOffset += new Vector3(d.x, 0, d.z);
                }
            }

            if (flipped)
            {
                if (aiming)
                {
                    weaponAngle -= extensions?.AttackAngleOffset ?? 0;
                }

                weaponPosOffset += extOffset;

                // flip x position offset
                if (pawn.Rotation != Rot4.South)
                {
                    weaponPosOffset.x *= -1;
                }
            }
            else
            {
                if (aiming)
                {
                    weaponAngle += extensions?.AttackAngleOffset ?? 0;
                }

                weaponPosOffset += extOffset;
            }
        }
        public static void SetPositionsForHandsOnWeapons(Vector3 weaponPosition, bool flipped, float weaponAngle,
                                                         [CanBeNull]
                                                         CompProperties_WeaponExtensions compWeaponExtensions,
                                                         CompBodyAnimator animator, float sizeMod)
        {
            // Prepare everything for DrawHands, but don't draw
            if (compWeaponExtensions == null)
            {
                return;
            }

            animator.FirstHandPosition  = compWeaponExtensions.RightHandPosition;
            animator.SecondHandPosition = compWeaponExtensions.LeftHandPosition;

            // Only put the second hand on when aiming or not moving => free left hand for running
            //  bool leftOnWeapon = true;// aiming || !animator.IsMoving;

            if (animator.FirstHandPosition != Vector3.zero)
            {
                float x = animator.FirstHandPosition.x;
                float y = animator.FirstHandPosition.y;
                float z = animator.FirstHandPosition.z;
                if (flipped)
                {
                    x *= -1f;
                    y *= -1f;
                }

                //if (pawn.Rotation == Rot4.North)
                //{
                //    y *= -1f;
                //}
                x *= sizeMod;
                z *= sizeMod;
                animator.FirstHandPosition =
                    weaponPosition + new Vector3(x, y, z).RotatedBy(weaponAngle);
            }

            if (animator.HasLeftHandPosition)
            {
                float x2 = animator.SecondHandPosition.x;
                float y2 = animator.SecondHandPosition.y;
                float z2 = animator.SecondHandPosition.z;
                if (flipped)
                {
                    x2 *= -1f;
                    y2 *= -1f;
                }

                x2 *= sizeMod;
                z2 *= sizeMod;

                //if (pawn.Rotation == Rot4.North)
                //{
                //    y2 *= -1f;
                //}

                animator.SecondHandPosition =
                    weaponPosition + new Vector3(x2, y2, z2).RotatedBy(weaponAngle);
            }

            // Swap left and right hand position when flipped

            animator.WeaponQuat = Quaternion.AngleAxis(weaponAngle, Vector3.up);
        }
        //  private static float RecoilMax = -0.15f;
        //  private static  Vector3 curOffset = new Vector3(0f, 0f, 0f);
        //  public static void AddOffset(float dist, float dir)
        //  {
        //      curOffset += Quaternion.AngleAxis(dir, Vector3.up) * Vector3.forward * dist;
        //      if (curOffset.sqrMagnitude > RecoilMax        * RecoilMax)
        //      {
        //          curOffset *= RecoilMax / curOffset.magnitude;
        //      }
        //  }
        public static void DoWeaponOffsets(Pawn pawn, Thing eq, ref Vector3 drawLoc, ref float weaponAngle,
                                           ref Mesh weaponMesh)
        {
            CompProperties_WeaponExtensions extensions = eq.def.GetCompProperties <CompProperties_WeaponExtensions>();

            bool flipped = weaponMesh == MeshPool.plane10Flip;

            if ((pawn == null) || (!pawn.GetCompAnim(out CompBodyAnimator animator)) || (extensions == null))
            {
                return;
            }

            float sizeMod = 1f;

            //  if (Controller.settings.IReallyLikeBigGuns) { sizeMod = 2.0f; }
            //     else if (Controller.settings.ILikeBigGuns)
            //  {
            //      sizeMod = 1.4f;
            //  }
            //  else
            //  {
            //      sizeMod = 1f;
            //  }

            if (Find.TickManager.TicksGame == animator.LastPosUpdate[(int)equipment] ||
                MainTabWindow_WalkAnimator.IsOpen && MainTabWindow_WalkAnimator.Pawn != pawn)
            {
                drawLoc     = animator.LastPosition[(int)equipment];
                weaponAngle = animator.LastWeaponAngle;
            }
            else
            {
                animator.LastPosUpdate[(int)equipment] = Find.TickManager.TicksGame;

                CalculatePositionsWeapon(pawn,
                                         ref weaponAngle,
                                         extensions,
                                         out Vector3 weaponPosOffset,
                                         out bool aiming,
                                         flipped);

                // weapon angle and position offsets based on current attack keyframes sequence

                DoAttackAnimationOffsetsWeapons(pawn, ref weaponAngle, ref weaponPosOffset, flipped, animator,
                                                out bool noTween);

                drawLoc += weaponPosOffset * sizeMod;

                Vector3Tween eqTween = animator.Vector3Tweens[(int)equipment];

                if (pawn.pather.MovedRecently(5))
                {
                    noTween = true;
                }

                switch (eqTween.State)
                {
                case TweenState.Running:
                    if (noTween || animator.IsMoving)
                    {
                        eqTween.Stop(StopBehavior.ForceComplete);
                    }

                    drawLoc = eqTween.CurrentValue;
                    break;

                case TweenState.Paused:
                    break;

                case TweenState.Stopped:
                    if (noTween || (animator.IsMoving))
                    {
                        break;
                    }

                    ScaleFunc scaleFunc = ScaleFuncs.SineEaseOut;


                    Vector3 start    = animator.LastPosition[(int)equipment];
                    float   distance = Vector3.Distance(start, drawLoc);
                    float   duration = Mathf.Abs(distance * 50f);
                    if (start != Vector3.zero && duration > 12f)
                    {
                        start.y = drawLoc.y;
                        eqTween.Start(start, drawLoc, duration, scaleFunc);
                        drawLoc = start;
                    }

                    break;
                }


                // // fix the reset to default pos is target is changing
                // bool isAimAngle = (Math.Abs(aimAngle - angleStanding) <= 0.1f);
                // bool isAimAngleFlipped = (Math.Abs(aimAngle - angleStandingFlipped) <= 0.1f);
                //
                // if (aiming && (isAimAngle || isAimAngleFlipped))
                // {
                //     // use the last known position to avoid 1 frame flipping when target changes
                //     drawLoc = animator.lastPosition[(int)equipment];
                //     weaponAngle = animator.lastWeaponAngle;
                // }
                // else
                {
                    animator.LastPosition[(int)equipment] = drawLoc;
                    animator.LastWeaponAngle = weaponAngle;
                    animator.MeshFlipped     = flipped;
                }
            }

            // Now the remaining hands if possible
            if (animator.Props.bipedWithHands && Controller.settings.UseHands)
            {
                SetPositionsForHandsOnWeapons(
                    drawLoc,
                    flipped,
                    weaponAngle,
                    extensions, animator, sizeMod);
            }
        }