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); } }
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); }
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); }
public static AlienPartGenerator GetPartGenerator([NotNull] this ThingDef_AlienRace alienRace) { if (alienRace == null) { throw new ArgumentNullException(nameof(alienRace)); } return(alienRace.alienRace?.generalSettings?.alienPartGenerator); }
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"); } }
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); }
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); }
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 } } } }
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); }
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); }
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); } }
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); }
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; }
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); } } } }
public static bool AlienRaceHasOrganicFlesh(Pawn pawn) { ThingDef_AlienRace raceDef = pawn.def as ThingDef_AlienRace; return(raceDef?.alienRace.compatibility.IsFlesh ?? true); }
/// <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(); } }
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; } }
// 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(); } } } }
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); }
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); }
public static bool AlienCorpseHasOrganicFlesh(ThingDef def) { ThingDef_AlienRace corpseAlienRace = ThingDef.Named(def.ToString().Substring("Corpse_".Length)) as ThingDef_AlienRace; return(!corpseAlienRace.alienRace.compatibility.IsFlesh); }
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); }
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) }); }
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); }
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; } } } } } } } } }
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"); } } } }
/// <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. }); }