예제 #1
0
        private static void AddAddonsToRace([NotNull] ThingDef_AlienRace race, [NotNull] List <AlienPartGenerator.BodyAddon> allAddons)
        {
            if (race.alienRace == null)
            {
                race.alienRace = new ThingDef_AlienRace.AlienSettings();
            }

            if (race.alienRace.generalSettings == null)
            {
                race.alienRace.generalSettings = new GeneralSettings();
            }

            if (race.alienRace.generalSettings.alienPartGenerator == null)
            {
                race.alienRace.generalSettings.alienPartGenerator = new AlienPartGenerator();
            }

            var partGen = race.alienRace.generalSettings.alienPartGenerator;

            if (partGen.bodyAddons == null)
            {
                partGen.bodyAddons = new List <AlienPartGenerator.BodyAddon>();
            }

            foreach (AlienPartGenerator.BodyAddon bodyAddon in allAddons)
            {
                var cpy = CloneAddon(bodyAddon);
                partGen.bodyAddons.Add(cpy);
            }
        }
예제 #2
0
        public static void Androidify(Pawn pawn)
        {
            ThingDef_AlienRace alien = ThingDefOf.ChjAndroid as ThingDef_AlienRace;

            pawn.story.hairColor = alien.alienRace.generalSettings.alienPartGenerator.colorChannels.FirstOrDefault(channel => channel.name == "hair").first.NewRandomizedColor();
            AlienComp alienComp = pawn.TryGetComp <AlienComp>();

            if (alienComp != null)
            {
                alienComp.ColorChannels["skin"].first = alien.alienRace.generalSettings.alienPartGenerator.colorChannels.FirstOrDefault(channel => channel.name == "skin").first.NewRandomizedColor();
            }
            PortraitsCache.SetDirty(pawn);
            PortraitsCache.PortraitsCacheUpdate();

            //Add Android Hediff.
            pawn.health.AddHediff(HediffDefOf.ChjAndroidLike);

            //Remove old wounds and bad birthday related ones.
            List <Hediff> hediffs = pawn.health.hediffSet.hediffs.ToList();

            foreach (Hediff hediff in hediffs)
            {
                if (hediff is Hediff_Injury injury && injury.IsPermanent())
                {
                    pawn.health.hediffSet.hediffs.Remove(injury);
                    injury.PostRemoved();
                    pawn.health.Notify_HediffChanged(null);
                }
예제 #3
0
        public static AlienPartGenerator.RotationOffset DrawOffsets(AlienPartGenerator.RotationOffset original, Pawn pawn, AlienRace.AlienPartGenerator.BodyAddon addon)
        {
            AlienPartGenerator.RotationOffset result = original;
            LinkedBodyAddon linked = addon as LinkedBodyAddon;

            if (linked != null && linked.alignWithHead)
            {
                ThingDef_AlienRace thingDef_AlienRace = pawn.def as ThingDef_AlienRace;
                GraphicPaths       paths = thingDef_AlienRace.alienRace.graphicPaths.GetCurrentGraphicPath(pawn.ageTracker.CurLifeStage);
                result           = new AlienPartGenerator.RotationOffset();
                result.bodyTypes = original.bodyTypes;

                /*
                 * for (int i = 0; i < result.bodyTypes.Count; i++)
                 * {
                 *  AlienPartGenerator.BodyTypeOffset body = result.bodyTypes[i];
                 *  body.offset += linked.useHeadDrawSize ? paths.hea : paths.customDrawSize
                 * }
                 */
                result.crownTypes = original.crownTypes;
                for (int i = 0; i < result.crownTypes.Count; i++)
                {
                    AlienPartGenerator.CrownTypeOffset body = result.crownTypes[i];
                    body.offset += paths.headOffsetDirectional?.GetOffset(pawn.Rotation) ?? Vector2.zero;
                }
                Log.Message("DrawOffsets result: " + result);
            }

            return(result);
        }
예제 #4
0
 public static AlienPartGenerator GetPartGenerator([NotNull] this ThingDef_AlienRace alienRace)
 {
     if (alienRace == null)
     {
         throw new ArgumentNullException(nameof(alienRace));
     }
     return(alienRace.alienRace?.generalSettings?.alienPartGenerator);
 }
예제 #5
0
 static HumanoidAlienRaces()
 {
     // Add types from humanoid alien races
     if (ModCompatibilityCheck.HumanoidAlienRaces)
     {
         ThingDef_AlienRace = GenTypes.GetTypeInAnyAssembly("AlienRace.ThingDef_AlienRace", "AlienRace");
         AlienSettings      = ThingDef_AlienRace.GetNestedType("AlienSettings", BindingFlags.Public | BindingFlags.Instance);
         HairSettings       = GenTypes.GetTypeInAnyAssembly("AlienRace.HairSettings", "AlienRace");
     }
 }
예제 #6
0
        public static bool TryGetBackstory_DisallowedTrait(ThingDef thingDef, Pawn pawn, TraitDef td)
        {
            bool traitIsAllowed = true;

            //Log.Message("checking for alien races...");
            if (Validate.AlienHumanoidRaces.IsInitialized())
            {
                //Log.Message("initialized. Checking if " + thingDef.defName + " is an alien race...");
                ThingDef_AlienRace alienDef = thingDef as ThingDef_AlienRace;
                if (alienDef != null && alienDef.alienRace != null && alienDef.alienRace.raceRestriction != null && alienDef.alienRace.raceRestriction.traitList != null)
                {
                    if (alienDef.alienRace.raceRestriction.traitList.Contains(td))
                    {
                        traitIsAllowed = false;
                    }
                    //AlienTraitEntry ate = new AlienTraitEntry();
                    //ate.defName = (from def in DefDatabase<TraitDef>.AllDefs
                    //              where (def.defName == traitString)
                    //              select def).FirstOrDefault();
                    ////Log.Message("alien race. checking if " + traitString + " is allowed for backstory...");
                    //if (alienDef.alienRace.generalSettings != null && alienDef.alienRace.generalSettings. != null && alienDef.alienRace.generalSettings.disallowedTraits.)
                    //{
                    //    traitIsAllowed = false;
                    //}
                    if (pawn.story != null && pawn.story.AllBackstories != null)
                    {
                        foreach (Backstory bs in pawn.story.AllBackstories)
                        {
                            IEnumerable <BackstoryDef> enumerable = from def in DefDatabase <BackstoryDef> .AllDefs
                                                                    where (def.backstory == bs)
                                                                    select def;
                            foreach (BackstoryDef current in enumerable)
                            {
                                //Log.Message(current.LabelCap + " has disallowed traits: " + current.disallowedTraits.Count);
                                for (int i = 0; i < current.disallowedTraits.Count; i++)
                                {
                                    //Log.Message("" + current.disallowedTraits[i].defName);
                                    if (current.disallowedTraits[i].defName == td)
                                    {
                                        //Log.Message("trait is disallowed");
                                        traitIsAllowed = false;
                                    }
                                }
                            }
                        }
                    }
                }
            }

            //Log.Message("trait " + traitString + " is allowed: " + traitIsAllowed);
            return(traitIsAllowed);
        }
예제 #7
0
        public static bool AlienCorpseHasOrganicFlesh(ThingDef def)
        {
            ThingDef corpseAlienRace = ThingDef.Named(def.ToString().Substring("Corpse_".Length));

            if (corpseAlienRace.race.Humanlike)
            {
                ThingDef_AlienRace test = corpseAlienRace as ThingDef_AlienRace;

                return(test.alienRace.compatibility.IsFlesh);
            }

            return(false);
        }
예제 #8
0
        static void ReRollRaceTraits(Pawn pawn, ThingDef_AlienRace newRace)
        {
            var traitSet = pawn.story?.traits;

            if (traitSet == null)
            {
                return;
            }
            var allAlienTraits = newRace.alienRace.generalSettings?.forcedRaceTraitEntries;

            if (allAlienTraits == null || allAlienTraits.Count == 0)
            {
                return;
            }
            //removing traits not supported right now, Rimworld doesn't like it when you remove traits


            var traitsToAdd = allAlienTraits;

            foreach (AlienTraitEntry alienTraitEntry in traitsToAdd)
            {
                var def = TraitDef.Named(alienTraitEntry.defName);
                if (traitSet.HasTrait(def))
                {
                    continue;                         //don't add traits that are already added
                }
                var add = (Rand.RangeInclusive(0, 100) <= alienTraitEntry.chance);

                if (add && pawn.gender == Gender.Male && alienTraitEntry.commonalityMale > 0)
                {
                    add = Rand.RangeInclusive(0, 100) <= alienTraitEntry.commonalityMale;
                }
                else if (add && pawn.gender == Gender.Female && alienTraitEntry.commonalityFemale > 0) //only check gender chance if the add roll has passed
                {                                                                                      //this is consistent with how the alien race framework handles it
                    add = Rand.RangeInclusive(0, 100) <= alienTraitEntry.commonalityMale;
                }


                if (add)
                {
                    var degree = def.degreeDatas[alienTraitEntry.degree];

                    traitSet.GainTrait(new Trait(def, alienTraitEntry.degree, true));
                    if (degree.skillGains != null)
                    {
                        UpdateSkillsPostAdd(pawn, degree.skillGains); //need to update the skills manually
                    }
                }
            }
        }
예제 #9
0
        public static AlienRace GetAlienRace(ThingDef_AlienRace def, Pawn p)
        {
            if (lookup.TryGetValue(def, out AlienRace result))
            {
                return(result);
            }

            result = InitializeAlienRace(def, p);
            if (result != null)
            {
                lookup.Add(def, result);
            }

            return(result);
        }
예제 #10
0
        private static ThingDef_AlienRace GenerateImplicitRace([NotNull] ThingDef_AlienRace humanDef, [NotNull] MorphDef morph)
        {
            var impliedRace = new ThingDef_AlienRace
            {
                defName                 = morph.defName + "Race_Implied", //most of these are guesses, should figure out what's safe to change and what isn't
                label                   = morph.label,
                race                    = GenerateHybridProperties(humanDef.race, morph.race.race),
                thingCategories         = humanDef.thingCategories,
                thingClass              = humanDef.thingClass,
                category                = humanDef.category,
                selectable              = humanDef.selectable,
                tickerType              = humanDef.tickerType,
                altitudeLayer           = humanDef.altitudeLayer,
                useHitPoints            = humanDef.useHitPoints,
                hasTooltip              = humanDef.hasTooltip,
                soundImpactDefault      = morph.race.soundImpactDefault,
                statBases               = GenerateHybridStatModifiers(humanDef.statBases, morph.race.statBases, morph.raceSettings.statModifiers),
                inspectorTabs           = humanDef.inspectorTabs.ToList(), //do we want any custom tabs?
                comps                   = humanDef.comps.ToList(),
                drawGUIOverlay          = humanDef.drawGUIOverlay,
                description             = string.IsNullOrEmpty(morph.description) ? morph.race.description : morph.description,
                modContentPack          = morph.modContentPack,
                inspectorTabsResolved   = humanDef.inspectorTabsResolved?.ToList() ?? new List <InspectTabBase>(),
                recipes                 = new List <RecipeDef>(humanDef.recipes.MakeSafe()), //this is where the surgery operations live
                filth                   = morph.race.filth,
                filthLeaving            = morph.race.filthLeaving,
                soundDrop               = morph.race.soundDrop,
                soundInteract           = morph.race.soundInteract,
                soundPickup             = morph.race.soundPickup,
                socialPropernessMatters = humanDef.socialPropernessMatters,
                stuffCategories         = humanDef.stuffCategories?.ToList(),
                designationCategory     = humanDef.designationCategory,
                tradeTags               = humanDef.tradeTags?.ToList(),
                tradeability            = humanDef.tradeability,
                fillPercent             = morph.raceSettings.coverPercent
            };

            impliedRace.tools = new List <Tool>(humanDef.tools.MakeSafe().Concat(morph.race.tools.MakeSafe()));
            var verbField = typeof(ThingDef).GetField("verbs", BindingFlags.NonPublic | BindingFlags.Instance);
            var vLst      = impliedRace.Verbs.MakeSafe().Concat(morph.race.Verbs.MakeSafe()).ToList();

            verbField.SetValue(impliedRace, vLst);


            impliedRace.alienRace = GenerateHybridAlienSettings(humanDef.alienRace, morph, impliedRace);

            return(impliedRace);
        }
예제 #11
0
 private static void CreateImplicitMeshes(StringBuilder builder, ThingDef_AlienRace race)
 {
     try
     {
         //generate any meshes the implied race might need
         if (race.alienRace?.graphicPaths != null)
         {
             builder.AppendLine($"Generating mesh pools for {race.defName}");
             race.alienRace.generalSettings?.alienPartGenerator?.GenerateMeshsAndMeshPools();
         }
     }
     catch (Exception e)
     {
         throw new ModInitializationException($"while updating graphics for {race.defName}, caught {e.GetType().Name}", e);
     }
 }
예제 #12
0
        public static Vector2 AlienRacesPatch(Pawn pawn, Thing eq)
        {
            ThingDef_AlienRace alienDef = pawn.def as ThingDef_AlienRace;
            Vector2            s;

            if (alienDef != null)
            {
                //	AlienRace.GraphicPaths paths = alienDef.alienRace.graphicPaths.GetCurrentGraphicPath(pawn.ageTracker.CurLifeStage);
                //	Log.Message(pawn.Name + " " + pawn.def.LabelCap + " is ThingDef_AlienRace");
                s = alienDef.alienRace.generalSettings.alienPartGenerator.customDrawSize;
            }
            else
            {
                //	Log.Message(pawn.Name + " " + pawn.def.LabelCap + " not ThingDef_AlienRace");
                s = new Vector3(eq.def.graphicData.drawSize.x, 1f, eq.def.graphicData.drawSize.y);
            }
            return(s);
        }
예제 #13
0
        private static IEnumerable <ThingDef_AlienRace> GenerateAllImpliedRaces()
        {
            IEnumerable <MorphDef> morphs = DefDatabase <MorphDef> .AllDefs;
            ThingDef_AlienRace     human;

            try
            {
                human = (ThingDef_AlienRace)ThingDef.Named("Human");
            }
            catch (InvalidCastException e)
            {
                throw new
                      ModInitializationException($"could not convert human ThingDef to {nameof(ThingDef_AlienRace)}! is HAF up to date?", e);
            }


            var builder = new StringBuilder();

            // ReSharper disable once PossibleNullReferenceException
            foreach (MorphDef morphDef in morphs)
            {
                builder.AppendLine($"generating implied race for {morphDef.defName}");
                ThingDef_AlienRace race = GenerateImplicitRace(human, morphDef);
                _raceLookupTable[race] = morphDef;

                if (morphDef.ExplicitHybridRace == null) //still generate the race so we don't break saves, but don't set them
                {
                    morphDef.hybridRaceDef = race;
                }
                else
                {
                    _raceLookupTable[morphDef.ExplicitHybridRace] = morphDef;
                    builder.AppendLine($"\t\t{morphDef.defName} has explicit hybrid race {morphDef.ExplicitHybridRace.defName}, {race.defName} will not be used but still generated");
                }



                CreateImplicitMeshes(builder, race);

                yield return(race);
            }

            Log.Message(builder.ToString());
        }
        public Dialog_AlienFaceStyling(CompFace face, ThingDef_AlienRace alienProp) : base(face)
        {
            Pawn = face.Pawn;
            PawnColorUtils.InitializeColors();
            this.alienRace = ProviderAlienRaces.GetAlienRace(alienProp, Pawn);
            AlienRace race = this.alienRace;

            if (race != null && race.HasHair)
            {
                HairDefs = DefDatabase <HairDef> .AllDefsListForReading.FindAll(
                    x =>
                    x.hairTags
                    .SharesElementWith(this.alienRace
                                       .HairTags) && !x.IsBeardNotHair());

                CurrentFilter = race.HairTags;
            }

            this.useSkincolorForHair = ((ThingDef_AlienRace)this.CompFace.Pawn.def)
                                       .alienRace.generalSettings.alienPartGenerator
                                       .useSkincolorForHair;
            this.genderTab = GenderTab.All;
        }
예제 #15
0
        static PostDefFixer()
        {
            Log.Message("Androids: Fixing surgery recipes for Droids.");
            //Fix Droid recipes.
            foreach (RecipeDef recipe in DefDatabase <RecipeDef> .AllDefs)
            {
                if (recipe.defName.StartsWith("Administer_"))
                {
                    int removedNum = recipe.recipeUsers.RemoveAll(thingDef => thingDef.HasModExtension <MechanicalPawnProperties>());
                    if (Prefs.LogVerbose && removedNum > 0)
                    {
                        Log.Message("Androids: Removed '" + removedNum + "' recipes for Droids.");
                    }
                }
            }

            Log.Message("Androids: Fixing belts whitelist for AlienRace.ThingDef_AlienRace with defName='ChjBattleDroid'.");
            //Fix Battle droid belts.
            ThingDef_AlienRace ChjBattleDroid = (ThingDef_AlienRace)ThingDef.Named("ChjBattleDroid");
            {
                List <string> whitelist = ChjBattleDroid.alienRace.raceRestriction.whiteApparelList;
                foreach (ThingDef thingDef in DefDatabase <ThingDef> .AllDefs)
                {
                    if (thingDef.IsApparel &&
                        (thingDef.apparel.bodyPartGroups != null && thingDef.apparel.bodyPartGroups.Count == 1 && thingDef.apparel.bodyPartGroups.First().defName == "Waist") &&
                        (thingDef.apparel.layers != null && thingDef.apparel.layers.Count == 1 && thingDef.apparel.layers.First().defName == "Belt") &&
                        !whitelist.Any(item => item == thingDef.defName))
                    {
                        if (Prefs.LogVerbose)
                        {
                            Log.Message("Androids: Belt found and added: " + thingDef.defName);
                        }
                        whitelist.Add(thingDef.defName);
                    }
                }
            }
        }
예제 #16
0
        public static bool AlienRaceHasOrganicFlesh(Pawn pawn)
        {
            ThingDef_AlienRace raceDef = pawn.def as ThingDef_AlienRace;

            return(raceDef?.alienRace.compatibility.IsFlesh ?? true);
        }
예제 #17
0
        /// <summary>
        /// Does the window contents.
        /// </summary>
        /// <param name="inRect">The in rect.</param>
        public override void DoWindowContents(Rect inRect)
        {
            // Draw the window title.
            Text.Font = GameFont.Medium;
            string titleLabel  = $"{WINDOW_TITLE_LOC_STRING.Translate()} - {pawn.Name.ToStringShort} ({pawn.def.LabelCap})";
            float  titleHeight = Text.CalcHeight(titleLabel, inRect.width);
            Rect   titleRect   = new Rect(inRect.x, inRect.y, inRect.width, titleHeight);

            Widgets.Label(titleRect, titleLabel);
            Text.Font = GameFont.Small;

            // Determine draw areas for parts list and descriptions.
            float columnWidth  = (inRect.width - PREVIEW_SIZE.x) / 2 - SPACER_SIZE;
            float columnHeight = inRect.height - titleHeight - Math.Max(APPLY_BUTTON_SIZE.y, Math.Max(RESET_BUTTON_SIZE.y, CANCEL_BUTTON_SIZE.y)) - 2 * SPACER_SIZE;

            // Draw parts list as the left column. This displays all mutable parts and the mutations currently applied to them.
            Rect partListOutRect  = new Rect(inRect.x, titleHeight + SPACER_SIZE, columnWidth, columnHeight);
            Rect partListViewRect = new Rect(partListOutRect.x, partListOutRect.y, partListScrollSize.x, partListScrollSize.y);

            DrawPartsList(partListOutRect, partListViewRect);

            // Draw the preview area, mode toggle buttons, body/crown type selection and aspect selection in the middle column (Might need to outsource these to a helper function).
            // First the preview...
            float curY        = titleHeight + SPACER_SIZE;
            Rect  previewRect = new Rect(columnWidth + SPACER_SIZE, curY, PREVIEW_SIZE.x, PREVIEW_SIZE.y);

            if (recachePreview || previewImage == null)
            {
                SetPawnPreview();
            }
            GUI.DrawTexture(previewRect, previewImage);
            curY += previewRect.height;

            // Then the preview buttons...
            float rotCWHorPos          = previewRect.x + previewRect.width / 2 - TOGGLE_CLOTHES_BUTTON_SIZE.x / 2 - ROTATE_CW_BUTTON_SIZE.x - SPACER_SIZE;
            float toggleClothingHorPos = previewRect.x + previewRect.width / 2 - TOGGLE_CLOTHES_BUTTON_SIZE.x / 2;
            float rotCCWHorPos         = previewRect.x + previewRect.width / 2 + TOGGLE_CLOTHES_BUTTON_SIZE.x / 2 + SPACER_SIZE;
            Rect  rotCWRect            = new Rect(rotCWHorPos, curY, ROTATE_CW_BUTTON_SIZE.x, ROTATE_CW_BUTTON_SIZE.y);
            Rect  toggleClothesRect    = new Rect(toggleClothingHorPos, curY, TOGGLE_CLOTHES_BUTTON_SIZE.x, TOGGLE_CLOTHES_BUTTON_SIZE.y);
            Rect  rotCCWRect           = new Rect(rotCCWHorPos, curY, ROTATE_CCW_BUTTON_SIZE.x, ROTATE_CCW_BUTTON_SIZE.y);

            curY += SPACER_SIZE;
            if (Widgets.ButtonImageFitted(rotCWRect, ButtonTexturesPM.rotCW, Color.white, GenUI.MouseoverColor))
            {
                previewRot.Rotate(RotationDirection.Clockwise);
                SoundDefOf.Tick_Tiny.PlayOneShotOnCamera();
                recachePreview = true;
            }
            TooltipHandler.TipRegionByKey(rotCWRect, ROTATE_CW_LOC_STRING);
            if (Widgets.ButtonImageFitted(toggleClothesRect, ButtonTexturesPM.toggleClothes, Color.white, GenUI.MouseoverColor))
            {
                toggleClothesEnabled = !toggleClothesEnabled;
                (toggleClothesEnabled ? SoundDefOf.Checkbox_TurnedOn : SoundDefOf.Checkbox_TurnedOff).PlayOneShotOnCamera();
                recachePreview = true;
            }
            TooltipHandler.TipRegionByKey(toggleClothesRect, TOGGLE_CLOTHES_LOC_STRING);
            if (Widgets.ButtonImageFitted(rotCCWRect, ButtonTexturesPM.rotCCW, Color.white, GenUI.MouseoverColor))
            {
                previewRot.Rotate(RotationDirection.Counterclockwise);
                SoundDefOf.Tick_Tiny.PlayOneShotOnCamera();
                recachePreview = true;
            }
            TooltipHandler.TipRegionByKey(rotCCWRect, ROTATE_CCW_LOC_STRING);
            curY += Math.Max(TOGGLE_CLOTHES_BUTTON_SIZE.y, Math.Max(ROTATE_CW_BUTTON_SIZE.y, ROTATE_CCW_BUTTON_SIZE.y));

            // Then the crown and body type selectors...
            Rect crownLabelRect  = new Rect(previewRect.x, curY, previewRect.width / 3, Text.CalcHeight(CROWN_LABEL_LOC_STRING.Translate(), previewRect.width / 3));
            Rect crownButtonRect = new Rect(previewRect.x + previewRect.width / 3, curY, previewRect.width * 2 / 3, Text.CalcHeight(pawn.GetComp <AlienPartGenerator.AlienComp>().crownType.Replace('_', ' '), previewRect.width * 2 / 3));

            Widgets.Label(crownLabelRect, CROWN_LABEL_LOC_STRING.Translate());
            if (Widgets.ButtonText(crownButtonRect, pawn.GetComp <AlienPartGenerator.AlienComp>().crownType.Replace('_', ' ')))
            {
                List <FloatMenuOption> options = new List <FloatMenuOption>();
                ThingDef_AlienRace     pawnDef = pawn.def as ThingDef_AlienRace;
                foreach (string crownType in pawnDef.alienRace.generalSettings.alienPartGenerator.aliencrowntypes)
                {
                    void changeHeadType()
                    {
                        pawn.GetComp <AlienPartGenerator.AlienComp>().crownType = crownType;
                        recachePreview = true;
                    }

                    options.Add(new FloatMenuOption(crownType.Replace('_', ' '), changeHeadType));
                }
                Find.WindowStack.Add(new FloatMenu(options));
            }
            curY += Math.Max(crownLabelRect.height, crownButtonRect.height);

            Rect bodyLabelRect  = new Rect(previewRect.x, curY, previewRect.width / 3, Text.CalcHeight(BODY_LABEL_LOC_STRING.Translate(), previewRect.width / 3));
            Rect bodyButtonRect = new Rect(previewRect.x + previewRect.width / 3, curY, previewRect.width * 2 / 3, Text.CalcHeight(pawn.story.bodyType.defName, previewRect.width * 2 / 3));

            Widgets.Label(bodyLabelRect, BODY_LABEL_LOC_STRING.Translate());
            if (Widgets.ButtonText(bodyButtonRect, pawn.story.bodyType.defName))
            {
                List <FloatMenuOption> options = new List <FloatMenuOption>();
                foreach (BodyTypeDef bodyType in DefDatabase <BodyTypeDef> .AllDefs)
                {
                    void changeBodyType()
                    {
                        pawn.story.bodyType = bodyType;
                        recachePreview      = true;
                    }

                    options.Add(new FloatMenuOption(bodyType.defName, changeBodyType));
                }
                Find.WindowStack.Add(new FloatMenu(options));
            }
            curY += Math.Max(bodyLabelRect.height, bodyButtonRect.height);

            // Then the parts list toggles...
            string skinSyncText = SKIN_SYNC_LOC_STRING.Translate();
            Rect   skinSyncRect = new Rect(columnWidth + SPACER_SIZE, curY, PREVIEW_SIZE.x, Text.CalcHeight(skinSyncText, PREVIEW_SIZE.x));

            Widgets.CheckboxLabeled(skinSyncRect, skinSyncText, ref skinSync);
            curY += skinSyncRect.height;

            string symmetryToggleText = DO_SYMMETRY_LOC_STRING.Translate();
            Rect   symmetryToggleRect = new Rect(columnWidth + SPACER_SIZE, curY, PREVIEW_SIZE.x, Text.CalcHeight(symmetryToggleText, PREVIEW_SIZE.x));

            Widgets.CheckboxLabeled(symmetryToggleRect, symmetryToggleText, ref doSymmetry);
            curY += symmetryToggleRect.height;

            // Then finally the Aspect selection list.
            // Remember this needs scrolling, Brennen.

            // Draw the right column, consisting of the modification summary (top box) and the currently hovered over mutation description (bottom box).
            DrawDescriptionBoxes(new Rect(inRect.width - columnWidth, titleHeight + SPACER_SIZE, columnWidth, columnHeight));

            // Draw the apply, reset and cancel buttons.
            float buttonVertPos = inRect.height - Math.Max(APPLY_BUTTON_SIZE.y, Math.Max(RESET_BUTTON_SIZE.y, CANCEL_BUTTON_SIZE.y));
            float applyHorPos   = inRect.width / 2 - APPLY_BUTTON_SIZE.x - RESET_BUTTON_SIZE.x / 2 - SPACER_SIZE;
            float resetHorPos   = inRect.width / 2 - RESET_BUTTON_SIZE.x / 2;
            float cancelHorPos  = inRect.width / 2 + RESET_BUTTON_SIZE.x / 2 + SPACER_SIZE;

            if (Widgets.ButtonText(new Rect(applyHorPos, buttonVertPos, APPLY_BUTTON_SIZE.x, APPLY_BUTTON_SIZE.y), APPLY_BUTTON_LOC_STRING.Translate()))
            {
                OnAcceptKeyPressed();
            }
            if (Widgets.ButtonText(new Rect(resetHorPos, buttonVertPos, RESET_BUTTON_SIZE.x, RESET_BUTTON_SIZE.y), RESET_BUTTON_LOC_STRING.Translate()))
            {
                SoundDefOf.Checkbox_TurnedOff.PlayOneShotOnCamera(null);
                Reset();
            }
            if (Widgets.ButtonText(new Rect(cancelHorPos, buttonVertPos, CANCEL_BUTTON_SIZE.x, CANCEL_BUTTON_SIZE.y), CANCEL_BUTTON_LOC_STRING.Translate()))
            {
                OnCancelKeyPressed();
            }
        }
예제 #18
0
        private static void ValidateGraphicsPaths([NotNull] Pawn pawn, [NotNull] ThingDef_AlienRace oldRace, [NotNull] ThingDef_AlienRace race)
        {
            //this implimentation is a work in progress
            //currently, when shifting to an explicit race the body and head types will come out 'shuffled'
            //
            var alienComp    = pawn.GetComp <AlienPartGenerator.AlienComp>();
            var graphicsComp = pawn.GetComp <InitialGraphicsComp>();
            var story        = pawn.story;

            if (alienComp == null)
            {
                Log.Error($"trying to validate the graphics of {pawn.Name} but they don't have an {nameof(AlienPartGenerator.AlienComp)}!");
                return;
            }

            if (graphicsComp == null)
            {
                Log.Error($"trying to validate the graphics of {pawn.Name} but they don't have an {nameof(InitialGraphicsComp)}!");
            }



            var oldGen = oldRace.alienRace.generalSettings.alienPartGenerator;
            var newGen = race.alienRace.generalSettings.alienPartGenerator;

            //get the new head type
            var   oldHIndex = oldGen.aliencrowntypes.FindIndex(s => s == alienComp.crownType);
            float hRatio    = newGen.aliencrowntypes.Count / ((float)oldGen.aliencrowntypes.Count);

            int newHIndex;

            if (oldHIndex == -1)                                         //-1 means not found
            {
                newHIndex = Rand.Range(0, newGen.aliencrowntypes.Count); //just pick a random head
            }
            else
            {
                newHIndex = Mathf.FloorToInt(oldHIndex * hRatio); //squeeze the old index into the range of the new crow type
            }


            //now get the new body type

            var bRatio    = newGen.alienbodytypes.Count / ((float)oldGen.alienbodytypes.Count);
            var oldBIndex = oldGen.alienbodytypes.FindIndex(b => b == story.bodyType);

            int newBIndex;

            if (oldBIndex == -1)
            {
                newBIndex = Rand.Range(0, newGen.alienbodytypes.Count);
            }
            else
            {
                newBIndex = Mathf.FloorToInt(oldBIndex * bRatio);
            }



            //now set the body and head type

            var newHeadType = newGen.aliencrowntypes[newHIndex];

            alienComp.crownType = newHeadType;

            if (newGen.alienbodytypes.Count > 0)
            {
                var newBType = newGen.alienbodytypes[newBIndex];
                story.bodyType = newBType;
            }

            if (oldRace.alienRace.hairSettings?.hasHair == true && race.alienRace.hairSettings?.hasHair == false)
            {
                story.hairDef = HairDefOf.Shaved;
            }
        }
예제 #19
0
        // 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_NewTemp(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_NewTemp(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);
                    }
                }
            }
            ThingDef_AlienRace def     = pawn.def as ThingDef_AlienRace;
            Vector2            hOffset = def != null?def.alienRace.graphicPaths.GetCurrentGraphicPath(pawn.ageTracker.CurLifeStage).headOffset : Vector2.zero;

            HarmonyPatches.DrawAddons(false, vector3, hOffset, pawn, quaternion, previewRot, false);
            if (toggleClothesEnabled)
            {
                if (pawn.apparel != null)
                {
                    foreach (Apparel apparel in pawn.apparel.WornApparel)
                    {
                        apparel.DrawWornExtras();
                    }
                }
            }
        }
