Beispiel #1
0
        public PawnBodyGraphic(CompBodyAnimator compAni)
        {
            this.CompAni = compAni;
            this._pawn   = compAni.Pawn;

            this.Initialize();
        }
        public static void DoAttackAnimationOffsetsWeapons(Pawn pawn, ref float weaponAngle,
                                                           ref Vector3 weaponPosition,
                                                           bool flipped, CompBodyAnimator animator,
                                                           out bool noTween)
        {
            CompEquippable primaryEq = pawn.equipment?.PrimaryEq;

            noTween = false;

            // DamageDef damageDef = primaryEq?.PrimaryVerb?.verbProps?.meleeDamageDef;
            if (primaryEq?.parent?.def == null)
            {
                return;
            }

            Stance_Busy busy = pawn.stances.curStance as Stance_Busy;

            if (busy == null)
            {
                return;
            }

            if (busy.verb == null || !busy.verb.IsMeleeAttack)
            {
                return;
            }

            DamageDef
                damageDef = busy.verb.GetDamageDef(); //ThingUtility.PrimaryMeleeWeaponDamageType(primaryEq.parent.def);

            if (damageDef == null)
            {
                return;
            }

            // total weapon angle change during animation sequence
            int     totalSwingAngle = 0;
            Vector3 currentOffset   = animator.Jitterer.CurrentOffset;

            float jitterMax             = animator.JitterMax;
            float magnitude             = currentOffset.magnitude;
            float animationPhasePercent = magnitude / jitterMax;

            if (damageDef == DamageDefOf.Stab)
            {
                weaponPosition += currentOffset;

                // + new Vector3(0, 0, Mathf.Pow(this.CompFace.Jitterer.CurrentOffset.magnitude, 0.25f))/2;
            }
            else if (damageDef == DamageDefOf.Blunt || damageDef == DamageDefOf.Cut)
            {
                totalSwingAngle = 120;
                weaponPosition += currentOffset + new Vector3(0, 0, Mathf.Sin(magnitude * Mathf.PI / jitterMax) / 10);
                weaponAngle    += flipped
                               ? -animationPhasePercent * totalSwingAngle
                               : animationPhasePercent * totalSwingAngle;
                noTween = true;
            }
        }
Beispiel #3
0
        private static void RecalcRootLocY(ref Vector3 rootLoc, Pawn pawn, CompBodyAnimator compAnimator)
        {
            Vector3  loc      = rootLoc;
            CellRect viewRect = Find.CameraDriver.CurrentViewRect;

            viewRect = viewRect.ExpandedBy(1);

            List <Pawn> pawns = new List <Pawn>();

            foreach (Pawn otherPawn in pawn.Map.mapPawns.AllPawnsSpawned)
            {
                if (!viewRect.Contains(otherPawn.Position))
                {
                    continue;
                }
                if (otherPawn == pawn)
                {
                    continue;
                }
                if (otherPawn.DrawPos.x < loc.x - 0.5f)
                {
                    continue;
                }

                if (otherPawn.DrawPos.x > loc.x + 0.5f)
                {
                    continue;
                }

                if (otherPawn.DrawPos.z >= loc.z)
                {
                    continue;
                }                                               // ignore above

                pawns.Add(otherPawn);
            }
            // pawns = pawn.Map.mapPawns.AllPawnsSpawned
            //                .Where(
            //                       otherPawn => _viewRect.Contains(otherPawn.Position) &&
            //                       otherPawn != pawn &&
            //                                    otherPawn.DrawPos.x >= loc.x - 1 &&
            //                                    otherPawn.DrawPos.x <= loc.x + 1 &&
            //                                    otherPawn.DrawPos.z <= loc.z).ToList();
            //  List<Pawn> leftOfPawn = pawns.Where(other => other.DrawPos.x <= loc.x).ToList();
            bool flag = compAnimator != null;

            if (!pawns.NullOrEmpty())
            {
                float pawnOffset = YOffsetPawns * pawns.Count;
                loc.y -= pawnOffset;
                if (flag)
                {
                    compAnimator.DrawOffsetY = pawnOffset;
                }
                //   loc.y -= 0.1f * leftOfPawn.Count;
            }
            else
            {
                if (flag)
                {
                    compAnimator.DrawOffsetY = 0f;
                }
            }
            rootLoc = loc;
        }
