Example #1
0
        static AlienPartGenerator.BodyAddon CloneAddon([NotNull] AlienPartGenerator.BodyAddon addon)
        {
            var pType               = typeof(AlienPartGenerator.BodyAddon);
            var shaderField         = pType.GetField("shaderType", BindingFlags.Instance | BindingFlags.NonPublic);
            var prioritizationField = pType.GetField("prioritization", BindingFlags.Instance | BindingFlags.NonPublic);
            var colorChannelField   = pType.GetField("colorChannel", BindingFlags.Instance | BindingFlags.NonPublic);
            var copy = new AlienPartGenerator.BodyAddon()
            {
                angle                 = addon.angle,
                backstoryGraphics     = addon.backstoryGraphics.MakeSafe().ToList(),
                backstoryRequirement  = addon.backstoryRequirement,
                bodyPart              = addon.bodyPart,
                debug                 = addon.debug,
                drawForFemale         = addon.drawForFemale,
                drawForMale           = addon.drawForMale,
                drawnInBed            = addon.drawnInBed,
                drawnOnGround         = addon.drawnOnGround,
                drawSize              = addon.drawSize,
                hiddenUnderApparelFor = addon.hiddenUnderApparelFor.MakeSafe().ToList(),
                path    = addon.path,
                offsets = addon.offsets,
                linkVariantIndexWithPrevious = addon.linkVariantIndexWithPrevious,
                inFrontOfBody         = addon.inFrontOfBody,
                layerInvert           = addon.layerInvert,
                variantCount          = addon.variantCount,
                hediffGraphics        = addon.hediffGraphics.MakeSafe().ToList(),
                layerOffset           = addon.layerOffset,
                hiddenUnderApparelTag = addon.hiddenUnderApparelTag,
            };

            shaderField.SetValue(copy, addon.ShaderType);
            prioritizationField.SetValue(copy, addon.Prioritization.ToList());
            colorChannelField.SetValue(copy, addon.ColorChannel);
            return(copy);
        }
        /// <summary>
        /// Checks a body addon if it should be drawn. This checks if the pawn is:
        /// - Dead
        /// - In a lit room
        /// - Asleep
        /// - Severely incompacitated.
        /// </summary>
        /// <param name="__result">If we should draw this addon.</param>
        /// <param name="pawn">The pawn the addon belongs to.</param>
        /// <returns>Returns true if we want to continue checking the addon in the regular method, false if we don't want to draw this addon.</returns>
        private static bool CuteboldCanDrawAddonPrefix(Pawn pawn, ref bool __result, AlienPartGenerator.BodyAddon __instance)
        {
            if (pawn.def.defName != Cutebold_Assemblies.RaceName || (__instance.bodyPart != "left eye" && __instance.bodyPart != "right eye"))
            {
                return(true);
            }

            __result = true;

            if (pawn.Dead ||
                ((pawn.ParentHolder as Map) != null ? pawn.Map.glowGrid.GameGlowAt(pawn.Position) : (pawn.CarriedBy != null ? pawn.CarriedBy.Map.glowGrid.GameGlowAt(pawn.CarriedBy.Position) : 0.5f)) >= 0.3f ||
                (pawn.CurJob != null && pawn.jobs.curDriver.asleep) ||
                pawn.health.capacities.GetLevel(PawnCapacityDefOf.Sight) == 0f ||
                pawn.health.capacities.GetLevel(PawnCapacityDefOf.Consciousness) <= 0.1f)
            {
                __result = false;
            }
            else if (eyeBlink)
            {
                // Blink Fucntion; somewhat regular blinking, but not exactly even nor completely random.
                var offsetTicks = Math.Abs(pawn.HashOffsetTicks());
                if (Math.Abs((offsetTicks % 182) / 1.8 - Math.Abs(80 * Math.Sin(offsetTicks / 89))) < 1)
                {
                    __result = false;
                }
            }

            return(__result);
        }