예제 #20
0
        private static void CreateNewPawnKind(PawnKindDef pkOld, string label, string defname)
        {
            // if it already exists then don't recreate it
            if (DefDatabase <PawnKindDef> .GetNamedSilentFail(defname) != null)
            {
                return;
            }
            PawnKindDef pk = new PawnKindDef
            {
                defName = defname,
                label   = pkOld.label + " (" + label.ToLower() + ")",

                allowRoyalApparelRequirements = pkOld.allowRoyalApparelRequirements,
                allowRoyalRoomRequirements    = pkOld.allowRoyalRoomRequirements,
                alternateGraphicChance        = pkOld.alternateGraphicChance,
                alternateGraphics             = pkOld.alternateGraphics.ListFullCopyOrNull <AlternateGraphic>(),
                apparelRequired                 = pkOld.apparelRequired.ListFullCopyOrNull <ThingDef>(),
                apparelDisallowTags             = pkOld.apparelDisallowTags.ListFullCopyOrNull <string>(),
                apparelTags                     = pkOld.apparelTags.ListFullCopyOrNull <string>(),
                apparelAllowHeadgearChance      = pkOld.apparelAllowHeadgearChance,
                aiAvoidCover                    = pkOld.aiAvoidCover,
                apparelColor                    = pkOld.apparelColor,
                apparelIgnoreSeasons            = pkOld.apparelIgnoreSeasons,
                apparelMoney                    = new FloatRange(min: pkOld.apparelMoney.min, max: pkOld.apparelMoney.max),
                backstoryCategories             = pkOld.backstoryCategories.ListFullCopyOrNull <string>(),
                backstoryFilters                = pkOld.backstoryFilters.ListFullCopyOrNull <BackstoryCategoryFilter>(),
                backstoryFiltersOverride        = pkOld.backstoryFiltersOverride.ListFullCopyOrNull <BackstoryCategoryFilter>(),
                backstoryCryptosleepCommonality = pkOld.backstoryCryptosleepCommonality,
                baseRecruitDifficulty           = pkOld.baseRecruitDifficulty,
                biocodeWeaponChance             = pkOld.biocodeWeaponChance,
                canArriveManhunter              = pkOld.canArriveManhunter,
                canBeSapper                     = pkOld.canBeSapper,
                chemicalAddictionChance         = pkOld.chemicalAddictionChance,
                combatEnhancingDrugsChance      = pkOld.combatEnhancingDrugsChance,
                combatEnhancingDrugsCount       = pkOld.combatEnhancingDrugsCount,
                combatPower                     = pkOld.combatPower,
                defaultFactionType              = pkOld.defaultFactionType,
                description                     = pkOld.description,
                defendPointRadius               = pkOld.defendPointRadius,
                destroyGearOnDrop               = pkOld.destroyGearOnDrop,
                disallowedTraits                = pkOld.disallowedTraits.ListFullCopyOrNull <TraitDef>(),
                ecoSystemWeight                 = pkOld.ecoSystemWeight,
                factionLeader                   = pkOld.factionLeader,
                fixedInventory                  = pkOld.fixedInventory.ListFullCopyOrNull <ThingDefCountClass>(),
                fleeHealthThresholdRange        = new FloatRange(min: pkOld.fleeHealthThresholdRange.min, max: pkOld.fleeHealthThresholdRange.max),
                forceNormalGearQuality          = pkOld.forceNormalGearQuality,
                gearHealthRange                 = new FloatRange(min: pkOld.gearHealthRange.min, max: pkOld.gearHealthRange.max),
                generated         = pkOld.generated,
                inventoryOptions  = pkOld.inventoryOptions,
                invFoodDef        = pkOld.invFoodDef,
                invNutrition      = pkOld.invNutrition,
                isFighter         = pkOld.isFighter,
                itemQuality       = pkOld.itemQuality,
                labelMale         = pkOld.labelMale,
                labelMalePlural   = pkOld.labelMalePlural,
                labelFemale       = pkOld.labelFemale,
                labelFemalePlural = pkOld.labelFemalePlural,
                labelPlural       = pkOld.labelPlural,
                lifeStages        = pkOld.lifeStages.ListFullCopyOrNull <PawnKindLifeStage>(),
                maxGenerationAge  = pkOld.maxGenerationAge,
                minGenerationAge  = pkOld.minGenerationAge,
                modContentPack    = pkOld.modContentPack,
                modExtensions     = pkOld.modExtensions,
                royalTitleChance  = pkOld.royalTitleChance,
                skills            = pkOld.skills.ListFullCopyOrNull <SkillRange>()
            };

            pk.specificApparelRequirements = pkOld.specificApparelRequirements.ListFullCopyOrNull <SpecificApparelRequirement>();
            pk.trader                  = pkOld.trader;
            pk.titleSelectOne          = pkOld.titleSelectOne.ListFullCopyOrNull <RoyalTitleDef>();
            pk.techHediffsRequired     = pkOld.techHediffsRequired.ListFullCopyOrNull <ThingDef>();
            pk.techHediffsChance       = pkOld.techHediffsChance;
            pk.techHediffsMaxAmount    = pkOld.techHediffsMaxAmount;
            pk.techHediffsMoney        = new FloatRange(min: pkOld.techHediffsMoney.min, max: pkOld.techHediffsMoney.max);
            pk.techHediffsTags         = pkOld.techHediffsTags.ListFullCopyOrNull <string>();
            pk.techHediffsDisallowTags = pkOld.techHediffsDisallowTags.ListFullCopyOrNull <string>();
            pk.weaponMoney             = new FloatRange(min: pkOld.weaponMoney.min, max: pkOld.weaponMoney.max);
            pk.weaponTags              = pkOld.weaponTags.ListFullCopyOrNull <string>();
            pk.wildGroupSize           = pkOld.wildGroupSize;
            pk.initialResistanceRange  = pkOld.initialResistanceRange.GetValueOrDefault();
            pk.initialWillRange        = pkOld.initialWillRange.GetValueOrDefault();


            switch (label)
            {
            case "Togruta":
                ThingDef_AlienRace thisRace = DefDatabase <ThingDef_AlienRace> .GetNamed("StarWarsRaces_Togruta");

                pk.race = thisRace;
                pk.apparelAllowHeadgearChance = 0f;
                break;

            default:
                ThingDef_AlienRace newRace = DefDatabase <ThingDef_AlienRace> .GetNamed("StarWarsRaces_" + label);

                pk.race = newRace;
                break;
            }
            DefDatabase <PawnKindDef> .Add(pk);
        }