Beispiel #4
0
        public static bool Prefix(PawnRenderer __instance,
                                  ref Vector3 rootLoc,
                                  float angle,
                                  bool renderBody,
                                  Rot4 bodyFacing,
                                  Rot4 headFacing,
                                  RotDrawMode bodyDrawType,
                                  bool portrait,
                                  bool headStump)
        {
            // Pawn pawn = (Pawn)PawnFieldInfo?.GetValue(__instance);
            PawnGraphicSet graphics = __instance.graphics;

            Pawn pawn = graphics.pawn;

            if (!pawn.RaceProps.Humanlike && !Controller.settings.UsePaws)
            {
                return(true);
            }

            if (!graphics.AllResolved)
            {
                graphics.ResolveAllGraphics();
            }

            CompFace compFace = pawn.GetCompFace();
            bool     hasFace  = compFace != null;

            // Let vanilla do the job if no FacePawn or pawn not a teenager or any other known mod accessing the renderer
            if (hasFace)
            {
                if (compFace.IsChild || compFace.Deactivated)
                {
                    return(true);
                }
            }

            CompBodyAnimator compAnim = pawn.GetCompAnim();
            bool             showFeet = compAnim != null && Controller.settings.UseFeet;

            // No face, no animator, return
            if (!hasFace && compAnim == null)
            {
                return(true);
            }

            PawnWoundDrawer woundDrawer = (PawnWoundDrawer)WoundOverlayFieldInfo?.GetValue(__instance);

            // if (Patches2.Plants)
            // {
            //     if (pawn.Spawned)
            //     {
            //         Plant plant = (pawn.Position + IntVec3.South).GetPlant(pawn.Map);
            //         if (plant != null && Patches2.plantMoved.Contains(plant))
            //         {
            //             rootLoc.y = plant.DrawPos.y - (Patches2.steps / 2);
            //         }
            //     }
            // }

            // Try to move the y position behind while another pawn is standing near
            if (compAnim != null && (!portrait && pawn.Spawned && !compAnim.IsRider))
            {
                RecalcRootLocY(ref rootLoc, pawn, compAnim);
            }

            Vector3 baseDrawLoc = rootLoc;
            // Let's save the basic location for later
            Vector3 footPos = baseDrawLoc;



            // No face => must be animal, simplify it
            Quaternion quat     = Quaternion.AngleAxis(angle, Vector3.up);
            Quaternion bodyQuat = quat;
            Quaternion footQuat = bodyQuat;


            if (MainTabWindow_WalkAnimator.IsOpen)
            {
                bodyFacing = MainTabWindow_BaseAnimator.BodyRot;
                headFacing = MainTabWindow_BaseAnimator.HeadRot;
            }

            compFace?.TickDrawers(bodyFacing, headFacing, graphics);

            compAnim?.TickDrawers(bodyFacing, graphics);

            // Use the basic quat
            Quaternion headQuat = bodyQuat;

            // Rotate head if possible and wobble around
            if (!portrait || MainTabWindow_WalkAnimator.IsOpen)
            {
                if (showFeet)
                {
                    compAnim.ApplyBodyWobble(ref baseDrawLoc, ref footPos, ref bodyQuat);
                }

                // Reset the quat as it has been changed
                headQuat = bodyQuat;
                compFace?.ApplyHeadRotation(renderBody, ref headQuat);
            }

            // Regular FacePawn rendering 14+ years

            // Render body
            // if (renderBody)
            compAnim?.DrawBody(baseDrawLoc, bodyQuat, bodyDrawType, woundDrawer, renderBody, portrait);

            Vector3 bodyPos = baseDrawLoc;
            Vector3 headPos = baseDrawLoc;

            if (bodyFacing == Rot4.North)
            {
                headPos.y += YOffset_Shell;
                bodyPos.y += YOffset_Head;
            }
            else
            {
                headPos.y += YOffset_Head;
                bodyPos.y += YOffset_Shell;
            }


            if (graphics.headGraphic != null)
            {
                // Rendererd pawn faces

                Vector3 offsetAt = !hasFace
                                   ? __instance.BaseHeadOffsetAt(bodyFacing)
                                   : compFace.BaseHeadOffsetAt(portrait);

                Vector3 b           = bodyQuat * offsetAt;
                Vector3 headDrawLoc = headPos + b;

                if (!hasFace)
                {
                    Material material = graphics.HeadMatAt(headFacing, bodyDrawType, headStump);
                    if (material != null)
                    {
                        Mesh mesh2 = MeshPool.humanlikeHeadSet.MeshAt(headFacing);
                        GenDraw.DrawMeshNowOrLater(mesh2, headDrawLoc, quat, material, portrait);
                    }
                }
                else
                {
                    compFace.DrawBasicHead(out bool headDrawn, bodyDrawType, portrait, headStump, headDrawLoc, headQuat);
                    if (headDrawn)
                    {
                        if (bodyDrawType != RotDrawMode.Dessicated && !headStump)
                        {
                            if (compFace.Props.hasWrinkles)
                            {
                                Vector3 wrinkleLoc = headDrawLoc;
                                wrinkleLoc.y += YOffset_Wrinkles;
                                compFace.DrawWrinkles(bodyDrawType, wrinkleLoc, headQuat, portrait);
                            }

                            if (compFace.Props.hasEyes)
                            {
                                Vector3 eyeLoc = headDrawLoc;
                                eyeLoc.y += YOffset_Eyes;

                                compFace.DrawNaturalEyes(eyeLoc, portrait, headQuat);

                                Vector3 browLoc = headDrawLoc;
                                browLoc.y += YOffset_Brows;
                                // the brow above
                                compFace.DrawBrows(browLoc, headQuat, portrait);

                                // and now the added eye parts
                                Vector3 unnaturalEyeLoc = headDrawLoc;
                                unnaturalEyeLoc.y += YOffset_UnnaturalEyes;
                                compFace.DrawUnnaturalEyeParts(unnaturalEyeLoc, headQuat, portrait);
                            }

                            // Portrait obviously ignores the y offset, thus render the beard after the body apparel (again)
                            if (compFace.Props.hasBeard)
                            {
                                Vector3 beardLoc = headDrawLoc;
                                Vector3 tacheLoc = headDrawLoc;

                                beardLoc.y += headFacing == Rot4.North ? -YOffset_Head - YOffset_Beard : YOffset_Beard;
                                tacheLoc.y += headFacing == Rot4.North ? -YOffset_Head - YOffset_Tache : YOffset_Tache;

                                compFace.DrawBeardAndTache(beardLoc, tacheLoc, portrait, headQuat);
                            }

                            if (compFace.Props.hasMouth)
                            {
                                Vector3 mouthLoc = headDrawLoc;
                                mouthLoc.y += YOffset_Mouth;
                                compFace.DrawNaturalMouth(mouthLoc, portrait, headQuat);
                            }
                            // Deactivated, looks kinda crappy ATM
                            // if (pawn.Dead)
                            // {
                            // Material deadEyeMat = faceComp.DeadEyeMatAt(headFacing, bodyDrawType);
                            // if (deadEyeMat != null)
                            // {
                            // GenDraw.DrawMeshNowOrLater(mesh2, locFacialY, headQuat, deadEyeMat, portrait);
                            // locFacialY.y += YOffsetInterval_OnFace;
                            // }

                            // }
                            // else
                        }
                    }
                }


                if (!headStump)
                {
                    Vector3 overHead = baseDrawLoc + b;
                    overHead.y += YOffset_OnHead;

                    Vector3 hairLoc          = overHead;
                    Vector3 headgearLoc      = overHead;
                    Vector3 hatInFrontOfFace = baseDrawLoc + b;


                    hairLoc.y          += YOffset_HairOnHead;
                    headgearLoc.y      += YOffset_GearOnHead;
                    hatInFrontOfFace.y += ((!(headFacing == Rot4.North)) ? YOffset_PostHead : YOffset_Behind);

                    compFace?.DrawHairAndHeadGear(hairLoc, headgearLoc,
                                                  bodyDrawType,
                                                  portrait,
                                                  renderBody,
                                                  headQuat, hatInFrontOfFace);

                    compFace?.DrawAlienHeadAddons(headPos, portrait, headQuat, overHead);
                }
            }

            if (!portrait)
            {
                //   Traverse.Create(__instance).Method("DrawEquipment", rootLoc).GetValue();

                DrawEquipmentMethodInfo?.Invoke(__instance, new object[] { baseDrawLoc });
            }

            if (!portrait)
            {
                if (pawn.apparel != null)
                {
                    List <Apparel> wornApparel = pawn.apparel.WornApparel;
                    foreach (Apparel ap in wornApparel)
                    {
                        DrawPos_Patch.offset        = baseDrawLoc;
                        DrawPos_Patch.offsetEnabled = true;
                        ap.DrawWornExtras();
                        DrawPos_Patch.offsetEnabled = false;
                    }
                }

                Vector3 bodyLoc = baseDrawLoc;
                bodyLoc.y += YOffset_Status;

                PawnHeadOverlays headOverlays = (PawnHeadOverlays)PawnHeadOverlaysFieldInfo?.GetValue(__instance);
                if (headOverlays != null)
                {
                    compFace?.DrawHeadOverlays(headOverlays, bodyLoc, headQuat);
                }
            }


            compAnim?.DrawApparel(bodyQuat, bodyPos, portrait, renderBody);

            compAnim?.DrawAlienBodyAddons(bodyQuat, bodyPos, portrait, renderBody, bodyFacing);

            if (!portrait && pawn.RaceProps.Animal && pawn.inventory != null && pawn.inventory.innerContainer.Count > 0 &&
                graphics.packGraphic != null)
            {
                Mesh mesh = graphics.nakedGraphic.MeshAt(bodyFacing);
                Graphics.DrawMesh(mesh, bodyPos, quat, graphics.packGraphic.MatAt(bodyFacing), 0);
            }

            // No wobble for equipment, looks funnier - nah!
            // Vector3 equipPos = rootLoc;
            // equipPos.y = drawPos.y;

            //compAnim.DrawEquipment(drawPos, portrait);



            bool    showHands = Controller.settings.UseHands;
            Vector3 handPos   = bodyPos;

            if (renderBody || Controller.settings.IgnoreRenderBody)
            {
                if (showHands)
                {
                    // Reset the position for the hands
                    handPos.y = baseDrawLoc.y;
                    compAnim?.DrawHands(bodyQuat, handPos, portrait);
                }

                if (showFeet)
                {
                    compAnim.DrawFeet(bodyQuat, footQuat, footPos, portrait);
                }
            }

            return(false);
        }
Beispiel #5
0
 public BodyAnimator(Pawn p, CompBodyAnimator compAnim)
 {
     this._compAnim = compAnim;
 }
        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);
        }