Example #3
0
        private static List <AlienPartGenerator.BodyAddon> GenerateBodyAddons(List <AlienPartGenerator.BodyAddon> human, MorphDef morph)
        {
            List <AlienPartGenerator.BodyAddon> returnList = new List <AlienPartGenerator.BodyAddon>();

#if TEST_BODY_SIZE
            var     bodySizes = GetDebugBodySizes(morph);
            Vector2?bodySize  = bodySizes?.body;
            Vector2?headSize  = bodySizes?.head;

            if (bodySizes != null)
            {
                Log.Message($"{morph.defName} draw sizes are: bodySize={bodySizes.Value.body}, headSize={bodySizes.Value.head}");
            }
#else
            Vector2?bodySize = morph?.raceSettings?.graphicsSettings?.customDrawSize;
            Vector2?headSize = morph?.raceSettings?.graphicsSettings?.customHeadDrawSize;
#endif

            List <string> headParts = new List <string>();
            headParts.Add("Jaw");
            headParts.Add("Ear");
            headParts.Add("left ear");
            headParts.Add("right ear");
            headParts.Add("Skull");

            List <string> bodyParts = new List <string>();
            bodyParts.Add("Arm");
            bodyParts.Add("Tail");
            bodyParts.Add("Waist");

            foreach (AlienPartGenerator.BodyAddon addon in human)
            {
                AlienPartGenerator.BodyAddon temp = new AlienPartGenerator.BodyAddon()
                {
                    path     = addon.path,
                    bodyPart = addon.bodyPart,
                    offsets  = GenerateBodyAddonOffsets(addon.offsets, morph),
                    linkVariantIndexWithPrevious = addon.linkVariantIndexWithPrevious,
                    angle                 = addon.angle,
                    inFrontOfBody         = addon.inFrontOfBody,
                    layerOffset           = addon.layerOffset,
                    layerInvert           = addon.layerInvert,
                    drawnOnGround         = addon.drawnOnGround,
                    drawnInBed            = addon.drawnInBed,
                    drawForMale           = addon.drawForMale,
                    drawForFemale         = addon.drawForFemale,
                    drawSize              = addon.drawSize,
                    variantCount          = addon.variantCount,
                    hediffGraphics        = addon.hediffGraphics,
                    backstoryGraphics     = addon.backstoryGraphics,
                    hiddenUnderApparelFor = addon.hiddenUnderApparelFor,
                    hiddenUnderApparelTag = addon.hiddenUnderApparelTag,
                    backstoryRequirement  = addon.backstoryRequirement
                };

                if (headParts.Contains(temp.bodyPart))
                {
                    if (headSize != null)
                    {
                        temp.drawSize = headSize.GetValueOrDefault();
                    }
                    if (bodySize != null)
                    {
                        if (temp?.offsets?.south?.bodyTypes != null)
                        {
                            foreach (AlienPartGenerator.BodyTypeOffset bodyType in temp.offsets.south.bodyTypes)
                            {
                                bodyType.offset.y += 0.34f * (bodySize.GetValueOrDefault().y - 1f);
                            }
                        }
                        if (temp?.offsets?.north?.bodyTypes != null)
                        {
                            foreach (AlienPartGenerator.BodyTypeOffset bodyType in temp.offsets.north.bodyTypes)
                            {
                                bodyType.offset.y += 0.34f * (bodySize.GetValueOrDefault().y - 1f);
                            }
                        }
                        if (temp?.offsets?.east?.bodyTypes != null)
                        {
                            foreach (AlienPartGenerator.BodyTypeOffset bodyType in temp.offsets.east.bodyTypes)
                            {
                                bodyType.offset.y += 0.34f * (bodySize.GetValueOrDefault().y - 1f);
                            }
                        }
                        if (temp?.offsets?.west?.bodyTypes != null)
                        {
                            foreach (AlienPartGenerator.BodyTypeOffset bodyType in temp.offsets.west.bodyTypes)
                            {
                                bodyType.offset.y += 0.34f * (bodySize.GetValueOrDefault().y - 1f);
                            }
                        }
                    }
                }

                if (bodySize != null && bodyParts.Contains(temp.bodyPart))
                {
                    temp.drawSize = bodySize.GetValueOrDefault();
                }

                returnList.Add(temp);
            }

            return(returnList);
        }
        //public static bool DrawAddons_Prefix(bool portrait, Pawn pawn, Vector3 vector, Quaternion quat, Rot4 rotation)
        //{
        //    if (pawn.ageTracker.CurLifeStageIndex < AgeStage.Child)
        //    { return false; }
        //    return true;
        //}

        public static bool DrawAddons_Prefix(bool portrait, Pawn pawn, Vector3 vector, Quaternion quat, Rot4 rotation)
        {
            if (!(pawn.def is ThingDef_AlienRace alienProps))
            {
                return(false);
            }

            // don't make addon for baby & toddler
            if (pawn.ageTracker.CurLifeStageIndex < AgeStage.Child)
            {
                return(false);
            }

            List <AlienPartGenerator.BodyAddon> addons = alienProps.alienRace.generalSettings.alienPartGenerator.bodyAddons;

            AlienPartGenerator.AlienComp alienComp = pawn.GetComp <AlienPartGenerator.AlienComp>();
            for (int i = 0; i < addons.Count; i++)
            {
                AlienPartGenerator.BodyAddon ba = addons[index : i];

                if (!ba.CanDrawAddon(pawn: pawn))
                {
                    continue;
                }

                AlienPartGenerator.RotationOffset offset = rotation == Rot4.South ?
                                                           ba.offsets.south :
                                                           rotation == Rot4.North ?
                                                           ba.offsets.north :
                                                           rotation == Rot4.East ?
                                                           ba.offsets.east :
                                                           ba.offsets.west;

                Vector2 bodyOffset = (portrait ? offset?.portraitBodyTypes ?? offset?.bodyTypes : offset?.bodyTypes)?.FirstOrDefault(predicate: to => to.bodyType == pawn.story.bodyType)
                                     ?.offset ?? Vector2.zero;
                Vector2 crownOffset = (portrait ? offset?.portraitCrownTypes ?? offset?.crownTypes : offset?.crownTypes)?.FirstOrDefault(predicate: to => to.crownType == alienComp.crownType)
                                      ?.offset ?? Vector2.zero;

                //Defaults for tails
                //south 0.42f, -0.3f, -0.22f
                //north     0f,  0.3f, -0.55f
                //east -0.42f, -0.3f, -0.22f

                float moffsetX = 0.42f;
                float moffsetZ = -0.22f;
                float moffsetY = ba.inFrontOfBody ? 0.3f + ba.layerOffset : -0.3f - ba.layerOffset;
                float num      = ba.angle;

                if (rotation == Rot4.North)
                {
                    moffsetX = 0f;
                    moffsetY = !ba.inFrontOfBody ? -0.3f - ba.layerOffset : 0.3f + ba.layerOffset;
                    moffsetZ = -0.55f;
                    num      = 0;
                }

                moffsetX += bodyOffset.x + crownOffset.x;
                moffsetZ += bodyOffset.y + crownOffset.y;

                if (rotation == Rot4.East)
                {
                    moffsetX = -moffsetX;
                    num      = -num; //Angle
                }

                Vector3 offsetVector = new Vector3(x: moffsetX, y: moffsetY, z: moffsetZ);

                Material dmat    = alienComp.addonGraphics[index : i].MatAt(rot : rotation);
                Vector3  rootloc = vector;

                // adjust tail scale
                if (pawn.ageTracker.CurLifeStageIndex == AgeStage.Child && !ba.inFrontOfBody)
                {
                    const float TextureScaleX  = 1.225f;
                    const float TextureScaleY  = 1.225f;
                    const float TextureOffsetX = -0.09f;
                    const float TextureOffsetY = 0f;
                    const float dVectorOffsetX = 0.16f;
                    const float dVectorOffsetY = 0f;
                    const float dVectorOffsetZ = 0.32f;
                    Material    xmat           = new Material(dmat);

                    //float TextureScaleX = CnP_Settings.option_debug_scale_X;
                    //float TextureScaleY = CnP_Settings.option_debug_scale_Y;
                    //float TextureOffsetX = CnP_Settings.option_debug_offset_X;
                    //float TextureOffsetY = CnP_Settings.option_debug_offset_Y;
                    //float dVectorOffsetX = 0.16f;  // CnP_Settings.option_debug_loc_X;
                    //float dVectorOffsetY = 0f;   // CnP_Settings.option_debug_loc_Y;
                    //float dVectorOffsetZ = 0.32f;   // CnP_Settings.option_debug_loc_Z;

                    if (rotation == Rot4.East)
                    {
                        offsetVector.x += dVectorOffsetX;
                    }
                    if (rotation == Rot4.West)
                    {
                        offsetVector.x -= dVectorOffsetX;
                    }

                    offsetVector.y += dVectorOffsetY;
                    offsetVector.z += dVectorOffsetZ;

                    xmat.mainTextureScale  = new Vector2(TextureScaleX, TextureScaleY);
                    xmat.mainTextureOffset = new Vector2(TextureOffsetX, TextureOffsetY);
                    dmat = xmat;
                }
                //////////////////////////////////////////////////////////////////////////////////////////////////

                GenDraw.DrawMeshNowOrLater(mesh: alienComp.addonGraphics[index: i].MeshAt(rot: rotation), loc: rootloc + offsetVector.RotatedBy(angle: Mathf.Acos(f: Quaternion.Dot(a: Quaternion.identity, b: quat)) * 2f * 57.29578f),
                                           quat: Quaternion.AngleAxis(angle: num, axis: Vector3.up) * quat, mat: dmat, drawNow: portrait);
            }
            return(false);
        }