Example #1
0
        public override void DrawHands(Quaternion bodyQuat, Vector3 drawPos,
                                       bool portrait,
                                       Thing carriedThing = null, bool flip = false)
        {
            if (this.Pawn.Dead || this.Pawn.Downed)
            {
                return;
            }

            if (portrait && !HarmonyPatchesFS.AnimatorIsOpen())
            {
                return;
            }

            if (!this.CompAnimator.Props.bipedWithHands)
            {
                return;
            }

            // return if hands already drawn on carrything
            bool carrying = carriedThing != null;

            if (this.CarryStuff() && !carrying)
            {
                return;
            }


            if (carrying)
            {
                this.ApplyEquipmentWobble(ref drawPos);
                carriedThing.DrawAt(drawPos, flip);
            }

            BodyAnimDef body = this.CompAnimator.BodyAnim;

            Rot4 rot = this.BodyFacing;

            if (body == null)
            {
                return;
            }

            JointLister shoulperPos = this.GetJointPositions(JointType.Shoulder,
                                                             body.shoulderOffsets[rot.AsInt],
                                                             body.shoulderOffsets[Rot4.North.AsInt].x,
                                                             carrying, this.Pawn.ShowWeaponOpenly());

            List <float> handSwingAngle = new List <float> {
                0f, 0f
            };
            List <float> shoulderAngle = new List <float> {
                0f, 0f
            };
            Vector3      rightHand = Vector3.zero;
            Vector3      leftHand  = Vector3.zero;
            WalkCycleDef walkCycle = this.CompAnimator.WalkCycle;
            PoseCycleDef poseCycle = this.CompAnimator.PoseCycle;

            if (walkCycle != null)
            {
                float offsetJoint = walkCycle.ShoulderOffsetHorizontalX.Evaluate(this.CompAnimator.MovedPercent);

                this.DoWalkCycleOffsets(
                    body.armLength,
                    ref rightHand,
                    ref leftHand,
                    ref shoulderAngle,
                    ref handSwingAngle,
                    ref shoulperPos,
                    carrying,
                    walkCycle.HandsSwingAngle,
                    offsetJoint);
            }

            if (poseCycle != null)
            {
                this.DoPoseCycleOffsets(ref rightHand,
                                        ref shoulderAngle,
                                        ref handSwingAngle, poseCycle);
            }

            this.DoAttackAnimationHandOffsets(ref handSwingAngle, ref rightHand, false);

            this.GetBipedMesh(out Mesh handMeshRight, out Mesh handMeshLeft);

            Material matLeft  = this.LeftHandMat;
            Material matRight = this.RightHandMat;

            if (MainTabWindow_BaseAnimator.Colored)
            {
                matLeft  = this.CompAnimator.PawnBodyGraphic?.HandGraphicLeftCol?.MatSingle;
                matRight = this.CompAnimator.PawnBodyGraphic?.HandGraphicRightCol?.MatSingle;
            }
            else if (carriedThing == null)
            {
                switch (rot.AsInt)
                {
                case 1:
                    matLeft = this.LeftHandShadowMat;
                    break;

                case 3:
                    matRight = this.RightHandShadowMat;
                    break;
                }
            }

            bool drawLeft  = matLeft != null && this.CompAnimator.BodyStat.HandLeft != PartStatus.Missing;
            bool drawRight = matRight != null && this.CompAnimator.BodyStat.HandRight != PartStatus.Missing;

            if (drawLeft)
            {
                Quaternion quat;
                Vector3    position;
                bool       noTween = false;
                if (!this.CompAnimator.IsMoving && this.CompAnimator.HasLeftHandPosition)
                {
                    position = this.CompAnimator.SecondHandPosition;
                    quat     = this.CompAnimator.WeaponQuat;
                    noTween  = true;
                }
                else
                {
                    shoulperPos.LeftJoint = bodyQuat * shoulperPos.LeftJoint;
                    leftHand = bodyQuat * leftHand.RotatedBy(-handSwingAngle[0] - shoulderAngle[0]);

                    position = drawPos + shoulperPos.LeftJoint + leftHand;
                    quat     = bodyQuat * Quaternion.AngleAxis(-handSwingAngle[0], Vector3.up);
                }

                TweenThing handLeft = TweenThing.HandLeft;
                this.DrawTweenedHand(position, handMeshLeft, matLeft, quat, handLeft, portrait, noTween);
                //GenDraw.DrawMeshNowOrLater(
                //                           handMeshLeft, position,
                //                           quat,
                //                           matLeft,
                //                           portrait);
            }

            if (drawRight)
            {
                Quaternion quat;
                Vector3    position;
                bool       noTween = false;
                if (this.CompAnimator.FirstHandPosition != Vector3.zero)
                {
                    quat     = this.CompAnimator.WeaponQuat;
                    position = this.CompAnimator.FirstHandPosition;
                    noTween  = true;
                }
                else
                {
                    shoulperPos.RightJoint = bodyQuat * shoulperPos.RightJoint;
                    rightHand =
                        bodyQuat * rightHand.RotatedBy(handSwingAngle[1] - shoulderAngle[1]);

                    position = drawPos + shoulperPos.RightJoint + rightHand;
                    quat     = bodyQuat * Quaternion.AngleAxis(handSwingAngle[1], Vector3.up);
                }

                TweenThing handRight = TweenThing.HandRight;
                this.DrawTweenedHand(position, handMeshRight, matRight, quat, handRight, portrait, noTween);
                // GenDraw.DrawMeshNowOrLater(
                //                            handMeshRight, position,
                //                            quat,
                //                            matRight,
                //                            portrait);
            }

            if (MainTabWindow_BaseAnimator.Develop)
            {
                // for debug
                Material centerMat = GraphicDatabase.Get <Graphic_Single>(
                    "Hands/Human_Hand_dev",
                    ShaderDatabase.CutoutSkin,
                    Vector2.one,
                    Color.white).MatSingle;

                GenDraw.DrawMeshNowOrLater(
                    handMeshLeft,
                    drawPos + shoulperPos.LeftJoint + new Vector3(0, -0.301f, 0),
                    bodyQuat * Quaternion.AngleAxis(-shoulderAngle[0], Vector3.up),
                    centerMat,
                    portrait);

                GenDraw.DrawMeshNowOrLater(
                    handMeshRight,
                    drawPos + shoulperPos.RightJoint + new Vector3(0, 0.301f, 0),
                    bodyQuat * Quaternion.AngleAxis(-shoulderAngle[1], Vector3.up),
                    centerMat,
                    portrait);
            }
        }
