/// <summary> /// Transfers the relations from pawn1 to pawn2 /// </summary> /// <param name="pawn1">The original.</param> /// <param name="pawn2">The animal.</param> /// <param name="predicate">optional predicate to dictate which relations get transferred</param> public static void TransferRelations([NotNull] Pawn pawn1, [NotNull] Pawn pawn2, Predicate <DirectPawnRelation> predicate) { if (pawn1.relations == null) { return; } List <DirectPawnRelation> enumerator = pawn1.relations.DirectRelations.MakeSafe().ToList(); foreach (DirectPawnRelation directPawnRelation in enumerator.Where(d => predicate?.Invoke(d) != false)) { if (directPawnRelation.def.implied) { continue; } pawn1.relations?.RemoveDirectRelation(directPawnRelation); //make sure we remove the relations first pawn2.relations?.AddDirectRelation(directPawnRelation.def, directPawnRelation.otherPawn); //TODO restrict these to special relationships? } foreach (Pawn pRelatedPawns in pawn1.relations.PotentiallyRelatedPawns.MakeSafe().ToList() ) //make copies so we don't invalidate the enumerator mid way through { Pawn_RelationsTracker rel2 = pRelatedPawns.relations; if (rel2 == null) { continue; } foreach (DirectPawnRelation pawnRelationDef in rel2 .DirectRelations.MakeSafe() .Where(d => predicate?.Invoke(d) != false && d.otherPawn == pawn1) .ToList()) { if (pawnRelationDef.def.implied) { continue; } rel2.RemoveDirectRelation(pawnRelationDef.def, pawn1); rel2.AddDirectRelation(pawnRelationDef.def, pawn2); } } }
protected override bool TryExecuteWorker(IncidentParms parms) { Map map = parms.target as Map; Pawn closestCat = TryGetClosestCatOnMap(map); GuardianProperties guardianProps = def.GetModExtension <GuardianProperties>(); if (closestCat != null) { //Transform Cat //Generate guardian Pawn newGuardian = PawnGenerator.GeneratePawn(new PawnGenerationRequest( guardianProps.guardianDef, Faction.OfPlayer, PawnGenerationContext.NonPlayer, -1, true, false, false, false, false, true, 0f, false, true, true, false, false, false, false, false, 0, null, 0, null, null, null, null, null, closestCat.ageTracker.AgeBiologicalYears, closestCat.ageTracker.AgeChronologicalYears, closestCat.gender, null, null)); //Transfer over family trees and relations to guardian from old cat. Pawn_RelationsTracker oldRelations = closestCat.relations; Pawn_RelationsTracker newRelations = newGuardian.relations; //Transfer over relations. List <DirectPawnRelation> relationList = new List <DirectPawnRelation>(oldRelations.DirectRelations); foreach (DirectPawnRelation relation in relationList) { newRelations.AddDirectRelation(relation.def, relation.otherPawn); oldRelations.RemoveDirectRelation(relation); } //Fully train. foreach (TrainableDef trainableDef in DefDatabase <TrainableDef> .AllDefs) { for (int step = 0; step < trainableDef.steps; step++) { newGuardian.training.Train(trainableDef, null); } } //Make a new name. if (closestCat.Name != null) { if (closestCat.gender == Gender.Male) { newGuardian.Name = new NameSingle(NameGenerator.GenerateName(RulePackDef.Named("NamerAnimalGenericMale")), false); } else { newGuardian.Name = new NameSingle(NameGenerator.GenerateName(RulePackDef.Named("NamerAnimalGenericFemale")), false); } } //Dump inventory, if any. closestCat?.inventory.DropAllNearPawn(closestCat.Position); Letter letter = LetterMaker.MakeLetter("Cults_BastGuardianTransformationLabel".Translate(closestCat.Name.ToStringShort), "Cults_BastGuardianTransformationDescription".Translate(closestCat.Name.ToStringFull), LetterDefOf.PositiveEvent, new GlobalTargetInfo(newGuardian)); //Remove old cat. IntVec3 catPosition = closestCat.Position; closestCat.Destroy(DestroyMode.Vanish); //Spawn in guardian. GenSpawn.Spawn(newGuardian, catPosition, map); MoteMaker.MakePowerBeamMote(catPosition, map); Current.Game.letterStack.ReceiveLetter(letter); } return(true); }