예제 #21
0
        public static AlienRace InitializeAlienRace(ThingDef_AlienRace raceDef, Pawn p)
        {
            ThingDef_AlienRace.AlienSettings race = raceDef.alienRace;
            GeneralSettings    generalSettings    = race?.generalSettings;
            AlienPartGenerator alienPartGenerator = generalSettings?.alienPartGenerator;

            if (alienPartGenerator == null)
            {
                return(null);
            }

            List <GraphicPaths> graphicsPaths = race.graphicPaths;

            if (graphicsPaths == null)
            {
                return(null);
            }

            // We have enough to start putting together the result object, so we instantiate it now.
            AlienRace result = new AlienRace();

            // Get the list of body types.
            List <BodyTypeDef> alienbodytypes = alienPartGenerator.alienbodytypes;

            if (alienbodytypes == null)
            {
                return(null);
            }

            List <BodyTypeDef> bodyTypes = new List <BodyTypeDef>();

            if (alienbodytypes.Count > 0)
            {
                foreach (BodyTypeDef o in alienbodytypes)
                {
                    bodyTypes.Add(o);
                }
            }

            result.BodyTypes = bodyTypes;

            // Determine if the alien races uses gender-specific heads.
            result.GenderSpecificHeads = alienPartGenerator.useGenderedHeads;

            result.CrownTypes = alienPartGenerator.aliencrowntypes;

            // Go through the graphics paths and find the heads path.
            string graphicsPathForHeads = null;

            foreach (GraphicPaths graphicsPath in graphicsPaths)
            {
                ICollection lifeStageCollection = GetFieldValueAsCollection(raceDef, graphicsPath, "lifeStageDefs");
                if (lifeStageCollection == null || lifeStageCollection.Count == 0)
                {
                    string path = GetFieldValueAsString(raceDef, graphicsPath, "head");
                    if (path != null)
                    {
                        graphicsPathForHeads = path;
                        break;
                    }
                }
            }

            result.GraphicsPathForHeads = graphicsPathForHeads;

            // Figure out colors.
            ColorGenerator primaryGenerator = alienPartGenerator.alienskincolorgen;

            result.UseMelaninLevels = true;
            if (primaryGenerator != null)
            {
                result.UseMelaninLevels = false;
                result.PrimaryColors    = primaryGenerator.GetColorList();
            }
            else
            {
                result.PrimaryColors = new List <Color>();
            }

            ColorGenerator secondaryGenerator = alienPartGenerator.alienskinsecondcolorgen;

            result.HasSecondaryColor = false;
            if (secondaryGenerator != null)
            {
                result.HasSecondaryColor = true;
                result.SecondaryColors   = secondaryGenerator.GetColorList();
            }
            else
            {
                result.SecondaryColors = new List <Color>();
            }

            // Hair properties.
            HairSettings hairSettings = race.hairSettings;

            result.HasHair = false;
            if (hairSettings != null)
            {
                result.HasHair = hairSettings.hasHair;

                if (hairSettings.hairTags.NullOrEmpty())
                {
                    result.HairTags = p.kindDef.defaultFactionType.hairTags;
                }
                else
                {
                    result.HairTags = hairSettings.hairTags;
                }
            }

            ColorGenerator hairColorGenerator = alienPartGenerator.alienhaircolorgen;

            if (hairColorGenerator != null)
            {
                result.HairColors = primaryGenerator.GetColorList();
            }
            else
            {
                result.HairColors = null;
            }

            return(result);
        }