Example #2
0
        private void DrawTweenedHand(Vector3 position, Mesh handsMesh, Material material, Quaternion quat,
                                     TweenThing tweenThing,
                                     bool portrait, bool noTween)
        {
            if (position == Vector3.zero || handsMesh == null || material == null || quat == null || tweenThing == null)
            {
                return;
            }
            if (!this.Pawn.Downed || !this.Pawn.Dead)
            {
                if (!HarmonyPatchesFS.AnimatorIsOpen() &&
                    Find.TickManager.TicksGame == this.CompAnimator.LastPosUpdate[(int)tweenThing] ||
                    HarmonyPatchesFS.AnimatorIsOpen() && MainTabWindow_BaseAnimator.Pawn != this.Pawn)
                {
                    position = this.CompAnimator.LastPosition[(int)tweenThing];
                }
                else
                {
                    if (this.Pawn.pather.MovedRecently(5))
                    {
                        noTween = true;
                    }

                    this.CompAnimator.LastPosUpdate[(int)tweenThing] = Find.TickManager.TicksGame;


                    Vector3Tween tween = this.CompAnimator.Vector3Tweens[(int)tweenThing];


                    switch (tween.State)
                    {
                    case TweenState.Running:
                        if (noTween || this.CompAnimator.IsMoving)
                        {
                            tween.Stop(StopBehavior.ForceComplete);
                        }

                        position = tween.CurrentValue;
                        break;

                    case TweenState.Paused:
                        break;

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

                        ScaleFunc scaleFunc = ScaleFuncs.SineEaseOut;


                        Vector3 start    = this.CompAnimator.LastPosition[(int)tweenThing];
                        float   distance = Vector3.Distance(start, position);
                        float   duration = Mathf.Abs(distance * 50f);
                        if (start != Vector3.zero && duration > 12f)
                        {
                            start.y = position.y;
                            tween.Start(start, position, duration, scaleFunc);
                            position = start;
                        }

                        break;
                    }

                    this.CompAnimator.LastPosition[(int)tweenThing] = position;
                }
            }

            //  tweener.PreThingPosCalculation(tweenThing, noTween);

            GenDraw.DrawMeshNowOrLater(
                handsMesh, position,
                quat,
                material,
                portrait);
        }