/// <summary> /// called every tick /// </summary> public override void CompTick() { base.CompTick(); if (parent.def.GetModExtension <FormerHumanSettings>()?.neverFormerHuman == true) { Log.Error($"{nameof(CompAlwaysFormerHuman)} found on {parent.def.defName} which should never be a former human!"); triggered = true; return; } if (!triggered) { triggered = true; if (Pawn.IsFormerHuman()) { return; } bool isManhunter = Pawn.MentalStateDef == MentalStateDefOf.Manhunter || Pawn.MentalStateDef == MentalStateDefOf.ManhunterPermanent; float sL = Rand.Value; FormerHumanUtilities.MakeAnimalSapient((Pawn)parent, sL, !isManhunter); FormerHumanUtilities.NotifyRelatedPawnsFormerHuman((Pawn)parent, FormerHumanUtilities.RELATED_WILD_FORMER_HUMAN_LETTER, FormerHumanUtilities .RELATED_WILD_FORMER_HUMAN_LETTER_LABEL); } }
/// <summary> /// called after the parent thing is spawned /// </summary> /// <param name="respawningAfterLoad">if set to <c>true</c> [respawning after load].</param> public override void PostSpawnSetup(bool respawningAfterLoad) { base.PostSpawnSetup(respawningAfterLoad); if (respawningAfterLoad) { return; } RandUtilities.PushState(); if (!triggered) { triggered = true; if (CanBeFormerHuman() && Rand.RangeInclusive(0, 100) <= Props.Chance) { float sL = Rand.Value; FormerHumanUtilities.MakeAnimalSapient((Pawn)parent, sL, false); FormerHumanUtilities.NotifyRelatedPawnsFormerHuman((Pawn)parent, FormerHumanUtilities.RELATED_WILD_FORMER_HUMAN_LETTER, FormerHumanUtilities .RELATED_WILD_FORMER_HUMAN_LETTER_LABEL); _isRelatedToColonist = Pawn.IsRelatedToColonistPawn(); } } RandUtilities.PopState(); }
/// <summary> /// called after the parent thing is spawned /// </summary> /// <param name="respawningAfterLoad">if set to <c>true</c> [respawning after load].</param> public override void PostSpawnSetup(bool respawningAfterLoad) { base.PostSpawnSetup(respawningAfterLoad); if (respawningAfterLoad) { return; } if (!triggered) { triggered = true; if (Pawn.health.hediffSet.HasHediff(TfHediffDefOf.TransformedHuman)) { return; } float sL = Rand.Value; FormerHumanUtilities.MakeAnimalSapient((Pawn)parent, sL, false); FormerHumanUtilities.NotifyRelatedPawnsFormerHuman((Pawn)parent, FormerHumanUtilities.RELATED_WILD_FORMER_HUMAN_LETTER, FormerHumanUtilities .RELATED_WILD_FORMER_HUMAN_LETTER_LABEL); } }
/// <summary> /// called after the parent thing is spawned /// </summary> /// <param name="respawningAfterLoad">if set to <c>true</c> [respawning after load].</param> public override void PostSpawnSetup(bool respawningAfterLoad) { base.PostSpawnSetup(respawningAfterLoad); if (respawningAfterLoad) { return; } if (parent.def.GetModExtension <FormerHumanSettings>()?.neverFormerHuman == true) { Log.Error($"{nameof(CompAlwaysFormerHuman)} found on {parent.def.defName} which should never be a former human!"); triggered = true; return; } if (!triggered) { triggered = true; if (Pawn.IsFormerHuman()) { return; } float sL = Rand.Value; FormerHumanUtilities.MakeAnimalSapient((Pawn)parent, sL, false); FormerHumanUtilities.NotifyRelatedPawnsFormerHuman((Pawn)parent, FormerHumanUtilities.RELATED_WILD_FORMER_HUMAN_LETTER, FormerHumanUtilities .RELATED_WILD_FORMER_HUMAN_LETTER_LABEL); } }
/// <summary> /// Tries the execute worker. /// </summary> /// <param name="parms">The parms.</param> /// <returns></returns> protected override bool TryExecuteWorker(IncidentParms parms) { var map = (Map)parms.target; if (!RCellFinder.TryFindRandomPawnEntryCell(out IntVec3 result, map, CellFinder.EdgeRoadChance_Animal)) { return(false); } PawnKindDef kind = PMPawnKindDefOf.Sheep; IntVec3 loc = CellFinder.RandomClosewalkCellNear(result, map, 12); Pawn pawn = PawnGenerator.GeneratePawn(kind); GenSpawn.Spawn(pawn, loc, map, Rot4.Random); pawn.SetFaction(Faction.OfPlayer); var oPawn = GenerateGordon(pawn); FormerHumanUtilities.MakeAnimalSapient(oPawn, pawn); if (pawn.story != null) { pawn.story.adulthood = PMBackstoryDefOf.PM_SheepChef.backstory; } if (pawn.skills != null) { var record = pawn.skills.GetSkill(SkillDefOf.Cooking); record.passion = Passion.Major; record.Level = Mathf.Max(5, record.Level); } SendStandardLetter("PMSheepChefLetterLabel".Translate(kind.label).CapitalizeFirst(), "PMSheepChefLetter".Translate(kind.label), LetterDefOf.PositiveEvent, parms, new TargetInfo(result, map)); var wComp = Find.World.GetComponent <PawnmorphGameComp>(); wComp.sheepChefEventFired = true; var pm = TfSys.TransformedPawn.Create(oPawn, pawn); Find.World.GetComponent <PawnmorphGameComp>().AddTransformedPawn(pm); return(true); }
static void MakeAnimalFormerHuman(Pawn pawn) { if (pawn == null) { return; } if (pawn.GetSapienceState() != null) { return; } if (!pawn.RaceProps.Animal) { return; } FormerHumanUtilities.MakeAnimalSapient(pawn, Rand.Range(0.1f, 1f)); }
static void MakeAnimalSapientFormerHuman(Pawn pawn) { if (pawn == null) { return; } if (pawn.IsFormerHuman()) { return; } if (!pawn.RaceProps.Animal) { return; } FormerHumanUtilities.MakeAnimalSapient(pawn); }
/// <summary> /// called every tick /// </summary> public override void CompTick() { base.CompTick(); if (!triggered) { triggered = true; if (CanBeFormerHuman() && Rand.RangeInclusive(0, 100) <= Props.Chance) { float sL = Rand.Value; FormerHumanUtilities.MakeAnimalSapient((Pawn)parent, sL); FormerHumanUtilities.NotifyRelatedPawnsFormerHuman((Pawn)parent, FormerHumanUtilities.RELATED_WILD_FORMER_HUMAN_LETTER, FormerHumanUtilities .RELATED_WILD_FORMER_HUMAN_LETTER_LABEL); _isRelatedToColonist = Pawn.IsRelatedToColonistPawn(); } } }
IEnumerable <Thing> GenerateThingEnumer(int forTile, Faction forFaction) { int numKinds = kindCountRange.RandomInRange; int count = countRange.RandomInRange; List <PawnKindDef> kinds = new List <PawnKindDef>(); for (int j = 0; j < numKinds; j++) { if (!(from k in DefDatabase <PawnKindDef> .AllDefs where !kinds.Contains(k) && PawnKindAllowed(k, forTile) select k).TryRandomElementByWeight((PawnKindDef k) => SelectionChance(k), out PawnKindDef result)) { break; } kinds.Add(result); } for (int i = 0; i < count; i++) { if (!kinds.TryRandomElement(out PawnKindDef kind)) { break; } PawnKindDef kind2 = kind; int tile = forTile; Pawn pawnOriginal = Find.WorldPawns.AllPawnsAlive.Where(p => !p.IsPlayerControlledCaravanMember() && (PawnUtility.ForSaleBySettlement(p) || p.kindDef == PawnKindDefOf.Slave || (PawnUtility.IsKidnappedPawn(p) && p.RaceProps.Humanlike) && !PawnUtility.IsFactionLeader(p))).RandomElement(); PawnGenerationRequest request = new PawnGenerationRequest(kind2, null, PawnGenerationContext.NonPlayer, tile); Pawn pawn = PawnGenerator.GeneratePawn(request); //Generate the animal! if (pawnOriginal == null) { Gender newGender = pawn.gender; if (Rand.RangeInclusive(0, 100) <= 25) { switch (pawn.gender) { case (Gender.Male): newGender = Gender.Female; break; case (Gender.Female): newGender = Gender.Male; break; default: break; } } float animalAge = pawn.ageTracker.AgeBiologicalYearsFloat; float animalLifeExpectancy = pawn.def.race.lifeExpectancy; float humanLifeExpectancy = 80f; float age = animalAge * humanLifeExpectancy / animalLifeExpectancy; age = Mathf.Max(age, 17); //make sure the human is at least 17 years old float chronoAge = pawn.ageTracker.AgeChronologicalYears * age / animalAge; var pkds = new List <PawnKindDef> { PawnKindDefOf.Slave, PawnKindDefOf.Colonist, PawnKindDefOf.SpaceRefugee, PawnKindDefOf.Villager, PawnKindDefOf.Drifter, PawnKindDefOf.AncientSoldier }; PawnKindDef rKind = pkds.RandElement(); var hRequest = new PawnGenerationRequest(rKind, Faction.OfPlayer, PawnGenerationContext.NonPlayer, fixedBiologicalAge: age, fixedChronologicalAge: chronoAge, fixedGender: newGender); pawnOriginal = PawnGenerator.GeneratePawn(hRequest); pawn.Name = pawnOriginal.Name; } else { pawn.Name = pawnOriginal.Name; Find.WorldPawns.RemovePawn(pawnOriginal); } var pm = TfSys.TransformedPawn.Create(pawnOriginal, pawn); //pawnOriginal is human, pawn is animal FormerHumanUtilities.MakeAnimalSapient(pawnOriginal, pawn, Rand.Range(0.5f, 1f)); Find.World.GetComponent <PawnmorphGameComp>().AddTransformedPawn(pm); yield return(pawn); } }
/// <summary> /// preform the requested transform /// </summary> /// <param name="request">The request.</param> /// <returns></returns> protected override TransformedPawnSingle TransformImpl(TransformationRequest request) { Pawn original = request.originals[0]; if (request.addMutationToOriginal) { TryAddMutationsToPawn(original, request.cause, request.outputDef); } var reactionStatus = original.GetFormerHumanReactionStatus(); float newAge = TransformerUtility.ConvertAge(original, request.outputDef.race.race); Faction faction; if (request.forcedFaction != null) //forced faction should be the highest priority if set { faction = request.forcedFaction; } else if (original.IsColonist) { faction = original.Faction; } else { faction = null; } Gender newGender = TransformerUtility.GetTransformedGender(original, request.forcedGender, request.forcedGenderChance); var pRequest = FormerHumanUtilities.CreateSapientAnimalRequest(request.outputDef, original, faction, fixedGender: newGender); Pawn animalToSpawn = PawnGenerator.GeneratePawn(pRequest); //make the temp pawn animalToSpawn.needs.food.CurLevel = original.needs.food.CurLevel; // Copies the original pawn's food need to the animal's. animalToSpawn.needs.rest.CurLevel = original.needs.rest.CurLevel; // Copies the original pawn's rest need to the animal's. animalToSpawn.Name = original.Name; // Copies the original pawn's name to the animal's. FormerHumanUtilities.MakeAnimalSapient(original, animalToSpawn, Rand.Range(0.4f, 1)); //use a normal distribution? Pawn spawnedAnimal = SpawnAnimal(original, animalToSpawn); // Spawns the animal into the map. ReactionsHelper.OnPawnTransforms(original, animalToSpawn, reactionStatus); //this needs to happen before MakeSapientAnimal because that removes relations var rFaction = request.factionResponsible ?? GetFactionResponsible(original); var inst = new TransformedPawnSingle { original = original, animal = spawnedAnimal, factionResponsible = rFaction, reactionStatus = reactionStatus }; if (original.Spawned) { for (var i = 0; i < 10; i++) // Create a cloud of magic. { IntermittentMagicSprayer.ThrowMagicPuffDown(spawnedAnimal.Position.ToVector3(), spawnedAnimal.MapHeld); IntermittentMagicSprayer.ThrowMagicPuffUp(spawnedAnimal.Position.ToVector3(), spawnedAnimal.MapHeld); } } if (request.tale != null) // If a tale was provided, push it to the tale recorder. { TaleRecorder.RecordTale(request.tale, original, animalToSpawn); } Faction oFaction = original.Faction; Map oMap = original.Map; //apply any other post tf effects ApplyPostTfEffects(original, spawnedAnimal); TransformerUtility .CleanUpHumanPawnPostTf(original, request.cause); //now clean up the original pawn (remove apparel, drop'em, ect) //notify the faction that their member has been transformed oFaction?.Notify_MemberTransformed(original, spawnedAnimal, oMap == null, oMap); if (!request.noLetter && reactionStatus == FormerHumanReactionStatus.Colonist || reactionStatus == FormerHumanReactionStatus.Prisoner) //only send the letter for colonists and prisoners { SendLetter(request, original, spawnedAnimal); } if (original.Spawned) { original.DeSpawn(); // Remove the original pawn from the current map. } DebugLogUtils.Assert(!PrisonBreakUtility.CanParticipateInPrisonBreak(original), $"{original.Name} has been cleaned up and de-spawned but can still participate in prison breaks"); return(inst); }