예제 #22
0
        public static bool AlienCorpseHasOrganicFlesh(ThingDef def)
        {
            ThingDef_AlienRace corpseAlienRace = ThingDef.Named(def.ToString().Substring("Corpse_".Length)) as ThingDef_AlienRace;

            return(!corpseAlienRace.alienRace.compatibility.IsFlesh);
        }
예제 #23
0
        public static bool DrawEquipmentAimingModded(Thing eq, Vector3 drawLoc, float aimAngle)
        {
            Pawn pawn;
            ThingDef_AlienRace alienRaceDef = HarmonyPatches.AlienDefFor(eq, out pawn);

            if (alienRaceDef != null)
            {
                switch (pawn.Rotation.AsInt)
                {
                case 1:
                {
                    drawLoc.x += (alienRaceDef.alienRace.generalSettings.alienPartGenerator.CustomDrawSize.x - 1);
                    break;
                }

                case 2:
                {
                    drawLoc.z -= (alienRaceDef.alienRace.generalSettings.alienPartGenerator.CustomDrawSize.x - 1);
                    break;
                }

                case 3:
                {
                    drawLoc.x -= (alienRaceDef.alienRace.generalSettings.alienPartGenerator.CustomDrawSize.x - 1);
                    break;
                }
                }
            }

            float num = aimAngle - 90f;
            Mesh  mesh;

            if (aimAngle > 20f && aimAngle < 160f)
            {
                mesh = MeshPool.plane10;
                num += eq.def.equippedAngleOffset;
            }
            else if (aimAngle > 200f && aimAngle < 340f)
            {
                mesh = MeshPool.plane10Flip;
                num -= 180f;
                num -= eq.def.equippedAngleOffset;
            }
            else
            {
                mesh = MeshPool.plane10;
                num += eq.def.equippedAngleOffset;
            }
            num %= 360f;
            Graphic_StackCount graphic_StackCount = eq.Graphic as Graphic_StackCount;
            Material           matSingle;

            if (graphic_StackCount != null)
            {
                matSingle = graphic_StackCount.SubGraphicForStackCount(1, eq.def).MatSingle;
            }
            else
            {
                matSingle = eq.Graphic.MatSingle;
            }

            if (eq.GetType() == typeof(FactionItem))
            {
                FactionItemDef facdef    = eq.def as FactionItemDef;
                float          scalePawn = alienRaceDef != null ? alienRaceDef.alienRace.generalSettings.alienPartGenerator.CustomDrawSize.x : 1f;
                Vector3        scale     = facdef.ItemMeshSize * scalePawn;
                Material       Mat       = eq.Graphic.MatAt(eq.Rotation);
                Matrix4x4      matrix    = default(Matrix4x4);
                matrix.SetTRS(drawLoc, Quaternion.AngleAxis(num, Vector3.up), scale * 1.2f);
                Graphics.DrawMesh(mesh, matrix, matSingle, 0);

                //                Matrix4x4 matrix = default(Matrix4x4);
                //                matrix.SetTRS(drawLoc, Quaternion.AngleAxis(num, Vector3.up), facdef.ItemMeshSize);
                //                Graphics.DrawMesh(mesh, matrix, matSingle, 0);
                //               Graphics.DrawMesh()
            }

            else
            {
                Graphics.DrawMesh(mesh, drawLoc, Quaternion.AngleAxis(num, Vector3.up), matSingle, 0);
            }

            return(false);
        }
