// Taken from RenderingTool.RenderPawnInternal in CharacterEditor private void RenderPawn() { PawnGraphicSet graphics = pawn.Drawer.renderer.graphics; Quaternion quaternion = Quaternion.AngleAxis(0f, Vector3.up); Mesh bodyMesh = pawn.RaceProps.Humanlike ? MeshPool.humanlikeBodySet.MeshAt(previewRot) : graphics.nakedGraphic.MeshAt(previewRot); Vector3 bodyOffset = new Vector3(0f, pawn.Position.y + 0.007575758f, 0f); foreach (Material mat in graphics.MatsBodyBaseAt(previewRot)) { Material damagedMat = graphics.flasher.GetDamagedMat(mat); GenDraw.DrawMeshNowOrLater(bodyMesh, bodyOffset, quaternion, damagedMat, false); bodyOffset.y += 0.00390625f; if (!toggleClothesEnabled) { break; } } Vector3 vector3 = new Vector3(0f, pawn.Position.y + (previewRot == Rot4.North ? 0.026515152f : 0.022727273f), 0f); Vector3 vector4 = new Vector3(0f, pawn.Position.y + (previewRot == Rot4.North ? 0.022727273f : 0.026515152f), 0f); if (graphics.headGraphic != null) { Mesh mesh2 = MeshPool.humanlikeHeadSet.MeshAt(previewRot); Vector3 headOffset = quaternion * pawn.Drawer.renderer.BaseHeadOffsetAt(previewRot); Material material = graphics.HeadMatAt(previewRot); GenDraw.DrawMeshNowOrLater(mesh2, vector4 + headOffset, quaternion, material, false); Mesh hairMesh = graphics.HairMeshSet.MeshAt(previewRot); Vector3 hairOffset = new Vector3(headOffset.x, pawn.Position.y + 0.030303031f, headOffset.z); bool isWearingHat = false; if (toggleClothesEnabled) { foreach (ApparelGraphicRecord apparel in graphics.apparelGraphics) { if (apparel.sourceApparel.def.apparel.LastLayer == ApparelLayerDefOf.Overhead) { Material hatMat = graphics.flasher.GetDamagedMat(apparel.graphic.MatAt(previewRot)); if (apparel.sourceApparel.def.apparel.hatRenderedFrontOfFace) { isWearingHat = true; hairOffset.y += 0.03f; GenDraw.DrawMeshNowOrLater(hairMesh, hairOffset, quaternion, hatMat, false); } else { Vector3 hatOffset = new Vector3(headOffset.x, pawn.Position.y + (previewRot == Rot4.North ? 0.003787879f : 0.03409091f), headOffset.z); GenDraw.DrawMeshNowOrLater(hairMesh, hatOffset, quaternion, hatMat, false); } } } } if (!isWearingHat) { Material hairMat = graphics.HairMatAt(previewRot); GenDraw.DrawMeshNowOrLater(hairMesh, hairOffset, quaternion, hairMat, false); } } if (toggleClothesEnabled) { foreach (ApparelGraphicRecord graphicsSet in graphics.apparelGraphics) { if (graphicsSet.sourceApparel.def.apparel.LastLayer == ApparelLayerDefOf.Shell) { Material clothingMat = graphics.flasher.GetDamagedMat(graphicsSet.graphic.MatAt(previewRot)); GenDraw.DrawMeshNowOrLater(bodyMesh, vector3, quaternion, clothingMat, false); } } } HarmonyPatches.DrawAddons(false, vector3, pawn, quaternion, previewRot, false); if (toggleClothesEnabled) { if (pawn.apparel != null) { foreach (Apparel apparel in pawn.apparel.WornApparel) { apparel.DrawWornExtras(); } } } }
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); }
public virtual void DrawInnerThing(Pawn pawn, Vector3 rootLoc, float angle, bool renderBody, Rot4 bodyFacing, Rot4 headFacing, RotDrawMode bodyDrawType, bool portrait, bool headStump) { PawnGraphicSet graphics = pawn.Drawer.renderer.graphics; PawnRenderer renderer = pawn.Drawer.renderer; if (!graphics.AllResolved) { graphics.ResolveAllGraphics(); } Quaternion quaternion = Quaternion.AngleAxis(angle, Vector3.up); Mesh mesh = null; if (renderBody) { Vector3 loc = rootLoc; loc.y += 0.0078125f; if (bodyDrawType == RotDrawMode.Dessicated && !pawn.RaceProps.Humanlike && graphics.dessicatedGraphic != null && !portrait) { graphics.dessicatedGraphic.Draw(loc, bodyFacing, pawn, angle); } else { if (pawn.RaceProps.Humanlike) { mesh = MeshPool.humanlikeBodySet.MeshAt(bodyFacing); } else { mesh = graphics.nakedGraphic.MeshAt(bodyFacing); } List <Material> list = graphics.MatsBodyBaseAt(bodyFacing, bodyDrawType); for (int i = 0; i < list.Count; i++) { Material damagedMat = graphics.flasher.GetDamagedMat(list[i]); GenDraw.DrawMeshNowOrLater(mesh, loc, quaternion, damagedMat, portrait); loc.y += 0.00390625f; } } } Vector3 vector = rootLoc; Vector3 a = rootLoc; if (bodyFacing != Rot4.North) { a.y += 0.02734375f; vector.y += 0.0234375f; } else { a.y += 0.0234375f; vector.y += 0.02734375f; } if (graphics.headGraphic != null) { Vector3 b = quaternion * renderer.BaseHeadOffsetAt(headFacing); Material material = graphics.HeadMatAt(headFacing, bodyDrawType, headStump); if (material != null) { Mesh mesh2 = MeshPool.humanlikeHeadSet.MeshAt(headFacing); GenDraw.DrawMeshNowOrLater(mesh2, a + b, quaternion, material, portrait); } Vector3 loc2 = rootLoc + b; loc2.y += 0.03125f; bool flag = false; if (!portrait || !Prefs.HatsOnlyOnMap) { Mesh mesh3 = graphics.HairMeshSet.MeshAt(headFacing); List <ApparelGraphicRecord> apparelGraphics = graphics.apparelGraphics; for (int j = 0; j < apparelGraphics.Count; j++) { if (apparelGraphics[j].sourceApparel.def.apparel.LastLayer == ApparelLayerDefOf.Overhead) { if (!apparelGraphics[j].sourceApparel.def.apparel.hatRenderedFrontOfFace) { flag = true; Material material2 = apparelGraphics[j].graphic.MatAt(bodyFacing, null); material2 = graphics.flasher.GetDamagedMat(material2); GenDraw.DrawMeshNowOrLater(mesh3, loc2, quaternion, material2, portrait); } else { Material material3 = apparelGraphics[j].graphic.MatAt(bodyFacing, null); material3 = graphics.flasher.GetDamagedMat(material3); Vector3 loc3 = rootLoc + b; loc3.y += ((!(bodyFacing == Rot4.North)) ? 0.03515625f : 0.00390625f); GenDraw.DrawMeshNowOrLater(mesh3, loc3, quaternion, material3, portrait); } } } } if (!flag && bodyDrawType != RotDrawMode.Dessicated && !headStump) { Mesh mesh4 = graphics.HairMeshSet.MeshAt(headFacing); Material mat = graphics.HairMatAt(headFacing); GenDraw.DrawMeshNowOrLater(mesh4, loc2, quaternion, mat, portrait); } } if (renderBody) { for (int k = 0; k < graphics.apparelGraphics.Count; k++) { ApparelGraphicRecord apparelGraphicRecord = graphics.apparelGraphics[k]; if (apparelGraphicRecord.sourceApparel.def.apparel.LastLayer == ApparelLayerDefOf.Shell) { Material material4 = apparelGraphicRecord.graphic.MatAt(bodyFacing, null); material4 = graphics.flasher.GetDamagedMat(material4); GenDraw.DrawMeshNowOrLater(mesh, vector, quaternion, material4, portrait); } } } if (!portrait && pawn.RaceProps.Animal && pawn.inventory != null && pawn.inventory.innerContainer.Count > 0 && graphics.packGraphic != null) { Graphics.DrawMesh(mesh, vector, quaternion, graphics.packGraphic.MatAt(bodyFacing, null), 0); } if (!portrait) { if (pawn.apparel != null) { List <Apparel> wornApparel = pawn.apparel.WornApparel; for (int l = 0; l < wornApparel.Count; l++) { wornApparel[l].DrawWornExtras(); } } Vector3 bodyLoc = rootLoc; bodyLoc.y += 0.04296875f; } }