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