예제 #24
0
 private static ThingDef_AlienRace.AlienSettings GenerateHybridAlienSettings(ThingDef_AlienRace.AlienSettings human, MorphDef morph, ThingDef_AlienRace impliedRace)
 {
     return(new ThingDef_AlienRace.AlienSettings
     {
         generalSettings = GenerateHybridGeneralSettings(human.generalSettings, morph, impliedRace),
         graphicPaths = GenerateGraphicPaths(human.graphicPaths, morph),
         hairSettings = human.hairSettings,
         raceRestriction = GenerateHybridRestrictionSettings(human.raceRestriction, morph),
         relationSettings = human.relationSettings,
         thoughtSettings = morph.raceSettings.GenerateThoughtSettings(human.thoughtSettings, morph)
     });
 }
예제 #25
0
        private static AlienPartGenerator GenerateHybridGenerator(AlienPartGenerator human, MorphDef morph, ThingDef_AlienRace impliedRace)
        {
            AlienPartGenerator gen = new AlienPartGenerator
            {
                alienbodytypes  = human.alienbodytypes.MakeSafe().ToList(),
                aliencrowntypes = human.aliencrowntypes.MakeSafe().ToList(),
                bodyAddons      = GenerateBodyAddons(human.bodyAddons, morph),
                alienProps      = impliedRace
            };

            return(gen);
        }
