/// <summary> Executed every time the pawn is updated </summary> public override void TickRare() { base.TickRare(); if (pather == null) { return; // this can occur if the pawn leaves the map area } if (ageTracker == null) { return; } if (Prefs.DevMode) { Log.Message($"setup replacements"); } // initialize the replacements (once per lifestage) if (lifeStageBefore != ageTracker.CurKindLifeStage) { SetupReplacements(); lifeStageBefore = ageTracker.CurKindLifeStage; } if (Prefs.DevMode) { Log.Message($"updating gfx"); } UpdateActiveGraphic(); }
public void ResolveAllGraphics() { ClearCache(); if (pawn.RaceProps.Humanlike) { nakedGraphic = GraphicDatabase.Get <Graphic_Multi>(pawn.story.bodyType.bodyNakedGraphicPath, ShaderDatabase.CutoutSkin, Vector2.one, pawn.story.SkinColor); rottingGraphic = GraphicDatabase.Get <Graphic_Multi>(pawn.story.bodyType.bodyNakedGraphicPath, ShaderDatabase.CutoutSkin, Vector2.one, RottingColor); dessicatedGraphic = GraphicDatabase.Get <Graphic_Multi>(pawn.story.bodyType.bodyDessicatedGraphicPath, ShaderDatabase.Cutout); headGraphic = GraphicDatabaseHeadRecords.GetHeadNamed(pawn.story.HeadGraphicPath, pawn.story.SkinColor); desiccatedHeadGraphic = GraphicDatabaseHeadRecords.GetHeadNamed(pawn.story.HeadGraphicPath, RottingColor); skullGraphic = GraphicDatabaseHeadRecords.GetSkull(); headStumpGraphic = GraphicDatabaseHeadRecords.GetStump(pawn.story.SkinColor); desiccatedHeadStumpGraphic = GraphicDatabaseHeadRecords.GetStump(RottingColor); hairGraphic = GraphicDatabase.Get <Graphic_Multi>(pawn.story.hairDef.texPath, ShaderDatabase.Cutout, Vector2.one, pawn.story.hairColor); ResolveApparelGraphics(); return; } PawnKindLifeStage curKindLifeStage = pawn.ageTracker.CurKindLifeStage; if (pawn.gender != Gender.Female || curKindLifeStage.femaleGraphicData == null) { nakedGraphic = curKindLifeStage.bodyGraphicData.Graphic; } else { nakedGraphic = curKindLifeStage.femaleGraphicData.Graphic; } if (pawn.RaceProps.packAnimal) { packGraphic = GraphicDatabase.Get <Graphic_Multi>(nakedGraphic.path + "Pack", ShaderDatabase.Cutout, nakedGraphic.drawSize, Color.white); } rottingGraphic = nakedGraphic.GetColoredVersion(ShaderDatabase.CutoutSkin, RottingColor, RottingColor); if (curKindLifeStage.dessicatedBodyGraphicData != null) { if (pawn.gender != Gender.Female || curKindLifeStage.femaleDessicatedBodyGraphicData == null) { dessicatedGraphic = curKindLifeStage.dessicatedBodyGraphicData.GraphicColoredFor(pawn); } else { dessicatedGraphic = curKindLifeStage.femaleDessicatedBodyGraphicData.GraphicColoredFor(pawn); } } if (!pawn.kindDef.alternateGraphics.NullOrEmpty()) { Rand.PushState(pawn.thingIDNumber ^ 0xB415); if (Rand.Value <= pawn.kindDef.alternateGraphicChance) { nakedGraphic = pawn.kindDef.alternateGraphics.RandomElementByWeight((AlternateGraphic x) => x.Weight).GetGraphic(nakedGraphic); } Rand.PopState(); } }
public void ResolveAllGraphics() { this.ClearCache(); if (this.pawn.RaceProps.Humanlike) { this.nakedGraphic = GraphicDatabase.Get <Graphic_Multi>(this.pawn.story.bodyType.bodyNakedGraphicPath, ShaderDatabase.CutoutSkin, Vector2.one, this.pawn.story.SkinColor); this.rottingGraphic = GraphicDatabase.Get <Graphic_Multi>(this.pawn.story.bodyType.bodyNakedGraphicPath, ShaderDatabase.CutoutSkin, Vector2.one, PawnGraphicSet.RottingColor); this.dessicatedGraphic = GraphicDatabase.Get <Graphic_Multi>(this.pawn.story.bodyType.bodyDessicatedGraphicPath, ShaderDatabase.Cutout); this.headGraphic = GraphicDatabaseHeadRecords.GetHeadNamed(this.pawn.story.HeadGraphicPath, this.pawn.story.SkinColor); this.desiccatedHeadGraphic = GraphicDatabaseHeadRecords.GetHeadNamed(this.pawn.story.HeadGraphicPath, PawnGraphicSet.RottingColor); this.skullGraphic = GraphicDatabaseHeadRecords.GetSkull(); this.headStumpGraphic = GraphicDatabaseHeadRecords.GetStump(this.pawn.story.SkinColor); this.desiccatedHeadStumpGraphic = GraphicDatabaseHeadRecords.GetStump(PawnGraphicSet.RottingColor); this.hairGraphic = GraphicDatabase.Get <Graphic_Multi>(this.pawn.story.hairDef.texPath, ShaderDatabase.Cutout, Vector2.one, this.pawn.story.hairColor); this.ResolveApparelGraphics(); } else { PawnKindLifeStage curKindLifeStage = this.pawn.ageTracker.CurKindLifeStage; if (this.pawn.gender != Gender.Female || curKindLifeStage.femaleGraphicData == null) { this.nakedGraphic = curKindLifeStage.bodyGraphicData.Graphic; } else { this.nakedGraphic = curKindLifeStage.femaleGraphicData.Graphic; } this.rottingGraphic = this.nakedGraphic.GetColoredVersion(ShaderDatabase.CutoutSkin, PawnGraphicSet.RottingColor, PawnGraphicSet.RottingColor); if (this.pawn.RaceProps.packAnimal) { this.packGraphic = GraphicDatabase.Get <Graphic_Multi>(this.nakedGraphic.path + "Pack", ShaderDatabase.Cutout, this.nakedGraphic.drawSize, Color.white); } if (curKindLifeStage.dessicatedBodyGraphicData != null) { if (this.pawn.gender != Gender.Female || curKindLifeStage.femaleDessicatedBodyGraphicData == null) { this.dessicatedGraphic = curKindLifeStage.dessicatedBodyGraphicData.GraphicColoredFor(this.pawn); } else { this.dessicatedGraphic = curKindLifeStage.femaleDessicatedBodyGraphicData.GraphicColoredFor(this.pawn); } } } }
/// <summary> Update the graphic if the life stage changed and swap the body graphic if moving </summary> public override void Tick() { base.Tick(); if (GenTicks.TicksAbs % Frameskip != FrameskipOffset) { return; // frameskip } if (!Spawned) { return; } if (Destroyed) { return; } if (pather == null) { return; // this can occur if the pawn leaves the map area } if (Drawer?.renderer == null) { return; } // initialize the replacement graphics (once per lifestage) if (lifeStageBefore != ageTracker.CurKindLifeStage) { SetupReplacements(); lifeStageBefore = ageTracker.CurKindLifeStage; } // avoid hunting tamed animals, accept non-ideal food instead if (Faction != Faction.OfPlayer && jobs?.curJob?.def == JobDefOf.PredatorHunt) { if ((jobs.curJob.targetA.Thing as Pawn)?.Faction == Faction.OfPlayer) { jobs.StopAll(); // stop predator hunt job if (needs.food.TicksStarving < 30000) { // find food var food = GenClosest.ClosestThingReachable(Position, Map, ThingRequest.ForGroup(ThingRequestGroup.HaulableAlways), AI.PathEndMode.OnCell, TraverseParms.For(this, Danger.Deadly, TraverseMode.ByPawn, false), maxDistance: 100f, validator: (thing) => thing.def.category == ThingCategory.Item && thing.def.IsNutritionGivingIngestible /*&& RaceProps.CanEverEat(thing)*/, // omit food preferences customGlobalSearchSet: null, searchRegionsMax: -1, forceAllowGlobalSearch: false); if (food != null) { // try to find other food jobs.StartJob(new AI.Job(JobDefOf.Ingest, food)); } else { // wander until food is found or too starving to continue StartJobWander(); } } else // if desperate { IntVec3 exit_dest; if (RCellFinder.TryFindBestExitSpot(this, out exit_dest, TraverseMode.ByPawn)) { // exit map jobs.StartJob(new AI.Job(JobDefOf.Goto, exit_dest) { exitMapOnArrival = true }); } else { // fallback to wandering StartJobWander(); } } } } // attempt to find a replacement graphic foreach (var replacement in replacements) { if (replacement.TryReplace(Drawer.renderer)) { break; // break on first successful replacement } } }