예제 #26
0
        private static void RenderPawnInternal(PawnRenderer __instance, Vector3 rootLoc, Quaternion quat, bool renderBody, Rot4 bodyFacing, Rot4 headFacing, RotDrawMode bodyDrawType = RotDrawMode.Fresh, bool portrait = false)
        {
            Pawn pawn = Traverse.Create(__instance).Field("pawn").GetValue <Pawn>();

            if (!pawn.def.race.Humanlike)
            {
                return;
            }

            Corruption.CompPsyker         compPsyker     = pawn.TryGetComp <CompPsyker>();
            List <HediffComp_DrawImplant> implantDrawers = HarmonyPatches.implantDrawers(pawn);
            string patronName = "Emperor";
            bool   drawChaos  = false;

            if (compPsyker != null)
            {
                patronName = compPsyker.patronName;
                //        Log.Message("GettingComp: " + patronName);
                if (patronName == "Khorne" || patronName == "Nurgle" || patronName == "Tzeentch" || patronName == "Undivided")
                {
                    //            Log.Message("drawChaos");
                    drawChaos = true;
                }
            }

            if (!__instance.graphics.AllResolved)
            {
                __instance.graphics.ResolveAllGraphics();
            }
            Mesh mesh = null;

            if (renderBody)
            {
                Vector3 loc = rootLoc;
                loc.y += 0.005f;
                if (bodyDrawType == RotDrawMode.Dessicated && !pawn.RaceProps.Humanlike && __instance.graphics.dessicatedGraphic != null && !portrait)
                {
                    __instance.graphics.dessicatedGraphic.Draw(loc, bodyFacing, pawn);
                }
                else
                {
                    ThingDef_AlienRace alienDef = pawn.def as ThingDef_AlienRace;
                    if (alienDef != null)
                    {
                        Mesh mesh2;
                        if (bodyDrawType == RotDrawMode.Rotting)
                        {
                            if (__instance.graphics.dessicatedGraphic.ShouldDrawRotated)
                            {
                                mesh2 = MeshPool.GridPlane(portrait ? alienDef.alienRace.generalSettings.alienPartGenerator.CustomPortraitDrawSize : alienDef.alienRace.generalSettings.alienPartGenerator.CustomDrawSize);
                            }
                            else
                            {
                                Vector2 size = portrait ? alienDef.alienRace.generalSettings.alienPartGenerator.CustomPortraitDrawSize : alienDef.alienRace.generalSettings.alienPartGenerator.CustomDrawSize;
                                if (bodyFacing.IsHorizontal)
                                {
                                    size = size.Rotated();
                                }
                                if (bodyFacing == Rot4.West && (__instance.graphics.dessicatedGraphic.data == null || __instance.graphics.dessicatedGraphic.data.allowFlip))
                                {
                                    mesh = MeshPool.GridPlaneFlip(size);
                                }
                                mesh = MeshPool.GridPlane(size);
                            }
                        }
                        else
                        {
                            mesh = (portrait ? alienDef.alienRace.generalSettings.alienPartGenerator.bodyPortraitSet.MeshAt(bodyFacing) : alienDef.alienRace.generalSettings.alienPartGenerator.bodySet.MeshAt(bodyFacing));
                        }
                    }
                    else
                    {
                        if (pawn.RaceProps.Humanlike)
                        {
                            mesh = MeshPool.humanlikeBodySet.MeshAt(bodyFacing);
                        }
                        else
                        {
                            mesh = __instance.graphics.nakedGraphic.MeshAt(bodyFacing);
                        }
                    }
                    List <Material> list = __instance.graphics.MatsBodyBaseAt(bodyFacing, bodyDrawType);
                    for (int i = 0; i < list.Count; i++)
                    {
                        //               Material damagedMat = __instance.graphics.flasher.GetDamagedMat(list[i]);
                        //               GenDraw.DrawMeshNowOrLater(mesh, loc, quat, damagedMat, portrait);
                        loc.y += 0.005f;
                        if (i == 0)
                        {
                            if (drawChaos)
                            {
                                Material markMat = (Corruption.AfflictionDrawerUtility.GetBodyOverlay(pawn.story.bodyType, patronName).MatAt(bodyFacing));
                                if (pawn.ageTracker.CurLifeStageIndex == 2 && pawn.RaceProps.Humanlike)
                                {
                                    markMat.mainTextureScale  = new Vector2(1, 1.3f);
                                    markMat.mainTextureOffset = new Vector2(0, -0.2f);
                                    if (bodyFacing == Rot4.West || bodyFacing == Rot4.East)
                                    {
                                        markMat.mainTextureOffset = new Vector2(-0.015f, -0.2f);
                                    }
                                }
                                GenDraw.DrawMeshNowOrLater(mesh, loc, quat, markMat, portrait);
                                loc.y += 0.005f;
                            }
                        }

                        if (bodyDrawType == RotDrawMode.Fresh)
                        {
                            Vector3 drawLoc = rootLoc;
                            drawLoc.y += 0.02f;
                            //                    Traverse.Create(__instance).Field("woundOverlays").GetValue<PawnWoundDrawer>().RenderOverBody(drawLoc, mesh, quat, portrait);
                        }
                    }
                }
                Vector3 vector = rootLoc;
                Vector3 a      = rootLoc;
                if (bodyFacing != Rot4.North)
                {
                    a.y      += 0.03f;
                    vector.y += 0.0249999985f;
                }
                else
                {
                    a.y      += 0.0249999985f;
                    vector.y += 0.03f;
                }
                if (__instance.graphics.headGraphic != null)
                {
                    Vector3  b     = quat * __instance.BaseHeadOffsetAt(headFacing);
                    Mesh     mesh2 = MeshPool.humanlikeHeadSet.MeshAt(headFacing);
                    Material mat   = __instance.graphics.HeadMatAt(headFacing, bodyDrawType);
                    //            GenDraw.DrawMeshNowOrLater(mesh2, a + b, quat, mat, portrait);
                    if (drawChaos)
                    {
                        Material headMarkMat = (AfflictionDrawerUtility.GetHeadGraphic(pawn, patronName).MatAt(bodyFacing));
                        //   vector.y += 0.005f;
                        GenDraw.DrawMeshNowOrLater(mesh2, a + b + new Vector3(0f, 0.004f, 0f), quat, headMarkMat, portrait);
                    }

                    Vector3 loc2 = rootLoc + b;
                    loc2.y += 0.035f;
                    bool flag  = false;
                    Mesh mesh3 = __instance.graphics.HairMeshSet.MeshAt(headFacing);
                    List <ApparelGraphicRecord> apparelGraphics = __instance.graphics.apparelGraphics;
                    for (int j = 0; j < apparelGraphics.Count; j++)
                    {
                        if (apparelGraphics[j].sourceApparel.def.apparel.LastLayer == ApparelLayer.Overhead)
                        {
                            flag = true;
                            Material material = apparelGraphics[j].graphic.MatAt(bodyFacing, null);
                            material = __instance.graphics.flasher.GetDamagedMat(material);
                            //               GenDraw.DrawMeshNowOrLater(mesh3, loc2, quat, material, portrait);
                        }

                        if (!flag && bodyDrawType != RotDrawMode.Dessicated)
                        {
                            Mesh     mesh4 = __instance.graphics.HairMeshSet.MeshAt(headFacing);
                            Material mat2  = __instance.graphics.HairMatAt(headFacing);
                            //                   GenDraw.DrawMeshNowOrLater(mesh4, loc2, quat, mat2, portrait);
                        }
                    }
                    if (renderBody)
                    {
                        for (int k = 0; k < __instance.graphics.apparelGraphics.Count; k++)
                        {
                            Material pauldronMat;
                            if (CompPauldronDrawer.ShouldDrawPauldron(pawn, __instance.graphics.apparelGraphics[k].sourceApparel, bodyFacing, out pauldronMat))
                            {
                                if (pawn.ageTracker.CurLifeStageIndex == 2)
                                {
                                    pauldronMat.mainTextureScale  = new Vector2(1.00f, 1.22f);
                                    pauldronMat.mainTextureOffset = new Vector2(0, -0.1f);
                                }
                                vector.y += 0.035f;
                                GenDraw.DrawMeshNowOrLater(mesh, vector, quat, pauldronMat, portrait);
                            }
                            ApparelGraphicRecord apparelGraphicRecord = __instance.graphics.apparelGraphics[k];
                            if (apparelGraphicRecord.sourceApparel.def.apparel.LastLayer == ApparelLayer.Shell)
                            {
                                //           Material material2 = apparelGraphicRecord.graphic.MatAt(bodyFacing, null);
                                //           material2 = __instance.graphics.flasher.GetDamagedMat(material2);
                                //           GenDraw.DrawMeshNowOrLater(mesh, vector, quat, material2, portrait);
                            }
                            if (!pawn.Dead)
                            {
                                for (int l = 0; l < pawn.health.hediffSet.hediffs.Count; l++)
                                {
                                    HediffComp_DrawImplant drawer;
                                    if ((drawer = pawn.health.hediffSet.hediffs[l].TryGetComp <HediffComp_DrawImplant>()) != null)
                                    {
                                        if (drawer.implantDrawProps.implantDrawerType != ImplantDrawerType.Head)
                                        {
                                            vector.y += 0.005f;
                                            if (bodyFacing == Rot4.South && drawer.implantDrawProps.implantDrawerType == ImplantDrawerType.Backpack)
                                            {
                                                vector.y -= 0.3f;
                                            }
                                            Material implantMat = drawer.ImplantMaterial(pawn, bodyFacing);
                                            GenDraw.DrawMeshNowOrLater(mesh, vector, quat, implantMat, portrait);
                                            vector.y += 0.005f;
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
예제 #27
0
        static AddApparelRestrictionToAlienDef()
        {
            string report = "MoharFW - AddApparelRestrictionToAlienDef";

            if (!StaticCheck.IsOk)
            {
                return;
            }

            IEnumerable <RaceRestrictionItem> restrictions = DefDatabase <ApparelBlacklistDef> .AllDefs?.SelectMany(b => b.restrictions);

            if (restrictions.EnumerableNullOrEmpty())
            {
                if (MyDebug)
                {
                    Log.Warning(report + " found no restriction.");
                }
                return;
            }

            foreach (RaceRestrictionItem cur in restrictions)
            {
                ThingDef_AlienRace MyRace = DefDatabase <ThingDef_AlienRace> .AllDefs.Where(r => r == cur.race).FirstOrFallback();

                if (MyRace == null)
                {
                    if (cur.debug)
                    {
                        Log.Warning(report + " could not find " + cur.race.defName);
                    }
                    continue;
                }

                int apparelNum = DefDatabase <ThingDef> .AllDefs.Where(td => td.IsApparel).EnumerableCount();

                IEnumerable <ThingDef> WhitelistApparels = DefDatabase <ThingDef> .AllDefs.Where(td => td.IsApparel && !td.IsBlacklistedApparel(cur));

                if (WhitelistApparels.EnumerableNullOrEmpty())
                {
                    if (cur.debug)
                    {
                        Log.Warning(report + " could not find any apparel to restrict for " + cur.race.defName);
                    }
                }

                if (MyRace.alienRace.raceRestriction == null)
                {
                    MyRace.alienRace.raceRestriction = new RaceRestrictionSettings();
                }
                if (MyRace.alienRace.raceRestriction.whiteApparelList == null)
                {
                    MyRace.alienRace.raceRestriction.whiteApparelList = new List <ThingDef>();
                }
                if (MyRace.alienRace.raceRestriction.apparelList == null)
                {
                    MyRace.alienRace.raceRestriction.apparelList = new List <ThingDef>();
                }

                if (!MyRace.alienRace.raceRestriction.onlyUseRaceRestrictedApparel)
                {
                    if (cur.debug)
                    {
                        Log.Warning(report + " " + cur.race.defName + " - had to enable onlyUseRaceRestrictedApparel");
                    }
                    MyRace.alienRace.raceRestriction.onlyUseRaceRestrictedApparel = true;
                }

                int i = 0;
                //foreach (ThingDef td in WhitelistApparels.Except(MyRace.alienRace.raceRestriction.apparelList).Union(WhitelistApparels.Except(MyRace.alienRace.raceRestriction.apparelList)))
                foreach (ThingDef td in WhitelistApparels)
                {
                    if (cur.debug)
                    {
                        Log.Warning(cur.race.defName + " adding :" + td + " to whitelist");
                    }
                    //Dictionary<ThingDef, List<ThingDef_AlienRace>> dict = myObject.GetType();

                    Dictionary <ThingDef, List <ThingDef_AlienRace> > regularDict = RaceRestrictionSettings.apparelRestrictionDict;
                    List <ThingDef_AlienRace> raceL = regularDict.TryGetValue(td);
                    if (raceL.NullOrEmpty())
                    {
                        raceL = new List <ThingDef_AlienRace>();
                    }
                    raceL.Add(MyRace);
                    RaceRestrictionSettings.apparelRestrictionDict.SetOrAdd(td, raceL);
                    //regularDict.SetOrAdd(td, raceL);

                    Dictionary <ThingDef, List <ThingDef_AlienRace> > whiteDict = RaceRestrictionSettings.apparelWhiteDict;
                    List <ThingDef_AlienRace> raceL2 = regularDict.TryGetValue(td);
                    if (raceL2.NullOrEmpty())
                    {
                        raceL2 = new List <ThingDef_AlienRace>();
                    }
                    raceL2.Add(MyRace);
                    RaceRestrictionSettings.apparelRestrictionDict.SetOrAdd(td, raceL);

                    i++;
                }

                /*
                 * foreach (ThingDef td in BlacklistApparels)
                 * {
                 *  if (cur.debug) Log.Warning(cur.race.defName + " adding :" + td + " to whitelist");
                 *
                 *  MyRace.alienRace.raceRestriction.apparelList.Add(td);
                 *  MyRace.alienRace.raceRestriction.whiteApparelList.Add(td);
                 * }
                 */

                if (cur.reportResult)
                {
                    Log.Message(report + " whitelisted " + i + " apparel" + (i > 1 ? "s" : "") + " over " + apparelNum + " for " + cur.race.defName + "(blacklisted " + (apparelNum - i) + ")");
                }
                if (cur.debug)
                {
                    IEnumerable <ThingDef> BlacklistApparels = DefDatabase <ThingDef> .AllDefs.Where(td => td.IsApparel && td.IsBlacklistedApparel(cur));

                    if (BlacklistApparels.EnumerableNullOrEmpty())
                    {
                        Log.Warning(report + " could not find any apparel to restrict for " + cur.race.defName);
                    }
                    foreach (ThingDef td in BlacklistApparels)
                    {
                        Log.Warning(td + " blacklisted");
                    }
                }
            }
        }
예제 #28
0
        /// <summary>
        /// Generate general settings for the hybrid race given the human settings and morph def.
        /// </summary>
        /// <param name="human">The human.</param>
        /// <param name="morph">The morph.</param>
        /// <param name="impliedRace">The implied race.</param>
        /// <returns></returns>
        private static GeneralSettings GenerateHybridGeneralSettings(GeneralSettings human, MorphDef morph, ThingDef_AlienRace impliedRace)
        {
            var traitSettings = morph.raceSettings.traitSettings;

            return(new GeneralSettings
            {
                alienPartGenerator = GenerateHybridGenerator(human.alienPartGenerator, morph, impliedRace),
                humanRecipeImport = true,
                forcedRaceTraitEntries = traitSettings?.forcedTraits
                                         // Black list is not currently supported, Rimworld doesn't like it when you remove traits.
            });
        }